From patchwork Wed Mar 9 17:21:10 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 86134 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id AD2A4B6ED0 for ; Thu, 10 Mar 2011 04:26:47 +1100 (EST) Received: from localhost ([127.0.0.1]:41054 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PxN5w-0000Mo-DF for incoming@patchwork.ozlabs.org; Wed, 09 Mar 2011 12:22:44 -0500 Received: from [140.186.70.92] (port=58633 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PxN4h-0005KR-2x for qemu-devel@nongnu.org; Wed, 09 Mar 2011 12:21:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PxN4c-0006IU-7Q for qemu-devel@nongnu.org; Wed, 09 Mar 2011 12:21:23 -0500 Received: from mail-qw0-f45.google.com ([209.85.216.45]:65531) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PxN4c-0006IH-3P for qemu-devel@nongnu.org; Wed, 09 Mar 2011 12:21:22 -0500 Received: by qwj8 with SMTP id 8so663598qwj.4 for ; Wed, 09 Mar 2011 09:21:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:sender:from:to:subject:date:message-id:x-mailer :in-reply-to:references; bh=93ZX4zRWZY7S3Zp/Ec6+xRifYxhKLFsyfvpRcxp5QR8=; b=Y4Rfym04+5rQ6AfrkFhCO2D9YPHPr4653/tIzPSxtRrPEHD1QzSjvxZlVXxsUPg7Ee ok2ztKtTH+obFvnx+BcEBV4DSmxSVnYYyd/wI2cTHA89BxafTfaelXS+vw6pob/ft/An 7NzJpudWfkaSJi6wUDi84yQTgOQIq6nqvHupc= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:from:to:subject:date:message-id:x-mailer:in-reply-to :references; b=Wce4/B6q1+yfmo+LtCRAvbB83lMl1NJlXJpVgLllm2oSCvKjFWXHWII13qiGXw6Z6/ Glgm7Gd2100J7DsvlNQ+a94EIjkqVeA3KtMbd74kVY5CAs1j3GwKoGP9Xk9XjVuWCycO YMHiAfih8O6L9ykpbbdF3HeJJTY0trfbSJKvQ= Received: by 10.224.18.137 with SMTP id w9mr5886990qaa.241.1299691281539; Wed, 09 Mar 2011 09:21:21 -0800 (PST) Received: from localhost.localdomain (93-34-197-200.ip51.fastwebnet.it [93.34.197.200]) by mx.google.com with ESMTPS id s10sm1557622qco.23.2011.03.09.09.21.20 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 09 Mar 2011 09:21:20 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Wed, 9 Mar 2011 18:21:10 +0100 Message-Id: <1299691270-16328-3-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.7.4 In-Reply-To: <1299691270-16328-1-git-send-email-pbonzini@redhat.com> References: <1299691270-16328-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 209.85.216.45 Subject: [Qemu-devel] [PATCH 2/2] add a service to reap zombies, use it in SLIRP X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org SLIRP -smb support wants to fork a process and forget about reaping it. To please it, add a generic service to register a process id and let QEMU reap it. In the future it could be enhanced to pass a status, but this would be unused. With this in place, the SIGCHLD signal handler would not stomp on pclose anymore. Signed-off-by: Paolo Bonzini --- iohandler.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ os-posix.c | 9 -------- qemu-common.h | 1 + slirp/misc.c | 5 +++- 4 files changed, 69 insertions(+), 10 deletions(-) diff --git a/iohandler.c b/iohandler.c index 2e30fe3..2b82421 100644 --- a/iohandler.c +++ b/iohandler.c @@ -27,6 +27,10 @@ #include "qemu-char.h" #include "qemu-queue.h" +#ifndef _WIN32 +#include +#endif + typedef struct IOHandlerRecord { int fd; IOCanReadHandler *fd_read_poll; @@ -127,3 +131,63 @@ void qemu_iohandler_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, int re } } } + +/* reaping of zombies. right now we're not passing the status to + anyone, but it would be possible to add a callback. */ +#ifndef _WIN32 +typedef struct ChildProcessRecord { + int pid; + QLIST_ENTRY(ChildProcessRecord) next; +} ChildProcessRecord; + +static QLIST_HEAD(, ChildProcessRecord) child_watches = + QLIST_HEAD_INITIALIZER(child_watches); + +static QEMUBH *sigchld_bh; + +static void sigchld_handler(int signal) +{ + qemu_bh_schedule(sigchld_bh); +} + +static void sigchld_bh_handler(void *opaque) +{ + ChildProcessRecord *rec, *next; + + QLIST_FOREACH_SAFE(rec, &child_watches, next, next) { + if (waitpid(rec->pid, NULL, WNOHANG) == rec->pid) { + QLIST_REMOVE(rec, next); + qemu_free(rec); + } + } +} + +static void qemu_init_child_watch(void) +{ + struct sigaction act; + sigchld_bh = qemu_bh_new(sigchld_bh_handler, NULL); + + act.sa_handler = sigchld_handler; + act.sa_flags = SA_NOCLDSTOP; + sigaction(SIGCHLD, &act, NULL); +} + +int qemu_add_child_watch(pid_t pid) +{ + ChildProcessRecord *rec; + + if (!sigchld_bh) { + qemu_init_child_watch(); + } + + QLIST_FOREACH(rec, &child_watches, next) { + if (rec->pid == pid) { + return 1; + } + } + rec = qemu_mallocz(sizeof(ChildProcessRecord)); + rec->pid = pid; + QLIST_INSERT_HEAD(&child_watches, rec, next); + return 0; +} +#endif diff --git a/os-posix.c b/os-posix.c index 38c29d1..d9c17d8 100644 --- a/os-posix.c +++ b/os-posix.c @@ -66,11 +66,6 @@ static void termsig_handler(int signal) qemu_system_shutdown_request(); } -static void sigchld_handler(int signal) -{ - waitpid(-1, NULL, WNOHANG); -} - void os_setup_signal_handling(void) { struct sigaction act; @@ -80,10 +75,6 @@ void os_setup_signal_handling(void) sigaction(SIGINT, &act, NULL); sigaction(SIGHUP, &act, NULL); sigaction(SIGTERM, &act, NULL); - - act.sa_handler = sigchld_handler; - act.sa_flags = SA_NOCLDSTOP; - sigaction(SIGCHLD, &act, NULL); } /* Find a likely location for support files using the location of the binary. diff --git a/qemu-common.h b/qemu-common.h index 27855b0..c670c0e 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -210,6 +210,7 @@ ssize_t qemu_write_full(int fd, const void *buf, size_t count) void qemu_set_cloexec(int fd); #ifndef _WIN32 +int qemu_add_child_watch(pid_t pid); int qemu_eventfd(int pipefd[2]); int qemu_pipe(int pipefd[2]); #endif diff --git a/slirp/misc.c b/slirp/misc.c index 19dbec4..08eba6a 100644 --- a/slirp/misc.c +++ b/slirp/misc.c @@ -119,6 +119,7 @@ fork_exec(struct socket *so, const char *ex, int do_pty) char *bptr; const char *curarg; int c, i, ret; + pid_t pid; DEBUG_CALL("fork_exec"); DEBUG_ARG("so = %lx", (long)so); @@ -142,7 +143,8 @@ fork_exec(struct socket *so, const char *ex, int do_pty) } } - switch(fork()) { + pid = fork(); + switch(pid) { case -1: lprint("Error: fork failed: %s\n", strerror(errno)); close(s); @@ -206,6 +208,7 @@ fork_exec(struct socket *so, const char *ex, int do_pty) exit(1); default: + qemu_add_child_watch(pid); if (do_pty == 2) { close(s); so->s = master;