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