The Qemu 0.9 we're using is actually multi-threaded
because
1) The "AIO" in Qemu 0.9 means using the
library librt -- this library actually just uses pthreads to
"emulate" AIO;
2) In main() -> xenstore_parse_domain_config()
-> xs_watch(), one other pthread is created.
Normally by default, SIGUSR2 is not blocked, so the
signal masks of SIGUSR2 in all the threads are 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()…
The attached 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@xxxxxxxxx>