From a37c38b8d80f9fae9711e50f446e4edc85711b7a Mon Sep 17 00:00:00 2001 From: Peter Wemm Date: Tue, 11 Mar 1997 12:09:50 +0000 Subject: [PATCH] Merge Lite2 changes (rather bigish, the dump/restore folks should check) --- sbin/dump/dump.8 | 110 ++++++++++-------- sbin/dump/dump.h | 7 +- sbin/dump/dumprmt.c | 5 +- sbin/dump/main.c | 271 ++++++++++++++++++++++++------------------- sbin/dump/tape.c | 8 +- sbin/dump/traverse.c | 11 +- 6 files changed, 230 insertions(+), 182 deletions(-) diff --git a/sbin/dump/dump.8 b/sbin/dump/dump.8 index efa6d751a310..70c25befdbf2 100644 --- a/sbin/dump/dump.8 +++ b/sbin/dump/dump.8 @@ -30,10 +30,10 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)dump.8 8.1 (Berkeley) 6/16/93 -.\" $Id$ +.\" @(#)dump.8 8.3 (Berkeley) 5/1/95 +.\" $Id: dump.8,v 1.12 1997/02/22 14:32:16 peter Exp $ .\" -.Dd June 16, 1993 +.Dd May 1, 1995 .Dt DUMP 8 .Os BSD 4 .Sh NAME @@ -41,8 +41,23 @@ .Nd filesystem backup .Sh SYNOPSIS .Nm dump -.Op Cm 0123456789BTWabcdfhnsu Op Ar argument ... -.Op Ar filesystem +.Op Fl 0123456789acnu +.Op Fl B Ar records +.Op Fl b Ar blocksize +.Op Fl d Ar density +.Op Fl f Ar file +.Op Fl h Ar level +.Op Fl s Ar feet +.Op Fl T Ar date +.Ar filesystem +.Nm dump +.Op Fl W Li \&| Fl w +.Pp +.in -\\n(iSu +(The +.Bx 4.3 +option syntax is implemented for backward compatibility, but +is not documented here.) .Sh DESCRIPTION .Nm Dump examines files @@ -51,7 +66,7 @@ and determines which files need to be backed up. These files are copied to the given disk, tape or other storage medium for safe keeping (see the -.Cm f +.Fl f option below for doing remote backups). A dump that is larger than the output medium is broken into multiple volumes. @@ -70,26 +85,26 @@ By default, the same output file name is used for each volume after prompting the operator to change media. .Pp The following options are supported by -.Nm dump: -.Bl -tag -width 4n -.It Cm 0\-9 +.Nm dump : +.Bl -tag -width Ds +.It Fl 0\-9 Dump levels. A level 0, full backup, guarantees the entire file system is copied (but see also the -.Cm h +.Fl h option below). A level number above 0, incremental backup, tells dump to copy all files new or modified since the -last dump of the same or lower level. The default -level is 9. -.It Cm B Ar records +last dump of the same or lower level. +The default level is 9. +.It Fl B Ar records The number of dump records per volume. This option overrides the calculation of tape size based on length and density. -.It Cm a +.It Fl a .Dq auto-size . Bypass all tape length considerations, and enforce writing until an end-of-media indication is returned. This fits best @@ -97,12 +112,12 @@ for most modern tape drives. Use of this option is particularly recommended when appending to an existing tape, or using a tape drive with hardware compression (where you can never be sure about the compression ratio). -.It Cm b Ar blocksize +.It Fl b Ar blocksize The number of kilobytes per dump record. -.It Cm c +.It Fl c Change the defaults for use with a cartridge tape drive, with a density of 8000 bpi, and a length of 1700 feet. -.It Cm h Ar level +.It Fl h Ar level Honor the user .Dq nodump flag @@ -112,7 +127,11 @@ only for dumps at or above the given The default honor level is 1, so that incremental backups omit such files but full backups retain them. -.It Cm f Ar file +.It Fl d Ar density +Set tape density to +.Ar density . +The default is 1600BPI. +.It Fl f Ar file Write the backup to .Ar file ; .Ar file @@ -145,11 +164,7 @@ program is .Pa /etc/rmt ; this can be overridden by the environment variable .Ev RMT . -.It Cm d Ar density -Set tape density to -.Ar density . -The default is 1600BPI. -.It Cm n +.It Fl n Whenever .Nm dump requires operator attention, @@ -157,7 +172,7 @@ notify all operators in the group .Dq operator by means similar to a .Xr wall 1 . -.It Cm s Ar feet +.It Fl s Ar feet Attempt to calculate the amount of tape needed at a particular density. If this amount is exceeded, @@ -165,7 +180,21 @@ If this amount is exceeded, prompts for a new tape. It is recommended to be a bit conservative on this option. The default tape length is 2300 feet. -.It Cm u +.ne 1i +.It Fl T Ar date +Use the specified date as the starting time for the dump +instead of the time determined from looking in +.Pa /etc/dumpdates . +The format of date is the same as that of +.Xr ctime 3 . +This option is useful for automated dump scripts that wish to +dump over a specific period of time. +The +.Fl T +option is mutually exclusive from the +.Fl u +option. +.It Fl u Update the file .Pa /etc/dumpdates after a successful dump. @@ -183,20 +212,7 @@ The file .Pa /etc/dumpdates may be edited to change any of the fields, if necessary. -.It Cm T Ar date -Use the specified date as the starting time for the dump -instead of the time determined from looking in -.Pa /etc/dumpdates . -The format of date is the same as that of -.Xr ctime 3 . -This option is useful for automated dump scripts that wish to -dump over a specific period of time. -The -.Cm T -option is mutually exclusive from the -.Cm u -option. -.It Cm W +.It Fl W .Nm Dump tells the operator what file systems need to be dumped. This information is gleaned from the files @@ -204,7 +220,7 @@ This information is gleaned from the files and .Pa /etc/fstab . The -.Cm W +.Fl W option causes .Nm dump to print out, for each file system in @@ -212,11 +228,11 @@ to print out, for each file system in the most recent dump date and level, and highlights those file systems that should be dumped. If the -.Cm W +.Fl W option is set, all other options are ignored, and .Nm dump exits immediately. -.It Cm w +.It Fl w Is like W, but prints only those filesystems which need to be dumped. .El .Pp @@ -228,7 +244,7 @@ tape write error, tape open error or disk read error (if there are more than a threshold of 32). In addition to alerting all operators implied by the -.Cm n +.Fl n key, .Nm dump interacts with the operator on @@ -279,7 +295,7 @@ to minimize the number of tapes follows: .It Always start with a level 0 backup, for example: .Bd -literal -offset indent -/sbin/dump 0uf /dev/nrst0 /usr/src +/sbin/dump -0u -f /dev/nrst0 /usr/src .Ed .Pp This should be done at set intervals, say once a month or once every two months, @@ -334,8 +350,8 @@ Dump exits with zero status on success. Startup errors are indicated with an exit code of 1; abnormal termination is indicated with an exit code of 3. .Sh BUGS -.Pp Fewer than 32 read errors on the filesystem are ignored. +.Pp Each reel requires a new process, so parent processes for reels already written just hang around until the entire tape is written. @@ -349,9 +365,9 @@ will prevent this from happening. .Pp .Nm Dump with the -.Cm W +.Fl W or -.Cm w +.Fl w options does not report filesystems that have never been recorded in .Pa /etc/dumpdates , diff --git a/sbin/dump/dump.h b/sbin/dump/dump.h index 0da4c28ec482..6053198f57e7 100644 --- a/sbin/dump/dump.h +++ b/sbin/dump/dump.h @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)dump.h 8.1 (Berkeley) 6/5/93 + * @(#)dump.h 8.2 (Berkeley) 4/28/95 */ #define MAXINOPB (MAXBSIZE / sizeof(struct dinode)) @@ -186,8 +186,9 @@ void sig __P((int signo)); */ #ifdef COMPAT #include -extern char *index(), *rindex(), *strdup(); -extern char *ctime(); +#define strchr(a,b) index(a,b) +#define strrchr(a,b) rindex(a,b) +extern char *strdup(), *ctime(); extern int read(), write(); extern int errno; #endif diff --git a/sbin/dump/dumprmt.c b/sbin/dump/dumprmt.c index 08aa485f878b..59597897d5ce 100644 --- a/sbin/dump/dumprmt.c +++ b/sbin/dump/dumprmt.c @@ -32,7 +32,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)dumprmt.c 8.1 (Berkeley) 6/5/93"; +static char sccsid[] = "@(#)dumprmt.c 8.3 (Berkeley) 4/28/95"; #endif /* not lint */ #include @@ -55,6 +55,7 @@ static char sccsid[] = "@(#)dumprmt.c 8.1 (Berkeley) 6/5/93"; #include #include +#include #include #include #include @@ -157,7 +158,7 @@ rmtgetconn() exit(X_ABORT); } } - if ((cp = index(rmtpeer, '@')) != NULL) { + if ((cp = strchr(rmtpeer, '@')) != NULL) { tuser = rmtpeer; *cp = '\0'; if (!okname(tuser)) diff --git a/sbin/dump/main.c b/sbin/dump/main.c index e100f27f8c38..e918387dc6cd 100644 --- a/sbin/dump/main.c +++ b/sbin/dump/main.c @@ -38,7 +38,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)main.c 8.4 (Berkeley) 4/15/94"; +static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/1/95"; #endif /* not lint */ #include @@ -49,23 +49,22 @@ static char sccsid[] = "@(#)main.c 8.4 (Berkeley) 4/15/94"; #include #include #else -#include #include +#include #endif #include #include +#include #include #include #include #include #include -#ifdef __STDC__ #include #include #include -#endif #include "dump.h" #include "pathnames.h" @@ -84,20 +83,21 @@ long dev_bsize = 1; /* recalculated below */ long blocksperfile; /* output blocks per file */ char *host = NULL; /* remote host (if any) */ -static long numarg __P((int, char *, long, long, int *, char ***)); -static void missingarg __P((int, char *)) __dead2; +static long numarg __P((char *, long, long)); +static void obsolete __P((int *, char **[])); +static void usage __P((void)); int main(argc, argv) int argc; - char **argv; + char *argv[]; { register ino_t ino; register int dirty; register struct dinode *dp; register struct fstab *dt; register char *map; - register char *cp; + register int ch; int i, anydirskipped, bflag = 0, Tflag = 0, honorlevel = 1; ino_t maxino; @@ -112,62 +112,31 @@ main(argc, argv) if (TP_BSIZE / DEV_BSIZE == 0 || TP_BSIZE % DEV_BSIZE != 0) quit("TP_BSIZE must be a multiple of DEV_BSIZE\n"); level = '0'; - if (argc == 1) { - (void) fprintf(stderr, "Must specify a key.\n"); - Exit(X_ABORT); - } - argv++; - argc -= 2; - for (cp = *argv++; cp != NULL && *cp != '\0'; cp++) { - switch (*cp) { - case '-': + + if (argc < 2) + usage(); + + obsolete(&argc, &argv); + while ((ch = getopt(argc, argv, "0123456789B:b:cd:f:h:ns:T:uWw")) != -1) + switch (ch) { + /* dump level */ + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + level = ch; break; - case 'w': - lastdump('w'); /* tell us only what has to be done */ - exit(0); - - case 'W': /* what to do */ - lastdump('W'); /* tell us state of what is done */ - exit(0); /* do nothing else */ - - case 'f': /* output file */ - if (argc < 1) - missingarg('f', "output file"); - tape = *argv++; - argc--; + case 'a': /* `auto-size', Write to EOM. */ + unlimited = 1; break; - case 'd': /* density, in bits per inch */ - density = numarg('d', "density", - 10L, 327670L, &argc, &argv) / 10; - if (density >= 625 && !bflag) - ntrec = HIGHDENSITYTREC; - break; - - case 's': /* tape size, feet */ - tsize = numarg('s', "size", - 1L, 0L, &argc, &argv) * 12 * 10; - break; - - case 'T': /* time of last dump */ - if (argc < 1) - missingarg('T', "time of last dump"); - spcl.c_ddate = unctime(*argv); - if (spcl.c_ddate < 0) { - (void)fprintf(stderr, "bad time \"%s\"\n", - *argv); - exit(X_ABORT); - } - Tflag = 1; - lastlevel = '?'; - argc--; - argv++; + case 'B': /* blocks per output file */ + blocksperfile = numarg("number of blocks per file", + 1L, 0L); break; case 'b': /* blocks per tape write */ - ntrec = numarg('b', "number of blocks per write", - 1L, 1000L, &argc, &argv); + ntrec = numarg("number of blocks per write", + 1L, 1000L); /* * XXX * physio(9) currently slices all requests to @@ -184,43 +153,60 @@ main(argc, argv) } break; - case 'B': /* blocks per output file */ - blocksperfile = numarg('B', "number of blocks per file", - 1L, 0L, &argc, &argv); - break; - case 'c': /* Tape is cart. not 9-track */ cartridge = 1; break; - case 'a': /* `auto-size', Write to EOM. */ - unlimited = 1; + case 'd': /* density, in bits per inch */ + density = numarg("density", 10L, 327670L) / 10; + if (density >= 625 && !bflag) + ntrec = HIGHDENSITYTREC; break; - /* dump level */ - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - level = *cp; + case 'f': /* output file */ + tape = optarg; break; - case 'u': /* update /etc/dumpdates */ - uflag = 1; + case 'h': + honorlevel = numarg("honor level", 0L, 10L); break; case 'n': /* notify operators */ notify = 1; break; - case 'h': - honorlevel = numarg('h', "honor level", - 0L, 10L, &argc, &argv); + case 's': /* tape size, feet */ + tsize = numarg("tape size", 1L, 0L) * 12 * 10; break; + case 'T': /* time of last dump */ + spcl.c_ddate = unctime(optarg); + if (spcl.c_ddate < 0) { + (void)fprintf(stderr, "bad time \"%s\"\n", + optarg); + exit(X_ABORT); + } + Tflag = 1; + lastlevel = '?'; + argc--; + argv++; + break; + + case 'u': /* update /etc/dumpdates */ + uflag = 1; + break; + + case 'W': /* what to do */ + case 'w': + lastdump(ch); + exit(0); /* do nothing else */ + default: - (void)fprintf(stderr, "bad key '%c'\n", *cp); - exit(X_ABORT); + usage(); } - } + argc -= optind; + argv += optind; + if (argc < 1) { (void)fprintf(stderr, "Must specify disk or filesystem\n"); exit(X_ABORT); @@ -263,9 +249,9 @@ main(argc, argv) tsize = cartridge ? 1700L*120L : 2300L*120L; } - if (index(tape, ':')) { + if (strchr(tape, ':')) { host = tape; - tape = index(host, ':'); + tape = strchr(host, ':'); *tape++ = '\0'; #ifdef RDUMP if (index(tape, '\n')) { @@ -492,48 +478,33 @@ main(argc, argv) /* NOTREACHED */ } +static void +usage() +{ + + (void)fprintf(stderr, "usage: dump [-0123456789cnu] [-B records] [-b blocksize] [-d density] [-f file]\n [-h level] [-s feet] [-T date] filesystem\n"); + (void)fprintf(stderr, " dump [-W | -w]\n"); + exit(1); +} + /* * Pick up a numeric argument. It must be nonnegative and in the given * range (except that a vmax of 0 means unlimited). */ static long -numarg(letter, meaning, vmin, vmax, pargc, pargv) - int letter; +numarg(meaning, vmin, vmax) char *meaning; long vmin, vmax; - int *pargc; - char ***pargv; { - register char *p; + char *p; long val; - char *str; - if (--*pargc < 0) - missingarg(letter, meaning); - str = *(*pargv)++; - for (p = str; *p; p++) - if (!isdigit(*p)) - goto bad; - val = atol(str); + val = strtol(optarg, &p, 10); + if (*p) + errx(1, "illegal %s -- %s", meaning, optarg); if (val < vmin || (vmax && val > vmax)) - goto bad; + errx(1, "%s must be between %ld and %ld", meaning, vmin, vmax); return (val); - -bad: - (void)fprintf(stderr, "bad '%c' (%s) value \"%s\"\n", - letter, meaning, str); - exit(X_ABORT); -} - -static void -missingarg(letter, meaning) - int letter; - char *meaning; -{ - - (void)fprintf(stderr, "The '%c' flag (%s) requires an argument\n", - letter, meaning); - exit(X_ABORT); } void @@ -568,7 +539,7 @@ rawname(cp) char *cp; { static char rawbuf[MAXPATHLEN]; - char *dp = rindex(cp, '/'); + char *dp = strrchr(cp, '/'); if (dp == NULL) return (NULL); @@ -581,17 +552,77 @@ rawname(cp) return (rawbuf); } -#ifdef sunos -const char * -strerror(errnum) - int errnum; +/* + * obsolete -- + * Change set of key letters and ordered arguments into something + * getopt(3) will like. + */ +static void +obsolete(argcp, argvp) + int *argcp; + char **argvp[]; { - extern int sys_nerr; - extern const char *const sys_errlist[]; + int argc, flags; + char *ap, **argv, *flagsp, **nargv, *p; - if (errnum < sys_nerr) - return (sys_errlist[errnum]); - else - return ("bogus errno in strerror"); + /* Setup. */ + argv = *argvp; + argc = *argcp; + + /* Return if no arguments or first argument has leading dash. */ + ap = argv[1]; + if (argc == 1 || *ap == '-') + return; + + /* Allocate space for new arguments. */ + if ((*argvp = nargv = malloc((argc + 1) * sizeof(char *))) == NULL || + (p = flagsp = malloc(strlen(ap) + 2)) == NULL) + err(1, NULL); + + *nargv++ = *argv; + argv += 2; + + for (flags = 0; *ap; ++ap) { + switch (*ap) { + case 'a': + case 'B': + case 'b': + case 'd': + case 'f': + case 'h': + case 's': + case 'T': + if (*argv == NULL) { + warnx("option requires an argument -- %c", *ap); + usage(); + } + if ((nargv[0] = malloc(strlen(*argv) + 2 + 1)) == NULL) + err(1, NULL); + nargv[0][0] = '-'; + nargv[0][1] = *ap; + (void)strcpy(&nargv[0][2], *argv); + ++argv; + ++nargv; + break; + default: + if (!flags) { + *p++ = '-'; + flags = 1; + } + *p++ = *ap; + break; + } + } + + /* Terminate flags. */ + if (flags) { + *p = '\0'; + *nargv++ = flagsp; + } + + /* Copy remaining arguments. */ + while (*nargv++ = *argv++); + + /* Update argument count. */ + *argcp = nargv - *argvp - 1; } -#endif diff --git a/sbin/dump/tape.c b/sbin/dump/tape.c index 26aed1339ff6..9378d9fd1be3 100644 --- a/sbin/dump/tape.c +++ b/sbin/dump/tape.c @@ -32,7 +32,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)tape.c 8.2 (Berkeley) 3/17/94"; +static char sccsid[] = "@(#)tape.c 8.4 (Berkeley) 5/1/95"; #endif /* not lint */ #include @@ -45,8 +45,8 @@ static char sccsid[] = "@(#)tape.c 8.2 (Berkeley) 3/17/94"; #include #include #else -#include #include +#include #endif #include @@ -584,10 +584,10 @@ startnewtape(top) * the remaining names for subsequent volumes. */ tapeno++; /* current tape sequence */ - if (nexttape || index(tape, ',')) { + if (nexttape || strchr(tape, ',')) { if (nexttape && *nexttape) tape = nexttape; - if ((p = index(tape, ',')) != NULL) { + if ((p = strchr(tape, ',')) != NULL) { *p = '\0'; nexttape = p + 1; } else diff --git a/sbin/dump/traverse.c b/sbin/dump/traverse.c index 8b5a5150d01d..70c041432f7a 100644 --- a/sbin/dump/traverse.c +++ b/sbin/dump/traverse.c @@ -32,7 +32,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)traverse.c 8.2 (Berkeley) 9/23/93"; +static char sccsid[] = "@(#)traverse.c 8.7 (Berkeley) 6/15/95"; #endif /* not lint */ #include @@ -45,9 +45,9 @@ static char sccsid[] = "@(#)traverse.c 8.2 (Berkeley) 9/23/93"; #include #include #else -#include #include #include +#include #endif #include @@ -362,8 +362,7 @@ dumpino(dp, ino) spcl.c_addr[0] = 1; spcl.c_count = 1; writeheader(ino); - bcopy((caddr_t)dp->di_shortlink, buf, - (u_long)dp->di_size); + memmove(buf, dp->di_shortlink, (u_long)dp->di_size); buf[dp->di_size] = '\0'; writerec(buf, 0); return; @@ -418,7 +417,7 @@ dmpindir(ino, blk, ind_level, size) if (blk != 0) bread(fsbtodb(sblock, blk), (char *)idblk, (int) sblock->fs_bsize); else - bzero((char *)idblk, (int)sblock->fs_bsize); + memset(idblk, 0, (int)sblock->fs_bsize); if (ind_level <= 0) { if (*size < NINDIR(sblock) * sblock->fs_bsize) cnt = howmany(*size, sblock->fs_fsize); @@ -592,7 +591,7 @@ bread(blkno, buf, size) /* * Zero buffer, then try to read each sector of buffer separately. */ - bzero(buf, size); + memset(buf, 0, size); for (i = 0; i < size; i += dev_bsize, buf += dev_bsize, blkno++) { if (lseek(diskfd, ((off_t)blkno << dev_bshift), 0) != ((off_t)blkno << dev_bshift))