From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 2/2] add a service to reap zombies, use it in SLIRP
Date: Wed, 9 Mar 2011 18:21:10 +0100 [thread overview]
Message-ID: <1299691270-16328-3-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1299691270-16328-1-git-send-email-pbonzini@redhat.com>
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 <pbonzini@redhat.com>
---
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 <sys/wait.h>
+#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;
--
1.7.4
next prev parent reply other threads:[~2011-03-09 17:21 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-09 17:21 [Qemu-devel] [PATCH 0/2] avoid races on exec migration Paolo Bonzini
2011-03-09 17:21 ` [Qemu-devel] [PATCH 1/2] extract I/O handler lists to iohandler.c Paolo Bonzini
2011-04-03 3:18 ` Roy Tam
2011-03-09 17:21 ` Paolo Bonzini [this message]
2011-03-21 8:24 ` [Qemu-devel] Re: [PATCH 0/2] avoid races on exec migration Paolo Bonzini
2011-03-29 9:19 ` Paolo Bonzini
2011-03-29 11:52 ` [Qemu-devel] " Markus Armbruster
2011-03-29 12:24 ` [Qemu-devel] " Paolo Bonzini
2011-03-29 13:33 ` [Qemu-devel] " Anthony Liguori
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1299691270-16328-3-git-send-email-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).