[libvirt] [PATCH 4/6] Canonicalize qemu machine types

Mark McLoughlin markmc at redhat.com
Thu Jul 23 17:34:42 UTC 2009


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




More information about the libvir-list mailing list