patch: --force-change for hard links

dev dev at 26th.net
Thu Oct 1 08:27:29 MDT 2009


Hi All!

rsync-3.0.6 with fileflags.diff under FreeBSD 8.0-RC1: if there is a file
with uchg or schg flag in source directory and it's hard-linked (usual
case for /usr/bin), then rsync cannot create the link in destination
directory. Error message: rsync: link "/tmp/s/a" => b failed: Operation
not permitted (1)

The problem is that it's not allowed to link a *chg'ed file. Following
patch tries to remove the flag, link the file and then restore the file
(actually, the code is similar to code in the do_unlink function).

Regards
Anatoli Klassen

Test case:

# mkdir s d
# touch s/a
# ln s/a s/b
# chflags uchg s/a
# rsync -v --hard-links --archive --fileflags --force-change s/ d/
sending incremental file list
./
b
a => b

sent 102 bytes  received 43 bytes  290.00 bytes/sec
total size is 0  speedup is 0.00
# ll *
d:
total 0
-rw-r--r--  2 root  wheel  schg    0B Oct  1 15:50 a
-rw-r--r--  2 root  wheel  schg    0B Oct  1 15:50 b

s:
total 0
-rw-r--r--  2 root  wheel  schg    0B Oct  1 15:50 a
-rw-r--r--  2 root  wheel  schg    0B Oct  1 15:50 b

The patch:

--- orig/syscall.c       2009-09-29 15:34:03.293118000 +0200
+++ syscall.c   2009-09-29 16:11:29.400671306 +0200
@@ -82,7 +82,23 @@
 {
         if (dry_run) return 0;
         RETURN_ERROR_IF_RO_OR_LO;
-        return link(fname1, fname2);
+        if (link(fname1, fname2) == 0)
+                return 0;
+#ifdef SUPPORT_FORCE_CHANGE
+        if (force_change && errno == EPERM) {
+                STRUCT_STAT st;
+
+                if (x_lstat(fname1, &st, NULL) == 0
+                 && make_mutable(fname1, st.st_mode, st.st_flags,
force_change) > 0) {
+                        int ret = link(fname1, fname2);
+                        undo_make_mutable(fname1, st.st_flags);
+                        if (ret == 0)
+                                 return 0;
+                }
+                errno = EPERM;
+        }
+#endif
+        return -1;
 }
 #endif




More information about the rsync mailing list