rsync-2.6.2: NFS clients confused after an rsync
Wayne Davison
wayned at samba.org
Tue May 11 17:01:48 GMT 2004
On Thu, May 06, 2004 at 06:21:55PM -0400, Brian Childs wrote:
> rm -f /tmp/testpath/* $HOME/testpath/*
>
> #Prime it
> echo some data > /tmp/testpath/testfile
> sleep 1
> rsync -a /tmp/testpath/ $HOME/testpath/
> ssh $otherbox ls -li $HOME/testpath
>
> #Break it
> echo additional data >> /tmp/testpath/testfile
> sleep 1
> rsync -a -b /tmp/testpath/ $HOME/testpath/
> ssh $otherbox ls -li $HOME/testpath
Do you actually need to use the -b option for the breakage to happen?
In the output you show, not only is the new testfile~ not yet found,
but the extra data in testfile is not seen (including showing the wrong
inode). Since rsync isn't actually updating any files in-place, the
file gets a new inode while keeping the directory time unchanged, so
that may be enough to confuse NFS.
I had been considering making the preservation of directory times an
optional occurance with rsync. The appended patch implements this.
Comments?
..wayne..
-------------- next part --------------
--- options.c 6 May 2004 21:08:01 -0000 1.148
+++ options.c 11 May 2004 16:57:18 -0000
@@ -46,6 +46,7 @@ int preserve_devices = 0;
int preserve_uid = 0;
int preserve_gid = 0;
int preserve_times = 0;
+int preserve_dir_times = 0;
int update_only = 0;
int cvs_exclude = 0;
int dry_run = 0;
@@ -240,7 +241,8 @@ void usage(enum logcode F)
rprintf(F," -o, --owner preserve owner (root only)\n");
rprintf(F," -g, --group preserve group\n");
rprintf(F," -D, --devices preserve devices (root only)\n");
- rprintf(F," -t, --times preserve times\n");
+ rprintf(F," -t, --times preserve times on non-directories\n");
+ rprintf(F," -d, --dir-times preserve times on directories\n");
rprintf(F," -S, --sparse handle sparse files efficiently\n");
rprintf(F," -n, --dry-run show what would have been transferred\n");
rprintf(F," -W, --whole-file copy whole files, no incremental checks\n");
@@ -346,6 +348,7 @@ static struct poptOption long_options[]
{"group", 'g', POPT_ARG_NONE, &preserve_gid, 0, 0, 0 },
{"devices", 'D', POPT_ARG_NONE, &preserve_devices, 0, 0, 0 },
{"times", 't', POPT_ARG_NONE, &preserve_times, 0, 0, 0 },
+ {"dir-times", 'd', POPT_ARG_NONE, &preserve_dir_times, 0, 0, 0 },
{"checksum", 'c', POPT_ARG_NONE, &always_checksum, 0, 0, 0 },
{"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
{"quiet", 'q', POPT_ARG_NONE, 0, 'q', 0, 0 },
@@ -823,6 +826,8 @@ void server_options(char **args,int *arg
argstr[x++] = 'D';
if (preserve_times)
argstr[x++] = 't';
+ if (preserve_dir_times && am_sender)
+ argstr[x++] = 'd';
if (preserve_perms)
argstr[x++] = 'p';
if (recurse)
--- rsync.c 23 Mar 2004 16:16:15 -0000 1.135
+++ rsync.c 11 May 2004 16:57:19 -0000
@@ -25,6 +25,7 @@
extern int verbose;
extern int dry_run;
extern int preserve_times;
+extern int preserve_dir_times;
extern int am_root;
extern int am_server;
extern int am_sender;
@@ -125,9 +126,9 @@ int delete_file(char *fname)
int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
int report)
{
- int updated = 0;
STRUCT_STAT st2;
int change_uid, change_gid;
+ int keep_time, updated = 0;
if (dry_run) return 0;
@@ -140,12 +141,10 @@ int set_perms(char *fname,struct file_st
st = &st2;
}
- if (preserve_times && !S_ISLNK(st->st_mode) &&
- cmp_modtime(st->st_mtime, file->modtime) != 0) {
- /* don't complain about not setting times on directories
- * because some filesystems can't do it */
- if (set_modtime(fname,file->modtime) != 0 &&
- !S_ISDIR(st->st_mode)) {
+ keep_time = S_ISDIR(st->st_mode) ? preserve_dir_times
+ : preserve_times && !S_ISLNK(st->st_mode);
+ if (keep_time && cmp_modtime(st->st_mtime, file->modtime) != 0) {
+ if (set_modtime(fname,file->modtime) != 0) {
rprintf(FERROR, "failed to set times on %s: %s\n",
full_fname(fname), strerror(errno));
return 0;
--- rsync.yo 7 May 2004 00:18:37 -0000 1.169
+++ rsync.yo 11 May 2004 16:57:19 -0000
@@ -298,7 +298,8 @@ verb(
-o, --owner preserve owner (root only)
-g, --group preserve group
-D, --devices preserve devices (root only)
- -t, --times preserve times
+ -t, --times preserve times on non-directories
+ -d, --dir-times preserve times on directories
-S, --sparse handle sparse files efficiently
-n, --dry-run show what would have been transferred
-W, --whole-file copy whole files, no incremental checks
@@ -538,13 +539,22 @@ dit(bf(-D, --devices)) This option cause
block device information to the remote system to recreate these
devices. This option is only available to the super-user.
-dit(bf(-t, --times)) This tells rsync to transfer modification times along
-with the files and update them on the remote system. Note that if this
+dit(bf(-t, --times)) This tells rsync to preserve modification times of
+non-directories transferred to the remote system. Note that if this
option is not used, the optimization that excludes files that have not been
modified cannot be effective; in other words, a missing -t or -a will
cause the next transfer to behave as if it used -I, and all files will have
their checksums compared and show up in log messages even if they haven't
changed.
+
+dit(bf(-d, --dir-times)) This tells rsync to preserve the modification
+times of directories transferred to the remote system. On a modern
+rsync, these are left unpreserved by default to avoid causing problems
+for NFS.
+
+Note: when sending files to an older rsync, the --times option will
+imply --dir-times (if the option causes an error on the receiving
+system, omit it and use --times to preserve all file/directory times).
dit(bf(-n, --dry-run)) This tells rsync to not do any file transfers,
instead it will just report the actions it would have taken.
More information about the rsync
mailing list