From: Wayne Davison Date: Sun, 5 Apr 2020 21:52:32 +0000 (-0700) Subject: Add progress output via SIGINFO and SIGVTALRM X-Git-Tag: v3.2.0pre1~190 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=15fa9ab06d42965346b7a3941c0fd31cb0b5aec6;p=thirdparty%2Frsync.git Add progress output via SIGINFO and SIGVTALRM On BSD-ish systems you can type Ctrl+T to see the current file and the progress output (in --info=progress2 format). On hosts w/o SIGINFO, use something like "killall -VTALRM rsync" or a more targetted "kill -VTALRM PID ..." call (as needed). --- diff --git a/main.c b/main.c index eda8d624..b594ab82 100644 --- a/main.c +++ b/main.c @@ -76,6 +76,7 @@ extern pid_t cleanup_child_pid; extern size_t bwlimit_writemax; extern unsigned int module_dirlen; extern BOOL flist_receiving_enabled; +extern BOOL want_progress_now; extern BOOL shutting_down; extern int backup_dir_len; extern int basis_dir_cnt; @@ -1551,6 +1552,12 @@ static void sigusr2_handler(UNUSED(int val)) _exit(0); } +static void siginfo_handler(UNUSED(int val)) +{ + if (!am_server && !INFO_GTE(PROGRESS, 1)) + want_progress_now = True; +} + void remember_children(UNUSED(int val)) { #ifdef WNOHANG @@ -1648,6 +1655,12 @@ int main(int argc,char *argv[]) SIGACTMASK(SIGABRT, rsync_panic_handler); SIGACTMASK(SIGBUS, rsync_panic_handler); #endif +#ifdef SIGINFO + SIGACTMASK(SIGINFO, siginfo_handler); +#endif +#ifdef SIGVTALRM + SIGACTMASK(SIGVTALRM, siginfo_handler); +#endif starttime = time(NULL); our_uid = MY_UID(); diff --git a/progress.c b/progress.c index 6676126c..d1cf8caa 100644 --- a/progress.c +++ b/progress.c @@ -28,9 +28,12 @@ extern int flist_eof; extern int quiet; extern int need_unsorted_flist; extern int output_needs_newline; +extern int stdout_format_has_i; extern struct stats stats; extern struct file_list *cur_flist; +BOOL want_progress_now = False; + #define PROGRESS_HISTORY_SECS 5 #ifdef GETPGRP_VOID @@ -134,6 +137,16 @@ static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now, } } +void progress_init(void) +{ + if (!am_server && !INFO_GTE(PROGRESS, 1)) { + struct timeval now; + gettimeofday(&now, NULL); + ph_start.time.tv_sec = now.tv_sec; + ph_start.time.tv_usec = now.tv_usec; + } +} + void set_current_file_index(struct file_struct *file, int ndx) { if (!file) @@ -145,12 +158,21 @@ void set_current_file_index(struct file_struct *file, int ndx) current_file_index -= cur_flist->flist_num; } +void instant_progress(const char *fname) +{ + /* We only get here if want_progress_now is True */ + if (!stdout_format_has_i && !INFO_GTE(NAME, 1)) + rprintf(FINFO, "%s\n", fname); + end_progress(0); + want_progress_now = False; +} + void end_progress(OFF_T size) { if (!am_server) { struct timeval now; gettimeofday(&now, NULL); - if (INFO_GTE(PROGRESS, 2)) { + if (INFO_GTE(PROGRESS, 2) || want_progress_now) { rprint_progress(stats.total_transferred_size, stats.total_size, &now, True); } else { diff --git a/receiver.c b/receiver.c index e7441f4d..adfa8047 100644 --- a/receiver.c +++ b/receiver.c @@ -55,6 +55,7 @@ extern int inplace; extern int allowed_lull; extern int delay_updates; extern int xfersum_type; +extern BOOL want_progress_now; extern mode_t orig_umask; extern struct stats stats; extern char *tmpdir; @@ -537,6 +538,8 @@ int recv_files(int f_in, int f_out, char *local_name) if (delay_updates) delayed_bits = bitbag_create(cur_flist->used + 1); + progress_init(); + while (1) { cleanup_disable(); @@ -544,9 +547,10 @@ int recv_files(int f_in, int f_out, char *local_name) ndx = read_ndx_and_attrs(f_in, f_out, &iflags, &fnamecmp_type, xname, &xlen); if (ndx == NDX_DONE) { - if (!am_server && INFO_GTE(PROGRESS, 2) && cur_flist) { + if (!am_server && cur_flist) { set_current_file_index(NULL, 0); - end_progress(0); + if (INFO_GTE(PROGRESS, 2)) + end_progress(0); } if (inc_recurse && first_flist) { if (read_batch) { @@ -646,7 +650,7 @@ int recv_files(int f_in, int f_out, char *local_name) stats.created_files++; } - if (!am_server && INFO_GTE(PROGRESS, 1)) + if (!am_server) set_current_file_index(file, ndx); stats.xferred_files++; stats.total_transferred_size += F_LENGTH(file); @@ -859,6 +863,8 @@ int recv_files(int f_in, int f_out, char *local_name) recv_ok = receive_data(f_in, fnamecmp, fd1, st.st_size, fname, fd2, file); log_item(log_code, file, iflags, NULL); + if (want_progress_now) + instant_progress(fname); if (fd1 != -1) close(fd1); diff --git a/rsync.yo b/rsync.yo index 40b3fe7e..71378614 100644 --- a/rsync.yo +++ b/rsync.yo @@ -2581,6 +2581,17 @@ want to see how the transfer is doing without scrolling the screen with a lot of names. (You don't need to specify the bf(--progress) option in order to use bf(--info=progress2).) +Finally, you can get an instant progress report by sending rsync a signal of +either SIGINFO or SIGVTALRM On BSD systems a SIGINFO is often generated just by +typing a Ctrl+T (Linux doesn't currently support a SIGINFO signal). When the +client-side process receives one of those signals, it will output a single +progress report when the current file being transferred finishes (so it may +take a little time if a big file is being handled when the signal arrives). +A filename is output (if needed) followed by the --info=progress2 format of +progress info. You can send the SIGVTALRM signal to all of the rsync processes +but just the client-side process will respond. Be careful not to send that +signal to an older rsync, though, or it will die. + dit(bf(--password-file=FILE)) This option allows you to provide a password for accessing an rsync daemon via a file or via standard input if bf(FILE) is bf(-). The file should contain just the password on the first line (all other diff --git a/sender.c b/sender.c index 13113803..27c511ef 100644 --- a/sender.c +++ b/sender.c @@ -45,6 +45,7 @@ extern int inplace; extern int batch_fd; extern int write_batch; extern int file_old_total; +extern BOOL want_progress_now; extern struct stats stats; extern struct file_list *cur_flist, *first_flist, *dir_flist; @@ -206,6 +207,8 @@ void send_files(int f_in, int f_out) if (DEBUG_GTE(SEND, 1)) rprintf(FINFO, "send_files starting\n"); + progress_init(); + while (1) { if (inc_recurse) { send_extra_file_list(f_out, MIN_FILECNT_LOOKAHEAD); @@ -218,9 +221,10 @@ void send_files(int f_in, int f_out) extra_flist_sending_enabled = False; if (ndx == NDX_DONE) { - if (!am_server && INFO_GTE(PROGRESS, 2) && cur_flist) { + if (!am_server && cur_flist) { set_current_file_index(NULL, 0); - end_progress(0); + if (INFO_GTE(PROGRESS, 2)) + end_progress(0); } if (inc_recurse && first_flist) { file_old_total -= first_flist->used; @@ -315,7 +319,7 @@ void send_files(int f_in, int f_out) updating_basis_file = inplace && (protocol_version >= 29 ? fnamecmp_type == FNAMECMP_FNAME : make_backups <= 0); - if (!am_server && INFO_GTE(PROGRESS, 1)) + if (!am_server) set_current_file_index(file, ndx); stats.xferred_files++; stats.total_transferred_size += F_LENGTH(file); @@ -393,6 +397,8 @@ void send_files(int f_in, int f_out) match_sums(f_xfer, s, mbuf, st.st_size); if (INFO_GTE(PROGRESS, 1)) end_progress(st.st_size); + else if (want_progress_now) + instant_progress(fname); log_item(log_code, file, iflags, NULL);