[libvirt] [PATCH 3/4] remote: Print ssh stderr on connection failure

Cole Robinson crobinso at redhat.com
Fri Feb 12 15:32:16 UTC 2010


---
 src/remote/remote_driver.c |   37 ++++++++++++++++++++++++++++++++++---
 1 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 13534ce..7f92fd0 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -154,6 +154,7 @@ struct private_data {
     virMutex lock;
 
     int sock;                   /* Socket. */
+    int errsock;                /* Socket connected to remote stderr */
     int watch;                  /* File handle watch */
     pid_t pid;                  /* PID of tunnel process */
     int uses_tls;               /* TLS enabled on socket? */
@@ -783,6 +784,7 @@ doRemoteOpen (virConnectPtr conn,
     case trans_ext: {
         pid_t pid;
         int sv[2];
+        int errsock[2];
 
         /* Fork off the external process.  Use socketpair to create a private
          * (unnamed) Unix domain socket to the child process so we don't have
@@ -794,14 +796,21 @@ doRemoteOpen (virConnectPtr conn,
             goto failed;
         }
 
+        if (socketpair (PF_UNIX, SOCK_STREAM, 0, errsock) == -1) {
+            virReportSystemError(errno, "%s",
+                                 _("unable to create socket pair"));
+            goto failed;
+        }
+
         if (virExec((const char**)cmd_argv, NULL, NULL,
-                    &pid, sv[1], &(sv[1]), NULL,
+                    &pid, sv[1], &(sv[1]), &(errsock[1]),
                     VIR_EXEC_CLEAR_CAPS) < 0)
             goto failed;
 
         /* Parent continues here. */
         close (sv[1]);
         priv->sock = sv[0];
+        priv->errsock = errsock[0];
         priv->pid = pid;
 
         /* Do not set 'is_secure' flag since we can't guarentee
@@ -827,6 +836,12 @@ doRemoteOpen (virConnectPtr conn,
         goto failed;
     }
 
+    if ((priv->errsock != -1) && virSetNonBlock(priv->errsock) < 0) {
+        virReportSystemError(errno, "%s",
+                             _("unable to make socket non-blocking"));
+        goto failed;
+    }
+
     if (pipe(wakeupFD) < 0) {
         virReportSystemError(errno, "%s",
                              _("unable to make pipe"));
@@ -939,6 +954,9 @@ doRemoteOpen (virConnectPtr conn,
 
  failed:
     /* Close the socket if we failed. */
+    if (priv->errsock >= 0)
+        close(priv->errsock);
+
     if (priv->sock >= 0) {
         if (priv->uses_tls && priv->session) {
             gnutls_bye (priv->session, GNUTLS_SHUT_RDWR);
@@ -986,6 +1004,7 @@ remoteAllocPrivateData(virConnectPtr conn)
     priv->localUses = 1;
     priv->watch = -1;
     priv->sock = -1;
+    priv->errsock = -1;
 
     return priv;
 }
@@ -1408,6 +1427,7 @@ doRemoteClose (virConnectPtr conn, struct private_data *priv)
         sasl_dispose (&priv->saslconn);
 #endif
     close (priv->sock);
+    close (priv->errsock);
 
 #ifndef WIN32
     if (priv->pid > 0) {
@@ -7785,12 +7805,23 @@ remoteIOReadBuffer(virConnectPtr conn,
                 if (errno == EWOULDBLOCK)
                     return 0;
 
+                char errout[1024] = "\0";
+                if (priv->errsock) {
+                    recv(priv->errsock, errout, sizeof(errout), 0);
+                }
+
                 virReportSystemError(errno,
-                                     "%s", _("cannot recv data"));
+                                     _("cannot recv data: %s"), errout);
+
             } else {
+                char errout[1024] = "\0";
+                if (priv->errsock) {
+                    recv(priv->errsock, errout, sizeof(errout), 0);
+                }
+
                 errorf (in_open ? NULL : conn,
                         VIR_ERR_SYSTEM_ERROR,
-                        "%s", _("server closed connection"));
+                        _("server closed connection: %s"), errout);
             }
             return -1;
         }
-- 
1.6.5.2




More information about the libvir-list mailing list