}
+void
+qemuDomainReleaseMemoryDeviceSlot(virDomainObjPtr vm,
+ virDomainMemoryDefPtr mem)
+{
+ switch (mem->model) {
+ case VIR_DOMAIN_MEMORY_MODEL_DIMM:
+ case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
+ /* We don't need to release anything. Slot map is not
+ * kept around. It's constructed every time when
+ * assigning new slot. */
+ break;
+
+ case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
+ qemuDomainReleaseDeviceAddress(vm, &mem->info);
+ break;
+
+ case VIR_DOMAIN_MEMORY_MODEL_NONE:
+ case VIR_DOMAIN_MEMORY_MODEL_LAST:
+ break;
+ }
+}
+
+
static int
qemuDomainAssignMemorySlots(virDomainDefPtr def)
{
virDomainObjPtr vm,
virDomainMemoryDefPtr mem);
+void qemuDomainReleaseMemoryDeviceSlot(virDomainObjPtr vm,
+ virDomainMemoryDefPtr mem);
+
int qemuDomainEnsureVirtioAddress(bool *releaseAddr,
virDomainObjPtr vm,
virDomainDeviceDefPtr dev,
g_autofree char *devstr = NULL;
g_autofree char *objalias = NULL;
bool objAdded = false;
+ bool releaseaddr = false;
bool teardownlabel = false;
bool teardowncgroup = false;
bool teardowndevice = false;
if (qemuDomainAssignMemoryDeviceSlot(driver, vm, mem) < 0)
goto cleanup;
+ releaseaddr = true;
/* in cases where we are using a VM with aliases generated according to the
* index of the memory device we need to keep continue using that scheme */
if (teardowndevice &&
qemuDomainNamespaceTeardownMemory(vm, mem) < 0)
VIR_WARN("Unable to remove memory device from /dev");
+ if (releaseaddr)
+ qemuDomainReleaseMemoryDeviceSlot(vm, mem);
}
virJSONValueFree(props);
if (qemuProcessDestroyMemoryBackingPath(driver, vm, mem) < 0)
VIR_WARN("Unable to destroy memory backing path");
+ qemuDomainReleaseMemoryDeviceSlot(vm, mem);
+
virDomainMemoryDefFree(mem);
/* fix the balloon size */