IIUC, the new philosophy of symlink times is that -t preserves them to the extent that they are settable; when they aren't, it's just as if -t wasn't given. But rsync breaks this principle in the following case.
Suppose rsync is configured with HAVE_LUTIMES enabled but the lutimes call doesn't actually work (I simulated this via the attached patch). When rsync recreates a destination symlink to update its target path, rsync will fail to preserve the time, but it nevertheless itemizes "t". It should itemize "T" because the time is being incidentally changed, not preserved. To reproduce: ln -s ta a sleep 1 ln -s tb b rsync-dev -i -lt a b stat --format='%Y %n' a b Output: # Rsync claims to have preserved the time... cL..t...... a -> ta # ... but it differs 1205122328 a 1205122329 b The problem is that, for a recreated symlink (as opposed to a tweaked one), the generator itemizes ITEM_REPORT_TIME whether it succeeded or failed in setting the time. On a push, the sender is doing the logging and can't check the generator's FLAG_TIME_FAILED, so there is no way for it to tell these two cases apart; they have to look different in the itemize flags. Matt
diff --git a/util.c b/util.c index 9547eef..938d396 100644 --- a/util.c +++ b/util.c @@ -122,6 +122,12 @@ NORETURN void overflow_exit(const char *str) exit_cleanup(RERR_MALLOC); } +static int fake_lutimes(UNUSED(const char *file), UNUSED(const struct timeval tvp[2])) +{ + errno = ENOSYS; + return -1; +} + int set_modtime(const char *fname, time_t modtime, mode_t mode) { #if !defined HAVE_LUTIMES || !defined HAVE_UTIMES @@ -147,7 +153,7 @@ int set_modtime(const char *fname, time_t modtime, mode_t mode) t[1].tv_usec = 0; # ifdef HAVE_LUTIMES if (S_ISLNK(mode)) { - if (lutimes(fname, t) < 0) + if (fake_lutimes(fname, t) < 0) return errno == ENOSYS ? 1 : -1; return 0; }
-- To unsubscribe or change options: https://lists.samba.org/mailman/listinfo/rsync Before posting, read: http://www.catb.org/~esr/faqs/smart-questions.html