Commit 1ed9018e authored by Wayne Davison's avatar Wayne Davison

Fixed some itemized logging failures:

- If a symlink/device/special-file changes its value without any
  attribute changes, the itemized event no longer gets dropped.
- We put a 'c' into the checksum/change field now to indicate when
  a symlink/device/special-file changes its value without changing
  its type.  This lets us properly interpret the --copy-links output
  to know which items are getting copied without changes and which
  are getting created with new content.
- Fixed the 'T' itemized output for a symlink when rsync tries to
  set the right time but fails due to lack of OS/disk support.
parent ff0e1580
......@@ -271,6 +271,10 @@ void setup_protocol(int f_out,int f_in)
exit_cleanup(RERR_SYNTAX);
}
need_messages_from_generator = 1;
#if defined HAVE_LUTIMES && defined HAVE_UTIMES
} else if (!am_sender) {
receiver_symlink_times = 1;
#endif
}
if (need_unsorted_flist && (!am_sender || inc_recurse))
......
......@@ -27,7 +27,6 @@ extern int dry_run;
extern int do_xfers;
extern int stdout_format_has_i;
extern int logfile_format_has_i;
extern int receiver_symlink_times;
extern int am_root;
extern int am_server;
extern int am_daemon;
......@@ -111,6 +110,7 @@ static char *deldelay_buf = NULL;
static int deldelay_fd = -1;
static int lull_mod;
static int dir_tweaking;
static int symlink_timeset_failed_flags;
static int need_retouch_dir_times;
static int need_retouch_dir_perms;
static const char *solo_file = NULL;
......@@ -623,16 +623,20 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
int keep_time = !preserve_times ? 0
: S_ISDIR(file->mode) ? preserve_times > 1 :
#if defined HAVE_LUTIMES && defined HAVE_UTIMES
(receiver_symlink_times && !(file->flags & FLAG_TIME_FAILED)) ||
#endif
1;
#else
!S_ISLNK(file->mode);
#endif
if (S_ISREG(file->mode) && F_LENGTH(file) != sxp->st.st_size)
iflags |= ITEM_REPORT_SIZE;
if ((iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !keep_time
&& !(iflags & ITEM_MATCHED)
if (file->flags & FLAG_TIME_FAILED) { /* symlinks only */
if (iflags & ITEM_LOCAL_CHANGE)
iflags |= symlink_timeset_failed_flags;
} else if (keep_time
? cmp_time(file->modtime, sxp->st.st_mtime) != 0
: iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !(iflags & ITEM_MATCHED)
&& (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
|| (keep_time && cmp_time(file->modtime, sxp->st.st_mtime) != 0))
iflags |= ITEM_REPORT_TIME;
#if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST
if (S_ISLNK(file->mode)) {
......@@ -1159,8 +1163,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
if (itemizing && stdout_format_has_i
&& (verbose > 1 || stdout_format_has_i > 1)) {
int chg = compare_dest && type != TYPE_DIR ? 0
: ITEM_LOCAL_CHANGE
+ (match_level == 3 ? ITEM_XNAME_FOLLOWS : 0);
: ITEM_LOCAL_CHANGE + (match_level == 3 ? ITEM_XNAME_FOLLOWS : 0);
char *lp = match_level == 3 ? "" : NULL;
itemize(cmpbuf, file, ndx, 0, sxp, chg + ITEM_MATCHED, 0, lp);
}
......@@ -1538,7 +1541,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
set_file_attrs(fname, file, NULL, NULL, 0);
if (itemizing) {
itemize(fname, file, ndx, statret, &sx,
ITEM_LOCAL_CHANGE, 0, NULL);
ITEM_LOCAL_CHANGE|ITEM_REPORT_CHANGE, 0, NULL);
}
if (code != FNONE && verbose)
rprintf(code, "%s -> %s\n", fname, sl);
......@@ -1622,7 +1625,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
set_file_attrs(fname, file, NULL, NULL, 0);
if (itemizing) {
itemize(fname, file, ndx, statret, &sx,
ITEM_LOCAL_CHANGE, 0, NULL);
ITEM_LOCAL_CHANGE|ITEM_REPORT_CHANGE, 0, NULL);
}
if (code != FNONE && verbose)
rprintf(code, "%s\n", fname);
......@@ -1865,7 +1868,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
if (itemizing) {
int iflags = ITEM_TRANSFER;
if (always_checksum > 0)
iflags |= ITEM_REPORT_CHECKSUM;
iflags |= ITEM_REPORT_CHANGE;
if (fnamecmp_type != FNAMECMP_FNAME)
iflags |= ITEM_BASIS_TYPE_FOLLOWS;
if (fnamecmp_type == FNAMECMP_FUZZY)
......@@ -2076,6 +2079,8 @@ void generate_files(int f_out, const char *local_name)
dir_tweaking = !(list_only || solo_file || dry_run);
need_retouch_dir_times = preserve_times > 1;
lull_mod = allowed_lull * 5;
symlink_timeset_failed_flags = ITEM_REPORT_TIME
| (protocol_version >= 30 ? ITEM_REPORT_TIMEFAIL : 0 );
if (verbose > 2)
rprintf(FINFO, "generator starting pid=%ld\n", (long)getpid());
......
......@@ -632,15 +632,21 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
? iflags & ITEM_XNAME_FOLLOWS ? 'h' : 'c'
: !(iflags & ITEM_TRANSFER) ? '.'
: !local_server && *op == 's' ? '<' : '>';
c[1] = S_ISDIR(file->mode) ? 'd'
: IS_SPECIAL(file->mode) ? 'S'
: IS_DEVICE(file->mode) ? 'D'
: S_ISLNK(file->mode) ? 'L' : 'f';
c[2] = !(iflags & ITEM_REPORT_CHECKSUM) ? '.' : 'c';
c[3] = !(iflags & ITEM_REPORT_SIZE) ? '.' : 's';
c[4] = !(iflags & ITEM_REPORT_TIME) ? '.'
: !preserve_times || (!receiver_symlink_times && S_ISLNK(file->mode))
? 'T' : 't';
if (S_ISLNK(file->mode)) {
c[1] = 'L';
c[3] = '.';
c[4] = !(iflags & ITEM_REPORT_TIME) ? '.'
: !preserve_times || !receiver_symlink_times
|| (iflags & ITEM_REPORT_TIMEFAIL) ? 'T' : 't';
} else {
c[1] = S_ISDIR(file->mode) ? 'd'
: IS_SPECIAL(file->mode) ? 'S'
: IS_DEVICE(file->mode) ? 'D' : 'f';
c[3] = !(iflags & ITEM_REPORT_SIZE) ? '.' : 's';
c[4] = !(iflags & ITEM_REPORT_TIME) ? '.'
: !preserve_times ? 'T' : 't';
}
c[2] = !(iflags & ITEM_REPORT_CHANGE) ? '.' : 'c';
c[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
c[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
c[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
......
......@@ -166,8 +166,9 @@
/* For use by the itemize_changes code */
#define ITEM_REPORT_ATIME (1<<0)
#define ITEM_REPORT_CHECKSUM (1<<1)
#define ITEM_REPORT_SIZE (1<<2)
#define ITEM_REPORT_CHANGE (1<<1)
#define ITEM_REPORT_SIZE (1<<2) /* regular files only */
#define ITEM_REPORT_TIMEFAIL (1<<2) /* symlinks only */
#define ITEM_REPORT_TIME (1<<3)
#define ITEM_REPORT_PERMS (1<<4)
#define ITEM_REPORT_OWNER (1<<5)
......
......@@ -1674,8 +1674,9 @@ a "?" (this can happen when talking to an older rsync).
The attribute that is associated with each letter is as follows:
quote(itemization(
it() A bf(c) means the checksum of the file is different and will be
updated by the file transfer (requires bf(--checksum)).
it() A bf(c) means either that a regular file has a different checksum
(requires bf(--checksum)) or that a symlink, device, or special file has
a changed value.
it() A bf(s) means the size of the file is different and will be updated
by the file transfer.
it() A bf(t) means the modification time is different and is being updated
......@@ -1683,6 +1684,8 @@ quote(itemization(
means that the modification time will be set to the transfer time, which happens
when a file/symlink/device is updated without bf(--times) and when a
symlink is changed and the receiver can't set its time.
(Note: when using an rsync 3.0.0 client, you might see the bf(s) flag combined
with bf(t) instead of the proper bf(T) flag for this time-setting failure.)
it() A bf(p) means the permissions are different and are being updated to
the sender's value (requires bf(--perms)).
it() An bf(o) means the owner is different and is being updated to the
......
......@@ -78,14 +78,14 @@ ln "$fromdir/block3" "$fromdir/block2.5" || echo "Skipping hard-linked device te
mkfifo "$fromdir/fifo" || mknod "$fromdir/fifo" p || test_skipped "Can't run mkfifo"
touch -r "$fromdir/block" "$fromdir/block2"
$RSYNC -ai "$fromdir/block" "$todir/block2" \
$RSYNC -ait "$fromdir/block" "$todir/block2" \
| tee "$outfile"
cat <<EOT >"$chkfile"
cD$all_plus block
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed"
$RSYNC -ai "$fromdir/block2" "$todir/block" \
$RSYNC -ait "$fromdir/block2" "$todir/block" \
| tee "$outfile"
cat <<EOT >"$chkfile"
cD$all_plus block2
......@@ -97,7 +97,7 @@ sleep 1
$RSYNC -Di "$fromdir/block3" "$todir/block" \
| tee "$outfile"
cat <<EOT >"$chkfile"
cD..T.$dots block3
cDc.T.$dots block3
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
......@@ -106,8 +106,8 @@ $RSYNC -aiHvv "$fromdir/" "$todir/" \
filter_outfile
cat <<EOT >"$chkfile"
.d..t.$dots ./
cD..t.$dots block
cD$allspace block2
cDc.t.$dots block
cDc...$dots block2
cD$all_plus block3
hD$all_plus block2.5 => block3
cD$all_plus char
......
......@@ -96,7 +96,7 @@ cat <<EOT >"$chkfile"
.d..t.$dots foo/
.f..t.$dots foo/config1
>fcstp$dots foo/config2
cL.$T.$dots foo/sym -> ../bar/baz/rsync
cLc$T.$dots foo/sym -> ../bar/baz/rsync
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
......@@ -157,8 +157,8 @@ $RSYNC -ivvplrtH --copy-dest=../to "$fromdir/" "$to2dir/" \
| tee "$outfile"
filter_outfile
case `tail -1 "$outfile"` in
cL..t*)
sym_dots="..t.$dots"
cLc.t*)
sym_dots="c.t.$dots"
L_sym_dots="cL$sym_dots"
is_uptodate='-> ../bar/baz/rsync'
echo "cL$sym_dots foo/sym $is_uptodate" >"$chkfile.extra"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment