Add a qemu_system_exec_request() hook that causes the main loop to exit and re-exec qemu using the specified arguments.
Signed-off-by: Steve Sistare <steven.sist...@oracle.com> --- include/sysemu/runstate.h | 1 + softmmu/runstate.c | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/include/sysemu/runstate.h b/include/sysemu/runstate.h index 16c1c41..6b0b4f1 100644 --- a/include/sysemu/runstate.h +++ b/include/sysemu/runstate.h @@ -63,6 +63,7 @@ void qemu_system_wakeup_enable(WakeupReason reason, bool enabled); void qemu_register_wakeup_notifier(Notifier *notifier); void qemu_register_wakeup_support(void); void qemu_system_shutdown_request(ShutdownCause reason); +int qemu_system_exec_request(const strList *args, Error **errp); void qemu_system_powerdown_request(void); void qemu_register_powerdown_notifier(Notifier *notifier); void qemu_register_shutdown_notifier(Notifier *notifier); diff --git a/softmmu/runstate.c b/softmmu/runstate.c index cfd6aa9..c35ab09 100644 --- a/softmmu/runstate.c +++ b/softmmu/runstate.c @@ -37,6 +37,7 @@ #include "monitor/monitor.h" #include "net/net.h" #include "net/vhost_net.h" +#include "qapi/util.h" #include "qapi/error.h" #include "qapi/qapi-commands-run-state.h" #include "qapi/qapi-events-run-state.h" @@ -355,6 +356,7 @@ static NotifierList wakeup_notifiers = static NotifierList shutdown_notifiers = NOTIFIER_LIST_INITIALIZER(shutdown_notifiers); static uint32_t wakeup_reason_mask = ~(1 << QEMU_WAKEUP_REASON_NONE); +static GStrv exec_argv; ShutdownCause qemu_shutdown_requested_get(void) { @@ -371,6 +373,11 @@ static int qemu_shutdown_requested(void) return qatomic_xchg(&shutdown_requested, SHUTDOWN_CAUSE_NONE); } +static int qemu_exec_requested(void) +{ + return exec_argv != NULL; +} + static void qemu_kill_report(void) { if (!qtest_driver() && shutdown_signal) { @@ -641,6 +648,18 @@ void qemu_system_shutdown_request(ShutdownCause reason) qemu_notify_event(); } +int qemu_system_exec_request(const strList *args, Error **errp) +{ + exec_argv = strv_from_strList(args); + if (!exec_argv[0]) { + error_setg(errp, "qemu_system_exec_request: argv[0] is NULL"); + return 1; + } + shutdown_requested = 1; + qemu_notify_event(); + return 0; +} + static void qemu_system_powerdown(void) { qapi_event_send_powerdown(); @@ -689,6 +708,13 @@ static bool main_loop_should_exit(void) } request = qemu_shutdown_requested(); if (request) { + + if (qemu_exec_requested()) { + execvp(exec_argv[0], exec_argv); + error_report("execvp %s failed: %s", exec_argv[0], strerror(errno)); + g_strfreev(exec_argv); + exec_argv = NULL; + } qemu_kill_report(); qemu_system_shutdown(request); if (shutdown_action == SHUTDOWN_ACTION_PAUSE) { -- 1.8.3.1