summaryrefslogtreecommitdiffstats
path: root/daemon/upload.c
diff options
context:
space:
mode:
authorRichard Jones <rjones@redhat.com>2010-04-08 08:48:38 +0100
committerRichard Jones <rjones@redhat.com>2010-04-08 08:49:00 +0100
commit07f4b20ae959069fca41756b0dc103ec5fa99754 (patch)
treef07cd64a4a23dfa4f2ea9949bdc673d224bb11c6 /daemon/upload.c
parent4c50f4c38d9a50fbf983c79dd208d1b1598fef8a (diff)
downloadlibguestfs-07f4b20ae959069fca41756b0dc103ec5fa99754.tar.gz
libguestfs-07f4b20ae959069fca41756b0dc103ec5fa99754.tar.xz
libguestfs-07f4b20ae959069fca41756b0dc103ec5fa99754.zip
Fix tar-in command hangs when running out of disk space (RHBZ#580246).
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.
Diffstat (limited to 'daemon/upload.c')
-rw-r--r--daemon/upload.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/daemon/upload.c b/daemon/upload.c
index e15eadef..65c66675 100644
--- a/daemon/upload.c
+++ b/daemon/upload.c
@@ -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;