Hi

On Wed, Jul 7, 2021 at 9:46 PM Steve Sistare <steven.sist...@oracle.com>
wrote:

> Add a qemu_system_exec_request() hook that causes the main loop to exit and
> re-exec qemu using the specified arguments.
>

I assume it works ok with -sandbox on,spawn=allow ?


> Signed-off-by: Steve Sistare <steven.sist...@oracle.com>
> ---
>  include/sysemu/runstate.h |  1 +
>  softmmu/runstate.c        | 37 +++++++++++++++++++++++++++++++++++++
>  2 files changed, 38 insertions(+)
>
> diff --git a/include/sysemu/runstate.h b/include/sysemu/runstate.h
> index ed4b735..e1ae7e5 100644
> --- a/include/sysemu/runstate.h
> +++ b/include/sysemu/runstate.h
> @@ -57,6 +57,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);
> +void qemu_system_exec_request(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/softmmu/runstate.c b/softmmu/runstate.c
> index 7fe4967..8474a01 100644
> --- a/softmmu/runstate.c
> +++ b/softmmu/runstate.c
> @@ -355,6 +355,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 char **exec_argv;
>
>  ShutdownCause qemu_shutdown_requested_get(void)
>  {
> @@ -371,6 +372,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) {
> @@ -645,6 +651,32 @@ void qemu_system_shutdown_request(ShutdownCause
> reason)
>      qemu_notify_event();
>  }
>
> +static char **make_argv(strList *args)
>

I'd suggest making it a generic strv_from_strList() function. Take const as
argument too.


> +{
> +    strList *arg;
> +    char **argv;
> +    int n = 1, i = 0;
> +
> +    for (arg = args; arg != NULL; arg = arg->next) {
> +        n++;
> +    }
>

We could use a QAPI_LIST_LENGTH() in qapi/util.h

+
> +    argv = g_malloc(n * sizeof(char *));
> +    for (arg = args; arg != NULL; arg = arg->next) {
> +        argv[i++] = g_strdup(arg->value);
> +    }
> +    argv[i] = NULL;
> +
> +    return argv;
> +}
> +
> +void qemu_system_exec_request(strList *args)
>

const args, and documentation could help.

+{
> +    exec_argv = make_argv(args);
> +    shutdown_requested = 1;
> +    qemu_notify_event();
> +}
> +
>  static void qemu_system_powerdown(void)
>  {
>      qapi_event_send_powerdown();
> @@ -693,6 +725,11 @@ static bool main_loop_should_exit(void)
>      }
>      request = qemu_shutdown_requested();
>      if (request) {
> +
> +        if (qemu_exec_requested()) {
> +            execvp(exec_argv[0], exec_argv);
> +            error_setg_errno(&error_fatal, errno, "execvp failed");
>

Can this be handled more gracefully instead?

g_strfreev the argv and report an error?


> +        }
>          qemu_kill_report();
>          qemu_system_shutdown(request);
>          if (shutdown_action == SHUTDOWN_ACTION_PAUSE) {
> --
> 1.8.3.1
>
>
>

-- 
Marc-André Lureau

Reply via email to