[Libvir] PATCH: Explicit detection of KVM version

Daniel P. Berrange berrange at redhat.com
Thu Sep 20 03:05:21 UTC 2007


Before starting any guest, the QEMU driver needs to figure out what version
of QEMU is in use & thus determine whether it supports particular command 
line flags. We currently do that just by calling /usr/bin/qemu, since all
the various qemu-system-XXX binaries share the same syntax. The only problem
is that qemu-kvm does not neccessarily match the version of qemu installed.
So we detect QEMU version 0.8.2, but KVM is 0.9.0 based. The result is that
we pass the wrong style VNC argument to KVM & it fails to start. The second
problem is that even if you only ever want to run KVM guests, you still have
to have KVM itself installed.

This patch tweaks the feature/version detection so we do separate detection
just for KVM. With this applied I can successfully start KVM guests if the
QEMU version is different, or even if QEMU is not installed.

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  -=| 
-------------- next part --------------
? test.core
? test.save
Index: qemu_conf.c
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_conf.c,v
retrieving revision 1.13
diff -u -r1.13 qemu_conf.c
--- qemu_conf.c	13 Sep 2007 22:06:54 -0000	1.13
+++ qemu_conf.c	20 Sep 2007 03:00:41 -0000
@@ -408,14 +408,24 @@
 }
 
 int qemudExtractVersion(virConnectPtr conn,
-                        struct qemud_driver *driver) {
+                        struct qemud_driver *driver,
+                        int virtType) {
     char *binary = NULL;
     struct stat sb;
+    int *flags, *version;
 
-    if (driver->qemuVersion > 0)
+    if (virtType == QEMUD_VIRT_KVM) {
+        flags = &driver->kvmCmdFlags;
+        version = &driver->kvmVersion;
+    } else {
+        flags = &driver->qemuCmdFlags;
+        version = &driver->qemuVersion;
+    }
+
+    if (*version > 0)
         return 0;
 
-    if (!(binary = qemudLocateBinaryForArch(conn, driver, QEMUD_VIRT_QEMU, "i686")))
+    if (!(binary = qemudLocateBinaryForArch(conn, driver, virtType, "i686")))
         return -1;
 
     if (stat(binary, &sb) < 0) {
@@ -426,7 +436,7 @@
         return -1;
     }
 
-    if (qemudExtractVersionInfo(binary, &driver->qemuVersion, &driver->qemuCmdFlags) < 0) {
+    if (qemudExtractVersionInfo(binary, version, flags) < 0) {
         free(binary);
         return -1;
     }
@@ -1465,9 +1475,14 @@
     struct qemud_vm_input_def *input = vm->def->inputs;
     struct utsname ut;
     int disableKQEMU = 0;
+    int flags;
 
-    if (qemudExtractVersion(conn, driver) < 0)
+    if (qemudExtractVersion(conn, driver, vm->def->virtType) < 0)
         return -1;
+    if (vm->def->virtType == QEMUD_VIRT_KVM)
+        flags = driver->kvmCmdFlags;
+    else
+        flags = driver->qemuCmdFlags;
 
     uname(&ut);
 
@@ -1483,7 +1498,7 @@
      * 2. Guest is 'qemu'
      * 3. The qemu binary has the -no-kqemu flag
      */
-    if ((driver->qemuCmdFlags & QEMUD_CMD_FLAG_KQEMU) &&
+    if ((flags & QEMUD_CMD_FLAG_KQEMU) &&
         !strcmp(ut.machine, vm->def->os.arch) &&
         vm->def->virtType == QEMUD_VIRT_QEMU)
         disableKQEMU = 1;
@@ -1511,7 +1526,7 @@
         2 + /* boot device */
         2 + /* monitor */
         (vm->def->localtime ? 1 : 0) + /* localtime */
-        (driver->qemuCmdFlags & QEMUD_CMD_FLAG_NO_REBOOT &&
+        (flags & QEMUD_CMD_FLAG_NO_REBOOT &&
          vm->def->noReboot ? 1 : 0) + /* no-reboot */
         (vm->def->features & QEMUD_FEATURE_ACPI ? 0 : 1) + /* acpi */
         (vm->def->os.kernel[0] ? 2 : 0) + /* kernel */
@@ -1567,7 +1582,7 @@
             goto no_memory;
     }
 
-    if (driver->qemuCmdFlags & QEMUD_CMD_FLAG_NO_REBOOT &&
+    if (flags & QEMUD_CMD_FLAG_NO_REBOOT &&
         vm->def->noReboot) {
         if (!((*argv)[++n] = strdup("-no-reboot")))
             goto no_memory;
@@ -1748,7 +1763,7 @@
     if (vm->def->graphicsType == QEMUD_GRAPHICS_VNC) {
         char vncdisplay[BR_INET_ADDR_MAXLEN+20];
         int ret;
-        if (driver->qemuCmdFlags & QEMUD_CMD_FLAG_VNC_COLON)
+        if (flags & QEMUD_CMD_FLAG_VNC_COLON)
             ret = snprintf(vncdisplay, sizeof(vncdisplay), "%s:%d",
                            vm->def->vncListen,
                            vm->def->vncActivePort - 5900);
Index: qemu_conf.h
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_conf.h,v
retrieving revision 1.8
diff -u -r1.8 qemu_conf.h
--- qemu_conf.h	14 Aug 2007 01:28:47 -0000	1.8
+++ qemu_conf.h	20 Sep 2007 03:00:41 -0000
@@ -272,7 +272,9 @@
 /* Main driver state */
 struct qemud_driver {
     int qemuVersion;
+    int kvmVersion;
     int qemuCmdFlags; /* values from enum qemud_cmd_flags */
+    int kvmCmdFlags; /* values from enum qemud_cmd_flags */
     int nactivevms;
     int ninactivevms;
     struct qemud_vm *vms;
@@ -323,7 +325,8 @@
                                              const char *name);
 
 int         qemudExtractVersion         (virConnectPtr conn,
-                                         struct qemud_driver *driver);
+                                         struct qemud_driver *driver,
+                                         int virtType);
 int         qemudBuildCommandLine       (virConnectPtr conn,
                                          struct qemud_driver *driver,
                                          struct qemud_vm *vm,
Index: qemu_driver.c
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_driver.c,v
retrieving revision 1.23
diff -u -r1.23 qemu_driver.c
--- qemu_driver.c	21 Aug 2007 10:08:12 -0000	1.23
+++ qemu_driver.c	20 Sep 2007 03:00:43 -0000
@@ -1691,7 +1691,7 @@
 
 static int qemudGetVersion(virConnectPtr conn, unsigned long *version) {
     struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
-    if (qemudExtractVersion(conn, driver) < 0)
+    if (qemudExtractVersion(conn, driver, QEMUD_VIRT_QEMU) < 0)
         return -1;
 
     *version = qemu_driver->qemuVersion;


More information about the libvir-list mailing list