Commit f303b749 authored by Wayne Davison's avatar Wayne Davison

Added logic to the receiving side to ensure that the --delete-during

code will not delete in a directory prior to receiving an I/O error
for that directory (or not receiving it, as the case may be).
parent 91fd15b8
...@@ -86,6 +86,7 @@ extern int unsort_ndx; ...@@ -86,6 +86,7 @@ extern int unsort_ndx;
extern int max_delete; extern int max_delete;
extern int force_delete; extern int force_delete;
extern int one_file_system; extern int one_file_system;
extern int check_for_io_err;
extern struct stats stats; extern struct stats stats;
extern dev_t filesystem_dev; extern dev_t filesystem_dev;
extern mode_t orig_umask; extern mode_t orig_umask;
...@@ -2236,6 +2237,10 @@ void generate_files(int f_out, const char *local_name) ...@@ -2236,6 +2237,10 @@ void generate_files(int f_out, const char *local_name)
dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)); dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
} else } else
dirdev = MAKEDEV(0, 0); 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)
wait_for_receiver();
delete_in_dir(fbuf, fp, &dirdev); delete_in_dir(fbuf, fp, &dirdev);
} else } else
change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp)); change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp));
......
...@@ -63,6 +63,7 @@ int allowed_lull = 0; ...@@ -63,6 +63,7 @@ int allowed_lull = 0;
int ignore_timeout = 0; int ignore_timeout = 0;
int batch_fd = -1; int batch_fd = -1;
int msgdone_cnt = 0; int msgdone_cnt = 0;
int check_for_io_err = 0;
/* Ignore an EOF error if non-zero. See whine_about_eof(). */ /* Ignore an EOF error if non-zero. See whine_about_eof(). */
int kluge_around_eof = 0; int kluge_around_eof = 0;
...@@ -379,6 +380,8 @@ static void read_msg_fd(void) ...@@ -379,6 +380,8 @@ static void read_msg_fd(void)
len = tag & 0xFFFFFF; len = tag & 0xFFFFFF;
tag = (tag >> 24) - MPLEX_BASE; tag = (tag >> 24) - MPLEX_BASE;
check_for_io_err = 0;
switch (tag) { switch (tag) {
case MSG_DONE: case MSG_DONE:
if (len < 0 || len > 1 || !am_generator) { if (len < 0 || len > 1 || !am_generator) {
...@@ -413,6 +416,9 @@ static void read_msg_fd(void) ...@@ -413,6 +416,9 @@ static void read_msg_fd(void)
} }
flist = recv_file_list(fd); flist = recv_file_list(fd);
flist->parent_ndx = IVAL(buf,0); 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 #ifdef SUPPORT_HARD_LINKS
if (preserve_hard_links) if (preserve_hard_links)
match_hard_links(flist); match_hard_links(flist);
...@@ -1060,6 +1066,8 @@ static int readfd_unbuffered(int fd, char *buf, size_t len) ...@@ -1060,6 +1066,8 @@ static int readfd_unbuffered(int fd, char *buf, size_t len)
msg_bytes = tag & 0xFFFFFF; msg_bytes = tag & 0xFFFFFF;
tag = (tag >> 24) - MPLEX_BASE; tag = (tag >> 24) - MPLEX_BASE;
check_for_io_err = 0;
switch (tag) { switch (tag) {
case MSG_DATA: case MSG_DATA:
if (msg_bytes > iobuf_in_siz) { if (msg_bytes > iobuf_in_siz) {
......
...@@ -64,8 +64,11 @@ extern int whole_file; ...@@ -64,8 +64,11 @@ extern int whole_file;
extern int read_batch; extern int read_batch;
extern int write_batch; extern int write_batch;
extern int batch_fd; 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 pid_t cleanup_child_pid;
extern unsigned int module_dirlen; extern unsigned int module_dirlen;
extern struct stats stats; extern struct stats stats;
...@@ -765,6 +768,8 @@ static int do_recv(int f_in, int f_out, char *local_name) ...@@ -765,6 +768,8 @@ 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) { if (pid == 0) {
close(error_pipe[0]); close(error_pipe[0]);
if (f_in != f_out) if (f_in != f_out)
......
...@@ -48,6 +48,8 @@ extern int flist_eof; ...@@ -48,6 +48,8 @@ extern int flist_eof;
extern int msgs2stderr; extern int msgs2stderr;
extern int keep_dirlinks; extern int keep_dirlinks;
extern int make_backups; 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 file_list *cur_flist, *first_flist, *dir_flist;
extern struct chmod_mode_struct *daemon_chmod_modes; extern struct chmod_mode_struct *daemon_chmod_modes;
#ifdef ICONV_OPTION #ifdef ICONV_OPTION
...@@ -252,8 +254,15 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr, ...@@ -252,8 +254,15 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr,
while (1) { while (1) {
ndx = read_ndx(f_in); ndx = read_ndx(f_in);
if (ndx >= 0) 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;
}
break; break;
}
check_for_io_err = 0;
if (ndx == NDX_DONE) if (ndx == NDX_DONE)
return ndx; return ndx;
if (!inc_recurse || am_sender) if (!inc_recurse || am_sender)
...@@ -287,6 +296,10 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr, ...@@ -287,6 +296,10 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr,
stop_flist_forward(); stop_flist_forward();
if (!msgs2stderr) if (!msgs2stderr)
negate_output_levels(); /* restore info/debug output */ 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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment