Inadequate error checking in rsync 2.5.5

jw schultz jw at pegasys.ws
Fri Aug 15 11:20:36 EST 2003


On Thu, Aug 14, 2003 at 03:08:22PM -0700, jw schultz wrote:
> On Thu, Aug 14, 2003 at 12:41:19PM -0700, David Norwood wrote:
> [reformatted because someone doesn't know how to compose email]
> > I'm using rsync to mirror files from a Windows XP machine
> > mounted via smbfs.  Apparently I have something configured
> > wrong as I get a "permisson denied" error accessing some
> > of the files on the smbfs mount with cp, od, etc.
> > However, rsync produces no error messages on these files.
> > It happily creates files in the target directory that are
> > the right size, but filled with null bytes.  
> > 
> > This is repeatable on my system, until I figure out the
> > smbfs permisson problem.  I'm running RedHat 9.  I'm not
> > subscribed to this list, so please cc me on any replies.
> 
> If you are going to report problems the least you could do
> is upgrade to a current version.  Unfortunately, i don't
> expect that will fix this.
> 
> This looks like a situation similar to that which NFS can
> have where open succeeds but read fails.  Unfortunately
> there isn't really a good way to detect this until we get
> into it and then it is indistinguishable from a file
> being truncated out from under us.
> 
> It is down in map_ptr() where we don't have knowledge of the
> file name and can't really report errors to the caller.
> 
> 	if ((nread=read(map->fd,map->p + read_offset,read_size)) != read_size) {
> 		if (nread < 0) nread = 0;
> 		/* the best we can do is zero the buffer - the file
> 		   has changed mid transfer! */
> 		memset(map->p+read_offset+nread, 0, read_size - nread);
> 	}

I've had a chance to think on it.  Attached is a patch that
allows unmap_file() to report the first read error that
map_ptr found.  The behaviour is the same.  I doubt this will
apply against anything but CVS HEAD as of now.

This should probably use FERROR instead of FINFO so that a
partial transfer is reported.

Any thoughts guys?

-- 
________________________________________________________________
	J.W. Schultz            Pegasystems Technologies
	email address:		jw at pegasys.ws

		Remember Cernan and Schmitt
-------------- next part --------------
? receiver.diff
Index: fileio.c
===================================================================
RCS file: /data/cvs/rsync/fileio.c,v
retrieving revision 1.6
diff -u -r1.6 fileio.c
--- fileio.c	22 May 2003 23:24:44 -0000	1.6
+++ fileio.c	15 Aug 2003 01:11:14 -0000
@@ -115,6 +115,7 @@
 	map->p_offset = 0;
 	map->p_fd_offset = 0;
 	map->p_len = 0;
+	map->status = 0;
 
 	return map;
 }
@@ -191,7 +192,11 @@
 		}
 
 		if ((nread=read(map->fd,map->p + read_offset,read_size)) != read_size) {
-			if (nread < 0) nread = 0;
+			if (nread < 0) {
+				nread = 0;
+				if (!map->status)
+					map->status = errno;
+			}
 			/* the best we can do is zero the buffer - the file
 			   has changed mid transfer! */
 			memset(map->p+read_offset+nread, 0, read_size - nread);
@@ -206,13 +211,18 @@
 }
 
 
-void unmap_file(struct map_struct *map)
+int unmap_file(struct map_struct *map)
 {
+	int	ret;
+
 	if (map->p) {
 		free(map->p);
 		map->p = NULL;
 	}
+	ret = map->status;
 	memset(map, 0, sizeof(*map));
 	free(map);
+
+	return ret;
 }
 
Index: proto.h
===================================================================
RCS file: /data/cvs/rsync/proto.h,v
retrieving revision 1.158
diff -u -r1.158 proto.h
--- proto.h	1 Jul 2003 21:45:25 -0000	1.158
+++ proto.h	15 Aug 2003 01:11:14 -0000
@@ -71,7 +71,7 @@
 int write_file(int f,char *buf,size_t len);
 struct map_struct *map_file(int fd,OFF_T len);
 char *map_ptr(struct map_struct *map,OFF_T offset,int len);
-void unmap_file(struct map_struct *map);
+int unmap_file(struct map_struct *map);
 void show_flist_stats(void);
 int readlink_stat(const char *path, STRUCT_STAT * buffer, char *linkbuf);
 int link_stat(const char *path, STRUCT_STAT * buffer);
@@ -191,7 +191,7 @@
 void sig_int(void);
 void finish_transfer(char *fname, char *fnametmp, struct file_struct *file);
 void read_sum_head(int f, struct sum_struct *sum);
-void send_files(struct file_list *flist,int f_out,int f_in);
+void send_files(struct file_list *flist, int f_out, int f_in);
 int try_bind_local(int s,
 		   int ai_family, int ai_socktype,
 		   const char *bind_address);
Index: rsync.h
===================================================================
RCS file: /data/cvs/rsync/rsync.h,v
retrieving revision 1.152
diff -u -r1.152 rsync.h
--- rsync.h	30 Jul 2003 06:12:31 -0000	1.152
+++ rsync.h	15 Aug 2003 01:11:15 -0000
@@ -420,9 +420,17 @@
 };
 
 struct map_struct {
-	char *p;
-	int fd,p_size,p_len;
-	OFF_T file_size, p_offset, p_fd_offset;
+	char *p;		/* Window pointer			*/
+	int fd;			/* File Descriptor			*/
+	int p_size;		/* Window size at allocation		*/
+	int p_len;		/* Window size after fill		*/
+				/*    p_size and p_len could be
+				 *    consolodated by using a local
+				 *    variable in map_ptr()		*/
+	int status;		/* first errno from read errors		*/
+	OFF_T file_size;	/* File size (from stat)		*/
+	OFF_T p_offset;		/* Window start				*/
+	OFF_T p_fd_offset;	/* offset of cursor in fd ala lseek	*/
 };
 
 #define MATCHFLG_WILD		0x0001 /* pattern has '*', '[', and/or '?' */
Index: sender.c
===================================================================
RCS file: /data/cvs/rsync/sender.c,v
retrieving revision 1.21
diff -u -r1.21 sender.c
--- sender.c	15 Aug 2003 00:57:27 -0000	1.21
+++ sender.c	15 Aug 2003 01:11:15 -0000
@@ -279,7 +279,14 @@
 		}
 
 		if (!read_batch) { /* dw */
-			if (buf) unmap_file(buf);
+			if (buf) {
+				j = unmap_file(buf);
+				if (j)
+					rprintf(FINFO,
+					    "read errors mapping %s: %s\n",
+					    fname,
+					    strerror(j));
+			}
 			close(fd);
 		}
 


More information about the rsync mailing list