From: "Daniel P. Berrange" <berrange(a)redhat.com>
When XML for a new guest is received, the machine type is
immediately canonicalized into the version specific name.
This involves probing QEMU for supported machine types.
Replace this probing with a lookup of the machine types
in the (hopefully cached) qemuCapsPtr object
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/qemu/qemu_command.h | 3 --
src/qemu/qemu_driver.c | 133 ++++++++---------------------------------------
tests/qemuxml2argvtest.c | 12 ++++-
tests/qemuxmlnstest.c | 3 --
4 files changed, 33 insertions(+), 118 deletions(-)
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 97c87a8..253f65a 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -161,9 +161,6 @@ int qemuOpenVhostNet(virDomainDefPtr def,
qemuCapsPtr caps,
int *vhostfd);
-int qemudCanonicalizeMachine(struct qemud_driver *driver,
- virDomainDefPtr def);
-
/*
* NB: def->name can be NULL upon return and the caller
* *must* decide how to fill in a name in this case
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 3f2fab3..10af8ed 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1452,6 +1452,26 @@ static int qemudNumDomains(virConnectPtr conn) {
return n;
}
+
+static int
+qemuCanonicalizeMachine(virDomainDefPtr def, qemuCapsPtr caps)
+{
+ const char *canon = qemuCapsGetCanonicalMachine(caps, def->os.machine);
+
+ if (canon != def->os.machine) {
+ char *tmp;
+ if (!(tmp = strdup(canon))) {
+ virReportOOMError();
+ return -1;
+ }
+ VIR_FREE(def->os.machine);
+ def->os.machine = tmp;
+ }
+
+ return 0;
+}
+
+
static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
unsigned int flags) {
struct qemud_driver *driver = conn->privateData;
@@ -1486,7 +1506,7 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char
*xml,
if (!(caps = qemuCapsCacheLookup(driver->capsCache, def->emulator)))
goto cleanup;
- if (qemudCanonicalizeMachine(driver, def) < 0)
+ if (qemuCanonicalizeMachine(def, caps) < 0)
goto cleanup;
if (qemuDomainAssignAddresses(def, caps, NULL) < 0)
@@ -5412,113 +5432,6 @@ qemuDomainStart(virDomainPtr dom)
return qemuDomainStartWithFlags(dom, 0);
}
-static int
-qemudCanonicalizeMachineFromInfo(virDomainDefPtr def,
- virCapsGuestDomainInfoPtr info,
- char **canonical)
-{
- int i;
-
- *canonical = NULL;
-
- for (i = 0; i < info->nmachines; i++) {
- virCapsGuestMachinePtr machine = info->machines[i];
-
- if (!machine->canonical)
- continue;
-
- if (def->os.machine && STRNEQ(def->os.machine, machine->name))
- continue;
-
- if (!(*canonical = strdup(machine->canonical))) {
- virReportOOMError();
- return -1;
- }
-
- break;
- }
-
- return 0;
-}
-
-static int
-qemudCanonicalizeMachineDirect(virDomainDefPtr def, char **canonical)
-{
- virCapsGuestMachinePtr *machines = NULL;
- size_t i, nmachines = 0;
-
- /* XXX we should be checking emulator capabilities and pass them instead
- * of NULL so that -nodefconfig or -no-user-config is properly added when
- * probing machine types. Luckily, qemu does not support specifying new
- * machine types in its configuration files yet, which means passing this
- * additional parameter makes no difference now.
- */
- if (qemuCapsProbeMachineTypes(def->emulator, NULL,
- &machines, &nmachines) < 0)
- return -1;
-
- for (i = 0; i < nmachines; i++) {
- if (!machines[i]->canonical)
- continue;
-
- if (def->os.machine && STRNEQ(def->os.machine,
machines[i]->name))
- continue;
-
- *canonical = machines[i]->canonical;
- machines[i]->canonical = NULL;
- break;
- }
-
- virCapabilitiesFreeMachines(machines, nmachines);
-
- return 0;
-}
-
-int
-qemudCanonicalizeMachine(struct qemud_driver *driver, virDomainDefPtr def)
-{
- char *canonical = NULL;
- int i;
-
- for (i = 0; i < driver->caps->nguests; i++) {
- virCapsGuestPtr guest = driver->caps->guests[i];
- virCapsGuestDomainInfoPtr info;
- int j;
-
- for (j = 0; j < guest->arch.ndomains; j++) {
- info = &guest->arch.domains[j]->info;
-
- if (!info->emulator || !STREQ(info->emulator, def->emulator))
- continue;
-
- if (!info->nmachines)
- info = &guest->arch.defaultInfo;
-
- if (qemudCanonicalizeMachineFromInfo(def, info, &canonical) < 0)
- return -1;
- goto out;
- }
-
- info = &guest->arch.defaultInfo;
-
- if (info->emulator && STREQ(info->emulator, def->emulator)) {
- if (qemudCanonicalizeMachineFromInfo(def, info, &canonical) < 0)
- return -1;
- goto out;
- }
- }
-
- if (qemudCanonicalizeMachineDirect(def, &canonical) < 0)
- return -1;
-
-out:
- if (canonical) {
- VIR_FREE(def->os.machine);
- def->os.machine = canonical;
- }
- return 0;
-}
-
static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
struct qemud_driver *driver = conn->privateData;
virDomainDefPtr def;
@@ -5544,7 +5457,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char
*xml) {
if (!(caps = qemuCapsCacheLookup(driver->capsCache, def->emulator)))
goto cleanup;
- if (qemudCanonicalizeMachine(driver, def) < 0)
+ if (qemuCanonicalizeMachine(def, caps) < 0)
goto cleanup;
if (qemuDomainAssignAddresses(def, caps, NULL) < 0)
@@ -12444,7 +12357,7 @@ static virDomainPtr qemuDomainAttach(virConnectPtr conn,
if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
goto cleanup;
- if (qemudCanonicalizeMachine(driver, def) < 0)
+ if (qemuCanonicalizeMachine(def, caps) < 0)
goto cleanup;
if (qemuDomainAssignAddresses(def, caps, NULL) < 0)
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 51676a4..0f61fd5 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -142,8 +142,12 @@ static int testCompareXMLToArgvFiles(const char *xml,
QEMU_CAPS_NO_ACPI,
QEMU_CAPS_LAST);
- if (qemudCanonicalizeMachine(&driver, vmdef) < 0)
- goto out;
+ if (STREQ(vmdef->os.machine, "pc") &&
+ STREQ(vmdef->emulator, "/usr/bin/qemu-system-x86_64")) {
+ VIR_FREE(vmdef->os.machine);
+ if (!(vmdef->os.machine = strdup("pc-0.11")))
+ goto out;
+ }
if (qemuCapsGet(extraFlags, QEMU_CAPS_DEVICE)) {
if (qemuDomainAssignAddresses(vmdef, extraFlags, NULL)) {
@@ -157,6 +161,10 @@ static int testCompareXMLToArgvFiles(const char *xml,
VIR_FREE(log);
virResetLastError();
+ /* We do not call qemuCapsExtractVersionInfo() before calling
+ * qemuBuildCommandLine(), so we should set QEMU_CAPS_PCI_MULTIBUS for
+ * x86_64 and i686 architectures here.
+ */
if (STREQLEN(vmdef->os.arch, "x86_64", 6) ||
STREQLEN(vmdef->os.arch, "i686", 4)) {
qemuCapsSet(extraFlags, QEMU_CAPS_PCI_MULTIBUS);
diff --git a/tests/qemuxmlnstest.c b/tests/qemuxmlnstest.c
index dd56091..3b06539 100644
--- a/tests/qemuxmlnstest.c
+++ b/tests/qemuxmlnstest.c
@@ -92,9 +92,6 @@ static int testCompareXMLToArgvFiles(const char *xml,
QEMU_CAPS_NO_ACPI,
QEMU_CAPS_LAST);
- if (qemudCanonicalizeMachine(&driver, vmdef) < 0)
- goto fail;
-
if (qemuCapsGet(extraFlags, QEMU_CAPS_DEVICE))
qemuDomainAssignAddresses(vmdef, extraFlags, NULL);
--
1.7.11.4