On Mon, 4 Jun 2018 13:03:45 +0100 Daniel P. Berrangé <berra...@redhat.com> wrote:
> When using --daemonize, the initial lead process will fork a child and > then wait to be notified that setup is complete via a pipe, before it > exits. When using --preconfig there is an extra call to main_loop() > before the notification is done from os_setup_post(). Thus the parent > process won't exit until the mgmt application connects to the monitor > and tells QEMU to leave the RUN_STATE_PRECONFIG. The mgmt application > won't connect to the monitor until daemonizing has completed though. > > This is a chicken and egg problem, leading to deadlock at startup. > > The only viable way to fix this is to call os_setup_post() before > the early main_loop() call when in RUN_STATE_PRECONFIG. This has the > downside that any errors from this point onwards won't be handled > well by the mgmt application, because it will think QEMU has started > successfully, so not be expecting an abrupt exit. The only way to > deal with that is to move as much user input validation as possible > to before the main_loop() call. This is left as an exercise for > future interested developers. > > Signed-off-by: Daniel P. Berrangé <berra...@redhat.com> [...] How about combining ideas from yours and Michal's patches? It should fix broken iotests/libvirt sync point and we can think about NONE runstate idea at without rushing it. If it looks acceptable, I'll post proper patches + test case for it after some testing (to ensure that iotests Max pointed out are working as expected) diff --git a/vl.c b/vl.c index c4fe255..a2062d6 100644 --- a/vl.c +++ b/vl.c @@ -1953,10 +1953,15 @@ static bool main_loop_should_exit(void) static void main_loop(void) { + static bool os_setup_post_done = false; #ifdef CONFIG_PROFILER int64_t ti; #endif - do { + if (!os_setup_post_done) { + os_setup_post(); + os_setup_post_done = true; + } + while (!main_loop_should_exit()) { #ifdef CONFIG_PROFILER ti = profile_getclock(); #endif @@ -1964,7 +1969,7 @@ static void main_loop(void) #ifdef CONFIG_PROFILER dev_time += profile_getclock() - ti; #endif - } while (!main_loop_should_exit()); + } } static void version(void)