[libvirt] [PATCH v3] Fixes virsh save-restore/migration when memory detach not in LIFO

Nitesh Konkar niteshkonkar.libvirt at gmail.com
Tue Oct 4 13:06:12 UTC 2016


Currently the migration stream references the memory
blocks by name (which is supplied by libvirt) rather
than by there order. With the current code that is
assigning aliases for memory backend objects this
won't happen and since qemu is treating the memory
object links differently migration does not work in
such case.

This patch ensures slot number alocation for the memory
modules beforehand and assign alias accordingly. This
keeps slot numbers consistent with the aliases always.

Signed-off-by: Nitesh Konkar <nitkon12 at linux.vnet.ibm.com>
---
 src/conf/domain_conf.h  |  1 +
 src/qemu/qemu_alias.c   | 36 +++++++++++++++++++++++++-----------
 src/qemu/qemu_alias.h   |  6 ++++--
 src/qemu/qemu_domain.c  |  3 +++
 src/qemu/qemu_hotplug.c |  5 ++++-
 5 files changed, 37 insertions(+), 14 deletions(-)

diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index fd3ae8e..22b5fe1 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2145,6 +2145,7 @@ struct _virDomainDef {
 
     virDomainBlkiotune blkio;
     virDomainMemtune mem;
+    virBitmapPtr memslotsptr;
 
     virDomainVcpuDefPtr *vcpus;
     size_t maxvcpus;
diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c
index cc83fec..8deb054 100644
--- a/src/qemu/qemu_alias.c
+++ b/src/qemu/qemu_alias.c
@@ -332,21 +332,34 @@ qemuAssignDeviceRNGAlias(virDomainDefPtr def,
 }
 
 
-int
-qemuAssignDeviceMemoryAlias(virDomainDefPtr def,
-                            virDomainMemoryDefPtr mem)
+void
+qemuAssignDeviceMemorySlot(virDomainDefPtr def,
+                           virDomainMemoryDefPtr mem)
 {
     size_t i;
-    int maxidx = 0;
-    int idx;
+    int minidx = 0;
 
-    for (i = 0; i < def->nmems; i++) {
-        if ((idx = qemuDomainDeviceAliasIndex(&def->mems[i]->info, "dimm")) >= maxidx)
-            maxidx = idx + 1;
+    if (mem->info.addr.dimm.base) {
+        minidx = mem->info.addr.dimm.slot;
+    } else {
+        for (i = 0; i < def->mem.memory_slots; i++) {
+            if (!virBitmapIsBitSet(def->memslotsptr, i)) {
+                minidx = i;
+                break;
+            }
+        }
     }
 
-    if (virAsprintf(&mem->info.alias, "dimm%d", maxidx) < 0)
-        return -1;
+    ignore_value(virBitmapSetBit(def->memslotsptr, minidx));
+    mem->info.addr.dimm.slot = minidx;
+}
+
+
+int
+qemuAssignDeviceMemoryAlias(virDomainMemoryDefPtr mem)
+{
+    if (virAsprintf(&mem->info.alias, "dimm%d", mem->info.addr.dimm.slot) < 0)
+         return -1;
 
     return 0;
 }
@@ -475,7 +488,8 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
             return -1;
     }
     for (i = 0; i < def->nmems; i++) {
-        if (virAsprintf(&def->mems[i]->info.alias, "dimm%zu", i) < 0)
+        qemuAssignDeviceMemorySlot(def, def->mems[i]);
+        if (virAsprintf(&def->mems[i]->info.alias, "dimm%d", def->mems[i]->info.addr.dimm.slot) < 0)
             return -1;
     }
 
diff --git a/src/qemu/qemu_alias.h b/src/qemu/qemu_alias.h
index 11d9fde..c6cb568 100644
--- a/src/qemu/qemu_alias.h
+++ b/src/qemu/qemu_alias.h
@@ -57,8 +57,10 @@ int qemuAssignDeviceRedirdevAlias(virDomainDefPtr def,
 int qemuAssignDeviceRNGAlias(virDomainDefPtr def,
                              virDomainRNGDefPtr rng);
 
-int qemuAssignDeviceMemoryAlias(virDomainDefPtr def,
-                                virDomainMemoryDefPtr mems);
+void qemuAssignDeviceMemorySlot(virDomainDefPtr def,
+                                virDomainMemoryDefPtr);
+
+int qemuAssignDeviceMemoryAlias(virDomainMemoryDefPtr mems);
 
 int qemuAssignDeviceShmemAlias(virDomainDefPtr def,
                                virDomainShmemDefPtr shmem,
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 9b1a32e..263e78f 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2386,6 +2386,9 @@ qemuDomainDefPostParse(virDomainDefPtr def,
     if (qemuDomainDefVcpusPostParse(def) < 0)
         goto cleanup;
 
+    if (def->mem.memory_slots)
+        def->memslotsptr = virBitmapNew(def->mem.memory_slots);
+
     ret = 0;
  cleanup:
     virObjectUnref(qemuCaps);
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 72dd93b..5a3af10 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1898,7 +1898,9 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
     if (qemuDomainDefValidateMemoryHotplug(vm->def, priv->qemuCaps, mem) < 0)
         goto cleanup;
 
-    if (qemuAssignDeviceMemoryAlias(vm->def, mem) < 0)
+    qemuAssignDeviceMemorySlot(vm->def, mem);
+
+    if (qemuAssignDeviceMemoryAlias(mem) < 0)
         goto cleanup;
 
     if (virAsprintf(&objalias, "mem%s", mem->info.alias) < 0)
@@ -4427,6 +4429,7 @@ qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
     }
 
     mem = vm->def->mems[idx];
+    ignore_value(virBitmapClearBit(vm->def->memslotsptr, memdef->info.addr.dimm.slot));
 
     if (!mem->info.alias) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-- 
1.9.3




More information about the libvir-list mailing list