qemuBuildMemoryDeviceCommandLine: Generate via JSON

This includes the 'pc-dimm', 'nvdimm', 'virtio-pmem-pci' and
'virtio-mem-pci' devices.

The value types according to QEMU are:

'pc-dimm'
  node=<uint32>          -  (default: 0)
  memdev=<link<memory-backend>>

'nvdimm'
  label-size=<int>
  memdev=<link<memory-backend>>
  node=<uint32>          -  (default: 0)
  unarmed=<bool>         -  (default: false)
  uuid=<QemuUUID>

'virtio-pmem-pci'
  memdev=<link<memory-backend>>

'virtio-mem-pci'
  block-size=<size>
  memdev=<link<memory-backend>>
  node=<uint32>          -  (default: 0)
  requested-size=<size>

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2021-09-27 18:44:28 +02:00
parent a4229c087e
commit 04f007e7b3
3 changed files with 37 additions and 41 deletions

View File

@ -3730,13 +3730,15 @@ qemuBuildMemoryDimmBackendStr(virCommand *cmd,
} }
char * virJSONValue *
qemuBuildMemoryDeviceStr(const virDomainDef *def, qemuBuildMemoryDeviceProps(const virDomainDef *def,
virDomainMemoryDef *mem, virDomainMemoryDef *mem)
virQEMUCaps *qemuCaps G_GNUC_UNUSED)
{ {
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; g_autoptr(virJSONValue) props = NULL;
const char *device = NULL; const char *device = NULL;
g_autofree char *uuidstr = NULL;
virTristateBool unarmed = VIR_TRISTATE_BOOL_ABSENT;
g_autofree char *memdev = NULL;
if (!mem->info.alias) { if (!mem->info.alias) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@ -3744,6 +3746,8 @@ qemuBuildMemoryDeviceStr(const virDomainDef *def,
return NULL; return NULL;
} }
memdev = g_strdup_printf("mem%s", mem->info.alias);
switch (mem->model) { switch (mem->model) {
case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_DIMM:
device = "pc-dimm"; device = "pc-dimm";
@ -3768,37 +3772,31 @@ qemuBuildMemoryDeviceStr(const virDomainDef *def,
break; break;
} }
virBufferAsprintf(&buf, "%s,", device); if (mem->readonly)
unarmed = VIR_TRISTATE_BOOL_YES;
if (mem->targetNode >= 0)
virBufferAsprintf(&buf, "node=%d,", mem->targetNode);
if (mem->labelsize)
virBufferAsprintf(&buf, "label-size=%llu,", mem->labelsize * 1024);
if (mem->blocksize) {
virBufferAsprintf(&buf, "block-size=%llu,", mem->blocksize * 1024);
virBufferAsprintf(&buf, "requested-size=%llu,", mem->requestedsize * 1024);
}
if (mem->uuid) { if (mem->uuid) {
char uuidstr[VIR_UUID_STRING_BUFLEN]; uuidstr = g_new0(char, VIR_UUID_STRING_BUFLEN);
virUUIDFormat(mem->uuid, uuidstr); virUUIDFormat(mem->uuid, uuidstr);
virBufferAsprintf(&buf, "uuid=%s,", uuidstr);
} }
if (mem->readonly) { if (virJSONValueObjectCreate(&props,
virBufferAddLit(&buf, "unarmed=on,"); "s:driver", device,
} "k:node", mem->targetNode,
"P:label-size", mem->labelsize * 1024,
virBufferAsprintf(&buf, "memdev=mem%s,id=%s", "P:block-size", mem->blocksize * 1024,
mem->info.alias, mem->info.alias); "P:requested-size", mem->requestedsize * 1024,
"S:uuid", uuidstr,
if (qemuBuildDeviceAddressStr(&buf, def, &mem->info) < 0) "T:unarmed", unarmed,
"s:memdev", memdev,
"s:id", mem->info.alias,
NULL) < 0)
return NULL; return NULL;
return virBufferContentAndReset(&buf); if (qemuBuildDeviceAddressProps(props, def, &mem->info) < 0)
return NULL;
return g_steal_pointer(&props);
} }
@ -7863,17 +7861,16 @@ qemuBuildMemoryDeviceCommandLine(virCommand *cmd,
/* memory hotplug requires NUMA to be enabled - we already checked /* memory hotplug requires NUMA to be enabled - we already checked
* that memory devices are present only when NUMA is */ * that memory devices are present only when NUMA is */
for (i = 0; i < def->nmems; i++) { for (i = 0; i < def->nmems; i++) {
char *dimmStr; g_autoptr(virJSONValue) props = NULL;
if (qemuBuildMemoryDimmBackendStr(cmd, def->mems[i], def, cfg, priv) < 0) if (qemuBuildMemoryDimmBackendStr(cmd, def->mems[i], def, cfg, priv) < 0)
return -1; return -1;
if (!(dimmStr = qemuBuildMemoryDeviceStr(def, def->mems[i], priv->qemuCaps))) if (!(props = qemuBuildMemoryDeviceProps(def, def->mems[i])))
return -1; return -1;
virCommandAddArgList(cmd, "-device", dimmStr, NULL); if (qemuBuildDeviceCommandlineFromJSON(cmd, props, priv->qemuCaps) < 0)
return -1;
VIR_FREE(dimmStr);
} }
return 0; return 0;

View File

@ -160,10 +160,9 @@ int qemuBuildMemoryBackendProps(virJSONValue **backendProps,
bool force, bool force,
bool systemMemory); bool systemMemory);
char * virJSONValue *
qemuBuildMemoryDeviceStr(const virDomainDef *def, qemuBuildMemoryDeviceProps(const virDomainDef *def,
virDomainMemoryDef *mem, virDomainMemoryDef *mem);
virQEMUCaps *qemuCaps);
/* Current, best practice */ /* Current, best practice */
char *qemuBuildPCIHostdevDevStr(const virDomainDef *def, char *qemuBuildPCIHostdevDevStr(const virDomainDef *def,

View File

@ -2434,7 +2434,7 @@ qemuDomainAttachMemory(virQEMUDriver *driver,
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
unsigned long long oldmem = virDomainDefGetMemoryTotal(vm->def); unsigned long long oldmem = virDomainDefGetMemoryTotal(vm->def);
unsigned long long newmem = oldmem + mem->size; unsigned long long newmem = oldmem + mem->size;
g_autofree char *devstr = NULL; g_autoptr(virJSONValue) devprops = NULL;
g_autofree char *objalias = NULL; g_autofree char *objalias = NULL;
bool objAdded = false; bool objAdded = false;
bool releaseaddr = false; bool releaseaddr = false;
@ -2463,7 +2463,7 @@ qemuDomainAttachMemory(virQEMUDriver *driver,
objalias = g_strdup_printf("mem%s", mem->info.alias); objalias = g_strdup_printf("mem%s", mem->info.alias);
if (!(devstr = qemuBuildMemoryDeviceStr(vm->def, mem, priv->qemuCaps))) if (!(devprops = qemuBuildMemoryDeviceProps(vm->def, mem)))
goto cleanup; goto cleanup;
if (qemuBuildMemoryBackendProps(&props, objalias, cfg, if (qemuBuildMemoryBackendProps(&props, objalias, cfg,
@ -2495,7 +2495,7 @@ qemuDomainAttachMemory(virQEMUDriver *driver,
goto exit_monitor; goto exit_monitor;
objAdded = true; objAdded = true;
if (qemuMonitorAddDevice(priv->mon, devstr) < 0) if (qemuMonitorAddDeviceProps(priv->mon, &devprops) < 0)
goto exit_monitor; goto exit_monitor;
if (qemuDomainObjExitMonitor(driver, vm) < 0) { if (qemuDomainObjExitMonitor(driver, vm) < 0) {