[Libguestfs] [PATCH DISCUSSION ONLY] Enable alternate vmchannel method (non-upstream virtio-console).

Richard W.M. Jones rjones at redhat.com
Thu Sep 17 16:57:37 UTC 2009


This patch is for discussion only.  The multiport virtio-console is
not accepted upstream, and in any case is currently being rewritten
for the nth time.

Getting a test environment to test this out is also non-trivial.  It
look me about a day.

You need to compile the alternate qemu (see URL in the patch +
attached qemu patch on top of this).

You also need to compile the alternate kernel - NOTE: only linux-next
kernel given in the URL in the patch will work, earlier kernels will
definitely *not* work.  You need to create an RPM of this and then
build a custom appliance with this kernel.  NOTE: Do not use supermin!

Then you can test it with a qemu wrapper, like this:

LIBGUESTFS_QEMU=~/d/vs-qemu-kvm/qemu.wrapper \
  libtool --mode=execute \
  ./fish/guestfish -v alloc /tmp/test.img 10M : run : debug ll /

(or if you are more adventurous, try running 'make check').

Multiport virtio-console fails on my local machine if the host is
under moderate load.  I'm currently working on a smaller test case to
try to reproduce this more easily.

Rich.

-- 
Richard Jones, Emerging Technologies, Red Hat  http://et.redhat.com/~rjones
virt-p2v converts physical machines to virtual machines.  Boot with a
live CD or over the network (PXE) and turn machines into Xen guests.
http://et.redhat.com/~rjones/virt-p2v
-------------- next part --------------
>From e80f093e91e6769da072fe74a94e71719ce47931 Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones at trick.home.annexia.org>
Date: Thu, 17 Sep 2009 14:55:50 +0100
Subject: [PATCH 3/3] Enable alternate vmchannel method (non-upstream virtio-console).

This patch enables an alternate vmchannel method, Amit Shah's
non-upstream multiport virtio-console:

http://git.kernel.org/?p=linux/kernel/git/amit/vs-kernel.git;a=summary
http://git.kernel.org/?p=linux/kernel/git/amit/vs-qemu-kvm.git;a=summary

On the library side, we try to detect if qemu offers this feature,
and if so we use it in preference to guestfwd.

On the daemon side, we detect if this method is being used (/dev/vcon4
device will appear), and use that.

The only change required is in the code which enables/detects this
feature.  Apart from that, the socket and protocol all works exactly
the same way.

NOTE: multiport virtio-console doesn't work if there is any load on
the host.  Random read() calls return 0 (EOF) incorrectly.  For this
and other reasons, this patch is *not* to be applied to libguestfs.
---
 daemon/guestfsd.c |   30 +++++++++++++++++++++++++++---
 src/guestfs.c     |   23 +++++++++++++++++------
 2 files changed, 44 insertions(+), 9 deletions(-)

diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c
index bfd8139..ca85db7 100644
--- a/daemon/guestfsd.c
+++ b/daemon/guestfsd.c
@@ -45,6 +45,7 @@ static void usage (void);
 /* Also in guestfs.c */
 #define GUESTFWD_PORT "6666"
 #define GUESTFWD_ADDR "10.0.2.4"
+#define VIRTIOCONSOLE_PORT "4"
 
 int verbose = 0;
 
@@ -155,7 +156,16 @@ main (int argc, char *argv[])
   /* We document that umask defaults to 022 (it should be this anyway). */
   umask (022);
 
-  /* Resolve the hostname. */
+  /* Look for each possible vmchannel implementation in turn
+   * until one succeeds.
+   */
+
+  /* Look for Amit Shah's multiport virtio-console device. */
+  sock = open ("/dev/vcon" VIRTIOCONSOLE_PORT, O_RDWR);
+  if (sock >= 0)
+    goto connected;
+
+  /* Look for the QEmu guestfwd network port. */
   memset (&hints, 0, sizeof hints);
   hints.ai_socktype = SOCK_STREAM;
   hints.ai_flags = AI_ADDRCONFIG;
@@ -181,12 +191,26 @@ main (int argc, char *argv[])
   }
   freeaddrinfo (res);
 
+  /* All vmchannel methods failed. */
   if (sock == -1) {
-    fprintf (stderr, "connection to %s:%s failed\n",
-             GUESTFWD_ADDR, GUESTFWD_PORT);
+    fprintf (stderr,
+             "\n"
+             "Failed to connect to any vmchannel implementation.\n"
+             "\n"
+             "This is a fatal error and the appliance will now exit.\n"
+             "\n"
+             "Usually this error is caused by either QEMU or the appliance\n"
+             "kernel not supporting the vmchannel method that the\n"
+             "libguestfs library chose to use.  Please run\n"
+             "'libguestfs-test-tool' and provide the complete, unedited\n"
+             "output to the libguestfs developers, either in a bug report\n"
+             "or on the libguestfs at redhat.com mailing list.\n"
+             "\n"
+             );
     exit (1);
   }
 
+ connected:
   /* Send the magic length message which indicates that
    * userspace is up inside the guest.
    */
diff --git a/src/guestfs.c b/src/guestfs.c
index 069de45..7a09131 100644
--- a/src/guestfs.c
+++ b/src/guestfs.c
@@ -87,6 +87,7 @@ static void close_handles (void);
 /* Also in guestfsd.c */
 #define GUESTFWD_PORT 6666
 //#define GUESTFWD_ADDR "10.0.2.4"
+#define VIRTIOCONSOLE_PORT 4
 
 /* GuestFS handle and connection. */
 enum state { CONFIG, LAUNCHING, READY, BUSY, NO_HANDLE };
@@ -1025,6 +1026,14 @@ guestfs__launch (guestfs_h *g)
     add_cmdline (g, "-serial");
     add_cmdline (g, "stdio");
 
+    /* Choose a vmchannel method by detecting what qemu supports. */
+    if (qemu_supports (g, "virtio console (multiport)")) {
+      snprintf (vmchannel, sizeof vmchannel,
+                "unix:%s,server,nowait,port=%d",
+                unixsock, VIRTIOCONSOLE_PORT);
+      add_cmdline (g, "-virtioconsole");
+      add_cmdline (g, vmchannel);
+    } else
 #if 0
     /* Doesn't work.  See:
      * http://lists.gnu.org/archive/html/qemu-devel/2009-07/threads.html
@@ -1035,13 +1044,17 @@ guestfs__launch (guestfs_h *g)
        * http://git.savannah.gnu.org/cgit/qemu.git/commit/?id=c92ef6a22d3c71538fcc48fb61ad353f7ba03b62
        */
       snprintf (vmchannel, sizeof vmchannel,
-                "user,vlan=0,net=10.0.2.0/8,guestfwd=tcp:%s:%d-unix:%s,server,nowait",
+                "user,vlan=0,net=10.0.2.0/8,"
+                "guestfwd=tcp:%s:%d-unix:%s,server,nowait",
                 GUESTFWD_ADDR, GUESTFWD_PORT, unixsock);
 
       add_cmdline (g, "-net");
       add_cmdline (g, vmchannel);
-    } else {
+      add_cmdline (g, "-net");
+      add_cmdline (g, "nic,model=" NET_IF ",vlan=0");
+    } else
 #endif
+    {
       /* Not guestfwd.  HOPEFULLY this qemu uses the older -net channel
        * syntax, or if not then we'll get a quick failure.
        */
@@ -1053,11 +1066,9 @@ guestfs__launch (guestfs_h *g)
       add_cmdline (g, vmchannel);
       add_cmdline (g, "-net");
       add_cmdline (g, "user,vlan=0,net=10.0.2.0/8");
-#if 0
+      add_cmdline (g, "-net");
+      add_cmdline (g, "nic,model=" NET_IF ",vlan=0");
     }
-#endif
-    add_cmdline (g, "-net");
-    add_cmdline (g, "nic,model=" NET_IF ",vlan=0");
 
     /* These options recommended by KVM developers to improve reliability. */
     if (qemu_supports (g, "-no-hpet"))
-- 
1.6.2.5

-------------- next part --------------
diff --git a/qemu-options.hx b/qemu-options.hx
index e2b8e36..485bfab 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1596,7 +1596,7 @@ ETEXI
 
 DEF("virtioconsole", HAS_ARG, QEMU_OPTION_virtiocon, \
     "-virtioconsole c\n" \
-    "                define virtio console\n")
+    "                define virtio console (multiport)\n")
 STEXI
 @item -virtioconsole @var{c}
 Set virtio console.


More information about the Libguestfs mailing list