Add a qemu_system_exec_request() hook that causes the main loop to exit and exec a command using the specified arguments. This will be used during CPR to exec a new version of QEMU.
Signed-off-by: Steve Sistare <steven.sist...@oracle.com> --- include/system/runstate.h | 3 +++ system/runstate.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/include/system/runstate.h b/include/system/runstate.h index 929379a..c005f49 100644 --- a/include/system/runstate.h +++ b/include/system/runstate.h @@ -128,6 +128,8 @@ typedef enum WakeupReason { QEMU_WAKEUP_REASON_OTHER, } WakeupReason; +typedef void (*qemu_exec_func)(char **exec_argv); + void qemu_system_reset_request(ShutdownCause reason); void qemu_system_suspend_request(void); void qemu_register_suspend_notifier(Notifier *notifier); @@ -139,6 +141,7 @@ void qemu_register_wakeup_support(void); void qemu_system_shutdown_request_with_code(ShutdownCause reason, int exit_code); void qemu_system_shutdown_request(ShutdownCause reason); +void qemu_system_exec_request(qemu_exec_func func, const strList *args); void qemu_system_powerdown_request(void); void qemu_register_powerdown_notifier(Notifier *notifier); void qemu_register_shutdown_notifier(Notifier *notifier); diff --git a/system/runstate.c b/system/runstate.c index 6178b00..b4980ff 100644 --- a/system/runstate.c +++ b/system/runstate.c @@ -41,6 +41,7 @@ #include "qapi/error.h" #include "qapi/qapi-commands-run-state.h" #include "qapi/qapi-events-run-state.h" +#include "qapi/type-helpers.h" #include "qemu/accel.h" #include "qemu/error-report.h" #include "qemu/job.h" @@ -422,6 +423,8 @@ static NotifierList wakeup_notifiers = static NotifierList shutdown_notifiers = NOTIFIER_LIST_INITIALIZER(shutdown_notifiers); static uint32_t wakeup_reason_mask = ~(1 << QEMU_WAKEUP_REASON_NONE); +qemu_exec_func exec_func; +static char **exec_argv; ShutdownCause qemu_shutdown_requested_get(void) { @@ -443,6 +446,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) { @@ -803,6 +811,23 @@ void qemu_system_shutdown_request(ShutdownCause reason) qemu_notify_event(); } +static void qemu_system_exec(void) +{ + exec_func(exec_argv); + + /* exec failed */ + g_strfreev(exec_argv); + exec_argv = NULL; + exec_func = NULL; +} + +void qemu_system_exec_request(qemu_exec_func func, const strList *args) +{ + exec_func = func; + exec_argv = strv_from_str_list(args); + qemu_notify_event(); +} + static void qemu_system_powerdown(void) { qapi_event_send_powerdown(); @@ -849,6 +874,10 @@ static bool main_loop_should_exit(int *status) if (qemu_suspend_requested()) { qemu_system_suspend(); } + if (qemu_exec_requested()) { + qemu_system_exec(); + return false; + } request = qemu_shutdown_requested(); if (request) { qemu_kill_report(); -- 1.8.3.1