mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-21 22:53:37 +00:00
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 5922d7084d.
More details can be found here:
https://bugzilla.redhat.com/show_bug.cgi?id=576879#c5
This commit is contained in:
34
daemon/tar.c
34
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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user