Rather than numerous instances of:
emulator = vm->def->emulator;
if (!emulator)
emulator = virDomainDefDefaultEmulator(conn, vm->def, driver->caps);
if (!emulator)
return -1;
Set this value at XML parse time in the domain config, so we can depend on
it for all future emulator accesses. There were unchecked accesses in the
qemu driver that were tripping up on this if no emulator was specified in
the XML, see:
http://www.redhat.com/archives/libvir-list/2008-October/msg00602.html
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
src/domain_conf.c | 66 ++++++++++++++++++++++++++-------------------
src/domain_conf.h | 4 ---
src/libvirt_private.syms | 1 -
src/lxc_driver.c | 5 ---
src/qemu_conf.c | 5 ---
src/qemu_driver.c | 8 -----
6 files changed, 38 insertions(+), 51 deletions(-)
diff --git a/src/domain_conf.c b/src/domain_conf.c
index e83f776..c695820 100644
--- a/src/domain_conf.c
+++ b/src/domain_conf.c
@@ -2109,6 +2109,39 @@ int virDomainDiskQSort(const void *a, const void *b)
}
#ifndef PROXY
+static char *virDomainDefDefaultEmulator(virConnectPtr conn,
+ virDomainDefPtr def,
+ virCapsPtr caps) {
+ const char *type;
+ const char *emulator;
+ char *retemu;
+
+ 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;
+ }
+
+ retemu = strdup(emulator);
+ if (!retemu)
+ virReportOOMError(conn);
+
+ return retemu;
+}
+
static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
virCapsPtr caps,
xmlXPathContextPtr ctxt, int flags)
@@ -2358,6 +2391,11 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
}
def->emulator = virXPathString(conn, "string(./devices/emulator[1])",
ctxt);
+ if (!def->emulator && virCapabilitiesIsEmulatorRequired(caps)) {
+ def->emulator = virDomainDefDefaultEmulator(conn, def, caps);
+ if (!def->emulator)
+ goto error;
+ }
/* analysis of the disk devices */
if ((n = virXPathNodeSet(conn, "./devices/disk", ctxt, &nodes)) < 0)
{
@@ -4230,34 +4268,6 @@ int virDiskNameToBusDeviceIndex(const virDomainDiskDefPtr disk,
return 0;
}
-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;
-}
-
virDomainFSDefPtr virDomainGetRootFilesystem(virDomainDefPtr def)
{
int i;
diff --git a/src/domain_conf.h b/src/domain_conf.h
index aef1ec4..51310c1 100644
--- a/src/domain_conf.h
+++ b/src/domain_conf.h
@@ -665,10 +665,6 @@ int virDiskNameToBusDeviceIndex(virDomainDiskDefPtr disk,
int *busIdx,
int *devIdx);
-const char *virDomainDefDefaultEmulator(virConnectPtr conn,
- virDomainDefPtr def,
- virCapsPtr caps);
-
virDomainFSDefPtr virDomainGetRootFilesystem(virDomainDefPtr def);
void virDomainObjLock(virDomainObjPtr obj);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 5ac904f..f63fa05 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -65,7 +65,6 @@ virDomainCpuSetParse;
virDomainChrDefFree;
virDomainChrTypeFromString;
virDomainChrTypeToString;
-virDomainDefDefaultEmulator;
virDomainDefFormat;
virDomainDefFree;
virDomainDefParseFile;
diff --git a/src/lxc_driver.c b/src/lxc_driver.c
index e798c79..3503573 100644
--- a/src/lxc_driver.c
+++ b/src/lxc_driver.c
@@ -758,7 +758,6 @@ static int lxcControllerStart(virConnectPtr conn,
fd_set keepfd;
char appPtyStr[30];
const char *emulator;
- lxc_driver_t *driver = conn->privateData;
FD_ZERO(&keepfd);
@@ -787,10 +786,6 @@ static int lxcControllerStart(virConnectPtr conn,
snprintf(appPtyStr, sizeof(appPtyStr), "%d", appPty);
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");
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index 8c657be..ff11d2d 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -920,11 +920,6 @@ int qemudBuildCommandLine(virConnectPtr conn,
}
emulator = def->emulator;
- if (!emulator)
- emulator = virDomainDefDefaultEmulator(conn, def, driver->caps);
- if (!emulator)
- return -1;
-
/* Need to explicitly disable KQEMU if
* 1. Arch matches host arch
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 665bc8d..d3eb3ad 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1377,10 +1377,6 @@ static int qemudStartVMDaemon(virConnectPtr conn,
goto cleanup;
emulator = vm->def->emulator;
- if (!emulator)
- emulator = virDomainDefDefaultEmulator(conn, vm->def, driver->caps);
- if (!emulator)
- goto cleanup;
/* Make sure the binary we are about to try exec'ing exists.
* Technically we could catch the exec() failure, but that's
@@ -3425,10 +3421,6 @@ static char *qemuDomainXMLToNative(virConnectPtr conn,
def->graphics[i]->data.vnc.port = 5900;
}
emulator = def->emulator;
- if (!emulator)
- emulator = virDomainDefDefaultEmulator(conn, def, driver->caps);
- if (!emulator)
- goto cleanup;
/* Make sure the binary we are about to try exec'ing exists.
* Technically we could catch the exec() failure, but that's
--
1.6.0.6