mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-08 05:55:19 +00:00
qemuDomainChangeEjectableMedia: Unlock domain while waiting for event
In84c59ffa
I've tried to fix changing ejectable media process. The process should go like this: 1) we need to call 'eject' on the monitor 2) we should wait for 'DEVICE_TRAY_MOVED' event 3) now we can issue 'change' command However, while waiting in step 2) the domain monitor was locked. So even if qemu reported the desired event, the proper callback was not called immediately. The monitor handling code needs to lock the monitor in order to read the event. So that's the first lock we must not hold while waiting. The second one is the domain lock. When monitor handling code reads an event, the appropriate callback is called then. The first thing that each callback does is locking the corresponding domain as a domain or its device is about to change state. So we need to unlock both monitor and VM lock. Well, holding any lock while sleep()-ing is not the best thing to do anyway. (cherry picked from commit543af79a14
)
This commit is contained in:
parent
0e6aa8fcd2
commit
dc0efacb6f
@ -93,15 +93,20 @@ int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
|
||||
|
||||
qemuDomainObjEnterMonitor(driver, vm);
|
||||
ret = qemuMonitorEjectMedia(priv->mon, driveAlias, force);
|
||||
qemuDomainObjExitMonitor(driver, vm);
|
||||
|
||||
virObjectRef(vm);
|
||||
/* we don't want to report errors from media tray_open polling */
|
||||
while (retries--) {
|
||||
if (origdisk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)
|
||||
break;
|
||||
|
||||
virObjectUnlock(vm);
|
||||
VIR_DEBUG("Waiting 500ms for tray to open. Retries left %d", retries);
|
||||
usleep(500 * 1000); /* sleep 500ms */
|
||||
virObjectLock(vm);
|
||||
}
|
||||
virObjectUnref(vm);
|
||||
|
||||
if (disk->src) {
|
||||
/* deliberately don't depend on 'ret' as 'eject' may have failed for the
|
||||
@ -114,7 +119,7 @@ int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
|
||||
if (retries <= 0) {
|
||||
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
||||
_("Unable to eject media before changing it"));
|
||||
goto exit_monitor;
|
||||
goto audit;
|
||||
}
|
||||
|
||||
if (disk->type != VIR_DOMAIN_DISK_TYPE_DIR) {
|
||||
@ -123,13 +128,13 @@ int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
|
||||
else if (origdisk->format > 0)
|
||||
format = virStorageFileFormatTypeToString(origdisk->format);
|
||||
}
|
||||
qemuDomainObjEnterMonitor(driver, vm);
|
||||
ret = qemuMonitorChangeMedia(priv->mon,
|
||||
driveAlias,
|
||||
disk->src, format);
|
||||
qemuDomainObjExitMonitor(driver, vm);
|
||||
}
|
||||
exit_monitor:
|
||||
qemuDomainObjExitMonitor(driver, vm);
|
||||
|
||||
audit:
|
||||
virDomainAuditDisk(vm, origdisk->src, disk->src, "update", ret >= 0);
|
||||
|
||||
if (ret < 0)
|
||||
|
Loading…
Reference in New Issue
Block a user