From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> 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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list