[Libguestfs] [PATCH 1/2] Fix tar-in command hangs when running out of disk space
Richard W.M. Jones
rjones at redhat.com
Thu Apr 8 07:58:37 UTC 2010
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
New in Fedora 11: Fedora Windows cross-compiler. Compile Windows
programs, test, and build Windows installers. Over 70 libraries supprt'd
http://fedoraproject.org/wiki/MinGW http://www.annexia.org/fedora_mingw
-------------- next part --------------
>From 07f4b20ae959069fca41756b0dc103ec5fa99754 Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones at redhat.com>
Date: Thu, 8 Apr 2010 08:48:38 +0100
Subject: [PATCH 1/2] 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.
---
daemon/tar.c | 6 ++++--
daemon/upload.c | 3 ++-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/daemon/tar.c b/daemon/tar.c
index ebcaded..bb0e483 100644
--- a/daemon/tar.c
+++ b/daemon/tar.c
@@ -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;
diff --git a/daemon/upload.c b/daemon/upload.c
index e15eade..65c6667 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;
--
1.6.6.1
More information about the Libguestfs
mailing list