[libvirt] [PATCH v2 4/7] qemu: command: Move dimm device checks from formatter to checker

Peter Krempa pkrempa at redhat.com
Tue Nov 10 14:44:46 UTC 2015


Aggregate the checks of the dimm device into the verification function
rather than having them in the formatter.
---
 src/qemu/qemu_command.c | 65 ++--------------------------------
 src/qemu/qemu_command.h |  4 +--
 src/qemu/qemu_domain.c  | 92 ++++++++++++++++++++++++++++++++++++++++++++-----
 src/qemu/qemu_hotplug.c |  2 +-
 4 files changed, 87 insertions(+), 76 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 5dbe650..e6c240c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5272,44 +5272,8 @@ qemuBuildMemoryDimmBackendStr(virDomainMemoryDefPtr mem,
 }


-static bool
-qemuCheckMemoryDimmConflict(virDomainDefPtr def,
-                            virDomainMemoryDefPtr mem)
-{
-    size_t i;
-
-    for (i = 0; i < def->nmems; i++) {
-         virDomainMemoryDefPtr tmp = def->mems[i];
-
-         if (tmp == mem ||
-             tmp->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM)
-             continue;
-
-         if (mem->info.addr.dimm.slot == tmp->info.addr.dimm.slot) {
-             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                            _("memory device slot '%u' is already being "
-                              "used by another memory device"),
-                            mem->info.addr.dimm.slot);
-             return true;
-         }
-
-         if (mem->info.addr.dimm.base != 0 &&
-             mem->info.addr.dimm.base == tmp->info.addr.dimm.base) {
-             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                            _("memory device base '0x%llx' is already being "
-                              "used by another memory device"),
-                            mem->info.addr.dimm.base);
-             return true;
-         }
-    }
-
-    return false;
-}
-
 char *
-qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem,
-                         virDomainDefPtr def,
-                         virQEMUCapsPtr qemuCaps)
+qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem)
 {
     virBuffer buf = VIR_BUFFER_INITIALIZER;

@@ -5321,35 +5285,10 @@ qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem,

     switch ((virDomainMemoryModel) mem->model) {
     case VIR_DOMAIN_MEMORY_MODEL_DIMM:
-        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PC_DIMM)) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("this qemu doesn't support the pc-dimm device"));
-            return NULL;
-        }
-
-        if (mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM &&
-            mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("only 'dimm' addresses are supported for the "
-                             "pc-dimm device"));
-            return NULL;
-        }
-
-        if (mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM &&
-            mem->info.addr.dimm.slot >= def->mem.memory_slots) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                           _("memory device slot '%u' exceeds slots count '%u'"),
-                           mem->info.addr.dimm.slot, def->mem.memory_slots);
-            return NULL;
-        }
-
         virBufferAsprintf(&buf, "pc-dimm,node=%d,memdev=mem%s,id=%s",
                           mem->targetNode, mem->info.alias, mem->info.alias);

         if (mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM) {
-            if (qemuCheckMemoryDimmConflict(def, mem))
-                return NULL;
-
             virBufferAsprintf(&buf, ",slot=%d", mem->info.addr.dimm.slot);
             virBufferAsprintf(&buf, ",addr=%llu", mem->info.addr.dimm.base);
         }
@@ -9403,7 +9342,7 @@ qemuBuildCommandLine(virConnectPtr conn,
                                                       qemuCaps, cfg)))
             goto error;

-        if (!(dimmStr = qemuBuildMemoryDeviceStr(def->mems[i], def, qemuCaps))) {
+        if (!(dimmStr = qemuBuildMemoryDeviceStr(def->mems[i]))) {
             VIR_FREE(backStr);
             goto error;
         }
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index d1af3b7..6e550a8 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -173,9 +173,7 @@ int qemuBuildMemoryBackendStr(unsigned long long size,
                               virJSONValuePtr *backendProps,
                               bool force);

-char *qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem,
-                               virDomainDefPtr def,
-                               virQEMUCapsPtr qemuCaps);
+char *qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem);

 /* Legacy, pre device support */
 char *qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev,
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index cca66ac..e17c57d 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1347,14 +1347,6 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
         }
     }

-    if (dev->type == VIR_DOMAIN_DEVICE_MEMORY &&
-        !virDomainDefHasMemoryHotplug(def)) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                       _("maxMemory has to be specified when using memory "
-                         "devices "));
-        goto cleanup;
-    }
-
     ret = 0;

  cleanup:
@@ -3552,6 +3544,79 @@ qemuDomainMachineIsS390CCW(const virDomainDef *def)
 }


+static bool
+qemuCheckMemoryDimmConflict(const virDomainDef *def,
+                            const virDomainMemoryDef *mem)
+{
+    size_t i;
+
+    for (i = 0; i < def->nmems; i++) {
+         virDomainMemoryDefPtr tmp = def->mems[i];
+
+         if (tmp == mem ||
+             tmp->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM)
+             continue;
+
+         if (mem->info.addr.dimm.slot == tmp->info.addr.dimm.slot) {
+             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                            _("memory device slot '%u' is already being "
+                              "used by another memory device"),
+                            mem->info.addr.dimm.slot);
+             return true;
+         }
+
+         if (mem->info.addr.dimm.base != 0 &&
+             mem->info.addr.dimm.base == tmp->info.addr.dimm.base) {
+             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                            _("memory device base '0x%llx' is already being "
+                              "used by another memory device"),
+                            mem->info.addr.dimm.base);
+             return true;
+         }
+    }
+
+    return false;
+}
+static int
+qemuDomainDefValidateMemoryHotplugDevice(const virDomainMemoryDef *mem,
+                                         const virDomainDef *def)
+{
+    switch ((virDomainMemoryModel) mem->model) {
+    case VIR_DOMAIN_MEMORY_MODEL_DIMM:
+        if (mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM &&
+            mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("only 'dimm' addresses are supported for the "
+                             "pc-dimm device"));
+            return -1;
+        }
+
+        if (mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM) {
+            if (mem->info.addr.dimm.slot >= def->mem.memory_slots) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("memory device slot '%u' exceeds slots "
+                                 "count '%u'"),
+                               mem->info.addr.dimm.slot, def->mem.memory_slots);
+                return -1;
+            }
+
+
+            if (qemuCheckMemoryDimmConflict(def, mem))
+                return -1;
+        }
+        break;
+
+    case VIR_DOMAIN_MEMORY_MODEL_NONE:
+    case VIR_DOMAIN_MEMORY_MODEL_LAST:
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("invalid memory device type"));
+        return -1;
+    }
+
+    return 0;
+}
+
+
 /**
  * qemuDomainDefValidateMemoryHotplug:
  * @def: domain definition
@@ -3580,6 +3645,9 @@ qemuDomainDefValidateMemoryHotplug(const virDomainDef *def,
     if (mem) {
         nmems++;
         hotplugMemory = mem->size;
+
+        if (qemuDomainDefValidateMemoryHotplugDevice(mem, def) < 0)
+            return -1;
     }

     if (!virDomainDefHasMemoryHotplug(def)) {
@@ -3617,9 +3685,15 @@ qemuDomainDefValidateMemoryHotplug(const virDomainDef *def,
         return -1;
     }

-    for (i = 0; i < def->nmems; i++)
+    for (i = 0; i < def->nmems; i++) {
         hotplugMemory += def->mems[i]->size;

+        /* already existing devices don't need to be checked on hotplug */
+        if (!mem &&
+            qemuDomainDefValidateMemoryHotplugDevice(def->mems[i], def) < 0)
+            return -1;
+    }
+
     if (hotplugMemory > hotplugSpace) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                        _("memory device total size exceeds hotplug space"));
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index ccef8d5..89e5c0d 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1781,7 +1781,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
     if (vm->def->mem.cur_balloon == virDomainDefGetMemoryActual(vm->def))
         fix_balloon = true;

-    if (!(devstr = qemuBuildMemoryDeviceStr(mem, vm->def, priv->qemuCaps)))
+    if (!(devstr = qemuBuildMemoryDeviceStr(mem)))
         goto cleanup;

     if (qemuBuildMemoryBackendStr(mem->size, mem->pagesize,
-- 
2.6.2




More information about the libvir-list mailing list