Commit 4005b473 authored by Denis V. Lunev's avatar Denis V. Lunev Committed by Michael Roth
Browse files

qga: handle possible SIGPIPE in guest-file-write



qemu-ga should not exit on guest-file-write to pipe without read end
but proper error code should be returned. The behavior of the
spawned process should be default thus SIGPIPE processing should be
reset to default after fork() but before exec().

Signed-off-by: default avatarDenis V. Lunev <den@openvz.org>
Signed-off-by: default avatarYuri Pudgorodskiy <yur@virtuozzo.com>
Reviewed-by: default avatarMichael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: default avatarDenis V. Lunev <den@openvz.org>
Signed-off-by: default avatarMichael Roth <mdroth@linux.vnet.ibm.com>
parent d697e30c
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
@@ -225,6 +225,22 @@ static void guest_exec_child_watch(GPid pid, gint status, gpointer data)
    g_spawn_close_pid(pid);
}

/** Reset ignored signals back to default. */
static void guest_exec_task_setup(gpointer data)
{
#if !defined(G_OS_WIN32)
    struct sigaction sigact;

    memset(&sigact, 0, sizeof(struct sigaction));
    sigact.sa_handler = SIG_DFL;

    if (sigaction(SIGPIPE, &sigact, NULL) != 0) {
        slog("sigaction() failed to reset child process's SIGPIPE: %s",
             strerror(errno));
    }
#endif
}

GuestExec *qmp_guest_exec(const char *path,
                       bool has_arg, strList *arg,
                       bool has_env, strList *env,
@@ -250,7 +266,7 @@ GuestExec *qmp_guest_exec(const char *path,
            G_SPAWN_SEARCH_PATH |
            G_SPAWN_DO_NOT_REAP_CHILD |
            G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
            NULL, NULL, &pid, NULL, NULL, NULL, &gerr);
            guest_exec_task_setup, NULL, &pid, NULL, NULL, NULL, &gerr);
    if (!ret) {
        error_setg(err, QERR_QGA_COMMAND_FAILED, gerr->message);
        g_error_free(gerr);
+6 −0
Original line number Diff line number Diff line
@@ -161,6 +161,12 @@ static gboolean register_signal_handlers(void)
        g_error("error configuring signal handler: %s", strerror(errno));
    }

    sigact.sa_handler = SIG_IGN;
    if (sigaction(SIGPIPE, &sigact, NULL) != 0) {
        g_error("error configuring SIGPIPE signal handler: %s",
                strerror(errno));
    }

    return true;
}