[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Libvir] PATCH: Prevent zombie ssh tunnels



I noticed that when using the SSH tunnel for the remote driver I ended up
with alot of zombie SSH processes. We simply forgot to waitpid() on the
child when a connection attempt failed, or when shutting down an open remote
connection. Attached is a possible patch

Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 
Index: remote_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/remote_internal.c,v
retrieving revision 1.21
diff -u -p -r1.21 remote_internal.c
--- remote_internal.c	21 Aug 2007 10:08:12 -0000	1.21
+++ remote_internal.c	10 Sep 2007 23:58:01 -0000
@@ -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
 
         /*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
         /* Parent continues here. */
         close (sv[1]);
         priv->sock = sv[0];
+        priv->pid = pid;
     }
     } /* switch (transport) */
 
@@ -646,6 +648,19 @@ doRemoteOpen (virConnectPtr conn, struct
             gnutls_bye (priv->session, GNUTLS_SHUT_RDWR);
         close (priv->sock);
     }
+    if (priv->pid > 0) {
+        pid_t reap;
+        int status, n = 0;
+        kill(priv->pid, SIGTERM);
+        do {
+            if (n)
+                usleep(n*1000);
+            if (n > 3)
+                kill(priv->pid, SIGKILL);
+            reap = waitpid(priv->pid, &status, WNOHANG);
+            n++;
+        } while (reap != -1 && reap != priv->pid);
+    }
 
     /* Free up the URL and strings. */
     xmlFreeURI (uri);
@@ -1170,6 +1185,20 @@ doRemoteClose (virConnectPtr conn, struc
         gnutls_bye (priv->session, GNUTLS_SHUT_RDWR);
     close (priv->sock);
 
+    if (priv->pid > 0) {
+        pid_t reap;
+        int status, n = 0;
+        kill(priv->pid, SIGTERM);
+        do {
+            if (n)
+                usleep(n*1000);
+            if (n > 3)
+                kill(priv->pid, SIGKILL);
+            reap = waitpid(priv->pid, &status, WNOHANG);
+            n++;
+        } while (reap != -1 && reap != priv->pid);
+    }
+
     /* See comment for remoteType. */
     if (priv->type) free (priv->type);
 

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]