DO NOT REPLY [Bug 5820] New: rsync does not replace symlink atomically

samba-bugs at samba.org samba-bugs at samba.org
Thu Oct 9 07:25:53 GMT 2008


https://bugzilla.samba.org/show_bug.cgi?id=5820

           Summary: rsync does not replace symlink atomically
           Product: rsync
           Version: 3.0.4
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P3
         Component: core
        AssignedTo: wayned at samba.org
        ReportedBy: rsync at sysoev.ru
         QAContact: rsync-qa at samba.org


rsync does not replace symlink atomically, i.e, first it unlinks an old symlink
and then creates a new symlink. There is short time when symlink does not exist
at all. The attached patch against 3.0.4 fixes the issue. However, it has been
tested on FreeBSD only. The patch is also available on
http://sysoev.ru/tmp/rsync.symlink.patch

--- generator.c 2008-08-31 20:51:29.000000000 +0400
+++ generator.c 2008-10-08 23:10:17.000000000 +0400
@@ -1556,9 +1556,40 @@
                                if (remove_source_files == 1)
                                        goto return_with_success;
                                goto cleanup;
+                       } else {
+                               char fnametmp[MAXPATHLEN];
+
+                               /* Replace the symlink atomically. */
+                               if (!get_tmpname(fnametmp, fname))
+                                       goto cleanup;
+                               if (!mktemp(fnametmp))
+                                       goto cleanup;
+                               if (do_symlink(sl, fnametmp) != 0) {
+                                       rsyserr(FERROR_XFER, errno, "symlink %s
-> \"%s\" failed",
+                                               full_fname(fnametmp), sl);
+                                       goto cleanup;
+                               }
+                               set_file_attrs(fnametmp, file, NULL, NULL, 0);
+                               if (do_rename(fnametmp, fname) != 0) {
+                                       rsyserr(FERROR_XFER, errno, "rename %s
-> %s failed",
+                                               full_fname(fnametmp),
full_fname(fname));
+                                       goto cleanup;
+                               }
+                               if (itemizing) {
+                                       itemize(fname, file, ndx, statret, &sx,
+                                              
ITEM_LOCAL_CHANGE|ITEM_REPORT_CHANGE, 0, NULL);
+                               }
+                               if (verbose)
+                                       rprintf(code, "%s -> %s\n", fname, sl);
+#ifdef SUPPORT_HARD_LINKS
+                               if (preserve_hard_links && F_IS_HLINKED(file))
+                                       finish_hard_link(file, fname, ndx,
NULL, itemizing, code, -1);
+#endif
+                               if (remove_source_files)
+                                       goto return_with_success;
+                               goto cleanup;
                        }
-                       /* Not the right symlink (or not a symlink), so
-                        * delete it. */
+                       /* Not not a symlink, so delete it. */
                        if (delete_item(fname, sx.st.st_mode, del_opts |
DEL_FOR_SYMLINK) != 0)
                                goto cleanup;
                } else if (basis_dir[0] != NULL) {


-- 
Configure bugmail: https://bugzilla.samba.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug, or are watching the QA contact.


More information about the rsync mailing list