[libvirt] PATCH: Only pass in emulator if user requested it

Daniel P. Berrange berrange at redhat.com
Mon Sep 1 14:55:57 UTC 2008


Previouly with Xen we would only specify an emulator path to XenD if there
was one provided in the XML. With the new domain XML routines we will always
lookup the default emulator path internally using our capabilities data.
So XenD sees an explicit emulator path even if the user didn't request one.

This works fine, except for paravirt guests where you only want to have
the text console active, and not the graphical framebuffer. In this 
scenario, XenD starts QEMU-DM to handle the text console, but it crashes
because PVFB isn't configured.

This patch switches us back to the old behaviour where we only pass an
emulator to XenD if the user actually specified one - XenD is intelligent
enough to auto-configure a QEMU instance for paravirt framebuffers as
needed.

The logic looking up the default emulator did live in the generic XML
parsing routines. This patch removes it from the XML parsing stage,
and pushes it down into the individual drivers at time of use (if they
so desire).

 src/domain_conf.c                              |   47 +++++++++++++++----------
 src/domain_conf.h                              |    5 ++
 src/lxc_driver.c                               |   10 ++++-
 src/qemu_conf.c                                |    6 +++
 src/qemu_driver.c                              |   15 +++++--
 src/xm_internal.c                              |   20 ----------
 tests/xmconfigdata/test-paravirt-net-e1000.xml |    1 
 tests/xmconfigdata/test-paravirt-new-pvfb.xml  |    1 
 tests/xmconfigdata/test-paravirt-old-pvfb.xml  |    1 
 tests/xml2sexprdata/xml2sexpr-fv-kernel.xml    |    1 
 tests/xml2sexprdata/xml2sexpr-pv-vfb-new.sexpr |    2 -
 11 files changed, 62 insertions(+), 47 deletions(-)

Daniel

diff -r d1308575c2d3 src/domain_conf.c
--- a/src/domain_conf.c	Mon Sep 01 14:48:19 2008 +0100
+++ b/src/domain_conf.c	Mon Sep 01 15:00:46 2008 +0100
@@ -1917,24 +1917,6 @@ static virDomainDefPtr virDomainDefParse
     }
 
     def->emulator = virXPathString(conn, "string(./devices/emulator[1])", ctxt);
-    if (!def->emulator) {
-        const char *type = virDomainVirtTypeToString(def->virtType);
-        if (!type) {
-            virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                 "%s", _("unknown virt type"));
-            goto error;
-        }
-        const char *emulator = virCapabilitiesDefaultGuestEmulator(caps,
-                                                                   def->os.type,
-                                                                   def->os.arch,
-                                                                   type);
-
-        if (emulator &&
-            !(def->emulator = strdup(emulator))) {
-            virDomainReportError(conn, VIR_ERR_NO_MEMORY, NULL);
-            goto error;
-        }
-    }
 
     /* analysis of the disk devices */
     if ((n = virXPathNodeSet(conn, "./devices/disk", ctxt, &nodes)) < 0) {
@@ -3404,4 +3386,33 @@ char *virDomainConfigFile(virConnectPtr 
 }
 
 
+const char *virDomainDefDefaultEmulator(virConnectPtr conn,
+                                        virDomainDefPtr def,
+                                        virCapsPtr caps) {
+    const char *type;
+    const char *emulator;
+
+    type = virDomainVirtTypeToString(def->virtType);
+    if (!type) {
+        virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                             "%s", _("unknown virt type"));
+        return NULL;
+    }
+
+    emulator = virCapabilitiesDefaultGuestEmulator(caps,
+                                                   def->os.type,
+                                                   def->os.arch,
+                                                   type);
+
+    if (!emulator) {
+        virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                             _("no emulator for domain %s os type %s on architecture %s"),
+                             type, def->os.type, def->os.arch);
+        return NULL;
+    }
+
+    return emulator;
+}
+
+
 #endif /* ! PROXY */
diff -r d1308575c2d3 src/domain_conf.h
--- a/src/domain_conf.h	Mon Sep 01 14:48:19 2008 +0100
+++ b/src/domain_conf.h	Mon Sep 01 15:00:57 2008 +0100
@@ -556,6 +556,11 @@ virDomainNetDefPtr virDomainNetDefParseX
 virDomainNetDefPtr virDomainNetDefParseXML(virConnectPtr conn,
                         xmlNodePtr node);
 
+const char *virDomainDefDefaultEmulator(virConnectPtr conn,
+                                        virDomainDefPtr def,
+                                        virCapsPtr caps);
+
+
 VIR_ENUM_DECL(virDomainVirt)
 VIR_ENUM_DECL(virDomainBoot)
 VIR_ENUM_DECL(virDomainFeature)
diff -r d1308575c2d3 src/lxc_driver.c
--- a/src/lxc_driver.c	Mon Sep 01 14:48:19 2008 +0100
+++ b/src/lxc_driver.c	Mon Sep 01 15:12:34 2008 +0100
@@ -623,6 +623,8 @@ static int lxcControllerStart(virConnect
     int status;
     fd_set keepfd;
     char appPtyStr[30];
+    const char *emulator;
+    lxc_driver_t *driver = conn->privateData;
 
     FD_ZERO(&keepfd);
 
@@ -650,7 +652,13 @@ static int lxcControllerStart(virConnect
 
     snprintf(appPtyStr, sizeof(appPtyStr), "%d", appPty);
 
-    ADD_ARG_LIT(vm->def->emulator);
+    emulator = vm->def->emulator;
+    if (!emulator)
+        emulator = virDomainDefDefaultEmulator(conn, vm->def, driver->caps);
+    if (!emulator)
+        return -1;
+
+    ADD_ARG_LIT(emulator);
     ADD_ARG_LIT("--name");
     ADD_ARG_LIT(vm->def->name);
     ADD_ARG_LIT("--console");
diff -r d1308575c2d3 src/qemu_conf.c
--- a/src/qemu_conf.c	Mon Sep 01 14:48:19 2008 +0100
+++ b/src/qemu_conf.c	Mon Sep 01 15:10:36 2008 +0100
@@ -712,6 +712,7 @@ int qemudBuildCommandLine(virConnectPtr 
     int disableKQEMU = 0;
     int qargc = 0, qarga = 0;
     const char **qargv = NULL;
+    const char *emulator;
 
     uname(&ut);
 
@@ -767,6 +768,11 @@ int qemudBuildCommandLine(virConnectPtr 
     snprintf(memory, sizeof(memory), "%lu", vm->def->memory/1024);
     snprintf(vcpus, sizeof(vcpus), "%lu", vm->def->vcpus);
 
+    emulator = vm->def->emulator;
+    if (!emulator)
+        emulator = virDomainDefDefaultEmulator(conn, vm->def, driver->caps);
+    if (!emulator)
+        return -1;
 
     ADD_ARG_LIT(vm->def->emulator);
     ADD_ARG_LIT("-S");
diff -r d1308575c2d3 src/qemu_driver.c
--- a/src/qemu_driver.c	Mon Sep 01 14:48:19 2008 +0100
+++ b/src/qemu_driver.c	Mon Sep 01 15:10:47 2008 +0100
@@ -849,6 +849,7 @@ static int qemudStartVMDaemon(virConnect
     int ntapfds = 0;
     unsigned int qemuCmdFlags;
     fd_set keepfd;
+    const char *emulator;
 
     FD_ZERO(&keepfd);
 
@@ -908,24 +909,30 @@ static int qemudStartVMDaemon(virConnect
         return -1;
     }
 
+    emulator = vm->def->emulator;
+    if (!emulator)
+        emulator = virDomainDefDefaultEmulator(conn, vm->def, driver->caps);
+    if (!emulator)
+        return -1;
+
     /* Make sure the binary we are about to try exec'ing exists.
      * Technically we could catch the exec() failure, but that's
      * in a sub-process so its hard to feed back a useful error
      */
-    if (stat(vm->def->emulator, &sb) < 0) {
+    if (stat(emulator, &sb) < 0) {
         qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
                          _("Cannot find QEMU binary %s: %s"),
-                         vm->def->emulator,
+                         emulator,
                          strerror(errno));
         return -1;
     }
 
-    if (qemudExtractVersionInfo(vm->def->emulator,
+    if (qemudExtractVersionInfo(emulator,
                                 NULL,
                                 &qemuCmdFlags) < 0) {
         qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
                          _("Cannot determine QEMU argv syntax %s"),
-                         vm->def->emulator);
+                         emulator);
         return -1;
     }
 
diff -r d1308575c2d3 src/xm_internal.c
--- a/src/xm_internal.c	Mon Sep 01 14:48:19 2008 +0100
+++ b/src/xm_internal.c	Mon Sep 01 15:08:37 2008 +0100
@@ -785,26 +785,6 @@ xenXMDomainConfigParse(virConnectPtr con
     if (xenXMConfigCopyStringOpt(conn, conf, "device_model", &def->emulator) < 0)
         goto cleanup;
 
-    if (def->emulator == NULL) {
-        const char *type = virDomainVirtTypeToString(def->virtType);
-        if (!type) {
-            xenXMError(conn, VIR_ERR_INTERNAL_ERROR,
-                       "%s", _("unknown virt type"));
-            goto cleanup;
-        }
-        const char *emulator = virCapabilitiesDefaultGuestEmulator(priv->caps,
-                                                                   def->os.type,
-                                                                   def->os.arch,
-                                                                   type);
-        if (!emulator) {
-            xenXMError(conn, VIR_ERR_INTERNAL_ERROR,
-                       "%s", _("unsupported guest type"));
-            goto cleanup;
-        }
-        if (!(def->emulator = strdup(emulator)))
-            goto no_memory;
-    }
-
     list = virConfGetValue(conf, "disk");
     if (list && list->type == VIR_CONF_LIST) {
         list = list->list;
diff -r d1308575c2d3 tests/xmconfigdata/test-paravirt-net-e1000.xml
--- a/tests/xmconfigdata/test-paravirt-net-e1000.xml	Mon Sep 01 14:48:19 2008 +0100
+++ b/tests/xmconfigdata/test-paravirt-net-e1000.xml	Mon Sep 01 15:21:27 2008 +0100
@@ -13,7 +13,6 @@
   <on_reboot>restart</on_reboot>
   <on_crash>restart</on_crash>
   <devices>
-    <emulator>/usr/lib/xen/bin/qemu-dm</emulator>
     <disk type='block' device='disk'>
       <driver name='phy'/>
       <source dev='/dev/HostVG/XenGuest1'/>
diff -r d1308575c2d3 tests/xmconfigdata/test-paravirt-new-pvfb.xml
--- a/tests/xmconfigdata/test-paravirt-new-pvfb.xml	Mon Sep 01 14:48:19 2008 +0100
+++ b/tests/xmconfigdata/test-paravirt-new-pvfb.xml	Mon Sep 01 15:20:59 2008 +0100
@@ -13,7 +13,6 @@
   <on_reboot>restart</on_reboot>
   <on_crash>restart</on_crash>
   <devices>
-    <emulator>/usr/lib/xen/bin/qemu-dm</emulator>
     <disk type='block' device='disk'>
       <driver name='phy'/>
       <source dev='/dev/HostVG/XenGuest1'/>
diff -r d1308575c2d3 tests/xmconfigdata/test-paravirt-old-pvfb.xml
--- a/tests/xmconfigdata/test-paravirt-old-pvfb.xml	Mon Sep 01 14:48:19 2008 +0100
+++ b/tests/xmconfigdata/test-paravirt-old-pvfb.xml	Mon Sep 01 15:21:15 2008 +0100
@@ -13,7 +13,6 @@
   <on_reboot>restart</on_reboot>
   <on_crash>restart</on_crash>
   <devices>
-    <emulator>/usr/lib/xen/bin/qemu-dm</emulator>
     <disk type='block' device='disk'>
       <driver name='phy'/>
       <source dev='/dev/HostVG/XenGuest1'/>
diff -r d1308575c2d3 tests/xml2sexprdata/xml2sexpr-fv-kernel.xml
--- a/tests/xml2sexprdata/xml2sexpr-fv-kernel.xml	Mon Sep 01 14:48:19 2008 +0100
+++ b/tests/xml2sexprdata/xml2sexpr-fv-kernel.xml	Mon Sep 01 15:19:55 2008 +0100
@@ -14,6 +14,7 @@
   <on_reboot>destroy</on_reboot>
   <on_crash>destroy</on_crash>
   <devices>
+    <emulator>/usr/lib/xen/bin/qemu-dm</emulator>
     <disk type='file' device='disk'>
       <source file='/root/some.img'/>
       <target dev='xvda'/>
diff -r d1308575c2d3 tests/xml2sexprdata/xml2sexpr-pv-vfb-new.sexpr
--- a/tests/xml2sexprdata/xml2sexpr-pv-vfb-new.sexpr	Mon Sep 01 14:48:19 2008 +0100
+++ b/tests/xml2sexprdata/xml2sexpr-pv-vfb-new.sexpr	Mon Sep 01 15:20:16 2008 +0100
@@ -1,1 +1,1 @@
-(vm (name 'pvtest')(memory 420)(maxmem 420)(vcpus 2)(uuid '596a5d21-71f4-8fb2-e068-e2386a5c413e')(on_poweroff 'destroy')(on_reboot 'destroy')(on_crash 'destroy')(image (linux (kernel '/var/lib/xen/vmlinuz.2Dn2YT')(ramdisk '/var/lib/xen/initrd.img.0u-Vhq')(args ' method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os  ')(device_model '/usr/lib/xen/bin/qemu-dm')))(device (vbd (dev 'xvda')(uname 'file:/root/some.img')(mode 'w')))(device (vkbd))(device (vfb (type vnc)(vncunused 0)(vncdisplay 6)(vnclisten '127.0.0.1')(vncpasswd '123456')(keymap 'ja'))))
\ No newline at end of file
+(vm (name 'pvtest')(memory 420)(maxmem 420)(vcpus 2)(uuid '596a5d21-71f4-8fb2-e068-e2386a5c413e')(on_poweroff 'destroy')(on_reboot 'destroy')(on_crash 'destroy')(image (linux (kernel '/var/lib/xen/vmlinuz.2Dn2YT')(ramdisk '/var/lib/xen/initrd.img.0u-Vhq')(args ' method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os  ')))(device (vbd (dev 'xvda')(uname 'file:/root/some.img')(mode 'w')))(device (vkbd))(device (vfb (type vnc)(vncunused 0)(vncdisplay 6)(vnclisten '127.0.0.1')(vncpasswd '123456')(keymap 'ja'))))
\ No newline at end of file

-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




More information about the libvir-list mailing list