Mike Bombich
2008-Apr-14 19:43 UTC
[PATCH] xattrs not set on locked files that already exist on target
Working with rsync 3.0.2, it appears that rsync isn't unlocking files before setting the file attributes when those files already exist. This generates error messages on subsequent such as: rsync: rsync_xal_set: lsetxattr("locked_file","test_xattr") failed: Operation not permitted (1) rsync: rsync_xal_clear: lremovexattr("locked_file","test_xattr.temp") failed: Operation not permitted (1) I assume this would also affect ACLs. Presumably, this is what -- force-change is supposed to do, so I extended that functionality to apply to this test case. Here's the test case (tested on HEAD+fileflags+crtime, but the patch below applies to 3.0.2): ###### #!/bin/sh xattr=/usr/local/bin/xattr rsync="/Users/bombich/Desktop/rsync-HEAD-20080412-0558GMT/rsync" src=`mktemp -d /tmp/src.XXXXXX` tgt=`mktemp -d /tmp/tgt.XXXXXX` touch $src/locked_file $xattr -s test_xattr "Test attribute" $src/locked_file $xattr -s test_xattr.temp "Temp attribute" $src/locked_file chflags uchg $src/locked_file ## First backup printf "### Initial backup ###\n\n" "$rsync" -vaX --fileflags --force-change $src/ $tgt/ ## Change the source file chflags nouchg $src/locked_file $xattr -s test_xattr "Modified attribute" $src/locked_file $xattr -d test_xattr.temp $src/locked_file chflags uchg $src/locked_file ## Second backup printf "\n### Second backup ###\n\n" "$rsync" -vaX --fileflags --force-change $src/ $tgt/ # Cleanup chflags -R nouchg $src chflags -R nouchg $tgt rm -rf $src $tgt ###### Example output: [bombich:~] ~/Desktop/locked_xattrs.sh ### Initial backup ### sending incremental file list locked_file sent 173 bytes received 32 bytes 410.00 bytes/sec total size is 0 speedup is 0.00 ### Second backup ### sending incremental file list rsync: rsync_xal_set: lsetxattr("locked_file","test_xattr") failed: Operation not permitted (1) rsync: rsync_xal_clear: lremovexattr("locked_file","test_xattr.temp") failed: Operation not permitted (1) sent 104 bytes received 16 bytes 240.00 bytes/sec total size is 0 speedup is 0.00 rsync error: some files could not be transferred (code 23) at main.c(1031) [sender=3.0.3dev] PATCH: --- rsync-3.0.2_base/rsync.c 2008-04-08 21:37:18.000000000 -0500 +++ rsync-3.0.2/rsync.c 2008-04-14 13:05:44.000000000 -0500 @@ -31,6 +31,7 @@ extern int dry_run; extern int preserve_acls; extern int preserve_xattrs; +extern int force_change; extern int preserve_perms; extern int preserve_fileflags; extern int preserve_executability; @@ -445,6 +446,11 @@ if (daemon_chmod_modes && !S_ISLNK(new_mode)) new_mode = tweak_mode(new_mode, daemon_chmod_modes); +#ifdef SUPPORT_FORCE_CHANGE + if (force_change) + make_mutable(fname, sxp->st.st_mode, sxp->st.st_flags, force_change); +#endif + #ifdef SUPPORT_ACLS if (preserve_acls && !S_ISLNK(file->mode) && !ACL_READY(*sxp)) get_acl(fname, sxp); ## Note: I'm not using undo_make_mutable because set_fileflags is called at the end of this method if we care about fileflags.