From 08f15335b5b469b29cbdacd0fc5ba48d76acf280 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 28 Jan 2000 12:37:58 +0000 Subject: [PATCH] switch to using socketpair instead of pipe if possible. This fixes the ssh clag problems as long as you also fix the same problem in sshd removed all the old read buffering code from io.c as this was only there to try to reduce the chance of clagging up sshd. --- configure.in | 2 +- io.c | 84 ++-------------------------------------------------- main.c | 4 +-- rsync.h | 1 - util.c | 20 ++++++++++--- 5 files changed, 21 insertions(+), 90 deletions(-) diff --git a/configure.in b/configure.in index 0257de9d..1e7da12a 100644 --- a/configure.in +++ b/configure.in @@ -53,7 +53,7 @@ AC_FUNC_UTIME_NULL AC_CHECK_FUNCS(waitpid wait4 getcwd strdup strerror chown chmod mknod) AC_CHECK_FUNCS(fchmod fstat strchr readlink link utime utimes strftime) AC_CHECK_FUNCS(memmove lchown vsnprintf snprintf setsid glob strpbrk) -AC_CHECK_FUNCS(strlcat strlcpy inet_aton) +AC_CHECK_FUNCS(strlcat strlcpy inet_aton socketpair) AC_CACHE_CHECK([for working fnmatch],rsync_cv_HAVE_FNMATCH,[ AC_TRY_RUN([#include diff --git a/io.c b/io.c index 26b6e4b3..6f3854e3 100644 --- a/io.c +++ b/io.c @@ -18,7 +18,7 @@ */ /* - Utilities used in rsync + socket and pipe IO utilities used in rsync tridge, June 1996 */ @@ -39,7 +39,6 @@ extern struct stats stats; static int buffer_f_in = -1; static int io_error_fd = -1; -static int in_read_check; void setup_readbuffer(int f_in) { @@ -89,12 +88,7 @@ static void read_error_fd(void) } -static char *read_buffer; -static char *read_buffer_p; -static int read_buffer_len; -static int read_buffer_size; static int no_flush; -static int no_flush_read; /* read from a socket with IO timeout. return the number of bytes read. If no bytes can be read then exit, never return @@ -103,9 +97,7 @@ static int read_timeout(int fd, char *buf, int len) { int n, ret=0; - no_flush_read++; io_flush(); - no_flush_read--; while (ret == 0) { fd_set fds; @@ -231,49 +223,12 @@ static int read_unbuffered(int fd, char *buf, int len) rprintf(tag,"%s", line); remaining = 0; - - if (in_read_check) break; } return ret; } - -/* This function was added to overcome a deadlock problem when using - * ssh. It looks like we can't allow our receive queue to get full or - * ssh will clag up. Uggh. */ -static void read_check(int f) -{ - int n = 8192; - - in_read_check = 1; - - if (f == -1) return; - - if (read_buffer_len == 0) { - read_buffer_p = read_buffer; - } - - if (read_buffer_p != read_buffer) { - memmove(read_buffer,read_buffer_p,read_buffer_len); - read_buffer_p = read_buffer; - } - - if (n > (read_buffer_size - read_buffer_len)) { - read_buffer_size += n; - read_buffer = (char *)Realloc(read_buffer,read_buffer_size); - if (!read_buffer) out_of_memory("read check"); - read_buffer_p = read_buffer; - } - - n = read_unbuffered(f,read_buffer+read_buffer_len,n); - read_buffer_len += n; - - in_read_check = 0; -} - - /* do a buffered read from fd. don't return until all N bytes have been read. If all N can't be read then exit with an error */ static void readfd(int fd,char *buffer,int N) @@ -281,23 +236,8 @@ static void readfd(int fd,char *buffer,int N) int ret; int total=0; - if ((read_buffer_len < N) && (N < 1024)) { - read_check(buffer_f_in); - } - while (total < N) { - if (read_buffer_len > 0 && buffer_f_in == fd) { - ret = MIN(read_buffer_len,N-total); - memcpy(buffer+total,read_buffer_p,ret); - read_buffer_p += ret; - read_buffer_len -= ret; - total += ret; - continue; - } - - no_flush_read++; io_flush(); - no_flush_read--; ret = read_unbuffered(fd,buffer + total,N-total); total += ret; @@ -371,7 +311,6 @@ static void writefd_unbuffered(int fd,char *buf,int len) fd_set w_fds, r_fds; int fd_count, count; struct timeval tv; - int reading=0; no_flush++; @@ -381,17 +320,6 @@ static void writefd_unbuffered(int fd,char *buf,int len) FD_SET(fd,&w_fds); fd_count = fd; - if (!no_flush_read) { - reading = (buffer_f_in != -1) && - (read_buffer_len < MAX_READ_BUFFER); - } - - if (reading) { - FD_SET(buffer_f_in,&r_fds); - if (buffer_f_in > fd_count) - fd_count = buffer_f_in; - } - if (io_error_fd != -1) { FD_SET(io_error_fd,&r_fds); if (io_error_fd > fd_count) @@ -404,7 +332,7 @@ static void writefd_unbuffered(int fd,char *buf,int len) errno = 0; count = select(fd_count+1, - (reading || io_error_fd != -1)?&r_fds:NULL, + io_error_fd != -1?&r_fds:NULL, &w_fds,NULL, &tv); @@ -416,10 +344,6 @@ static void writefd_unbuffered(int fd,char *buf,int len) continue; } - if (reading && FD_ISSET(buffer_f_in, &r_fds)) { - read_check(buffer_f_in); - } - if (io_error_fd != -1 && FD_ISSET(io_error_fd, &r_fds)) { read_error_fd(); } @@ -611,10 +535,6 @@ void io_start_multiplex_in(int fd) { multiplex_in_fd = fd; io_flush(); - if (read_buffer_len) { - exit_cleanup(RERR_STREAMIO); - } - io_multiplexing_in = 1; } diff --git a/main.c b/main.c index a5467782..80839de3 100644 --- a/main.c +++ b/main.c @@ -294,12 +294,12 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name) } } - if (pipe(recv_pipe) < 0) { + if (fd_pair(recv_pipe) < 0) { rprintf(FERROR,"pipe failed in do_recv\n"); exit_cleanup(RERR_SOCKETIO); } - if (pipe(error_pipe) < 0) { + if (fd_pair(error_pipe) < 0) { rprintf(FERROR,"error pipe failed in do_recv\n"); exit_cleanup(RERR_SOCKETIO); } diff --git a/rsync.h b/rsync.h index 53cd02a2..9e7775c7 100644 --- a/rsync.h +++ b/rsync.h @@ -58,7 +58,6 @@ #define CHUNK_SIZE (32*1024) #define MAX_MAP_SIZE (256*1024) #define IO_BUFFER_SIZE (4092) -#define MAX_READ_BUFFER (10*1024*1024) #define MAX_ARGS 1000 diff --git a/util.c b/util.c index 4382300e..a0e2707e 100644 --- a/util.c +++ b/util.c @@ -26,6 +26,18 @@ extern int verbose; +/* create a file descriptor - like pipe() but use socketpair if + possible (because of blocking issues on pipes */ +int fd_pair(int fd[2]) +{ +#if HAVE_SOCKETPAIR + return socketpair(AF_UNIX, SOCK_STREAM, 0, fd); +#else + return pipe(fd); +#endif +} + + /* this is taken from CVS */ int piped_child(char **command,int *f_in,int *f_out) { @@ -33,8 +45,8 @@ int piped_child(char **command,int *f_in,int *f_out) int to_child_pipe[2]; int from_child_pipe[2]; - if (pipe(to_child_pipe) < 0 || - pipe(from_child_pipe) < 0) { + if (fd_pair(to_child_pipe) < 0 || + fd_pair(from_child_pipe) < 0) { rprintf(FERROR,"pipe: %s\n",strerror(errno)); exit_cleanup(RERR_IPC); } @@ -83,8 +95,8 @@ int local_child(int argc, char **argv,int *f_in,int *f_out) int to_child_pipe[2]; int from_child_pipe[2]; - if (pipe(to_child_pipe) < 0 || - pipe(from_child_pipe) < 0) { + if (fd_pair(to_child_pipe) < 0 || + fd_pair(from_child_pipe) < 0) { rprintf(FERROR,"pipe: %s\n",strerror(errno)); exit_cleanup(RERR_IPC); } -- 2.34.1