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

[libvirt] [PATCH 4/4] remote: Detect 'nc' version incompatibilities



This ugly thing is a shell script to detect availability of
the -q option for 'nc': debian and suse based distros need this
flag to ensure the remote nc will exit on EOF, so it will go away
when we close the tunnel. If it doesn't go away, a useless 'nc'
process is left sitting on the remote host.

Fedora's 'nc' doesn't have this option, so we can't blindly pass -q.
More info here:

http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=564034

We also detect the -U option, since some nc versions don't support it, which
has caused quite some user confusion. Connecting to a box and using the
incorrect nc:

virsh --connect qemu+ssh://root debhost/system?netcat=/bin/nc.traditional
error: server closed connection: /bin/nc.traditional: invalid option -- U
nc -h for help
openbsd nc is required

error: failed to connect to the hypervisor

Test with Fedora 12, RHEL 5.4, and Debian Lenny
---
 src/remote/remote_driver.c |   52 ++++++++++++++++++++++++++++++++++++++------
 1 files changed, 45 insertions(+), 7 deletions(-)

diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 7f92fd0..c3258d3 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -732,8 +732,49 @@ doRemoteOpen (virConnectPtr conn,
     }
 
     case trans_ssh: {
-        int j, nr_args = 6;
+        int j, nr_args = 0;
+        char *nc_command;
+
+        const char *nc_bin = netcat ? netcat : "nc";
+        const char *sock_path = (sockname ? sockname :
+                                 (flags & VIR_CONNECT_RO
+                                  ? LIBVIRTD_PRIV_UNIX_SOCKET_RO
+                                  : LIBVIRTD_PRIV_UNIX_SOCKET));
+
+        /*
+         * Build 'nc' command run on the remote host
+         *
+         * This ugly thing is a shell script to detect availability of
+         * the -q option for 'nc': debian and suse based distros need this
+         * flag to ensure the remote nc will exit on EOF, so it will go away
+         * when we close the tunnel. If it doesn't go away, a useless 'nc'
+         * process is left sitting on the remote host.
+         *
+         * Fedora's 'nc' doesn't have this option, and apparently defaults
+         * to the desired behavior.
+         */
+        const char *nc_detect_template = (
+            "NCOUT=$(%s -U 2>&1);"
+            "echo \"$NCOUT\" | grep -q 'invalid option';"
+            "if [ $? -eq 0 ] ; then"
+            "   echo \"$NCOUT\" >&2;"
+            "   echo openbsd 'nc' is required >&2;"
+            "   exit 1;"
+            "fi;"
+            ""
+            "%s -q 2>&1 | grep -q 'requires an argument';"
+            "if [ $? -eq 0 ] ; then"
+            "   CMD='-q 0';"
+            "else"
+            "   CMD='';"
+            "fi;"
+            "%s $CMD -U %s;");
+
+        if (virAsprintf(&nc_command, nc_detect_template,
+                        nc_bin, nc_bin, nc_bin, sock_path) < 0)
+            goto out_of_memory;
 
+        nr_args += 4;               /* ssh $hostname $netcat_command NULL*/
         if (username) nr_args += 2; /* For -l username */
         if (no_tty) nr_args += 5;   /* For -T -o BatchMode=yes -e none */
         if (port) nr_args += 2;     /* For -p port */
@@ -765,12 +806,9 @@ doRemoteOpen (virConnectPtr conn,
             cmd_argv[j++] = strdup ("none");
         }
         cmd_argv[j++] = strdup (priv->hostname);
-        cmd_argv[j++] = strdup (netcat ? netcat : "nc");
-        cmd_argv[j++] = strdup ("-U");
-        cmd_argv[j++] = strdup (sockname ? sockname :
-                                (flags & VIR_CONNECT_RO
-                                 ? LIBVIRTD_PRIV_UNIX_SOCKET_RO
-                                 : LIBVIRTD_PRIV_UNIX_SOCKET));
+
+        cmd_argv[j++] = nc_command;
+
         cmd_argv[j++] = 0;
         assert (j == nr_args);
         for (j = 0; j < (nr_args-1); j++)
-- 
1.6.5.2


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