Improved the fix that ensures that the generator gets notified about an
authorWayne Davison <wayned@samba.org>
Sun, 31 Aug 2008 16:03:50 +0000 (09:03 -0700)
committerWayne Davison <wayned@samba.org>
Sun, 31 Aug 2008 16:43:39 +0000 (09:43 -0700)
I/O error for the incremental directory that generated the error.  The
PROTOCOL_VERSION was bumped to 31 to implement this.

NEWS
OLDNEWS
flist.c
generator.c
io.c
main.c
rsync.c
rsync.h

diff --git a/NEWS b/NEWS
index 02be935..6703aa6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,5 @@
 NEWS for rsync 3.1.0 (UNRELEASED)
 NEWS for rsync 3.1.0 (UNRELEASED)
-Protocol: 30 (unchanged)
+Protocol: 31 (changed)
 Changes since 3.0.4:
 
   BUG FIXES:
 Changes since 3.0.4:
 
   BUG FIXES:
diff --git a/OLDNEWS b/OLDNEWS
index bb0f17d..33348a1 100644 (file)
--- a/OLDNEWS
+++ b/OLDNEWS
@@ -2841,7 +2841,7 @@ Changes since 2.4.6:
 \f
 Partial Protocol History
        RELEASE DATE    VER.    DATE OF COMMIT* PROTOCOL
 \f
 Partial Protocol History
        RELEASE DATE    VER.    DATE OF COMMIT* PROTOCOL
-       ?? ??? 2008     3.1.0                   30
+       ?? ??? 2008     3.1.0   31 Aug 2008     31
        29 Jun 2008     3.0.3                   30
        08 Apr 2008     3.0.2                   30
        03 Apr 2008     3.0.1                   30
        29 Jun 2008     3.0.3                   30
        08 Apr 2008     3.0.2                   30
        03 Apr 2008     3.0.1                   30
diff --git a/flist.c b/flist.c
index d11437f..92e89a2 100644 (file)
--- a/flist.c
+++ b/flist.c
@@ -1916,7 +1916,12 @@ void send_extra_file_list(int f, int at_least)
                        dp = F_DIR_NODE_P(file);
                }
 
                        dp = F_DIR_NODE_P(file);
                }
 
-               write_byte(f, 0);
+               if (protocol_version < 31 || io_error == save_io_error || ignore_errors)
+                       write_byte(f, 0);
+               else {
+                       write_shortint(f, XMIT_EXTENDED_FLAGS|XMIT_IO_ERROR_ENDLIST);
+                       write_int(f, io_error);
+               }
 
                if (need_unsorted_flist) {
                        if (!(flist->sorted = new_array(struct file_struct *, flist->used)))
 
                if (need_unsorted_flist) {
                        if (!(flist->sorted = new_array(struct file_struct *, flist->used)))
@@ -1957,7 +1962,7 @@ void send_extra_file_list(int f, int at_least)
        }
 
   finish:
        }
 
   finish:
-       if (io_error != save_io_error && !ignore_errors)
+       if (io_error != save_io_error && protocol_version == 30 && !ignore_errors)
                send_msg_int(MSG_IO_ERROR, io_error);
 }
 
                send_msg_int(MSG_IO_ERROR, io_error);
 }
 
@@ -2213,7 +2218,13 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
                stats.flist_buildtime = 1;
        start_tv = end_tv;
 
                stats.flist_buildtime = 1;
        start_tv = end_tv;
 
-       write_byte(f, 0); /* Indicate end of file list */
+       /* Indicate end of file list */
+       if (protocol_version < 31 || io_error == 0 || ignore_errors)
+               write_byte(f, 0);
+       else {
+               write_shortint(f, XMIT_EXTENDED_FLAGS|XMIT_IO_ERROR_ENDLIST);
+               write_int(f, io_error);
+       }
 
 #ifdef SUPPORT_HARD_LINKS
        if (preserve_hard_links && protocol_version >= 30 && !inc_recurse)
 
 #ifdef SUPPORT_HARD_LINKS
        if (preserve_hard_links && protocol_version >= 30 && !inc_recurse)
@@ -2251,7 +2262,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
        /* send the io_error flag */
        if (protocol_version < 30)
                write_int(f, ignore_errors ? 0 : io_error);
        /* send the io_error flag */
        if (protocol_version < 30)
                write_int(f, ignore_errors ? 0 : io_error);
-       else if (io_error && !ignore_errors)
+       else if (io_error && protocol_version == 30 && !ignore_errors)
                send_msg_int(MSG_IO_ERROR, io_error);
 
        if (disable_buffering)
                send_msg_int(MSG_IO_ERROR, io_error);
 
        if (disable_buffering)
@@ -2322,10 +2333,22 @@ struct file_list *recv_file_list(int f)
        while ((flags = read_byte(f)) != 0) {
                struct file_struct *file;
 
        while ((flags = read_byte(f)) != 0) {
                struct file_struct *file;
 
-               flist_expand(flist, 1);
-
                if (protocol_version >= 28 && (flags & XMIT_EXTENDED_FLAGS))
                        flags |= read_byte(f) << 8;
                if (protocol_version >= 28 && (flags & XMIT_EXTENDED_FLAGS))
                        flags |= read_byte(f) << 8;
+
+               if (flags == (XMIT_EXTENDED_FLAGS|XMIT_IO_ERROR_ENDLIST)) {
+                       int err;
+                       if (protocol_version < 31) {
+                               rprintf(FERROR, "Invalid flist flag: %x\n", flags);
+                               exit_cleanup(RERR_PROTOCOL);
+                       }
+                       err = read_int(f);
+                       if (!ignore_errors)
+                               io_error |= err;
+                       break;
+               }
+
+               flist_expand(flist, 1);
                file = recv_file_entry(flist, flags, f);
 
                if (inc_recurse && S_ISDIR(file->mode)) {
                file = recv_file_entry(flist, flags, f);
 
                if (inc_recurse && S_ISDIR(file->mode)) {
@@ -2389,10 +2412,9 @@ struct file_list *recv_file_list(int f)
 
        if (protocol_version < 30) {
                /* Recv the io_error flag */
 
        if (protocol_version < 30) {
                /* Recv the io_error flag */
-               if (ignore_errors)
-                       read_int(f);
-               else
-                       io_error |= read_int(f);
+               int err = read_int(f);
+               if (!ignore_errors)
+                       io_error |= err;
        } else if (inc_recurse && flist->ndx_start == 1) {
                if (!file_total || strcmp(flist->sorted[flist->low]->basename, ".") != 0)
                        flist->parent_ndx = -1;
        } else if (inc_recurse && flist->ndx_start == 1) {
                if (!file_total || strcmp(flist->sorted[flist->low]->basename, ".") != 0)
                        flist->parent_ndx = -1;
index 5c3653f..80e9826 100644 (file)
@@ -86,7 +86,6 @@ extern int unsort_ndx;
 extern int max_delete;
 extern int force_delete;
 extern int one_file_system;
 extern int max_delete;
 extern int force_delete;
 extern int one_file_system;
-extern int check_for_io_err;
 extern struct stats stats;
 extern dev_t filesystem_dev;
 extern mode_t orig_umask;
 extern struct stats stats;
 extern dev_t filesystem_dev;
 extern mode_t orig_umask;
@@ -2236,10 +2235,6 @@ void generate_files(int f_out, const char *local_name)
                                                dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
                                        } else
                                                dirdev = MAKEDEV(0, 0);
                                                dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
                                        } else
                                                dirdev = MAKEDEV(0, 0);
-                                       /* We must be sure we've had a chance to receive an I/O
-                                        * error for this directory before we delete in it. */
-                                       while (check_for_io_err && !cur_flist->next && !flist_eof)
-                                               wait_for_receiver();
                                        delete_in_dir(fbuf, fp, &dirdev);
                                } else
                                        change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp));
                                        delete_in_dir(fbuf, fp, &dirdev);
                                } else
                                        change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp));
diff --git a/io.c b/io.c
index cc2561f..1752d86 100644 (file)
--- a/io.c
+++ b/io.c
@@ -63,7 +63,6 @@ int allowed_lull = 0;
 int ignore_timeout = 0;
 int batch_fd = -1;
 int msgdone_cnt = 0;
 int ignore_timeout = 0;
 int batch_fd = -1;
 int msgdone_cnt = 0;
-int check_for_io_err = 0;
 
 /* Ignore an EOF error if non-zero. See whine_about_eof(). */
 int kluge_around_eof = 0;
 
 /* Ignore an EOF error if non-zero. See whine_about_eof(). */
 int kluge_around_eof = 0;
@@ -377,8 +376,6 @@ static void read_msg_fd(void)
        len = tag & 0xFFFFFF;
        tag = (tag >> 24) - MPLEX_BASE;
 
        len = tag & 0xFFFFFF;
        tag = (tag >> 24) - MPLEX_BASE;
 
-       check_for_io_err = 0;
-
        switch (tag) {
        case MSG_DONE:
                if (len < 0 || len > 1 || !am_generator) {
        switch (tag) {
        case MSG_DONE:
                if (len < 0 || len > 1 || !am_generator) {
@@ -413,9 +410,6 @@ static void read_msg_fd(void)
                }
                flist = recv_file_list(fd);
                flist->parent_ndx = IVAL(buf,0);
                }
                flist = recv_file_list(fd);
                flist->parent_ndx = IVAL(buf,0);
-               /* If the sender is going to send us an MSG_IO_ERROR value, it
-                * will always be the very next message following MSG_FLIST. */
-               check_for_io_err = 1;
 #ifdef SUPPORT_HARD_LINKS
                if (preserve_hard_links)
                        match_hard_links(flist);
 #ifdef SUPPORT_HARD_LINKS
                if (preserve_hard_links)
                        match_hard_links(flist);
@@ -1063,8 +1057,6 @@ static int readfd_unbuffered(int fd, char *buf, size_t len)
                msg_bytes = tag & 0xFFFFFF;
                tag = (tag >> 24) - MPLEX_BASE;
 
                msg_bytes = tag & 0xFFFFFF;
                tag = (tag >> 24) - MPLEX_BASE;
 
-               check_for_io_err = 0;
-
                switch (tag) {
                case MSG_DATA:
                        if (msg_bytes > iobuf_in_siz) {
                switch (tag) {
                case MSG_DATA:
                        if (msg_bytes > iobuf_in_siz) {
diff --git a/main.c b/main.c
index dc3c533..c32457d 100644 (file)
--- a/main.c
+++ b/main.c
@@ -64,11 +64,8 @@ extern int whole_file;
 extern int read_batch;
 extern int write_batch;
 extern int batch_fd;
 extern int read_batch;
 extern int write_batch;
 extern int batch_fd;
-extern int flist_eof;
 extern int filesfrom_fd;
 extern int filesfrom_fd;
-extern int delete_during;
 extern int connect_timeout;
 extern int connect_timeout;
-extern int check_for_io_err;
 extern pid_t cleanup_child_pid;
 extern unsigned int module_dirlen;
 extern struct stats stats;
 extern pid_t cleanup_child_pid;
 extern unsigned int module_dirlen;
 extern struct stats stats;
@@ -768,8 +765,6 @@ static int do_recv(int f_in, int f_out, char *local_name)
                exit_cleanup(RERR_IPC);
        }
 
                exit_cleanup(RERR_IPC);
        }
 
-       check_for_io_err = inc_recurse && delete_during && !flist_eof;
-
        if (pid == 0) {
                close(error_pipe[0]);
                if (f_in != f_out)
        if (pid == 0) {
                close(error_pipe[0]);
                if (f_in != f_out)
diff --git a/rsync.c b/rsync.c
index f26f212..2d8e5e4 100644 (file)
--- a/rsync.c
+++ b/rsync.c
@@ -48,8 +48,6 @@ extern int flist_eof;
 extern int msgs2stderr;
 extern int keep_dirlinks;
 extern int make_backups;
 extern int msgs2stderr;
 extern int keep_dirlinks;
 extern int make_backups;
-extern int delete_during;
-extern int check_for_io_err;
 extern struct file_list *cur_flist, *first_flist, *dir_flist;
 extern struct chmod_mode_struct *daemon_chmod_modes;
 #ifdef ICONV_OPTION
 extern struct file_list *cur_flist, *first_flist, *dir_flist;
 extern struct chmod_mode_struct *daemon_chmod_modes;
 #ifdef ICONV_OPTION
@@ -254,15 +252,8 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr,
        while (1) {
                ndx = read_ndx(f_in);
 
        while (1) {
                ndx = read_ndx(f_in);
 
-               if (ndx >= 0) {
-                       if (check_for_io_err) {
-                               /* Let generator know there was no I/O error. */
-                               send_msg_int(MSG_IO_ERROR, 0);
-                               check_for_io_err = 0;
-                       }
+               if (ndx >= 0)
                        break;
                        break;
-               }
-               check_for_io_err = 0;
                if (ndx == NDX_DONE)
                        return ndx;
                if (!inc_recurse || am_sender) {
                if (ndx == NDX_DONE)
                        return ndx;
                if (!inc_recurse || am_sender) {
@@ -306,10 +297,6 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr,
                stop_flist_forward();
                if (!msgs2stderr)
                        negate_output_levels(); /* restore info/debug output */
                stop_flist_forward();
                if (!msgs2stderr)
                        negate_output_levels(); /* restore info/debug output */
-               /* If the sender is going to send us an MSG_IO_ERROR value, it
-                * will always be the very next message following a file list. */
-               if (delete_during)
-                       check_for_io_err = 1;
        }
 
        iflags = protocol_version >= 29 ? read_shortint(f_in)
        }
 
        iflags = protocol_version >= 29 ? read_shortint(f_in)
diff --git a/rsync.h b/rsync.h
index 320d340..c23e523 100644 (file)
--- a/rsync.h
+++ b/rsync.h
@@ -60,6 +60,7 @@
 #define XMIT_RDEV_MINOR_8_pre30 (1<<11)        /* protocols 28 - 29  */
 #define XMIT_GROUP_NAME_FOLLOWS (1<<11) /* protocols 30 - now */
 #define XMIT_HLINK_FIRST (1<<12)       /* protocols 30 - now (HLINKED files only) */
 #define XMIT_RDEV_MINOR_8_pre30 (1<<11)        /* protocols 28 - 29  */
 #define XMIT_GROUP_NAME_FOLLOWS (1<<11) /* protocols 30 - now */
 #define XMIT_HLINK_FIRST (1<<12)       /* protocols 30 - now (HLINKED files only) */
+#define XMIT_IO_ERROR_ENDLIST (1<<12)  /* protocols 31 - now (w/XMIT_EXTENDED_FLAGS) */
 
 /* These flags are used in the live flist data. */
 
 
 /* These flags are used in the live flist data. */
 
                             == ((unsigned)(b2) & (unsigned)(mask)))
 
 /* update this if you make incompatible changes */
                             == ((unsigned)(b2) & (unsigned)(mask)))
 
 /* update this if you make incompatible changes */
-#define PROTOCOL_VERSION 30
+#define PROTOCOL_VERSION 31
 
 /* 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.
 
 /* 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! */
-#define SUBPROTOCOL_VERSION 0
+ * It must ALWAYS be 0 when the protocol goes final (and NEVER before)! */
+#define SUBPROTOCOL_VERSION 1
 
 /* 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
 
 /* 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