Patch: Offline transfer mode
Wayne Davison
wayned at samba.org
Thu Mar 24 07:14:24 GMT 2005
On Wed, Mar 23, 2005 at 08:14:51PM -0800, Steve Traugott wrote:
> Do you mean just set f_out to batch_fd at the right time in
> send_files, then set it back before protocol shutdown?
Almost. I was thinking of just added an extra variable, f_xfer, that
would either have the f_out value in it or the batch_fd value.
> Looks like I'd still need to play with write_batch_monitor_out to get
> writefd() to call write() instead of letting it stray into
> writefd_unbuffered() or the iobuf stuff...
No, it's OK to use the normal write path to write to the batch_fd (and
there are other places in the code that already do this).
I'll append a patch that I made that takes what you did and tweaks it in
the way I talked about (it also happens to fix --dry-run when combined
with --read-batch or --write-batch).
My current choice of option name is to use --only-write-batch=FILE for
the mode that avoids updating the destination. This is certainly still
debatable, but I don't want to change the behavior of the normal
--write-batch=FILE option due to backward-compatibility reasons (i.e.
the --only-write-batch option sometimes needs to be sent to the server,
and older rsync versions might create remote batch files in such a
situation, which it would be good to avoid).
I've only minimally tested this so far, so check it out and see what you
think. This is not going to make it into 2.6.4 (which is too close to
final release), but a diff should make it into the patches dir.
..wayne..
-------------- next part --------------
--- batch.c 14 Mar 2005 17:30:10 -0000 1.51
+++ batch.c 24 Mar 2005 07:07:10 -0000
@@ -129,7 +129,7 @@ static void write_filter_rules(int fd)
* (hopefully) work. */
void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
{
- int fd, i;
+ int fd, i, len;
char *p, filename[MAXPATHLEN];
stringjoin(filename, sizeof filename,
@@ -165,11 +165,12 @@ void write_batch_shell_file(int argc, ch
continue;
}
write(fd, " ", 1);
- if (strncmp(p, "--write-batch", 13) == 0) {
+ if (strncmp(p, "--write-batch", len = 13) == 0
+ || strncmp(p, "--only-write-batch", len = 18) == 0) {
write(fd, "--read-batch", 12);
- if (p[13] == '=') {
+ if (p[len] == '=') {
write(fd, "=", 1);
- write_arg(fd, p + 14);
+ write_arg(fd, p + len + 1);
}
} else
write_arg(fd, p);
--- generator.c 17 Mar 2005 08:59:48 -0000 1.190
+++ generator.c 24 Mar 2005 07:07:12 -0000
@@ -25,6 +25,7 @@
extern int verbose;
extern int dry_run;
+extern int do_xfers;
extern int log_format_has_i;
extern int log_format_has_o_or_i;
extern int daemon_log_format_has_i;
@@ -1002,7 +1003,7 @@ prepare_to_open:
statret = 0;
}
- if (dry_run || read_batch || whole_file)
+ if (!do_xfers || read_batch || whole_file)
goto notify_others;
if (fuzzy_basis) {
@@ -1074,7 +1075,7 @@ notify_others:
fuzzy_file ? fuzzy_file->basename : NULL);
}
- if (dry_run) {
+ if (!do_xfers) {
if (preserve_hard_links && file->link_u.links)
hard_link_cluster(file, ndx, itemizing, code);
return;
@@ -1122,9 +1123,9 @@ void generate_files(int f_out, struct fi
maybe_PERMS_REPORT = log_format_has_i ? 0 : PERMS_REPORT;
code = daemon_log_format_has_i ? 0 : FLOG;
} else if (am_daemon) {
- itemizing = daemon_log_format_has_i && !dry_run;
+ itemizing = daemon_log_format_has_i && do_xfers;
maybe_PERMS_REPORT = PERMS_REPORT;
- code = itemizing || dry_run ? FCLIENT : FINFO;
+ code = itemizing || !do_xfers ? FCLIENT : FINFO;
} else if (!am_server) {
itemizing = log_format_has_i;
maybe_PERMS_REPORT = log_format_has_i ? 0 : PERMS_REPORT;
--- main.c 15 Mar 2005 17:30:50 -0000 1.266
+++ main.c 24 Mar 2005 07:07:12 -0000
@@ -168,7 +168,7 @@ static void report(int f)
stats.flist_buildtime = read_longint(f);
stats.flist_xfertime = read_longint(f);
}
- } else if (write_batch) {
+ } else if (write_batch && !am_server) {
/* The --read-batch process is going to be a client
* receiver, so we need to give it the stats. */
write_longint(batch_fd, total_read);
@@ -583,7 +583,7 @@ static int do_recv(int f_in,int f_out,st
am_generator = 1;
close_multiplexing_in();
- if (write_batch)
+ if (write_batch && !am_server)
stop_write_batch();
close(error_pipe[1]);
@@ -756,7 +756,7 @@ int client_run(int f_in, int f_out, pid_
if (filesfrom_host)
filesfrom_fd = f_in;
- if (write_batch)
+ if (write_batch && !am_server)
start_write_batch(f_out);
flist = send_file_list(f_out, argc, argv);
set_msg_fd_in(-1);
@@ -793,7 +793,7 @@ int client_run(int f_in, int f_out, pid_
filesfrom_fd = -1;
}
- if (write_batch)
+ if (write_batch && !am_server)
start_write_batch(f_in);
flist = recv_file_list(f_in);
if (!flist || flist->count == 0) {
@@ -1111,7 +1111,7 @@ int main(int argc,char *argv[])
init_flist();
- if (write_batch || read_batch) {
+ if ((write_batch || read_batch) && !am_server) {
if (write_batch)
write_batch_shell_file(orig_argc, orig_argv, argc);
@@ -1130,6 +1130,8 @@ int main(int argc,char *argv[])
if (read_batch)
read_stream_flags(batch_fd);
}
+ if (write_batch < 0)
+ dry_run = 1;
if (am_daemon && !am_server)
return daemon_main();
--- options.c 17 Mar 2005 00:52:33 -0000 1.254
+++ options.c 24 Mar 2005 07:07:13 -0000
@@ -53,6 +53,7 @@ int omit_dir_times = 0;
int update_only = 0;
int cvs_exclude = 0;
int dry_run = 0;
+int do_xfers = 1;
int ignore_times = 0;
int delete_mode = 0;
int delete_during = 0;
@@ -344,6 +345,7 @@ void usage(enum logcode F)
rprintf(F," --list-only list the files instead of copying them\n");
rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
rprintf(F," --write-batch=FILE write a batched update to FILE\n");
+ rprintf(F," --only-write-batch=FILE like --write-batch but w/o updating destination\n");
rprintf(F," --read-batch=FILE read a batched update from FILE\n");
#ifdef INET6
rprintf(F," -4, --ipv4 prefer IPv4\n");
@@ -359,7 +361,8 @@ void usage(enum logcode F)
enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
OPT_FILTER, OPT_COMPARE_DEST, OPT_COPY_DEST, OPT_LINK_DEST,
OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
- OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_TIMEOUT, OPT_MAX_SIZE,
+ OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH,
+ OPT_TIMEOUT, OPT_MAX_SIZE,
OPT_REFUSED_BASE = 9000};
static struct poptOption long_options[] = {
@@ -449,6 +452,7 @@ static struct poptOption long_options[]
{"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links, 0, 0, 0 },
{"read-batch", 0, POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
{"write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
+ {"only-write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_ONLY_WRITE_BATCH, 0, 0 },
{"files-from", 0, POPT_ARG_STRING, &files_from, 0, 0, 0 },
{"from0", '0', POPT_ARG_NONE, &eol_nulls, 0, 0, 0},
{"no-implied-dirs", 0, POPT_ARG_VAL, &implied_dirs, 0, 0, 0 },
@@ -790,6 +794,11 @@ int parse_arguments(int *argc, const cha
write_batch = 1;
break;
+ case OPT_ONLY_WRITE_BATCH:
+ /* batch_name is already set */
+ write_batch = -1;
+ break;
+
case OPT_READ_BATCH:
/* batch_name is already set */
read_batch = 1;
@@ -900,13 +909,7 @@ int parse_arguments(int *argc, const cha
"--write-batch and --read-batch can not be used together\n");
return 0;
}
- if (write_batch || read_batch) {
- if (dry_run) {
- snprintf(err_buf, sizeof err_buf,
- "--%s-batch cannot be used with --dry_run (-n)\n",
- write_batch ? "write" : "read");
- return 0;
- }
+ if (write_batch > 0 || read_batch) {
if (am_server) {
rprintf(FINFO,
"ignoring --%s-batch option sent to server\n",
@@ -916,7 +919,8 @@ int parse_arguments(int *argc, const cha
* batch args to server. */
read_batch = write_batch = 0;
batch_name = NULL;
- }
+ } else if (dry_run)
+ write_batch = 0;
}
if (read_batch && files_from) {
snprintf(err_buf, sizeof err_buf,
@@ -1097,6 +1101,9 @@ int parse_arguments(int *argc, const cha
&& !am_server)
verbose = 1;
+ if (dry_run)
+ do_xfers = 0;
+
if (verbose && !log_format) {
log_format = "%n%L";
log_before_transfer = !am_server;
@@ -1250,7 +1257,7 @@ void server_options(char **args,int *arg
argstr[x++] = 'b';
if (update_only)
argstr[x++] = 'u';
- if (dry_run)
+ if (!do_xfers)
argstr[x++] = 'n';
if (preserve_links)
argstr[x++] = 'l';
@@ -1378,6 +1385,8 @@ void server_options(char **args,int *arg
args[ac++] = "--delete-after";
if (force_delete)
args[ac++] = "--force";
+ if (write_batch < 0)
+ args[ac++] = "--only-write-batch=X";
}
if (size_only)
--- pipe.c 7 Feb 2005 20:36:43 -0000 1.13
+++ pipe.c 24 Mar 2005 07:07:13 -0000
@@ -25,7 +25,6 @@ extern int am_sender;
extern int am_server;
extern int blocking_io;
extern int orig_umask;
-extern int write_batch;
extern int filesfrom_fd;
/**
@@ -128,10 +127,6 @@ pid_t local_child(int argc, char **argv,
am_sender = !am_sender;
am_server = 1;
- /* The server side never writes the batch, even if it
- * is local (it makes the logic easier elsewhere). */
- write_batch = 0;
-
if (!am_sender)
filesfrom_fd = -1;
--- receiver.c 15 Mar 2005 19:19:41 -0000 1.156
+++ receiver.c 24 Mar 2005 07:07:13 -0000
@@ -21,7 +21,7 @@
#include "rsync.h"
extern int verbose;
-extern int dry_run;
+extern int do_xfers;
extern int am_daemon;
extern int am_server;
extern int do_progress;
@@ -30,6 +30,7 @@ extern int log_format_has_i;
extern int daemon_log_format_has_i;
extern int csum_length;
extern int read_batch;
+extern int write_batch;
extern int batch_gen_fd;
extern int protocol_version;
extern int relative_paths;
@@ -435,9 +436,16 @@ int recv_files(int f_in, struct file_lis
exit_cleanup(RERR_PROTOCOL);
}
- if (dry_run) { /* log the transfer */
+ if (!do_xfers) { /* log the transfer */
if (!am_server && log_format)
log_item(file, &stats, iflags, NULL);
+ if (read_batch)
+ discard_receive_data(f_in, file->length);
+ continue;
+ }
+ if (write_batch < 0) {
+ log_item(file, &stats, iflags, NULL);
+ discard_receive_data(f_in, file->length);
continue;
}
--- sender.c 16 Mar 2005 01:06:33 -0000 1.84
+++ sender.c 24 Mar 2005 07:07:13 -0000
@@ -20,7 +20,7 @@
#include "rsync.h"
extern int verbose;
-extern int dry_run;
+extern int do_xfers;
extern int am_server;
extern int am_daemon;
extern int log_before_transfer;
@@ -34,6 +34,8 @@ extern int updating_basis_file;
extern int make_backups;
extern int do_progress;
extern int inplace;
+extern int batch_fd;
+extern int write_batch;
extern struct stats stats;
extern struct file_list *the_file_list;
extern char *log_format;
@@ -216,6 +218,7 @@ void send_files(struct file_list *flist,
int save_make_backups = make_backups;
int itemizing = am_daemon ? daemon_log_format_has_i
: !am_server && log_format_has_i;
+ int f_xfer = write_batch < 0 ? batch_fd : f_out;
int i, j;
if (verbose > 2)
@@ -238,7 +241,7 @@ void send_files(struct file_list *flist,
continue;
}
- iflags = read_item_attrs(f_in, f_out, i, &fnamecmp_type,
+ iflags = read_item_attrs(f_in, f_xfer, i, &fnamecmp_type,
xname, &xlen);
if (iflags == ITEM_IS_NEW) /* no-op packet */
continue;
@@ -274,10 +277,10 @@ void send_files(struct file_list *flist,
stats.num_transferred_files++;
stats.total_transferred_size += file->length;
- if (dry_run) { /* log the transfer */
+ if (!do_xfers) { /* log the transfer */
if (!am_server && log_format)
log_item(file, &stats, iflags, NULL);
- write_ndx_and_attrs(f_out, i, iflags, fnamecmp_type,
+ write_ndx_and_attrs(f_xfer, i, iflags, fnamecmp_type,
xname, xlen);
continue;
}
@@ -329,9 +332,9 @@ void send_files(struct file_list *flist,
safe_fname(fname), (double)st.st_size);
}
- write_ndx_and_attrs(f_out, i, iflags, fnamecmp_type,
+ write_ndx_and_attrs(f_xfer, i, iflags, fnamecmp_type,
xname, xlen);
- write_sum_head(f_out, s);
+ write_sum_head(f_xfer, s);
if (verbose > 2) {
rprintf(FINFO, "calling match_sums %s\n",
@@ -345,7 +348,7 @@ void send_files(struct file_list *flist,
set_compression(fname);
- match_sums(f_out, s, mbuf, st.st_size);
+ match_sums(f_xfer, s, mbuf, st.st_size);
if (do_progress)
end_progress(st.st_size);
More information about the rsync
mailing list