Skip to content

Commit

Permalink
Added --atimes and --set-noatime options.
Browse files Browse the repository at this point in the history
  • Loading branch information
WayneD committed Apr 23, 2020
1 parent 2b2a3c8 commit b936741
Show file tree
Hide file tree
Showing 17 changed files with 363 additions and 108 deletions.
4 changes: 4 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ Changes since 3.1.3:

ENHANCEMENTS:

- Improved the --atimes patch and promoted it to be in the release.

- Added --set-noatime option to open files using O_NOATIME.

- Improved the --write-devices patch and promoted it to be in the release.

- Added openssl support to the rsync-ssl script via its renamed helper
Expand Down
16 changes: 12 additions & 4 deletions compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ extern int protocol_version;
extern int protect_args;
extern int preserve_uid;
extern int preserve_gid;
extern int preserve_atimes;
extern int preserve_acls;
extern int preserve_xattrs;
extern int need_messages_from_generator;
Expand All @@ -65,7 +66,7 @@ extern char *iconv_opt;
#endif

/* These index values are for the file-list's extra-attribute array. */
int uid_ndx, gid_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
int pathname_ndx, depth_ndx, atimes_ndx, uid_ndx, gid_ndx, acls_ndx, xattrs_ndx, unsort_ndx;

int receiver_symlink_times = 0; /* receiver can set the time on a symlink */
int sender_symlink_iconv = 0; /* sender should convert symlink content */
Expand Down Expand Up @@ -136,10 +137,17 @@ void set_allow_inc_recurse(void)

void setup_protocol(int f_out,int f_in)
{
if (am_sender)
file_extra_cnt += PTR_EXTRA_CNT;
assert(file_extra_cnt == 0);
assert(EXTRA64_CNT == 2 || EXTRA64_CNT == 1);

/* All int64 values must be set first so that they are guaranteed to be
* aligned for direct int64-pointer memory access. */
if (preserve_atimes)
atimes_ndx = (file_extra_cnt += EXTRA64_CNT);
if (am_sender) /* This is most likely in the in64 union as well. */
pathname_ndx = (file_extra_cnt += PTR_EXTRA_CNT);
else
file_extra_cnt++;
depth_ndx = ++file_extra_cnt;
if (preserve_uid)
uid_ndx = ++file_extra_cnt;
if (preserve_gid)
Expand Down
27 changes: 25 additions & 2 deletions flist.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ extern int preserve_specials;
extern int delete_during;
extern int missing_args;
extern int eol_nulls;
extern int atimes_ndx;
extern int relative_paths;
extern int implied_dirs;
extern int ignore_perishable;
Expand Down Expand Up @@ -379,7 +380,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
#endif
int ndx, int first_ndx)
{
static time_t modtime;
static time_t modtime, atime;
static mode_t mode;
#ifdef SUPPORT_HARD_LINKS
static int64 dev;
Expand Down Expand Up @@ -479,6 +480,12 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
modtime = file->modtime;
if (NSEC_BUMP(file) && protocol_version >= 31)
xflags |= XMIT_MOD_NSEC;
if (atimes_ndx && !S_ISDIR(mode)) {
if (F_ATIME(file) == atime)
xflags |= XMIT_SAME_ATIME;
else
atime = F_ATIME(file);
}

#ifdef SUPPORT_HARD_LINKS
if (tmp_dev != -1) {
Expand Down Expand Up @@ -565,6 +572,8 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
write_varint(f, F_MOD_NSEC(file));
if (!(xflags & XMIT_SAME_MODE))
write_int(f, to_wire_mode(mode));
if (atimes_ndx && !S_ISDIR(mode) && !(xflags & XMIT_SAME_ATIME))
write_varlong(f, atime, 4);
if (preserve_uid && !(xflags & XMIT_SAME_UID)) {
if (protocol_version < 30)
write_int(f, uid);
Expand Down Expand Up @@ -652,7 +661,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,

static struct file_struct *recv_file_entry(int f, struct file_list *flist, int xflags)
{
static int64 modtime;
static int64 modtime, atime;
static mode_t mode;
#ifdef SUPPORT_HARD_LINKS
static int64 dev;
Expand Down Expand Up @@ -799,6 +808,16 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
modtime_nsec = 0;
if (!(xflags & XMIT_SAME_MODE))
mode = from_wire_mode(read_int(f));
if (atimes_ndx && !S_ISDIR(mode) && !(xflags & XMIT_SAME_ATIME)) {
atime = read_varlong(f, 4);
#if SIZEOF_TIME_T < SIZEOF_INT64
if (!am_generator && (int64)(time_t)atime != atime) {
rprintf(FERROR_XFER,
"Access time value of %s truncated on receiver.\n",
lastname);
}
#endif
}

if (chmod_modes && !S_ISLNK(mode) && mode)
mode = tweak_mode(mode, chmod_modes);
Expand Down Expand Up @@ -966,6 +985,8 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
F_GROUP(file) = gid;
file->flags |= gid_flags;
}
if (atimes_ndx)
F_ATIME(file) = atime;
if (unsort_ndx)
F_NDX(file) = flist->used + flist->ndx_start;

Expand Down Expand Up @@ -1363,6 +1384,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
F_GROUP(file) = st.st_gid;
if (am_generator && st.st_uid == our_uid)
file->flags |= FLAG_OWNED_BY_US;
if (atimes_ndx)
F_ATIME(file) = st.st_atime;

if (basename != thisname)
file->dirname = lastdir;
Expand Down
53 changes: 34 additions & 19 deletions generator.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
: iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !(iflags & ITEM_MATCHED)
&& (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
iflags |= ITEM_REPORT_TIME;
if (atimes_ndx && !S_ISDIR(file->mode) && !S_ISLNK(file->mode)
&& cmp_time(F_ATIME(file), 0, sxp->st.st_atime, 0) != 0)
iflags |= ITEM_REPORT_ATIME;
#if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST
if (S_ISLNK(file->mode)) {
;
Expand Down Expand Up @@ -916,6 +919,8 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
if (link_dest) {
if (!hard_link_one(file, fname, cmpbuf, 1))
goto try_a_copy;
if (atimes_ndx)
set_file_attrs(fname, file, sxp, NULL, 0);
if (preserve_hard_links && F_IS_HLINKED(file))
finish_hard_link(file, fname, ndx, &sxp->st, itemizing, code, j);
if (!maybe_ATTRS_REPORT && (INFO_GTE(NAME, 2) || stdout_format_has_i > 1)) {
Expand Down Expand Up @@ -1120,35 +1125,40 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
static void list_file_entry(struct file_struct *f)
{
char permbuf[PERMSTRING_SIZE];
int64 len;
int colwidth = human_readable ? 14 : 11;
const char *mtime_str = timestring(f->modtime);
int size_width = human_readable ? 14 : 11;
int mtime_width = 1 + strlen(mtime_str);
int atime_width = atimes_ndx ? mtime_width : 0;

if (!F_IS_ACTIVE(f)) {
/* this can happen if duplicate names were removed */
return;
}

permstring(permbuf, f->mode);
len = F_LENGTH(f);

/* TODO: indicate '+' if the entry has an ACL. */

#ifdef SUPPORT_LINKS
if (preserve_links && S_ISLNK(f->mode)) {
rprintf(FINFO, "%s %*s %s %s -> %s\n",
permbuf, colwidth, human_num(len),
timestring(f->modtime), f_name(f, NULL),
F_SYMLINK(f));
} else
#endif
if (missing_args == 2 && f->mode == 0) {
rprintf(FINFO, "%-*s %s\n",
colwidth + 31, "*missing",
10 + 1 + size_width + mtime_width + atime_width, "*missing",
f_name(f, NULL));
} else {
rprintf(FINFO, "%s %*s %s %s\n",
permbuf, colwidth, human_num(len),
timestring(f->modtime), f_name(f, NULL));
const char *atime_str = atimes_ndx && !S_ISDIR(f->mode) ? timestring(F_ATIME(f)) : "";
const char *arrow, *lnk;

permstring(permbuf, f->mode);

#ifdef SUPPORT_LINKS
if (preserve_links && S_ISLNK(f->mode)) {
arrow = " -> ";
lnk = F_SYMLINK(f);
} else
#endif
arrow = lnk = "";

rprintf(FINFO, "%s %*s %s%*s %s%s%s\n",
permbuf, size_width, human_num(F_LENGTH(f)),
timestring(f->modtime), atime_width, atime_str,
f_name(f, NULL), arrow, lnk);
}
}

Expand Down Expand Up @@ -2064,8 +2074,13 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
do_chmod(fname, file->mode);
if (need_retouch_dir_times) {
STRUCT_STAT st;
if (link_stat(fname, &st, 0) == 0 && time_diff(&st, file))
set_modtime(fname, file->modtime, F_MOD_NSEC_or_0(file), file->mode);
if (link_stat(fname, &st, 0) == 0 && time_diff(&st, file)) {
st.st_mtime = file->modtime;
#ifdef ST_MTIME_NSEC
st.ST_MTIME_NSEC = F_MOD_NSEC_or_0(file);
#endif
set_times(fname, &st);
}
}
if (counter >= loopchk_limit) {
if (allowed_lull)
Expand Down
3 changes: 2 additions & 1 deletion log.c
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,8 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
c[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
c[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
c[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
c[8] = !(iflags & ITEM_REPORT_ATIME) ? '.' : 'u';
c[8] = !(iflags & ITEM_REPORT_ATIME) ? '.'
: S_ISLNK(file->mode) ? 'U' : 'u';
c[9] = !(iflags & ITEM_REPORT_ACL) ? '.' : 'a';
c[10] = !(iflags & ITEM_REPORT_XATTR) ? '.' : 'x';
c[11] = '\0';
Expand Down
22 changes: 22 additions & 0 deletions options.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ int preserve_specials = 0;
int preserve_uid = 0;
int preserve_gid = 0;
int preserve_times = 0;
int preserve_atimes = 0;
int update_only = 0;
int set_noatime = 0;
int cvs_exclude = 0;
int dry_run = 0;
int do_xfers = 1;
Expand Down Expand Up @@ -711,6 +713,8 @@ void usage(enum logcode F)
rprintf(F," --specials preserve special files\n");
rprintf(F," -D same as --devices --specials\n");
rprintf(F," -t, --times preserve modification times\n");
rprintf(F," -U, --atimes preserve access (last-used) times\n");
rprintf(F," --set-noatime avoid changing the atime on accessed files\n");
rprintf(F," -O, --omit-dir-times omit directories from --times\n");
rprintf(F," -J, --omit-link-times omit symlinks from --times\n");
rprintf(F," --super receiver attempts super-user activities\n");
Expand Down Expand Up @@ -872,6 +876,11 @@ static struct poptOption long_options[] = {
{"times", 't', POPT_ARG_VAL, &preserve_times, 1, 0, 0 },
{"no-times", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 },
{"no-t", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 },
{"atimes", 'U', POPT_ARG_NONE, 0, 'U', 0, 0 },
{"no-atimes", 0, POPT_ARG_VAL, &preserve_atimes, 0, 0, 0 },
{"no-U", 0, POPT_ARG_VAL, &preserve_atimes, 0, 0, 0 },
{"set-noatime", 0, POPT_ARG_VAL, &set_noatime, 1, 0, 0 },
{"no-set-noatime", 0, POPT_ARG_VAL, &set_noatime, 0, 0, 0 },
{"omit-dir-times", 'O', POPT_ARG_VAL, &omit_dir_times, 1, 0, 0 },
{"no-omit-dir-times",0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 },
{"no-O", 0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 },
Expand Down Expand Up @@ -1543,6 +1552,11 @@ int parse_arguments(int *argc_p, const char ***argv_p)
itemize_changes++;
break;

case 'U':
if (++preserve_atimes > 1)
set_noatime = 1;
break;

case 'v':
verbose++;
break;
Expand Down Expand Up @@ -2493,6 +2507,11 @@ void server_options(char **args, int *argc_p)
argstr[x++] = 'D';
if (preserve_times)
argstr[x++] = 't';
if (preserve_atimes) {
argstr[x++] = 'U';
if (preserve_atimes > 1)
argstr[x++] = 'U';
}
if (preserve_perms)
argstr[x++] = 'p';
else if (preserve_executability && am_sender)
Expand Down Expand Up @@ -2831,6 +2850,9 @@ void server_options(char **args, int *argc_p)
if (preallocate_files && am_sender)
args[ac++] = "--preallocate";

if (set_noatime && preserve_atimes <= 1)
args[ac++] = "--set-noatime";

if (ac > MAX_SERVER_ARGS) { /* Not possible... */
rprintf(FERROR, "argc overflow in server_options().\n");
exit_cleanup(RERR_MALLOC);
Expand Down
Loading

0 comments on commit b936741

Please sign in to comment.