The Samba-Bugzilla – Attachment 2960 Details for
Bug 4561
Add options --tweak, --no-tweak, --no-tweak-hlinked
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Implementation of --tweak options
tweak-opts.diff (text/plain), 13.11 KB, created by
Matt McCutchen
on 2007-11-04 14:51:51 UTC
(
hide
)
Description:
Implementation of --tweak options
Filename:
MIME Type:
Creator:
Matt McCutchen
Created:
2007-11-04 14:51:51 UTC
Size:
13.11 KB
patch
obsolete
>This patch adds --tweak, --no-tweak-hlinked, and --no-tweak options that >specify that rsync is allowed to tweak the attributes of all destination >files, only singly linked files, or no files (respectively). >--no-tweak-hlinked is important when receiving into a backup that may >contain files hard-linked from previous backups. --no-tweak may be useful >when all attributes at the destination path need to change simultaneously. > >TODO: Make --no-tweak-hlinked compatible with --inplace and --append. > >TODO: When rsync is updating a destination file with matching data but >differing abbreviated xattrs, find a way to update those xattrs before >moving the recreated destination file into place. > >--- old/generator.c >+++ new/generator.c >@@ -57,6 +57,7 @@ extern int update_only; > extern int ignore_existing; > extern int ignore_non_existing; > extern int inplace; >+extern int tweak_attrs; > extern int append_mode; > extern int make_backups; > extern int csum_length; >@@ -1144,6 +1145,11 @@ static void list_file_entry(struct file_ > } > } > >+static int may_tweak(STRUCT_STAT *st) >+{ >+ return tweak_attrs == 2 || (tweak_attrs == 1 && st->st_nlink == 1); >+} >+ > static int phase = 0; > static int dflt_perms; > >@@ -1682,13 +1688,28 @@ static void recv_generator(char *fname, > else if (fnamecmp_type == FNAMECMP_FUZZY) > ; > else if (unchanged_file(fnamecmp, file, &sx.st)) { >+ /* fnamecmp == fname, fnamecmp_type == FNAMECMP_FNAME */ >+ int iflags = 0; >+ > if (partialptr) { > do_unlink(partialptr); > handle_partial_dir(partialptr, PDIR_DELETE); > } >- set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT); >+ if (may_tweak(&sx.st)) { >+ if (verbose > 2) >+ rprintf(FINFO, "Tweaking attributes of %s\n", fname); >+ set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT); >+ } else if (!unchanged_attrs(fname, file, &sx)) { >+ /* Need to recreate the file. >+ * copy_altdest_file sets its attributes, etc. */ >+ if (verbose > 2) >+ rprintf(FINFO, "Recreating %s in order to tweak its attributes\n", fname); >+ if (!dry_run && copy_altdest_file(fnamecmp, fname, file)) >+ goto cleanup; >+ iflags |= ITEM_LOCAL_CHANGE; >+ } > if (itemizing) >- itemize(fnamecmp, file, ndx, statret, &sx, 0, 0, NULL); >+ itemize(fnamecmp, file, ndx, statret, &sx, iflags, 0, NULL); > #ifdef SUPPORT_HARD_LINKS > if (preserve_hard_links && F_IS_HLINKED(file)) > finish_hard_link(file, fname, ndx, &sx.st, itemizing, code, -1); >--- old/options.c >+++ new/options.c >@@ -118,6 +118,7 @@ int modify_window = 0; > int blocking_io = -1; > int checksum_seed = 0; > int inplace = 0; >+int tweak_attrs = 2; /* 2 = always, 1 = if not hlinked, 0 = never */ > int delay_updates = 0; > long block_size = 0; /* "long" because popt can't set an int32. */ > char *skip_compress = NULL; >@@ -322,6 +323,8 @@ void usage(enum logcode F) > rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n"); > rprintf(F," --append append data onto shorter files\n"); > rprintf(F," --append-verify like --append, but with old data in file checksum\n"); >+ rprintf(F," --no-tweak recreate dest files instead of tweaking attrs\n"); >+ rprintf(F," --no-tweak-hlinked ... if they have multiple hard links\n"); > rprintf(F," -d, --dirs transfer directories without recursing\n"); > rprintf(F," -l, --links copy symlinks as symlinks\n"); > rprintf(F," -L, --copy-links transform symlink into referent file/dir\n"); >@@ -532,6 +535,9 @@ static struct poptOption long_options[] > {"append", 0, POPT_ARG_NONE, 0, OPT_APPEND, 0, 0 }, > {"append-verify", 0, POPT_ARG_VAL, &append_mode, 2, 0, 0 }, > {"no-append", 0, POPT_ARG_VAL, &append_mode, 0, 0, 0 }, >+ {"no-tweak", 0, POPT_ARG_VAL, &tweak_attrs, 0, 0, 0 }, >+ {"no-tweak-hlinked", 0, POPT_ARG_VAL, &tweak_attrs, 1, 0, 0 }, >+ {"tweak", 0, POPT_ARG_VAL, &tweak_attrs, 2, 0, 0 }, > {"del", 0, POPT_ARG_NONE, &delete_during, 0, 0, 0 }, > {"delete", 0, POPT_ARG_NONE, &delete_mode, 0, 0, 0 }, > {"delete-before", 0, POPT_ARG_NONE, &delete_before, 0, 0, 0 }, >@@ -1536,11 +1542,24 @@ int parse_arguments(int *argc_p, const c > partial_dir = tmp_partialdir; > > if (inplace) { >+ char *inplace_opt = append_mode ? "append" : "inplace"; > #ifdef HAVE_FTRUNCATE >+ if (tweak_attrs == 0) { >+ snprintf(err_buf, sizeof err_buf, >+ "--no-tweak controverts --%s. Remove --%s.\n", >+ inplace_opt, inplace_opt); >+ return 0; >+ } >+ if (tweak_attrs == 1) { >+ snprintf(err_buf, sizeof err_buf, >+ "The combination of --no-tweak-hlinked and --%s is not implemented.\n", >+ inplace_opt); >+ return 0; >+ } > if (partial_dir) { > snprintf(err_buf, sizeof err_buf, > "--%s cannot be used with --%s\n", >- append_mode ? "append" : "inplace", >+ inplace_opt, > delay_updates ? "delay-updates" : "partial-dir"); > return 0; > } >@@ -1554,7 +1573,7 @@ int parse_arguments(int *argc_p, const c > #else > snprintf(err_buf, sizeof err_buf, > "--%s is not supported on this %s\n", >- append_mode ? "append" : "inplace", >+ inplace_opt, > am_server ? "server" : "client"); > return 0; > #endif >@@ -1885,6 +1904,8 @@ void server_options(char **args, int *ar > args[ac++] = "--super"; > if (size_only) > args[ac++] = "--size-only"; >+ if (tweak_attrs != 2) >+ args[ac++] = (tweak_attrs == 1) ? "--no-tweak-hlinked" : "--no-tweak"; > } else { > if (skip_compress) { > if (asprintf(&arg, "--skip-compress=%s", skip_compress) < 0) >--- old/receiver.c >+++ new/receiver.c >@@ -448,6 +448,9 @@ int recv_files(int f_in, char *local_nam > maybe_log_item(file, iflags, itemizing, xname); > #ifdef SUPPORT_XATTRS > if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && !dry_run) >+ /* If the file needed to be recreated before we >+ * set xattrs, the generator has already noticed >+ * the difference in xattrs and done so. */ > set_file_attrs(fname, file, NULL, fname, 0); > #endif > continue; >--- old/rsync.1 >+++ new/rsync.1 >@@ -404,6 +404,8 @@ to the detailed description below for a > \-\-inplace update destination files in-place > \-\-append append data onto shorter files > \-\-append\-verify \-\-append w/old data in file cheksum >+ \-\-no\-tweak recreate dest files rather than tweak attrs >+ \-\-no\-tweak\-hlinked ... if they are hard-linked > \-d, \-\-dirs transfer directories without recursing > \-l, \-\-links copy symlinks as symlinks > \-L, \-\-copy\-links transform symlink into referent file/dir >@@ -855,6 +857,28 @@ Note: prior to rsync 3.0.0, the \fB\-\-a > transfer is using a protocol prior to 30), specifying either append option > will initiate an \fB\-\-append\-verify\fP transfer. > .IP >+.IP "\fB\-\-no\-tweak\fP" >+If corresponding source and destination files are >+determined to have identical data but differ in preserved attributes, >+rsync normally tweaks the attributes of the destination file in place. >+This option makes it recreate the destination file instead. This may >+be useful if all attributes at the destination path need to change >+simultaneously. Caveat: in the current implementation, some extended >+attributes may be set after the recreated file is moved into place. >+.IP >+This option doesn't make sense in combination with \fB\-\-inplace\fP or >+\fB\-\-append\fP. >+.IP >+.IP "\fB\-\-no\-tweak\-hlinked\fP" >+Tells rsync to recreate a destination file >+instead of tweaking its attributes if it has multiple hard links. >+You can use \fB\-\-no\-tweak\-linked\fP to safely update a backup >+that has files hard-linked from a previous backup. >+.IP >+This option currently conflicts with \fB\-\-inplace\fP and \fB\-\-append\fP. In >+the future it might selectively disable those options for multiply linked >+destination files. >+.IP > .IP "\fB\-d, \-\-dirs\fP" > Tell the sending side to include any directories that > are encountered. Unlike \fB\-\-recursive\fP, a directory's contents are not copied >--- old/rsync.yo >+++ new/rsync.yo >@@ -329,6 +329,8 @@ to the detailed description below for a > --inplace update destination files in-place > --append append data onto shorter files > --append-verify --append w/old data in file cheksum >+ --no-tweak recreate dest files rather than tweak attrs >+ --no-tweak-hlinked ... if they are hard-linked > -d, --dirs transfer directories without recursing > -l, --links copy symlinks as symlinks > -L, --copy-links transform symlink into referent file/dir >@@ -739,6 +741,26 @@ bf(--append-verify), so if you are inter > transfer is using a protocol prior to 30), specifying either append option > will initiate an bf(--append-verify) transfer. > >+dit(bf(--no-tweak)) If corresponding source and destination files are >+determined to have identical data but differ in preserved attributes, >+rsync normally tweaks the attributes of the destination file in place. >+This option makes it recreate the destination file instead. This may >+be useful if all attributes at the destination path need to change >+simultaneously. Caveat: in the current implementation, some extended >+attributes may be set after the recreated file is moved into place. >+ >+This option doesn't make sense in combination with bf(--inplace) or >+bf(--append). >+ >+dit(bf(--no-tweak-hlinked)) Tells rsync to recreate a destination file >+instead of tweaking its attributes if it has multiple hard links. >+You can use bf(--no-tweak-linked) to safely update a backup >+that has files hard-linked from a previous backup. >+ >+This option currently conflicts with bf(--inplace) and bf(--append). In >+the future it might selectively disable those options for multiply linked >+destination files. >+ > dit(bf(-d, --dirs)) Tell the sending side to include any directories that > are encountered. Unlike bf(--recursive), a directory's contents are not copied > unless the directory name specified is "." or ends with a trailing slash >--- /dev/null >+++ new/testsuite/tweak-opts.test >@@ -0,0 +1,105 @@ >+#! /bin/sh >+ >+# This program is distributable under the terms of the GNU GPL (see >+# COPYING). >+ >+# Test the --tweak, --no-tweak, and --no-tweak-hlinked options. >+ >+. $srcdir/testsuite/rsync.fns >+ >+chkfile="$scratchdir/rsync.chk" >+outfile="$scratchdir/rsync.out" >+ >+makepath "$fromdir" >+echo data >"$fromdir/file1" >+echo data >"$fromdir/file2" >+echo data >"$fromdir/file3" >+chmod 600 "$fromdir/file1" "$fromdir/file2" "$fromdir/file3" >+ >+# testit <option> <which-attr> <changes-file2hl> <<EOI >+# cf...p..... file1 >+# cf...p..... file2 >+# EOI >+testit() { >+ option="$1" >+ whichattr=$2 >+ cf2hl=$3 >+ >+ rm -rf "$todir" >+ $RSYNC -a "$fromdir/" "$todir/" >+ case $whichattr in >+ p) >+ chmod 700 "$todir/file1" "$todir/file2" >+ ;; >+ t) >+ # Make sure unchanged_attrs signals a difference in mtime >+ touch -d @1194208678 "$todir/file1" "$todir/file2" >+ option="$option --checksum" >+ ;; >+ esac >+ ln "$todir/file2" "$todir/file2hl" >+ ln "$todir/file3" "$todir/file3hl" >+ >+ testid="$option $whichattr" >+ echo "Running test: ($testid)" >+ cat >"$chkfile" >+ $RSYNC -a -i --omit-dir-times $option "$fromdir/" "$todir/" | tee "$outfile" >+ diff $diffopt "$chkfile" "$outfile" || test_fail "itemize mismatch for test ($testid)" >+ >+ if [ $cf2hl ]; then >+ [ "$todir/file2" -ef "$todir/file2hl" ] || test_fail "rsync should not have broken the file2 hard link" >+ if [ $whichattr == p ]; then >+ check_perms "$todir/file2hl" rw------- "test ($testid)" >+ fi >+ else >+ ! [ "$todir/file2" -ef "$todir/file2hl" ] || test_fail "rsync should have broken the file2 hard link" >+ if [ $whichattr == p ]; then >+ check_perms "$todir/file2hl" rwx------ "test ($testid)" >+ fi >+ fi >+ >+ [ "$todir/file3" -ef "$todir/file3hl" ] || test_fail "rsync should not have broken the file3 hard link" >+} >+ >+# Default: --tweak >+testit '' p 1 <<EOI >+.f...p..... file1 >+.f...p..... file2 >+EOI >+testit '' t 1 <<EOI >+.f..t...... file1 >+.f..t...... file2 >+EOI >+ >+# Same thing >+testit '--no-tweak --tweak' p 1 <<EOI >+.f...p..... file1 >+.f...p..... file2 >+EOI >+testit '--no-tweak --tweak' t 1 <<EOI >+.f..t...... file1 >+.f..t...... file2 >+EOI >+ >+# Should recreate the second file, and attributes of file2hl should not change >+testit '--no-tweak-hlinked' p '' <<EOI >+.f...p..... file1 >+cf...p..... file2 >+EOI >+testit '--no-tweak-hlinked' t '' <<EOI >+.f..t...... file1 >+cf..t...... file2 >+EOI >+ >+# Should recreate the first file too >+testit '--no-tweak' p '' <<EOI >+cf...p..... file1 >+cf...p..... file2 >+EOI >+testit '--no-tweak' t '' <<EOI >+cf..t...... file1 >+cf..t...... file2 >+EOI >+ >+# The script would have aborted on error, so getting here means we've won. >+exit 0 >--- old/util.c >+++ new/util.c >@@ -264,8 +264,8 @@ static int safe_read(int desc, char *ptr > /* Copy a file. If ofd < 0, copy_file unlinks and opens the "dest" file. > * Otherwise, it just writes to and closes the provided file descriptor. > * >- * This is used in conjunction with the --temp-dir, --backup, and >- * --copy-dest options. */ >+ * This is used in conjunction with the --temp-dir, --backup, >+ * --copy-dest, and --no-tweak* options. */ > int copy_file(const char *source, const char *dest, int ofd, > mode_t mode, int create_bak_dir) > {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 4561
: 2960