From 07f4b20ae959069fca41756b0dc103ec5fa99754 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Thu, 8 Apr 2010 08:48:38 +0100 Subject: [PATCH] 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.8.3.1