summaryrefslogtreecommitdiffstats
path: root/daemon/tar.c
diff options
context:
space:
mode:
authorRichard Jones <rjones@redhat.com>2010-05-12 19:55:06 +0100
committerRichard Jones <rjones@redhat.com>2010-05-13 17:08:02 +0100
commitdc706a639eec16084c0618baf7bfde00c6565f63 (patch)
treee96751894fe49bf81e704436fc089a173b0f44fc /daemon/tar.c
parent11a2ad8c9a1da7fe7f8142be69312d0cb5979e0a (diff)
downloadlibguestfs-dc706a639eec16084c0618baf7bfde00c6565f63.tar.gz
libguestfs-dc706a639eec16084c0618baf7bfde00c6565f63.tar.xz
libguestfs-dc706a639eec16084c0618baf7bfde00c6565f63.zip
Fix FileIn cmds losing synch if both ends send cancel messages (RHBZ#576879).
During a FileIn command (eg. upload, tar-in) if both sides experience errors, then both sides could send cancel messages, the result being lost synchronization. The reason for the lost synch was because the daemon was ignoring this case and sending an error message back which the library side (which had cancelled) was not expecting. Fix this by checking in the daemon for the case where the library also cancels during daemon cancellation, and not sending an error messages. This also includes an enhanced regression test which checks for this case. This extends the original fix in commit 5922d7084d6b43f0a1a15b664c7082dfeaf584d0. More details can be found here: https://bugzilla.redhat.com/show_bug.cgi?id=576879#c5
Diffstat (limited to 'daemon/tar.c')
-rw-r--r--daemon/tar.c34
1 files changed, 18 insertions, 16 deletions
diff --git a/daemon/tar.c b/daemon/tar.c
index 26a0d302..3f5f60a6 100644
--- a/daemon/tar.c
+++ b/daemon/tar.c
@@ -45,9 +45,9 @@ do_tar_in (const char *dir)
/* "tar -C /sysroot%s -xf -" but we have to quote the dir. */
if (asprintf_nowarn (&cmd, "tar -C %R -xf -", dir) == -1) {
err = errno;
- cancel_receive ();
+ r = cancel_receive ();
errno = err;
- reply_with_perror ("asprintf");
+ if (r != -2) reply_with_perror ("asprintf");
return -1;
}
@@ -57,9 +57,9 @@ do_tar_in (const char *dir)
fp = popen (cmd, "w");
if (fp == NULL) {
err = errno;
- cancel_receive ();
+ r = cancel_receive ();
errno = err;
- reply_with_perror ("%s", cmd);
+ if (r != -2) reply_with_perror ("%s", cmd);
free (cmd);
return -1;
}
@@ -72,8 +72,8 @@ do_tar_in (const char *dir)
r = receive_file (write_cb, &fd);
if (r == -1) { /* write error */
- cancel_receive ();
- reply_with_error ("write error on directory: %s", dir);
+ if (cancel_receive () != -2)
+ reply_with_error ("write error on directory: %s", dir);
pclose (fp);
return -1;
}
@@ -85,8 +85,9 @@ do_tar_in (const char *dir)
if (pclose (fp) != 0) {
if (r == -1) /* if r == 0, file transfer ended already */
- cancel_receive ();
- reply_with_error ("tar subcommand failed on directory: %s", dir);
+ r = cancel_receive ();
+ if (r != -2)
+ reply_with_error ("tar subcommand failed on directory: %s", dir);
return -1;
}
@@ -162,9 +163,9 @@ do_tXz_in (const char *dir, char filter)
/* "tar -C /sysroot%s -zxf -" but we have to quote the dir. */
if (asprintf_nowarn (&cmd, "tar -C %R -%cxf -", dir, filter) == -1) {
err = errno;
- cancel_receive ();
+ r = cancel_receive ();
errno = err;
- reply_with_perror ("asprintf");
+ if (r != -2) reply_with_perror ("asprintf");
return -1;
}
@@ -174,9 +175,9 @@ do_tXz_in (const char *dir, char filter)
fp = popen (cmd, "w");
if (fp == NULL) {
err = errno;
- cancel_receive ();
+ r = cancel_receive ();
errno = err;
- reply_with_perror ("%s", cmd);
+ if (r != -2) reply_with_perror ("%s", cmd);
free (cmd);
return -1;
}
@@ -186,8 +187,8 @@ do_tXz_in (const char *dir, char filter)
r = receive_file (write_cb, &fd);
if (r == -1) { /* write error */
- cancel_receive ();
- reply_with_error ("write error on directory: %s", dir);
+ r = cancel_receive ();
+ if (r != -2) reply_with_error ("write error on directory: %s", dir);
pclose (fp);
return -1;
}
@@ -199,8 +200,9 @@ do_tXz_in (const char *dir, char filter)
if (pclose (fp) != 0) {
if (r == -1) /* if r == 0, file transfer ended already */
- cancel_receive ();
- reply_with_error ("tar subcommand failed on directory: %s", dir);
+ r = cancel_receive ();
+ if (r != -2)
+ reply_with_error ("tar subcommand failed on directory: %s", dir);
return -1;
}