]> git.ipfire.org Git - thirdparty/rsync.git/commitdiff
Add progress output via SIGINFO and SIGVTALRM
authorWayne Davison <wayned@samba.org>
Sun, 5 Apr 2020 21:52:32 +0000 (14:52 -0700)
committerWayne Davison <wayned@samba.org>
Sun, 5 Apr 2020 22:07:31 +0000 (15:07 -0700)
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).

main.c
progress.c
receiver.c
rsync.yo
sender.c

diff --git a/main.c b/main.c
index eda8d62459002f87083040b13a98f941b310ef99..b594ab82829d6838ddedfd211814451ce2efa590 100644 (file)
--- 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();
index 6676126cfe59e5e4f0ff19df0739f4dc654a9468..d1cf8caa4de842f9bae79b658ca6a7fbe914409d 100644 (file)
@@ -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 {
index e7441f4d756b1f3f4111e04e6653424b611609b2..adfa8047189612fd68e4a15e38270625084949a7 100644 (file)
@@ -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);
index 40b3fe7e0cd5c849502b2bb83a8599703074a2a6..7137861493ff464345a6be22bbe4658e9b8598c6 100644 (file)
--- 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
index 131138033bee26f1b47ed61f6c0cb25bfecd4e4b..27c511ef63a3a69b2af0cad42f5a4ffd99aebf02 100644 (file)
--- 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);