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);