提交 105bcdde 编写于 作者: P Peter Krempa

qemu: hotplug: Fix detach of disk with managed persistent reservations

In commit 8bebb2b7 I've refactored how the detach of disk with a
managed persistent reservations object is handled. After the commit if
any disk with a managed PR object would be removed libvirt would also
attempt to remove the shared 'pr-manager-helper' object potentially used
by other disks.

Thankfully this should not have practical impact as qemu should reject
deletion of the object if it was still used and the rest of the code is
correct.

Fix this by removing the disk from the definition earlier and checking
if the shared/managed pr-manager-helper object is still needed.

This basically splits the detach code for the managed PR object from the
unmanaged ones. The same separation will follow for the attachment code
as well as it greatly simplifies -blockdev support for this.
Signed-off-by: NPeter Krempa <pkrempa@redhat.com>
上级 5276ec71
...@@ -3839,6 +3839,8 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver, ...@@ -3839,6 +3839,8 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
char *drivestr; char *drivestr;
char *objAlias = NULL; char *objAlias = NULL;
char *encAlias = NULL; char *encAlias = NULL;
bool prManaged = priv->prDaemonRunning;
bool prUsed = false;
VIR_DEBUG("Removing disk %s from domain %p %s", VIR_DEBUG("Removing disk %s from domain %p %s",
disk->info.alias, vm, vm->def->name); disk->info.alias, vm, vm->def->name);
...@@ -3876,6 +3878,16 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver, ...@@ -3876,6 +3878,16 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
} }
} }
for (i = 0; i < vm->def->ndisks; i++) {
if (vm->def->disks[i] == disk) {
virDomainDiskRemove(vm->def, i);
break;
}
}
/* check if the last disk with managed PR was just removed */
prUsed = virDomainDefHasManagedPR(vm->def);
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
qemuMonitorDriveDel(priv->mon, drivestr); qemuMonitorDriveDel(priv->mon, drivestr);
...@@ -3892,12 +3904,16 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver, ...@@ -3892,12 +3904,16 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
VIR_FREE(encAlias); VIR_FREE(encAlias);
/* If it fails, then so be it - it was a best shot */ /* If it fails, then so be it - it was a best shot */
if (disk->src->pr) if (disk->src->pr &&
!virStoragePRDefIsManaged(disk->src->pr))
ignore_value(qemuMonitorDelObject(priv->mon, disk->src->pr->mgralias)); ignore_value(qemuMonitorDelObject(priv->mon, disk->src->pr->mgralias));
if (disk->src->haveTLS) if (disk->src->haveTLS)
ignore_value(qemuMonitorDelObject(priv->mon, disk->src->tlsAlias)); ignore_value(qemuMonitorDelObject(priv->mon, disk->src->tlsAlias));
if (prManaged && !prUsed)
ignore_value(qemuMonitorDelObject(priv->mon, qemuDomainGetManagedPRAlias()));
if (qemuDomainObjExitMonitor(driver, vm) < 0) if (qemuDomainObjExitMonitor(driver, vm) < 0)
return -1; return -1;
...@@ -3906,16 +3922,7 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver, ...@@ -3906,16 +3922,7 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
event = virDomainEventDeviceRemovedNewFromObj(vm, disk->info.alias); event = virDomainEventDeviceRemovedNewFromObj(vm, disk->info.alias);
qemuDomainEventQueue(driver, event); qemuDomainEventQueue(driver, event);
for (i = 0; i < vm->def->ndisks; i++) { if (prManaged && !prUsed)
if (vm->def->disks[i] == disk) {
virDomainDiskRemove(vm->def, i);
break;
}
}
/* check if the last disk with managed PR was just removed */
if (priv->prDaemonRunning &&
!virDomainDefHasManagedPR(vm->def))
qemuProcessKillManagedPRDaemon(vm); qemuProcessKillManagedPRDaemon(vm);
qemuDomainReleaseDeviceAddress(vm, &disk->info, src); qemuDomainReleaseDeviceAddress(vm, &disk->info, src);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册