aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-06-20 14:36:11 +0100
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-06-20 14:36:11 +0100
commitd5efa0e4b7eacb505888eeea2c038b4c95b509df (patch)
tree755d5bc676d7e9c53b75c2c0487f517fbaec3c3c /tools
parent9b6d355987d5cb552305e595177346333f5a1746 (diff)
downloadxen-d5efa0e4b7eacb505888eeea2c038b4c95b509df.tar.gz
xen-d5efa0e4b7eacb505888eeea2c038b4c95b509df.tar.bz2
xen-d5efa0e4b7eacb505888eeea2c038b4c95b509df.zip
hvm: Fix ioemu Qcow support.
Normally by default, SIGUSR2 is not blocked, so the signal masks of SIGUSR2 in all threads is unblocked. When creating HVM guest, if we use the Qcow format image file, in the main thread, Qcow uses SIGUSR2 to be notified of the completion of the request after it issues an AIO request; in tools/ioemu/block.c: bdrv_read_em(), in some point between bdrv_aio_read() and qemu_aio_wait(), Dom0 may send a SIGUSR2 to Qemu immediately to indicate the completion of an AIO request -- since at the moment SIGUSR2 in main thread is blocked by qemu_aio_wait_start(), the signal may be delivered to one non-main thread, causing the signal handler of SIGUSR2 is invoked, then the main thread hangs in qemu_aio_wait()->syswait()... This patch blocks SIGUSR2 at the beginning of Qemu's main(), so it ensures SIGUSR2 is blocked by default when a new thread is created, then only the threads that use the signal unblock it. Signed-off-by: Dexuan Cui <dexuan.cui@intel.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/ioemu/block-raw.c2
-rw-r--r--tools/ioemu/vl.c12
2 files changed, 13 insertions, 1 deletions
diff --git a/tools/ioemu/block-raw.c b/tools/ioemu/block-raw.c
index 41c8abb413..9b01211bbf 100644
--- a/tools/ioemu/block-raw.c
+++ b/tools/ioemu/block-raw.c
@@ -166,7 +166,7 @@ typedef struct RawAIOCB {
struct RawAIOCB *next;
} RawAIOCB;
-static int aio_sig_num = SIGUSR2;
+const int aio_sig_num = SIGUSR2;
static RawAIOCB *first_aio; /* AIO issued */
static int aio_initialized = 0;
diff --git a/tools/ioemu/vl.c b/tools/ioemu/vl.c
index 696791f13c..02c3bb21a2 100644
--- a/tools/ioemu/vl.c
+++ b/tools/ioemu/vl.c
@@ -7059,6 +7059,18 @@ int main(int argc, char **argv)
#endif
char qemu_dm_logfilename[128];
+
+ /* Ensure that SIGUSR2 is blocked by default when a new thread is created,
+ then only the threads that use the signal unblock it -- this fixes a
+ race condition in Qcow support where the AIO signal is misdelivered. */
+ {
+ extern const int aio_sig_num;
+ sigset_t set;
+
+ sigemptyset(&set);
+ sigaddset(&set, aio_sig_num);
+ sigprocmask(SIG_BLOCK, &set, NULL);
+ }
LIST_INIT (&vm_change_state_head);
#ifndef _WIN32