diff options
author | Richard Jones <rjones@redhat.com> | 2010-05-12 19:55:06 +0100 |
---|---|---|
committer | Richard Jones <rjones@redhat.com> | 2010-05-13 17:08:02 +0100 |
commit | dc706a639eec16084c0618baf7bfde00c6565f63 (patch) | |
tree | e96751894fe49bf81e704436fc089a173b0f44fc /daemon/daemon.h | |
parent | 11a2ad8c9a1da7fe7f8142be69312d0cb5979e0a (diff) | |
download | libguestfs-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/daemon.h')
-rw-r--r-- | daemon/daemon.h | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/daemon/daemon.h b/daemon/daemon.h index 977dfdcb..de598cd3 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -139,10 +139,13 @@ typedef int (*receive_cb) (void *opaque, const void *buf, size_t len); extern int receive_file (receive_cb cb, void *opaque); /* daemon functions that receive files (FileIn) can call this - * to cancel incoming transfers (eg. if there is a local error), - * but they MUST then call reply_with_*. + * to cancel incoming transfers (eg. if there is a local error). + * + * If and only if this function does NOT return -2, they MUST then + * call reply_with_* + * (see https://bugzilla.redhat.com/show_bug.cgi?id=576879#c5). */ -extern void cancel_receive (void); +extern int cancel_receive (void); /* daemon functions that return files (FileOut) should call * reply, then send_file_* for each FileOut parameter. @@ -160,8 +163,8 @@ extern void reply (xdrproc_t xdrp, char *ret); #define NEED_ROOT(cancel_stmt,fail_stmt) \ do { \ if (!root_mounted) { \ - cancel_stmt; \ - reply_with_error ("%s: you must call 'mount' first to mount the root filesystem", __func__); \ + if ((cancel_stmt) != -2) \ + reply_with_error ("%s: you must call 'mount' first to mount the root filesystem", __func__); \ fail_stmt; \ } \ } \ @@ -173,8 +176,8 @@ extern void reply (xdrproc_t xdrp, char *ret); #define ABS_PATH(path,cancel_stmt,fail_stmt) \ do { \ if ((path)[0] != '/') { \ - cancel_stmt; \ - reply_with_error ("%s: path must start with a / character", __func__); \ + if ((cancel_stmt) != -2) \ + reply_with_error ("%s: path must start with a / character", __func__); \ fail_stmt; \ } \ } while (0) @@ -189,15 +192,16 @@ extern void reply (xdrproc_t xdrp, char *ret); #define RESOLVE_DEVICE(path,cancel_stmt,fail_stmt) \ do { \ if (STRNEQLEN ((path), "/dev/", 5)) { \ - cancel_stmt; \ - reply_with_error ("%s: %s: expecting a device name", __func__, (path)); \ + if ((cancel_stmt) != -2) \ + reply_with_error ("%s: %s: expecting a device name", __func__, (path)); \ fail_stmt; \ } \ if (device_name_translation ((path)) == -1) { \ int err = errno; \ - cancel_stmt; \ + int r = cancel_stmt; \ errno = err; \ - reply_with_perror ("%s: %s", __func__, path); \ + if (r != -2) \ + reply_with_perror ("%s: %s", __func__, path); \ fail_stmt; \ } \ } while (0) |