mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
qemu: Release <memory/> device address on failed hotplug
A few commits back I've introduced new 'virtio-pmem' <memory/> device. Since it's virtio it goes onto PCI bus. Therefore, on hotplug new PCI address is generated (or provided one is reserved). However, if hotplug fails (for whatever reason) the address needs to be released. This is different to 'dimm' type of address because for that type we don't keep a map of used slots rather generate one on each address assign request. The map is then thrown away. But for PCI addresses we keep internal state and thus has to keep it updated. Therefore, this new qemuDomainReleaseMemoryDeviceSlot() function is NOP for those models which use 'dimm' address type ('dimm' and 'nvdimm'). While I'm at it, let's release the address in case of hot unplug. Not that is supported (any such attempt fails with the following error: "virtio based memory devices cannot be unplugged" But if QEMU ever implements hot unplug then we don't have to remember to fix our code. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
parent
b1e6324ca2
commit
f8f7bc254f
@ -3122,6 +3122,29 @@ qemuDomainAssignMemoryDeviceSlot(virQEMUDriverPtr driver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
static int
|
||||||
qemuDomainAssignMemorySlots(virDomainDefPtr def)
|
qemuDomainAssignMemorySlots(virDomainDefPtr def)
|
||||||
{
|
{
|
||||||
|
@ -60,6 +60,9 @@ int qemuDomainAssignMemoryDeviceSlot(virQEMUDriverPtr driver,
|
|||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainMemoryDefPtr mem);
|
virDomainMemoryDefPtr mem);
|
||||||
|
|
||||||
|
void qemuDomainReleaseMemoryDeviceSlot(virDomainObjPtr vm,
|
||||||
|
virDomainMemoryDefPtr mem);
|
||||||
|
|
||||||
int qemuDomainEnsureVirtioAddress(bool *releaseAddr,
|
int qemuDomainEnsureVirtioAddress(bool *releaseAddr,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainDeviceDefPtr dev,
|
virDomainDeviceDefPtr dev,
|
||||||
|
@ -2400,6 +2400,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
|
|||||||
g_autofree char *devstr = NULL;
|
g_autofree char *devstr = NULL;
|
||||||
g_autofree char *objalias = NULL;
|
g_autofree char *objalias = NULL;
|
||||||
bool objAdded = false;
|
bool objAdded = false;
|
||||||
|
bool releaseaddr = false;
|
||||||
bool teardownlabel = false;
|
bool teardownlabel = false;
|
||||||
bool teardowncgroup = false;
|
bool teardowncgroup = false;
|
||||||
bool teardowndevice = false;
|
bool teardowndevice = false;
|
||||||
@ -2416,6 +2417,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
|
|||||||
|
|
||||||
if (qemuDomainAssignMemoryDeviceSlot(driver, vm, mem) < 0)
|
if (qemuDomainAssignMemoryDeviceSlot(driver, vm, mem) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
releaseaddr = true;
|
||||||
|
|
||||||
/* in cases where we are using a VM with aliases generated according to the
|
/* 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 */
|
* index of the memory device we need to keep continue using that scheme */
|
||||||
@ -2492,6 +2494,8 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
|
|||||||
if (teardowndevice &&
|
if (teardowndevice &&
|
||||||
qemuDomainNamespaceTeardownMemory(vm, mem) < 0)
|
qemuDomainNamespaceTeardownMemory(vm, mem) < 0)
|
||||||
VIR_WARN("Unable to remove memory device from /dev");
|
VIR_WARN("Unable to remove memory device from /dev");
|
||||||
|
if (releaseaddr)
|
||||||
|
qemuDomainReleaseMemoryDeviceSlot(vm, mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
virJSONValueFree(props);
|
virJSONValueFree(props);
|
||||||
@ -4457,6 +4461,8 @@ qemuDomainRemoveMemoryDevice(virQEMUDriverPtr driver,
|
|||||||
if (qemuProcessDestroyMemoryBackingPath(driver, vm, mem) < 0)
|
if (qemuProcessDestroyMemoryBackingPath(driver, vm, mem) < 0)
|
||||||
VIR_WARN("Unable to destroy memory backing path");
|
VIR_WARN("Unable to destroy memory backing path");
|
||||||
|
|
||||||
|
qemuDomainReleaseMemoryDeviceSlot(vm, mem);
|
||||||
|
|
||||||
virDomainMemoryDefFree(mem);
|
virDomainMemoryDefFree(mem);
|
||||||
|
|
||||||
/* fix the balloon size */
|
/* fix the balloon size */
|
||||||
|
Loading…
Reference in New Issue
Block a user