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:
Richard Jones
2010-05-12 19:55:06 +01:00
parent 11a2ad8c9a
commit dc706a639e
10 changed files with 71 additions and 54 deletions

View File

@@ -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;
}