Commit 885660bd authored by Michael Roth's avatar Michael Roth Committed by Anthony Liguori
Browse files

network scripts: don't block SIGCHLD before forking



This patch fixes a bug where child processes of launch_script() can
misbehave due to SIGCHLD being blocked. In the case of `sudo`, this
causes a permanent hang.

Previously a SIGCHLD handler was added to reap fork_exec()'d zombie
processes by calling waitpid(-1, ...). This required other
fork()/waitpid() callers to temporarilly block SIGCHILD to avoid
having the final wait status being intercepted by the SIGCHLD
handler:

7c3370d4

Since then, the qemu_add_child_watch() interface was added to allow
registration of such processes and reap only from that specific set
of PIDs:

4d54ec78

As a result, we can now avoid blocking SIGCHLD in launch_script(), so
drop that behavior.

Reviewed-by: default avatarJan Kiszka <jan.kiszka@siemens.com>
Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarMichael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
parent f603a687
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -346,15 +346,10 @@ static TAPState *net_tap_fd_init(VLANState *vlan,

static int launch_script(const char *setup_script, const char *ifname, int fd)
{
    sigset_t oldmask, mask;
    int pid, status;
    char *args[3];
    char **parg;

    sigemptyset(&mask);
    sigaddset(&mask, SIGCHLD);
    sigprocmask(SIG_BLOCK, &mask, &oldmask);

    /* try to launch network script */
    pid = fork();
    if (pid == 0) {
@@ -378,7 +373,6 @@ static int launch_script(const char *setup_script, const char *ifname, int fd)
        while (waitpid(pid, &status, 0) != pid) {
            /* loop */
        }
        sigprocmask(SIG_SETMASK, &oldmask, NULL);

        if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
            return 0;