qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] qemu-ga: guest-shutdown: use only async-signal-


From: Eric Blake
Subject: Re: [Qemu-devel] [PATCH] qemu-ga: guest-shutdown: use only async-signal-safe functions
Date: Mon, 14 May 2012 11:51:13 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20120430 Thunderbird/12.0.1

On 05/14/2012 11:40 AM, Luiz Capitulino wrote:
> POSIX mandates[1] that a child process of a multi-thread program uses
> only async-signal-safe functions before exec(). We consider qemu-ga
> to be multi-thread, because it uses glib.
> 
> However, qmp_guest_shutdown() uses functions that are not
> async-signal-safe. Fix it the following way:
> 
> - fclose() -> reopen_fd_to_null()
> - execl() -> execle()
> - exit() -> _exit()
> - drop slog() usage (which is not safe)
> 
>   [1] http://pubs.opengroup.org/onlinepubs/009695399/functions/fork.html
> 

>  # @guest-shutdown:
>  #
>  # Initiate guest-activated shutdown. Note: this is an asynchronous
> -# shutdown request, with no guaruntee of successful shutdown. Errors
> -# will be logged to guest's syslog.
> +# shutdown request, with no guaruntee of successful shutdown.

As long as you are changing docs, fix the typo:

s/guaruntee/guarantee/

> +++ b/qga/commands-posix.c
> @@ -57,16 +57,13 @@ void qmp_guest_shutdown(bool has_mode, const char *mode, 
> Error **err)
>      if (pid == 0) {
>          /* child, start the shutdown */
>          setsid();
> -        fclose(stdin);
> -        fclose(stdout);
> -        fclose(stderr);
> -
> -        ret = execl("/sbin/shutdown", "shutdown", shutdown_flag, "+0",
> -                    "hypervisor initiated shutdown", (char*)NULL);
> -        if (ret) {
> -            slog("guest-shutdown failed: %s", strerror(errno));
> -        }
> -        exit(!!ret);
> +        reopen_fd_to_null(0);
> +        reopen_fd_to_null(1);
> +        reopen_fd_to_null(2);

I prefer the POSIX-mandated macros STDIN_FILENO, STDOUT_FILENO, and
STDERR_FILENO, but don't know if qemu intends to rely on them (according
to gnulib, at least older mingw lacked those macro names from
<unistd.h>).  So I won't make you change this.

> +
> +        ret = execle("/sbin/shutdown", "shutdown", shutdown_flag, "+0",
> +                    "hypervisor initiated shutdown", (char*)NULL, environ);

Where was 'environ' declared?  POSIX says that environ must exist, but
that it is the one variable where you must declare it yourself rather
than getting it from a public header.  (For convenience, glibc declares
environ in <unistd.h> when using _GNU_SOURCE, but when you are asking
for strict standards namespace compliance, it disappears.)

> +        _exit(!!ret);

Why are we even bothering with ret?  If execle() returns, we _know_ we
had a failure, and !!ret will always be 1.

-- 
Eric Blake   address@hidden    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]