summaryrefslogtreecommitdiffstats
path: root/daemon/daemon.h
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/daemon.h
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/daemon.h')
-rw-r--r--daemon/daemon.h26
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)