diff --git a/sbin/dump/dump.8 b/sbin/dump/dump.8 index 6759bdaabdd4..a96995d8ed5a 100644 --- a/sbin/dump/dump.8 +++ b/sbin/dump/dump.8 @@ -38,7 +38,7 @@ .Nd file system backup .Sh SYNOPSIS .Nm -.Op Fl 0123456789acLnSu +.Op Fl 0123456789acLnrRSu .Op Fl B Ar records .Op Fl b Ar blocksize .Op Fl C Ar cachesize @@ -258,6 +258,27 @@ notify all operators in the group .Dq operator by means similar to a .Xr wall 1 . +.It Fl r +Be rsync-friendly. +Normally dump stores the date of the current +and prior dump in numerous places throughout the dump. +These scattered changes significantly slow down rsync or +another incremental file transfer program when they are +used to update a remote copy of a level 0 dump, +since the date changes for each dump. +This option sets both dates to the epoch, permitting +rsync to be much more efficient when transferring a dump file. +.It Fl R +Be even more rsync-friendly. +This option disables the storage of the actual inode access time +(storing it instead as the inode's modified time). +This option permits rsync to be even more efficient +when transferring dumps generated from filesystems with numerous files +which are not changing other than their access times. +The +.Fl R +option also sets +.Fl r . .It Fl S Display an estimate of the backup size and the number of tapes required, and exit without actually performing the dump. diff --git a/sbin/dump/dump.h b/sbin/dump/dump.h index d467668b7e82..73e2d0156ff4 100644 --- a/sbin/dump/dump.h +++ b/sbin/dump/dump.h @@ -75,6 +75,7 @@ int etapes; /* estimated number of tapes */ int nonodump; /* if set, do not honor UF_NODUMP user flags */ int unlimited; /* if set, write to end of medium */ int cachesize; /* size of block cache in bytes */ +int rsync_friendly; /* be friendly with rsync */ int notify; /* notify operator flag */ int blockswritten; /* number of blocks written on current tape */ diff --git a/sbin/dump/main.c b/sbin/dump/main.c index 827ffcc129f3..63e4845c53c2 100644 --- a/sbin/dump/main.c +++ b/sbin/dump/main.c @@ -117,13 +117,14 @@ main(int argc, char *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'; + rsync_friendly = 0; if (argc < 2) usage(); obsolete(&argc, &argv); while ((ch = getopt(argc, argv, - "0123456789aB:b:C:cD:d:f:h:LnP:Ss:T:uWw")) != -1) + "0123456789aB:b:C:cD:d:f:h:LnP:RrSs:T:uWw")) != -1) switch (ch) { /* dump level */ case '0': case '1': case '2': case '3': case '4': @@ -189,6 +190,16 @@ main(int argc, char *argv[]) popenout = optarg; break; + case 'r': /* store slightly less data to be friendly to rsync */ + if (rsync_friendly < 1) + rsync_friendly = 1; + break; + + case 'R': /* store even less data to be friendlier to rsync */ + if (rsync_friendly < 2) + rsync_friendly = 2; + break; + case 'S': /* exit after estimating # of tapes */ just_estimate = 1; break; @@ -236,6 +247,11 @@ main(int argc, char *argv[]) (void)fprintf(stderr, "\n"); exit(X_STARTUP); } + if (rsync_friendly && (level>'0')) { + (void)fprintf(stderr, "%s %s\n", "rsync friendly options", + "can be used only with level 0 dumps."); + exit(X_STARTUP); + } if (Tflag && uflag) { (void)fprintf(stderr, "You cannot use the T and u flags together.\n"); @@ -384,7 +400,11 @@ main(int argc, char *argv[]) (void)gethostname(spcl.c_host, NAMELEN); spcl.c_level = level - '0'; spcl.c_type = TS_TAPE; - + if (rsync_friendly) { + /* don't store real dump times */ + spcl.c_date = 0; + spcl.c_ddate = 0; + } if (spcl.c_date == 0) { tmsg = "the epoch\n"; } else { @@ -393,7 +413,7 @@ main(int argc, char *argv[]) } msg("Date of this level %c dump: %s", level, tmsg); - if (!Tflag) + if (!Tflag && (!rsync_friendly)) getdumptime(); /* /etc/dumpdates snarfed */ if (spcl.c_ddate == 0) { tmsg = "the epoch\n"; diff --git a/sbin/dump/traverse.c b/sbin/dump/traverse.c index 211cfa6370b9..f593244f40d1 100644 --- a/sbin/dump/traverse.c +++ b/sbin/dump/traverse.c @@ -842,6 +842,11 @@ writeheader(ino_t ino) { int32_t sum, cnt, *lp; + if (rsync_friendly >= 2) { + /* don't track changes to access time */ + spcl.c_atime = spcl.c_mtime; + spcl.c_atimensec = spcl.c_mtimensec; + } spcl.c_inumber = ino; spcl.c_magic = FS_UFS2_MAGIC; spcl.c_checksum = 0;