From 693c40a39aeb949f15480ce2f41a22e7b737fcf5 Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Fri, 23 May 2008 23:13:14 +0000 Subject: [PATCH] When using dump to generate level 0 dumps which are then rsync'ed to a remote machine, the fact that the dump date is stored with each header (inode) record makes rsync significantly less efficient than necessary. This also applies to inode access times when they are not important data to retain. When implementing an offsite backup solution of this type, these dates in particular are not important, especially if it prevents effective offsite backups. PR: bin/91049 Submitted by: Forrest W Christian --- sbin/dump/dump.8 | 23 ++++++++++++++++++++++- sbin/dump/dump.h | 1 + sbin/dump/main.c | 26 +++++++++++++++++++++++--- sbin/dump/traverse.c | 5 +++++ 4 files changed, 51 insertions(+), 4 deletions(-) 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;