124 lines
4.2 KiB
Diff
124 lines
4.2 KiB
Diff
|
From: Peter Krempa <pkrempa@redhat.com>
|
||
|
Date: Mon, 23 May 2016 14:50:17 +0200
|
||
|
Subject: [PATCH] qemu: hotplug: Extract code for waiting for tray eject
|
||
|
|
||
|
The code grew rather convoluted. Extract it to a separate function.
|
||
|
|
||
|
(cherry picked from commit 0aa19f35e0f3c1712f2569986d4d0a93b488c35c)
|
||
|
---
|
||
|
src/qemu/qemu_hotplug.c | 85 ++++++++++++++++++++++++++-----------------------
|
||
|
1 file changed, 46 insertions(+), 39 deletions(-)
|
||
|
|
||
|
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
|
||
|
index 12653e3..d180b38 100644
|
||
|
--- a/src/qemu/qemu_hotplug.c
|
||
|
+++ b/src/qemu/qemu_hotplug.c
|
||
|
@@ -144,6 +144,40 @@ qemuDomainPrepareDisk(virQEMUDriverPtr driver,
|
||
|
}
|
||
|
|
||
|
|
||
|
+static int
|
||
|
+qemuHotplugWaitForTrayEject(virQEMUDriverPtr driver,
|
||
|
+ virDomainObjPtr vm,
|
||
|
+ virDomainDiskDefPtr disk,
|
||
|
+ const char *driveAlias,
|
||
|
+ bool force)
|
||
|
+{
|
||
|
+ unsigned long long now;
|
||
|
+ int rc;
|
||
|
+
|
||
|
+ if (virTimeMillisNow(&now) < 0)
|
||
|
+ return -1;
|
||
|
+
|
||
|
+ while (disk->tray_status != VIR_DOMAIN_DISK_TRAY_OPEN) {
|
||
|
+ if ((rc = virDomainObjWaitUntil(vm, now + CHANGE_MEDIA_TIMEOUT)) < 0)
|
||
|
+ return -1;
|
||
|
+
|
||
|
+ if (rc > 0) {
|
||
|
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||
|
+ _("timed out waiting for disk tray status update"));
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ /* re-issue ejection command to pop out the media */
|
||
|
+ qemuDomainObjEnterMonitor(driver, vm);
|
||
|
+ rc = qemuMonitorEjectMedia(qemuDomainGetMonitor(vm), driveAlias, force);
|
||
|
+ if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
|
||
|
+ return -1;
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
/**
|
||
|
* qemuDomainChangeEjectableMedia:
|
||
|
* @driver: qemu driver structure
|
||
|
@@ -173,8 +207,6 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
|
||
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||
|
const char *format = NULL;
|
||
|
char *sourcestr = NULL;
|
||
|
- bool ejectRetry = false;
|
||
|
- unsigned long long now;
|
||
|
|
||
|
if (!disk->info.alias) {
|
||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||
|
@@ -196,45 +228,20 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
|
||
|
if (!(driveAlias = qemuDeviceDriveHostAlias(disk, priv->qemuCaps)))
|
||
|
goto error;
|
||
|
|
||
|
- do {
|
||
|
- qemuDomainObjEnterMonitor(driver, vm);
|
||
|
- rc = qemuMonitorEjectMedia(priv->mon, driveAlias, force);
|
||
|
- if (qemuDomainObjExitMonitor(driver, vm) < 0)
|
||
|
- goto cleanup;
|
||
|
-
|
||
|
- /* skip all retrying if qemu doesn't notify us on tray change */
|
||
|
- if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_TRAY_MOVED)) {
|
||
|
- if (rc == 0)
|
||
|
- break;
|
||
|
-
|
||
|
- if (rc < 0)
|
||
|
- goto error;
|
||
|
- }
|
||
|
-
|
||
|
- if (rc < 0) {
|
||
|
- /* we've already tried, error out */
|
||
|
- if (ejectRetry)
|
||
|
- goto error;
|
||
|
-
|
||
|
- ejectRetry = true;
|
||
|
- VIR_DEBUG("tray may be locked, wait for the guest to unlock "
|
||
|
- "the tray and try to eject it again");
|
||
|
- }
|
||
|
+ qemuDomainObjEnterMonitor(driver, vm);
|
||
|
+ rc = qemuMonitorEjectMedia(priv->mon, driveAlias, force);
|
||
|
+ if (qemuDomainObjExitMonitor(driver, vm) < 0)
|
||
|
+ goto cleanup;
|
||
|
|
||
|
- if (virTimeMillisNow(&now) < 0)
|
||
|
+ /* If the tray change event is supported wait for it to open. */
|
||
|
+ if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_TRAY_MOVED)) {
|
||
|
+ if (qemuHotplugWaitForTrayEject(driver, vm, disk, driveAlias, force) < 0)
|
||
|
goto error;
|
||
|
-
|
||
|
- while (disk->tray_status != VIR_DOMAIN_DISK_TRAY_OPEN) {
|
||
|
- int wait_rc = virDomainObjWaitUntil(vm, now + CHANGE_MEDIA_TIMEOUT);
|
||
|
- if (wait_rc > 0) {
|
||
|
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||
|
- _("timed out waiting for "
|
||
|
- "disk tray status update"));
|
||
|
- }
|
||
|
- if (wait_rc != 0)
|
||
|
- goto error;
|
||
|
- }
|
||
|
- } while (rc < 0);
|
||
|
+ } else {
|
||
|
+ /* otherwise report possible errors from the attempt to eject the media*/
|
||
|
+ if (rc < 0)
|
||
|
+ goto error;
|
||
|
+ }
|
||
|
|
||
|
if (!virStorageSourceIsEmpty(newsrc)) {
|
||
|
if (qemuGetDriveSourceString(newsrc, conn, &sourcestr) < 0)
|