qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH 1/2] qemu-ga: suspend: fix possible SIGCHLD duri


From: Laszlo Ersek
Subject: Re: [Qemu-devel] [PATCH 1/2] qemu-ga: suspend: fix possible SIGCHLD during close() and g_free()
Date: Thu, 19 Apr 2012 11:18:38 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.3) Gecko/20120307 Thunderbird/10.0.3

On 04/18/12 21:30, Luiz Capitulino wrote:
> A child created by bios_supports_mode() could terminate during the call
> to close() or g_free(). This could cause the SIGCHLD signal to be
> deliveried in the midle of their execution. Possible problems range from
> resource leak to segfault. Fix that by blocking SIGCHLD during those calls.
> 
> Also, tries to explain why bios_supports_mode() got so complex...
> 
> Signed-off-by: Luiz Capitulino <address@hidden>
> ---
>  qga/commands-posix.c |   14 ++++++++++++--
>  1 file changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/qga/commands-posix.c b/qga/commands-posix.c
> index faf970d..41ba0c5 100644
> --- a/qga/commands-posix.c
> +++ b/qga/commands-posix.c
> @@ -521,14 +521,18 @@ static void guest_fsfreeze_cleanup(void)
>   * This function forks twice and the information about the mode support
>   * status is passed to the qemu-ga process via a pipe.
>   *
> - * This approach allows us to keep the way we reap terminated children
> - * in qemu-ga quite simple.
> + * XXX: This approach is a bit complex, it's implemented this way to avoid
> + *      calling waitpid() from the main qemu-ga process, as this could cause
> + *      interference with other commands that create new processes. The
> + *      solution to this problem is to introduce an internal API to safely
> + *      create & wait for children processes.
>   */
>  static void bios_supports_mode(const char *pmutils_bin, const char 
> *pmutils_arg,
>                                 const char *sysfile_str, Error **err)
>  {
>      pid_t pid;
>      ssize_t ret;
> +    sigset_t sigset;
>      char *pmutils_path;
>      int status, pipefds[2];
>  
> @@ -603,9 +607,15 @@ static void bios_supports_mode(const char *pmutils_bin, 
> const char *pmutils_arg,
>          _exit(EXIT_SUCCESS);
>      }
>  
> +    sigemptyset(&sigset);
> +    sigaddset(&sigset, SIGCHLD);
> +    pthread_sigmask(SIG_BLOCK, &sigset, NULL);
> +
>      close(pipefds[1]);
>      g_free(pmutils_path);
>  
> +    pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
> +
>      if (pid < 0) {
>          error_set(err, QERR_UNDEFINED_ERROR);
>          goto out;

If "pid < 0" then we shouldn't have to expect a SIGCHLD, indeed. (I was
a bit worried about error_set().)

Looks good to me too.

Laszlo



reply via email to

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