From 2384225b8bd375ca4f57cb456531514239027f8a Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Tue, 18 Sep 2007 03:08:49 +0000 Subject: [PATCH] Avoid zombies with remote tunnels --- ChangeLog | 5 +++++ src/remote_internal.c | 21 ++++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2ceefeb3de..4ecdc0e506 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Mon Sep 17 23:04:00 EST 2007 Daniel P. Berrange + + * src/remote_internal.c: Track child pid and do waitpid to clean + up zombies if running over a tunnel + Thu Sep 13 17:58:00 EST 2007 Daniel P. Berrange * src/qemu_conf.c: Fix handling of tag for network PXE diff --git a/src/remote_internal.c b/src/remote_internal.c index 3506ca0bf1..21d6ee6723 100644 --- a/src/remote_internal.c +++ b/src/remote_internal.c @@ -62,6 +62,7 @@ struct private_data { int magic; /* Should be MAGIC or DEAD. */ int sock; /* Socket. */ + pid_t pid; /* PID of tunnel process */ int uses_tls; /* TLS enabled on socket? */ gnutls_session_t session; /* GnuTLS session (if uses_tls != 0). */ char *type; /* Cached return from remoteType. */ @@ -578,7 +579,7 @@ doRemoteOpen (virConnectPtr conn, struct private_data *priv, const char *uri_str /*FALLTHROUGH*/ case trans_ext: { - int pid; + pid_t pid; int sv[2]; /* Fork off the external process. Use socketpair to create a private @@ -617,6 +618,7 @@ doRemoteOpen (virConnectPtr conn, struct private_data *priv, const char *uri_str /* Parent continues here. */ close (sv[1]); priv->sock = sv[0]; + priv->pid = pid; } } /* switch (transport) */ @@ -646,6 +648,14 @@ doRemoteOpen (virConnectPtr conn, struct private_data *priv, const char *uri_str gnutls_bye (priv->session, GNUTLS_SHUT_RDWR); close (priv->sock); } + if (priv->pid > 0) { + pid_t reap; + do { + reap = waitpid(priv->pid, NULL, 0); + if (reap == -1 && errno == EINTR) + continue; + } while (reap != -1 && reap != priv->pid); + } /* Free up the URL and strings. */ xmlFreeURI (uri); @@ -1170,6 +1180,15 @@ doRemoteClose (virConnectPtr conn, struct private_data *priv) gnutls_bye (priv->session, GNUTLS_SHUT_RDWR); close (priv->sock); + if (priv->pid > 0) { + pid_t reap; + do { + reap = waitpid(priv->pid, NULL, 0); + if (reap == -1 && errno == EINTR) + continue; + } while (reap != -1 && reap != priv->pid); + } + /* See comment for remoteType. */ if (priv->type) free (priv->type);