On Thu, Apr 14, 2022 at 2:04 AM Andrew Deason <adea...@sinenomine.net>
wrote:

> On Solaris, instead of the -P, -H, and -r flags, we need to provide
> the target init state to the 'shutdown' command: state 5 is poweroff,
> 0 is halt, and 6 is reboot. We also need to pass -g0 to avoid the
> default 60-second delay, and -y to avoid a confirmation prompt.
>
> Implement this logic under an #ifdef CONFIG_SOLARIS, so the
> 'guest-shutdown' command works properly on Solaris.
>
> Signed-off-by: Andrew Deason <adea...@sinenomine.net>
>

Reviewed-by: Marc-André Lureau <marcandre.lur...@redhat.com>


> ---
> Changes since v1:
> - new in v2
>
>  qga/commands-posix.c | 21 ++++++++++++++++++---
>  1 file changed, 18 insertions(+), 3 deletions(-)
>
> diff --git a/qga/commands-posix.c b/qga/commands-posix.c
> index 97e001e998..8c30a9e575 100644
> --- a/qga/commands-posix.c
> +++ b/qga/commands-posix.c
> @@ -88,43 +88,58 @@ static void ga_wait_child(pid_t pid, int *status,
> Error **errp)
>      g_assert(rpid == pid);
>  }
>
>  void qmp_guest_shutdown(bool has_mode, const char *mode, Error **errp)
>  {
>      const char *shutdown_flag;
>      Error *local_err = NULL;
>      pid_t pid;
>      int status;
>
> +#ifdef CONFIG_SOLARIS
> +    const char *powerdown_flag = "-i5";
> +    const char *halt_flag = "-i0";
> +    const char *reboot_flag = "-i6";
> +#else
> +    const char *powerdown_flag = "-P";
> +    const char *halt_flag = "-H";
> +    const char *reboot_flag = "-r";
> +#endif
> +
>      slog("guest-shutdown called, mode: %s", mode);
>      if (!has_mode || strcmp(mode, "powerdown") == 0) {
> -        shutdown_flag = "-P";
> +        shutdown_flag = powerdown_flag;
>      } else if (strcmp(mode, "halt") == 0) {
> -        shutdown_flag = "-H";
> +        shutdown_flag = halt_flag;
>      } else if (strcmp(mode, "reboot") == 0) {
> -        shutdown_flag = "-r";
> +        shutdown_flag = reboot_flag;
>      } else {
>          error_setg(errp,
>                     "mode is invalid (valid values are:
> halt|powerdown|reboot");
>          return;
>      }
>
>      pid = fork();
>      if (pid == 0) {
>          /* child, start the shutdown */
>          setsid();
>          reopen_fd_to_null(0);
>          reopen_fd_to_null(1);
>          reopen_fd_to_null(2);
>
> +#ifdef CONFIG_SOLARIS
> +        execle("/sbin/shutdown", "shutdown", shutdown_flag, "-g0", "-y",
> +               "hypervisor initiated shutdown", (char *)NULL, environ);
> +#else
>          execle("/sbin/shutdown", "shutdown", "-h", shutdown_flag, "+0",
>                 "hypervisor initiated shutdown", (char *)NULL, environ);
> +#endif
>          _exit(EXIT_FAILURE);
>      } else if (pid < 0) {
>          error_setg_errno(errp, errno, "failed to create child process");
>          return;
>      }
>
>      ga_wait_child(pid, &status, &local_err);
>      if (local_err) {
>          error_propagate(errp, local_err);
>          return;
> --
> 2.11.0
>
>
>

-- 
Marc-André Lureau

Reply via email to