In qemu-0.11 there is a 'pc-0.10' machine type which allows you to run guests with a machine which is compatible with the pc machine in qemu-0.10 - e.g. using the original PCI class for virtio-blk and virtio-console and disabling MSI support in virtio-net. The idea here is that we don't want to suprise guests by changing the hardware when qemu is updated. I've just posted some patches for qemu-0.11 which allows libvirt to canonicalize the 'pc' machine alias to the latest machine version. This patches makes us use that so that when a guest is configured to use the 'pc' machine type, we resolve that to 'pc-0.11' machine and save that in the guest XML. See also: https://fedoraproject.org/wiki/Features/KVM_Stable_Guest_ABI * src/qemu_conf.c: add qemudCanonicalizeMachine() to canonicalize the machine type according to the machine aliases in capabilities * src/qemu_driver.c: parse aliases in qemudParseMachineTypesStr() --- src/qemu_conf.c | 11 +++++++- src/qemu_driver.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletions(-) diff --git a/src/qemu_conf.c b/src/qemu_conf.c index 022a7a9..6f89f33 100644 --- a/src/qemu_conf.c +++ b/src/qemu_conf.c @@ -271,7 +271,7 @@ static const struct qemu_arch_info const arch_info_xen[] = { /* Format is: - * <machine> <desc> [(default)] + * <machine> <desc> [(default)|(alias of <canonical>)] */ static int qemudParseMachineTypesStr(const char *output, @@ -319,6 +319,15 @@ qemudParseMachineTypesStr(const char *output, list[0] = machine; nitems++; } + + if ((t = strstr(p, "(alias of ")) && (!next || t < next)) { + p = t + strlen("(alias of "); + if (!(t = strchr(p, ')')) || (next && t >= next)) + continue; + + if (!(machine->canonical = strndup(p, t - p))) + goto error; + } } while ((p = next)); *machines = list; diff --git a/src/qemu_driver.c b/src/qemu_driver.c index 3b56092..e2fa4d4 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -4056,6 +4056,77 @@ cleanup: return ret; } +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 (strcmp(def->os.machine, machine->name) != 0) + continue; + + if (!(*canonical = strdup(machine->canonical))) + return -1; + + break; + } + + return 0; +} + +static int +qemudCanonicalizeMachine(virConnectPtr conn, virDomainDefPtr def) +{ + struct qemud_driver *driver = conn->privateData; + char *canonical = NULL; + int i; + + for (i = 0; i < driver->caps->nguests; i++) { + virCapsGuestPtr guest = driver->caps->guests[i]; + int j; + + for (j = 0; j < guest->arch.ndomains; j++) { + virCapsGuestDomainPtr dom = guest->arch.domains[j]; + + if (dom->info.emulator && + STREQ(dom->info.emulator, def->emulator)) { + if (qemudCanonicalizeMachineFromInfo(def, &dom->info, + &canonical) < 0) + return -1; + if (canonical) + goto out; + break; + } + } + + /* if we matched one of the domain's emulators, or if + * we match the default emulator + */ + if (j < guest->arch.ndomains || + (guest->arch.defaultInfo.emulator && + STREQ(guest->arch.defaultInfo.emulator, def->emulator))) { + if (qemudCanonicalizeMachineFromInfo(def, &guest->arch.defaultInfo, + &canonical) < 0) + return -1; + goto out; + } + } +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; @@ -4102,6 +4173,9 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) { } } + if (qemudCanonicalizeMachine(conn, def) < 0) + goto cleanup; + if (!(vm = virDomainAssignDef(conn, &driver->domains, def))) { -- 1.6.2.5 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list