From: Wayne Davison Date: Sat, 17 Jan 2009 22:46:42 +0000 (-0800) Subject: Fixed the delete statistics with --delete-delay and --delete-after. X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/commitdiff_plain/bc40a305032db262e72b92c938203fd2bd42e4c9 Fixed the delete statistics with --delete-delay and --delete-after. --- diff --git a/generator.c b/generator.c index 6b127206..cd67f0fc 100644 --- a/generator.c +++ b/generator.c @@ -121,6 +121,9 @@ static void handle_skipped_hlink(struct file_struct *file, int itemizing, enum logcode code, int f_out); #endif +#define EARLY_DELAY_DONE_MSG() (!delay_updates) +#define EARLY_DELETE_DONE_MSG() (!(delete_during == 2 || delete_after)) + static int start_delete_delay_temp(void) { char fnametmp[MAXPATHLEN]; @@ -2103,12 +2106,18 @@ void generate_files(int f_out, const char *local_name) rprintf(FINFO, "generate_files phase=%d\n", phase); write_ndx(f_out, NDX_DONE); - write_del_stats(f_out); /* Reduce round-trip lag-time for a useless delay-updates phase. */ - if (protocol_version >= 29 && !delay_updates) + if (protocol_version >= 29 && EARLY_DELAY_DONE_MSG()) write_ndx(f_out, NDX_DONE); + if (protocol_version >= 31 && EARLY_DELETE_DONE_MSG()) { + if ((INFO_GTE(STATS, 2) && (delete_mode || force_delete)) || read_batch) + write_del_stats(f_out); + if (EARLY_DELAY_DONE_MSG()) /* Can't send this before delay */ + write_ndx(f_out, NDX_DONE); + } + /* Read MSG_DONE for the redo phase (and any prior messages). */ while (1) { check_for_finished_files(itemizing, code, 0); @@ -2121,8 +2130,11 @@ void generate_files(int f_out, const char *local_name) phase++; if (DEBUG_GTE(GENR, 1)) rprintf(FINFO, "generate_files phase=%d\n", phase); - if (delay_updates) + if (!EARLY_DELAY_DONE_MSG()) { write_ndx(f_out, NDX_DONE); + if (protocol_version >= 31 && EARLY_DELETE_DONE_MSG()) + write_ndx(f_out, NDX_DONE); + } /* Read MSG_DONE for delay-updates phase & prior messages. */ while (msgdone_cnt == 2) wait_for_receiver(); @@ -2136,10 +2148,6 @@ void generate_files(int f_out, const char *local_name) if (delete_after && !solo_file && file_total > 0) do_delete_pass(); - if ((need_retouch_dir_perms || need_retouch_dir_times) - && dir_tweaking && (!inc_recurse || delete_during == 2)) - touch_up_dirs(dir_flist, -1); - if (max_delete >= 0 && skipped_deletes) { rprintf(FWARNING, "Deletions stopped due to --max-delete limit (%d skipped)\n", @@ -2147,6 +2155,22 @@ void generate_files(int f_out, const char *local_name) io_error |= IOERR_DEL_LIMIT; } + if (protocol_version >= 31) { + if (!EARLY_DELETE_DONE_MSG()) { + if (INFO_GTE(STATS, 2) || read_batch) + write_del_stats(f_out); + write_ndx(f_out, NDX_DONE); + } + + /* Read MSG_DONE for late-delete phase & prior messages. */ + while (msgdone_cnt == 3) + wait_for_receiver(); + } + + if ((need_retouch_dir_perms || need_retouch_dir_times) + && dir_tweaking && (!inc_recurse || delete_during == 2)) + touch_up_dirs(dir_flist, -1); + if (DEBUG_GTE(GENR, 1)) rprintf(FINFO, "generate_files finished\n"); } diff --git a/io.c b/io.c index 12e648d4..5f70e819 100644 --- a/io.c +++ b/io.c @@ -1049,6 +1049,13 @@ static int readfd_unbuffered(int fd, char *buf, size_t len) send_msg_int(MSG_IO_ERROR, IVAL(line, 0)); io_error |= IVAL(line, 0); break; + case MSG_DEL_STATS: + if (msg_bytes) + goto invalid_msg; + read_del_stats(fd); + if (am_sender && am_server) + write_del_stats(sock_f_out); + break; case MSG_DELETED: if (msg_bytes >= sizeof line) goto overflow; diff --git a/main.c b/main.c index 37496055..ec2e43ae 100644 --- a/main.c +++ b/main.c @@ -173,8 +173,10 @@ static void wait_process_with_flush(pid_t pid, int *exit_code_ptr) void write_del_stats(int f) { - if (!INFO_GTE(STATS, 2) || protocol_version < 31) - return; + if (read_batch) + write_int(f, NDX_DEL_STATS); + else + send_msg(MSG_DEL_STATS, "", 0, 0); write_varint(f, stats.deleted_files - stats.deleted_dirs - stats.deleted_symlinks - stats.deleted_devices - stats.deleted_specials); @@ -186,8 +188,6 @@ void write_del_stats(int f) void read_del_stats(int f) { - if (!INFO_GTE(STATS, 2) || protocol_version < 31) - return; stats.deleted_files = read_varint(f); stats.deleted_files += stats.deleted_dirs = read_varint(f); stats.deleted_files += stats.deleted_symlinks = read_varint(f); @@ -234,7 +234,6 @@ static void handle_stats(int f) write_varlong30(f, stats.flist_buildtime, 3); write_varlong30(f, stats.flist_xfertime, 3); } - write_del_stats(f); } return; } @@ -253,8 +252,6 @@ static void handle_stats(int f) stats.flist_buildtime = read_varlong30(f, 3); stats.flist_xfertime = read_varlong30(f, 3); } - if (!read_batch) - read_del_stats(f); } else if (write_batch) { /* The --read-batch process is going to be a client * receiver, so we need to give it the stats. */ @@ -265,8 +262,6 @@ static void handle_stats(int f) write_varlong30(batch_fd, stats.flist_buildtime, 3); write_varlong30(batch_fd, stats.flist_xfertime, 3); } - /* We don't write the del stats into the batch file -- they - * come from the generator when reading the batch. */ } } @@ -716,7 +711,7 @@ static void check_alt_basis_dirs(void) } /* This is only called by the sender. */ -static void read_final_goodbye(int f_in) +static void read_final_goodbye(int f_in, int f_out) { int i, iflags, xlen; uchar fnamecmp_type; @@ -725,8 +720,19 @@ static void read_final_goodbye(int f_in) if (protocol_version < 29) i = read_int(f_in); else { - i = read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type, - xname, &xlen); + i = read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type, xname, &xlen); + if (protocol_version >= 31 && i == NDX_DONE) { + if (am_sender) + write_ndx(f_out, NDX_DONE); + else { + if (batch_gen_fd >= 0) { + while (read_int(batch_gen_fd) != NDX_DEL_STATS) {} + read_del_stats(batch_gen_fd); + } + send_msg(MSG_DONE, "", 0, 0); + } + i = read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type, xname, &xlen); + } } if (i != NDX_DONE) { @@ -785,7 +791,7 @@ static void do_server_sender(int f_in, int f_out, int argc, char *argv[]) io_flush(FULL_FLUSH); handle_stats(f_out); if (protocol_version >= 24) - read_final_goodbye(f_in); + read_final_goodbye(f_in, f_out); io_flush(FULL_FLUSH); exit_cleanup(0); } @@ -846,15 +852,10 @@ static int do_recv(int f_in, int f_out, char *local_name) /* Handle any keep-alive packets from the post-processing work * that the generator does. */ if (protocol_version >= 29) { - int iflags, xlen; - uchar fnamecmp_type; - char xname[MAXPATHLEN]; - kluge_around_eof = -1; /* This should only get stopped via a USR2 signal. */ - read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type, - xname, &xlen); + read_final_goodbye(f_in, f_out); rprintf(FERROR, "Invalid packet at end of run [%s]\n", who_am_i()); @@ -1102,7 +1103,7 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) io_flush(FULL_FLUSH); handle_stats(-1); if (protocol_version >= 24) - read_final_goodbye(f_in); + read_final_goodbye(f_in, f_out); if (pid != -1) { if (DEBUG_GTE(EXIT, 2)) rprintf(FINFO,"client_run waiting on %d\n", (int) pid); diff --git a/receiver.c b/receiver.c index cd24320d..74c2e752 100644 --- a/receiver.c +++ b/receiver.c @@ -836,11 +836,6 @@ int recv_files(int f_in, char *local_name) if (phase == 2 && delay_updates) /* for protocol_version < 29 */ handle_delayed_updates(local_name); - if (read_batch) { - read_int(batch_gen_fd); /* Discard -1 */ - read_del_stats(batch_gen_fd); - } - if (DEBUG_GTE(RECV, 1)) rprintf(FINFO,"recv_files finished\n"); diff --git a/rsync.h b/rsync.h index bcce2f03..d6384f8b 100644 --- a/rsync.h +++ b/rsync.h @@ -96,7 +96,7 @@ /* This is used when working on a new protocol version in CVS, and should * be a new non-zero value for each CVS change that affects the protocol. * It must ALWAYS be 0 when the protocol goes final (and NEVER before)! */ -#define SUBPROTOCOL_VERSION 3 +#define SUBPROTOCOL_VERSION 4 /* We refuse to interoperate with versions that are not in this range. * Note that we assume we'll work with later versions: the onus is on @@ -226,6 +226,7 @@ enum msgcode { MSG_ERROR_UTF8=FERROR_UTF8, /* sibling logging */ MSG_LOG=FLOG, MSG_CLIENT=FCLIENT, /* sibling logging */ MSG_REDO=9, /* reprocess indicated flist index */ + MSG_DEL_STATS=10,/* delete-statistics data follows */ MSG_FLIST=20, /* extra file list over sibling socket */ MSG_FLIST_EOF=21,/* we've transmitted all the file lists */ MSG_IO_ERROR=22,/* the sending side had an I/O error */ @@ -238,6 +239,7 @@ enum msgcode { #define NDX_DONE -1 #define NDX_FLIST_EOF -2 +#define NDX_DEL_STATS -2 #define NDX_FLIST_OFFSET -101 /* For calling delete_item() and delete_dir_contents(). */ diff --git a/sender.c b/sender.c index 8506ac66..bf8221de 100644 --- a/sender.c +++ b/sender.c @@ -201,8 +201,6 @@ void send_files(int f_in, int f_out) break; if (DEBUG_GTE(SEND, 1)) rprintf(FINFO, "send_files phase=%d\n", phase); - if (phase == 2) - read_del_stats(f_in); write_ndx(f_out, NDX_DONE); continue; }