Fix tar-in command hangs when running out of disk space (RHBZ#580246).
authorRichard Jones <rjones@redhat.com>
Thu, 8 Apr 2010 07:48:38 +0000 (08:48 +0100)
committerRichard Jones <rjones@redhat.com>
Thu, 8 Apr 2010 07:49:00 +0000 (08:49 +0100)
The problem was this sequence of events:

 (1) File transfer goes through OK.

 (2) pclose returns failure (because 'tar' subprocess failed)

 (3) We try to cancel the transfer by calling cancel_receive.

Step (3) fails because the transfer (as far as the library is
concerned) has succeeded, so causing a hang.

The more fundamental reason why we see steps (1) and (2) is that
'tar' does NOT fail immediately if there is a write error.  Instead
it continues reading and discarding the input until the end of the
input before giving "Error exit delayed from previous errors".
IMHO this is a bug with tar, since an ENOSPC write error should
be fatal for tar.

daemon/tar.c
daemon/upload.c

index ebcaded..bb0e483 100644 (file)
@@ -88,7 +88,8 @@ do_tar_in (const char *dir)
 
   if (pclose (fp) != 0) {
     err = errno;
-    cancel_receive ();
+    if (r == -1)                /* if r == 0, file transfer ended already */
+      cancel_receive ();
     errno = err;
     reply_with_perror ("pclose: %s", dir);
     return -1;
@@ -209,7 +210,8 @@ do_tgz_in (const char *dir)
 
   if (pclose (fp) != 0) {
     err = errno;
-    cancel_receive ();
+    if (r == -1)                /* if r == 0, file transfer ended already */
+      cancel_receive ();
     errno = err;
     reply_with_perror ("pclose: %s", dir);
     return -1;
index e15eade..65c6667 100644 (file)
@@ -77,7 +77,8 @@ do_upload (const char *filename)
 
   if (close (fd) == -1) {
     err = errno;
-    cancel_receive ();
+    if (r == -1)                /* if r == 0, file transfer ended already */
+      cancel_receive ();
     errno = err;
     reply_with_perror ("close: %s", filename);
     return -1;