Don't disable auto_login of non-libvirt-managed iscsi (bz #1331552)

Fix floppy media change (bz #1341998)
This commit is contained in:
Cole Robinson 2016-06-23 16:47:05 -04:00
parent eb5c1154f4
commit 28f4698a20
16 changed files with 1356 additions and 1 deletions

View File

@ -11,6 +11,7 @@ Move the macro building into the %build target, which lets us
build up a shell variable and make things a bit more readable
https://bugzilla.redhat.com/show_bug.cgi?id=1335395
(cherry picked from commit e9ef4dfac88806d02bd2f31eeb3f3bbafe505888)
---
libvirt.spec.in | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)

View File

@ -0,0 +1,144 @@
From: John Ferlan <jferlan@redhat.com>
Date: Fri, 13 May 2016 12:36:39 -0400
Subject: [PATCH] util: Add exitstatus parameter to virCommandRunRegex
Rather than have virCommandRun just spit out the error, allow callers
to decide to pass the exitstatus so the caller can make intelligent
decisions based on the error.
(cherry picked from commit 8b1049473317c09d34b3ce9671d0f9e91dd4f1c0)
---
src/storage/storage_backend_fs.c | 2 +-
src/storage/storage_backend_logical.c | 10 ++++++----
src/util/vircommand.c | 9 ++++++---
src/util/vircommand.h | 3 ++-
src/util/viriscsi.c | 4 ++--
5 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index 692c9ff..93d65aa 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -261,7 +261,7 @@ virStorageBackendFileSystemNetFindNFSPoolSources(virNetfsDiscoverState *state)
if (virCommandRunRegex(cmd, 1, regexes, vars,
virStorageBackendFileSystemNetFindPoolSourcesFunc,
- state, NULL) < 0)
+ state, NULL, NULL) < 0)
goto cleanup;
ret = 0;
diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_backend_logical.c
index 90a194e..ca05fe1 100644
--- a/src/storage/storage_backend_logical.c
+++ b/src/storage/storage_backend_logical.c
@@ -398,7 +398,8 @@ virStorageBackendLogicalFindLVs(virStoragePoolObjPtr pool,
vars,
virStorageBackendLogicalMakeVol,
&cbdata,
- "lvs") < 0)
+ "lvs",
+ NULL) < 0)
goto cleanup;
ret = 0;
@@ -511,10 +512,10 @@ virStorageBackendLogicalGetPoolSources(virStoragePoolSourceListPtr sourceList)
cmd = virCommandNewArgList(PVS,
"--noheadings",
"-o", "pv_name,vg_name",
- NULL);
+ NULL, NULL);
if (virCommandRunRegex(cmd, 1, regexes, vars,
virStorageBackendLogicalFindPoolSourcesFunc,
- sourceList, "pvs") < 0)
+ sourceList, "pvs", NULL) < 0)
goto cleanup;
ret = 0;
@@ -799,7 +800,8 @@ virStorageBackendLogicalRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED,
vars,
virStorageBackendLogicalRefreshPoolFunc,
pool,
- "vgs") < 0)
+ "vgs",
+ NULL) < 0)
goto cleanup;
ret = 0;
diff --git a/src/util/vircommand.c b/src/util/vircommand.c
index 027cb64..f5bd7af 100644
--- a/src/util/vircommand.c
+++ b/src/util/vircommand.c
@@ -2900,6 +2900,7 @@ virCommandSetDryRun(virBufferPtr buf,
* needs to return 0 on success
* @data: additional data that will be passed to the callback function
* @prefix: prefix that will be skipped at the beginning of each line
+ * @exitstatus: allows the caller to handle command run exit failures
*
* Run an external program.
*
@@ -2917,7 +2918,8 @@ virCommandRunRegex(virCommandPtr cmd,
int *nvars,
virCommandRunRegexFunc func,
void *data,
- const char *prefix)
+ const char *prefix,
+ int *exitstatus)
{
int err;
regex_t *reg;
@@ -2959,7 +2961,7 @@ virCommandRunRegex(virCommandPtr cmd,
goto cleanup;
virCommandSetOutputBuffer(cmd, &outbuf);
- if (virCommandRun(cmd, NULL) < 0)
+ if (virCommandRun(cmd, exitstatus) < 0)
goto cleanup;
if (!outbuf) {
@@ -3114,7 +3116,8 @@ virCommandRunRegex(virCommandPtr cmd ATTRIBUTE_UNUSED,
int *nvars ATTRIBUTE_UNUSED,
virCommandRunRegexFunc func ATTRIBUTE_UNUSED,
void *data ATTRIBUTE_UNUSED,
- const char *prefix ATTRIBUTE_UNUSED)
+ const char *prefix ATTRIBUTE_UNUSED,
+ int *exitstatus ATTRIBUTE_UNUSED)
{
virReportError(VIR_ERR_INTERNAL_ERROR,
_("%s not implemented on Win32"), __FUNCTION__);
diff --git a/src/util/vircommand.h b/src/util/vircommand.h
index 198da2f..44818ef 100644
--- a/src/util/vircommand.h
+++ b/src/util/vircommand.h
@@ -205,7 +205,8 @@ int virCommandRunRegex(virCommandPtr cmd,
int *nvars,
virCommandRunRegexFunc func,
void *data,
- const char *cmd_to_ignore);
+ const char *cmd_to_ignore,
+ int *exitstatus);
int virCommandRunNul(virCommandPtr cmd,
size_t n_columns,
diff --git a/src/util/viriscsi.c b/src/util/viriscsi.c
index bd34fea..846ea68 100644
--- a/src/util/viriscsi.c
+++ b/src/util/viriscsi.c
@@ -87,7 +87,7 @@ virISCSIGetSession(const char *devpath,
regexes,
vars,
virISCSIExtractSession,
- &cbdata, NULL) < 0)
+ &cbdata, NULL, NULL) < 0)
goto cleanup;
if (cbdata.session == NULL && !probe) {
@@ -437,7 +437,7 @@ virISCSIScanTargets(const char *portal,
regexes,
vars,
virISCSIGetTargets,
- &list, NULL) < 0)
+ &list, NULL, NULL) < 0)
goto cleanup;
for (i = 0; i < list.ntargets; i++) {

View File

@ -0,0 +1,64 @@
From: John Ferlan <jferlan@redhat.com>
Date: Fri, 13 May 2016 13:25:30 -0400
Subject: [PATCH] iscsi: Add exit status checking for virISCSIGetSession
Utilize the exit status parameter for virCommandRunRegex in order to
check the return error from the 'iscsiadm --mode session' command.
Without this enabled, if there are no sessions running then virCommandRun
would have displayed an error such as:
2016-05-13 15:17:15.165+0000: 10920: error : virCommandWait:2553 :
internal error: Child process (iscsiadm --mode session)
unexpected exit status 21: iscsiadm: No active sessions.
It is possible that for certain paths (when probe is true) we only care
whether it's running or not to make certain decisions. Spitting out
the error for those paths is unnecessary.
If we do have a situation where probe = false and there's an error,
then display the error from iscsiadm if it's there.
(cherry picked from commit 8f54e0d6328eb593c2226459a03afed0da23043d)
---
src/util/viriscsi.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/src/util/viriscsi.c b/src/util/viriscsi.c
index 846ea68..65a8677 100644
--- a/src/util/viriscsi.c
+++ b/src/util/viriscsi.c
@@ -79,24 +79,28 @@ virISCSIGetSession(const char *devpath,
.session = NULL,
.devpath = devpath,
};
+ char *error = NULL;
+ int exitstatus = 0;
- virCommandPtr cmd = virCommandNewArgList(ISCSIADM, "--mode", "session", NULL);
+ virCommandPtr cmd = virCommandNewArgList(ISCSIADM, "--mode",
+ "session", NULL);
+ virCommandSetErrorBuffer(cmd, &error);
if (virCommandRunRegex(cmd,
1,
regexes,
vars,
virISCSIExtractSession,
- &cbdata, NULL, NULL) < 0)
+ &cbdata, NULL, &exitstatus) < 0)
goto cleanup;
- if (cbdata.session == NULL && !probe) {
+ if (cbdata.session == NULL && !probe)
virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("cannot find session"));
- goto cleanup;
- }
+ _("cannot find iscsiadm session: %s"),
+ NULLSTR(error));
cleanup:
+ VIR_FREE(error);
virCommandFree(cmd);
return cbdata.session;
}

View File

@ -0,0 +1,95 @@
From: Fritz Elfert <fritz@fritz-elfert.de>
Date: Fri, 13 May 2016 11:19:09 -0400
Subject: [PATCH] util: Remove disabling of autologin for iscsi-targets
https://bugzilla.redhat.com/show_bug.cgi?id=1331552
Instead of disabling auto-login of all scsi targets (even those
that do not "belong" to libvirt), use iscsiadm's "--op nonpersistent"
during discovery of iSCSI targets (e.g. "iscsiadm --mode discovery
--type sendtargets") in order to avoid the node database being altered
which led to the need for the "large hammer" approach taken by
commit id '3c12b654'.
This commit removes the virISCSITargetAutologin adjustment (eg. the setting
of node.startup to "manual"). The iscsiadm command has supported this mode
of operation as of commit id 'ad873767' to open-iscsi.
(cherry picked from commit 56057900dc53df490d953d56de1195ebfa025bdd)
---
src/util/viriscsi.c | 30 ++----------------------------
tests/viriscsitest.c | 4 +++-
2 files changed, 5 insertions(+), 29 deletions(-)
diff --git a/src/util/viriscsi.c b/src/util/viriscsi.c
index 65a8677..f4e3254 100644
--- a/src/util/viriscsi.c
+++ b/src/util/viriscsi.c
@@ -390,24 +390,9 @@ virISCSIGetTargets(char **const groups,
}
-static int
-virISCSITargetAutologin(const char *portal,
- const char *initiatoriqn,
- const char *target,
- bool enable)
-{
- const char *extraargv[] = { "--op", "update",
- "--name", "node.startup",
- "--value", enable ? "automatic" : "manual",
- NULL };
-
- return virISCSIConnection(portal, initiatoriqn, target, extraargv);
-}
-
-
int
virISCSIScanTargets(const char *portal,
- const char *initiatoriqn,
+ const char *initiatoriqn ATTRIBUTE_UNUSED,
size_t *ntargetsret,
char ***targetsret)
{
@@ -432,6 +417,7 @@ virISCSIScanTargets(const char *portal,
"--mode", "discovery",
"--type", "sendtargets",
"--portal", portal,
+ "--op", "nonpersistent",
NULL);
memset(&list, 0, sizeof(list));
@@ -444,18 +430,6 @@ virISCSIScanTargets(const char *portal,
&list, NULL, NULL) < 0)
goto cleanup;
- for (i = 0; i < list.ntargets; i++) {
- /* We have to ignore failure, because we can't undo
- * the results of 'sendtargets', unless we go scrubbing
- * around in the dirt in /var/lib/iscsi.
- */
- if (virISCSITargetAutologin(portal,
- initiatoriqn,
- list.targets[i], false) < 0)
- VIR_WARN("Unable to disable auto-login on iSCSI target %s: %s",
- portal, list.targets[i]);
- }
-
if (ntargetsret && targetsret) {
*ntargetsret = list.ntargets;
*targetsret = list.targets;
diff --git a/tests/viriscsitest.c b/tests/viriscsitest.c
index c697a4a..b5b0e20 100644
--- a/tests/viriscsitest.c
+++ b/tests/viriscsitest.c
@@ -90,7 +90,9 @@ static void testIscsiadmCb(const char *const*args,
args[4] && STREQ(args[4], "sendtargets") &&
args[5] && STREQ(args[5], "--portal") &&
args[6] && STREQ(args[6], "10.20.30.40:3260,1") &&
- args[7] == NULL) {
+ args[7] && STREQ(args[7], "--op") &&
+ args[8] && STREQ(args[8], "nonpersistent") &&
+ args[9] == NULL) {
ignore_value(VIR_STRDUP(*output, iscsiadmSendtargetsOutput));
} else {
*status = -1;

View File

@ -0,0 +1,87 @@
From: John Ferlan <jferlan@redhat.com>
Date: Fri, 13 May 2016 11:38:45 -0400
Subject: [PATCH] iscsi: Remove initiatoriqn from virISCSIScanTargets
No longer necessary to have it, so remove it.
(cherry picked from commit 027986f5bff0d89375e94e1344074f82eed27d7b)
---
src/storage/storage_backend_iscsi.c | 8 ++------
src/util/viriscsi.c | 3 +--
src/util/viriscsi.h | 1 -
tests/viriscsitest.c | 3 +--
4 files changed, 4 insertions(+), 11 deletions(-)
diff --git a/src/storage/storage_backend_iscsi.c b/src/storage/storage_backend_iscsi.c
index 9e2d01e..bccfba3 100644
--- a/src/storage/storage_backend_iscsi.c
+++ b/src/storage/storage_backend_iscsi.c
@@ -197,9 +197,7 @@ virStorageBackendISCSIFindPoolSources(virConnectPtr conn ATTRIBUTE_UNUSED,
if (!(portal = virStorageBackendISCSIPortal(source)))
goto cleanup;
- if (virISCSIScanTargets(portal,
- source->initiator.iqn,
- &ntargets, &targets) < 0)
+ if (virISCSIScanTargets(portal, &ntargets, &targets) < 0)
goto cleanup;
if (VIR_ALLOC_N(list.sources, ntargets) < 0)
@@ -399,9 +397,7 @@ virStorageBackendISCSIStartPool(virConnectPtr conn,
* iscsiadm doesn't let you login to a target, unless you've
* first issued a 'sendtargets' command to the portal :-(
*/
- if (virISCSIScanTargets(portal,
- pool->def->source.initiator.iqn,
- NULL, NULL) < 0)
+ if (virISCSIScanTargets(portal, NULL, NULL) < 0)
goto cleanup;
if (virStorageBackendISCSISetAuth(portal, conn, &pool->def->source) < 0)
diff --git a/src/util/viriscsi.c b/src/util/viriscsi.c
index f4e3254..e705517 100644
--- a/src/util/viriscsi.c
+++ b/src/util/viriscsi.c
@@ -307,7 +307,7 @@ virISCSIConnection(const char *portal,
* portal. Without the sendtargets all that is received is a
* "iscsiadm: No records found"
*/
- if (virISCSIScanTargets(portal, initiatoriqn, NULL, NULL) < 0)
+ if (virISCSIScanTargets(portal, NULL, NULL) < 0)
goto cleanup;
break;
@@ -392,7 +392,6 @@ virISCSIGetTargets(char **const groups,
int
virISCSIScanTargets(const char *portal,
- const char *initiatoriqn ATTRIBUTE_UNUSED,
size_t *ntargetsret,
char ***targetsret)
{
diff --git a/src/util/viriscsi.h b/src/util/viriscsi.h
index f4093f7..459249e 100644
--- a/src/util/viriscsi.h
+++ b/src/util/viriscsi.h
@@ -49,7 +49,6 @@ virISCSIRescanLUNs(const char *session)
int
virISCSIScanTargets(const char *portal,
- const char *initiatoriqn,
size_t *ntargetsret,
char ***targetsret)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
diff --git a/tests/viriscsitest.c b/tests/viriscsitest.c
index b5b0e20..40e4d10 100644
--- a/tests/viriscsitest.c
+++ b/tests/viriscsitest.c
@@ -145,8 +145,7 @@ testISCSIScanTargets(const void *data)
virCommandSetDryRun(NULL, testIscsiadmCb, NULL);
- if (virISCSIScanTargets(info->portal, NULL,
- &ntargets, &targets) < 0)
+ if (virISCSIScanTargets(info->portal, &ntargets, &targets) < 0)
goto cleanup;
if (info->nexpected != ntargets) {

View File

@ -0,0 +1,52 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 29 Apr 2016 13:38:51 +0200
Subject: [PATCH] qemu: process: Refresh ejectable media tray state on VM start
Empty floppy drives start with tray in "open" state and libvirt did not
refresh it after startup. The code that inserts media into the tray then
waited until the tray was open before inserting the media and thus
floppies could not be inserted.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1326660
(cherry picked from commit a34faf33011c5c0d7b47ee0849bf1e11635e17c5)
---
src/qemu/qemu_hotplug.c | 10 ++++++++--
src/qemu/qemu_process.c | 4 ++++
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 67fb624..b8ab068 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -299,8 +299,14 @@ qemuDomainCheckEjectableMedia(virQEMUDriverPtr driver,
if (!info)
goto cleanup;
- if (info->tray_open && virDomainDiskGetSource(disk))
- ignore_value(virDomainDiskSetSource(disk, NULL));
+ if (info->tray_open) {
+ if (virDomainDiskGetSource(disk))
+ ignore_value(virDomainDiskSetSource(disk, NULL));
+
+ disk->tray_status = VIR_DOMAIN_DISK_TRAY_OPEN;
+ } else {
+ disk->tray_status = VIR_DOMAIN_DISK_TRAY_CLOSED;
+ }
}
ret = 0;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e3df265..2698178 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5457,6 +5457,10 @@ qemuProcessLaunch(virConnectPtr conn,
if (qemuProcessUpdateVideoRamSize(driver, vm, asyncJob) < 0)
goto cleanup;
+ VIR_DEBUG("Updating ejectable media status");
+ if (qemuDomainCheckEjectableMedia(driver, vm, asyncJob) < 0)
+ goto cleanup;
+
if (flags & VIR_QEMU_PROCESS_START_AUTODESTROY &&
qemuProcessAutoDestroyAdd(driver, vm, conn) < 0)
goto cleanup;

View File

@ -0,0 +1,60 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 20 May 2016 07:21:04 +0200
Subject: [PATCH] qemu: Move struct qemuDomainDiskInfo to qemu_domain.h
(cherry picked from commit 5f963d89b1220460fadb1bf6fc347d26b311c1b2)
---
src/qemu/qemu_conf.h | 7 -------
src/qemu/qemu_domain.h | 7 +++++++
tests/qemumonitorjsontest.c | 2 +-
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index a714b84..1fdef70 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -287,13 +287,6 @@ virCapsPtr virQEMUDriverCreateCapabilities(virQEMUDriverPtr driver);
virCapsPtr virQEMUDriverGetCapabilities(virQEMUDriverPtr driver,
bool refresh);
-struct qemuDomainDiskInfo {
- bool removable;
- bool locked;
- bool tray_open;
- int io_status;
-};
-
typedef struct _qemuSharedDeviceEntry qemuSharedDeviceEntry;
typedef qemuSharedDeviceEntry *qemuSharedDeviceEntryPtr;
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 54d7bd7..ada4a17 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -238,6 +238,13 @@ struct _qemuDomainDiskPrivate {
bool migrating; /* the disk is being migrated */
};
+struct qemuDomainDiskInfo {
+ bool removable;
+ bool locked;
+ bool tray_open;
+ int io_status;
+};
+
typedef enum {
QEMU_PROCESS_EVENT_WATCHDOG = 0,
QEMU_PROCESS_EVENT_GUESTPANIC,
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index 1be0bee..cb917c2 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -22,7 +22,7 @@
#include "testutils.h"
#include "testutilsqemu.h"
#include "qemumonitortestutils.h"
-#include "qemu/qemu_conf.h"
+#include "qemu/qemu_domain.h"
#include "qemu/qemu_monitor_json.h"
#include "virthread.h"
#include "virerror.h"

View File

@ -0,0 +1,101 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 19 May 2016 14:57:41 +0200
Subject: [PATCH] qemu: Extract more information about qemu drives
Extract whether a given drive has a tray and whether there is no image
inserted.
Negative logic for the image insertion is chosen so that the flag is set
only if we are certain of the fact.
(cherry picked from commit f1690dc3d7934bf70f4fbc84d55bf210276c6f27)
---
src/qemu/qemu_domain.h | 2 ++
src/qemu/qemu_monitor_json.c | 12 +++++++-----
tests/qemumonitorjsontest.c | 23 +++++++++++++++++++++++
3 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index ada4a17..fbf5b1c 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -241,7 +241,9 @@ struct _qemuDomainDiskPrivate {
struct qemuDomainDiskInfo {
bool removable;
bool locked;
+ bool tray;
bool tray_open;
+ bool empty;
int io_status;
};
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index e140d0e..bd5537a 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -1797,11 +1797,13 @@ int qemuMonitorJSONGetBlockInfo(qemuMonitorPtr mon,
goto cleanup;
}
- /* Don't check for success here, because 'tray_open' is presented iff
- * medium is ejected.
- */
- ignore_value(virJSONValueObjectGetBoolean(dev, "tray_open",
- &info->tray_open));
+ /* 'tray_open' is present only if the device has a tray */
+ if (virJSONValueObjectGetBoolean(dev, "tray_open", &info->tray_open) == 0)
+ info->tray = true;
+
+ /* presence of 'inserted' notifies that a medium is in the device */
+ if (!virJSONValueObjectGetObject(dev, "inserted"))
+ info->empty = true;
/* Missing io-status indicates no error */
if ((status = virJSONValueObjectGetString(dev, "io-status"))) {
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index cb917c2..315baea 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -114,6 +114,14 @@ const char *queryBlockReply =
" },"
" \"tray_open\": false,"
" \"type\": \"unknown\""
+" },"
+" {"
+" \"io-status\": \"ok\","
+" \"device\": \"drive-ide0-1-1\","
+" \"locked\": false,"
+" \"removable\": true,"
+" \"tray_open\": false,"
+" \"type\": \"unknown\""
" }"
" ],"
" \"id\": \"libvirt-10\""
@@ -1404,12 +1412,27 @@ testQemuMonitorJSONqemuMonitorJSONGetBlockInfo(const void *data)
info->locked = true;
info->removable = true;
+ info->tray = true;
+
if (virHashAddEntry(expectedBlockDevices, "ide0-1-0", info) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
"Unable to create expectedBlockDevices hash table");
goto cleanup;
}
+ if (VIR_ALLOC(info) < 0)
+ goto cleanup;
+
+ info->removable = true;
+ info->tray = true;
+ info->empty = true;
+
+ if (virHashAddEntry(expectedBlockDevices, "ide0-1-1", info) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ "Unable to create expectedBlockDevices hash table");
+ goto cleanup;
+ }
+
if (qemuMonitorTestAddItem(test, "query-block", queryBlockReply) < 0)
goto cleanup;

View File

@ -0,0 +1,194 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 23 May 2016 14:00:35 +0200
Subject: [PATCH] qemu: Move and rename qemuDomainCheckEjectableMedia to
qemuProcessRefreshDisks
Move it to a more sane place since it's refreshing data about disks.
(cherry picked from commit d9bee413ade28e1e43ef222c7aaaa3c6d6fda0f1)
---
src/qemu/qemu_hotplug.c | 48 ----------------------------------------
src/qemu/qemu_hotplug.h | 3 ---
src/qemu/qemu_migration.c | 2 +-
src/qemu/qemu_process.c | 56 ++++++++++++++++++++++++++++++++++++++++++++---
src/qemu/qemu_process.h | 5 +++++
5 files changed, 59 insertions(+), 55 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index b8ab068..a58dd57 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -267,54 +267,6 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
goto cleanup;
}
-int
-qemuDomainCheckEjectableMedia(virQEMUDriverPtr driver,
- virDomainObjPtr vm,
- qemuDomainAsyncJob asyncJob)
-{
- qemuDomainObjPrivatePtr priv = vm->privateData;
- virHashTablePtr table = NULL;
- int ret = -1;
- size_t i;
-
- if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
- table = qemuMonitorGetBlockInfo(priv->mon);
- if (qemuDomainObjExitMonitor(driver, vm) < 0)
- goto cleanup;
- }
-
- if (!table)
- goto cleanup;
-
- for (i = 0; i < vm->def->ndisks; i++) {
- virDomainDiskDefPtr disk = vm->def->disks[i];
- struct qemuDomainDiskInfo *info;
-
- if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK ||
- disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
- continue;
- }
-
- info = qemuMonitorBlockInfoLookup(table, disk->info.alias);
- if (!info)
- goto cleanup;
-
- if (info->tray_open) {
- if (virDomainDiskGetSource(disk))
- ignore_value(virDomainDiskSetSource(disk, NULL));
-
- disk->tray_status = VIR_DOMAIN_DISK_TRAY_OPEN;
- } else {
- disk->tray_status = VIR_DOMAIN_DISK_TRAY_CLOSED;
- }
- }
-
- ret = 0;
-
- cleanup:
- virHashFree(table);
- return ret;
-}
static int
qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h
index 4140da3..fe7c563 100644
--- a/src/qemu/qemu_hotplug.h
+++ b/src/qemu/qemu_hotplug.h
@@ -34,9 +34,6 @@ int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
virDomainDiskDefPtr disk,
virStorageSourcePtr newsrc,
bool force);
-int qemuDomainCheckEjectableMedia(virQEMUDriverPtr driver,
- virDomainObjPtr vm,
- qemuDomainAsyncJob asyncJob);
int qemuDomainAttachControllerDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainControllerDefPtr controller);
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 8d2ca3b..6808a9c 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3273,7 +3273,7 @@ qemuMigrationBegin(virConnectPtr conn,
* We don't want to require them on the destination.
*/
if (!(flags & VIR_MIGRATE_OFFLINE) &&
- qemuDomainCheckEjectableMedia(driver, vm, asyncJob) < 0)
+ qemuProcessRefreshDisks(driver, vm, asyncJob) < 0)
goto endjob;
if (!(xml = qemuMigrationBeginPhase(driver, vm, xmlin, dname,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 2698178..f13d902 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3603,7 +3603,7 @@ qemuProcessReconnect(void *opaque)
if (qemuProcessFiltersInstantiate(obj->def))
goto error;
- if (qemuDomainCheckEjectableMedia(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
+ if (qemuProcessRefreshDisks(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
goto error;
if (qemuRefreshVirtioChannelState(driver, obj) < 0)
@@ -5457,8 +5457,8 @@ qemuProcessLaunch(virConnectPtr conn,
if (qemuProcessUpdateVideoRamSize(driver, vm, asyncJob) < 0)
goto cleanup;
- VIR_DEBUG("Updating ejectable media status");
- if (qemuDomainCheckEjectableMedia(driver, vm, asyncJob) < 0)
+ VIR_DEBUG("Updating disk data");
+ if (qemuProcessRefreshDisks(driver, vm, asyncJob) < 0)
goto cleanup;
if (flags & VIR_QEMU_PROCESS_START_AUTODESTROY &&
@@ -6380,3 +6380,53 @@ bool qemuProcessAutoDestroyActive(virQEMUDriverPtr driver,
cb = virCloseCallbacksGet(driver->closeCallbacks, vm, NULL);
return cb == qemuProcessAutoDestroy;
}
+
+
+int
+qemuProcessRefreshDisks(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ qemuDomainAsyncJob asyncJob)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ virHashTablePtr table = NULL;
+ int ret = -1;
+ size_t i;
+
+ if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
+ table = qemuMonitorGetBlockInfo(priv->mon);
+ if (qemuDomainObjExitMonitor(driver, vm) < 0)
+ goto cleanup;
+ }
+
+ if (!table)
+ goto cleanup;
+
+ for (i = 0; i < vm->def->ndisks; i++) {
+ virDomainDiskDefPtr disk = vm->def->disks[i];
+ struct qemuDomainDiskInfo *info;
+
+ if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK ||
+ disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
+ continue;
+ }
+
+ info = qemuMonitorBlockInfoLookup(table, disk->info.alias);
+ if (!info)
+ goto cleanup;
+
+ if (info->tray_open) {
+ if (virDomainDiskGetSource(disk))
+ ignore_value(virDomainDiskSetSource(disk, NULL));
+
+ disk->tray_status = VIR_DOMAIN_DISK_TRAY_OPEN;
+ } else {
+ disk->tray_status = VIR_DOMAIN_DISK_TRAY_CLOSED;
+ }
+ }
+
+ ret = 0;
+
+ cleanup:
+ virHashFree(table);
+ return ret;
+}
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index d5f50f2..7c67274 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -193,4 +193,9 @@ int qemuProcessSetupIOThread(virDomainObjPtr vm,
int qemuRefreshVirtioChannelState(virQEMUDriverPtr driver,
virDomainObjPtr vm);
+
+int qemuProcessRefreshDisks(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ qemuDomainAsyncJob asyncJob);
+
#endif /* __QEMU_PROCESS_H__ */

View File

@ -0,0 +1,119 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 19 May 2016 15:29:02 +0200
Subject: [PATCH] qemu: process: Fix and improve disk data extraction
Extract information for all disks and update tray state and source only
for removable drives. Additionally store whether a drive is removable
and whether it has a tray.
(cherry picked from commit 894dc85fd1ebcd63d8c897b355c550e68a5f432d)
---
src/qemu/qemu_domain.h | 4 ++++
src/qemu/qemu_monitor.c | 18 ------------------
src/qemu/qemu_monitor.h | 3 ---
src/qemu/qemu_process.c | 28 +++++++++++++++-------------
4 files changed, 19 insertions(+), 34 deletions(-)
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index fbf5b1c..15790ea 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -236,6 +236,10 @@ struct _qemuDomainDiskPrivate {
bool blockJobSync; /* the block job needs synchronized termination */
bool migrating; /* the disk is being migrated */
+
+ /* information about the device */
+ bool tray; /* device has tray */
+ bool removable; /* device media can be removed/changed */
};
struct qemuDomainDiskInfo {
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 96eac14..c994fec 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1807,24 +1807,6 @@ qemuMonitorGetBlockInfo(qemuMonitorPtr mon)
}
-struct qemuDomainDiskInfo *
-qemuMonitorBlockInfoLookup(virHashTablePtr blockInfo,
- const char *dev)
-{
- struct qemuDomainDiskInfo *info;
-
- VIR_DEBUG("blockInfo=%p dev=%s", blockInfo, NULLSTR(dev));
-
- if (!(info = virHashLookup(blockInfo, dev))) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot find info for device '%s'"),
- NULLSTR(dev));
- }
-
- return info;
-}
-
-
/**
* qemuMonitorGetAllBlockStatsInfo:
* @mon: monitor object
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 7906361..1a9d009 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -385,9 +385,6 @@ int qemuMonitorSetMemoryStatsPeriod(qemuMonitorPtr mon,
int qemuMonitorBlockIOStatusToError(const char *status);
virHashTablePtr qemuMonitorGetBlockInfo(qemuMonitorPtr mon);
-struct qemuDomainDiskInfo *
-qemuMonitorBlockInfoLookup(virHashTablePtr blockInfo,
- const char *dev_name);
typedef struct _qemuBlockStats qemuBlockStats;
typedef qemuBlockStats *qemuBlockStatsPtr;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index f13d902..aa56ccd 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6403,25 +6403,27 @@ qemuProcessRefreshDisks(virQEMUDriverPtr driver,
for (i = 0; i < vm->def->ndisks; i++) {
virDomainDiskDefPtr disk = vm->def->disks[i];
+ qemuDomainDiskPrivatePtr diskpriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
struct qemuDomainDiskInfo *info;
- if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK ||
- disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
- continue;
- }
-
- info = qemuMonitorBlockInfoLookup(table, disk->info.alias);
- if (!info)
- goto cleanup;
+ if (!(info = virHashLookup(table, disk->info.alias)))
+ continue;
- if (info->tray_open) {
- if (virDomainDiskGetSource(disk))
+ if (info->removable) {
+ if (info->empty)
ignore_value(virDomainDiskSetSource(disk, NULL));
- disk->tray_status = VIR_DOMAIN_DISK_TRAY_OPEN;
- } else {
- disk->tray_status = VIR_DOMAIN_DISK_TRAY_CLOSED;
+ if (info->tray) {
+ if (info->tray_open)
+ disk->tray_status = VIR_DOMAIN_DISK_TRAY_OPEN;
+ else
+ disk->tray_status = VIR_DOMAIN_DISK_TRAY_CLOSED;
+ }
}
+
+ /* fill in additional data */
+ diskpriv->removable = info->removable;
+ diskpriv->tray = info->tray;
}
ret = 0;

View File

@ -0,0 +1,179 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 29 Apr 2016 13:49:13 +0200
Subject: [PATCH] qemu: hotplug: Skip waiting for tray opening if qemu doesn't
notify us
If qemu doesn't support DEVICE_TRAY_MOVED event the code that attempts
to change media would attempt to re-eject the tray even if it wouldn't
be notified when the tray opened. Add a capability bit and skip retrying
for old qemus.
(cherry picked from commit 833ae6b4356934e7b779c4be01bd2bf051930dde)
---
src/qemu/qemu_capabilities.c | 2 ++
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_hotplug.c | 9 +++++++++
tests/qemucapabilitiesdata/caps_1.2.2-1.caps | 1 +
tests/qemucapabilitiesdata/caps_1.3.1-1.caps | 1 +
tests/qemucapabilitiesdata/caps_1.4.2-1.caps | 1 +
tests/qemucapabilitiesdata/caps_1.5.3-1.caps | 1 +
tests/qemucapabilitiesdata/caps_1.6.0-1.caps | 1 +
tests/qemucapabilitiesdata/caps_1.6.50-1.caps | 1 +
tests/qemucapabilitiesdata/caps_2.1.1-1.caps | 1 +
tests/qemucapabilitiesdata/caps_2.4.0-1.caps | 1 +
tests/qemucapabilitiesdata/caps_2.5.0-1.caps | 1 +
tests/qemucapabilitiesdata/caps_2.6.0-1.caps | 1 +
13 files changed, 22 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 57e2056..94a357f 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -321,6 +321,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
"qxl-vga.vram64_size_mb", /* 215 */
"chardev-logfile",
"debug-threads",
+ "device-tray-moved-event",
);
@@ -1493,6 +1494,7 @@ struct virQEMUCapsStringFlags virQEMUCapsEvents[] = {
{ "DEVICE_DELETED", QEMU_CAPS_DEVICE_DEL_EVENT },
{ "MIGRATION", QEMU_CAPS_MIGRATION_EVENT },
{ "VSERPORT_CHANGE", QEMU_CAPS_VSERPORT_CHANGE },
+ { "DEVICE_TRAY_MOVED", QEMU_CAPS_DEVICE_TRAY_MOVED },
};
struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index caf3d1b..c942be5 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -351,6 +351,7 @@ typedef enum {
QEMU_CAPS_QXL_VGA_VRAM64, /* -device qxl-vga.vram64_size_mb */
QEMU_CAPS_CHARDEV_LOGFILE, /* -chardev logfile=xxxx */
QEMU_CAPS_NAME_DEBUG_THREADS, /* Is -name debug-threads= available */
+ QEMU_CAPS_DEVICE_TRAY_MOVED, /* DEVICE_TRAY_MOVED event */
QEMU_CAPS_LAST /* this must always be the last item */
} virQEMUCapsFlags;
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index a58dd57..40d5683 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -202,6 +202,15 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
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)
diff --git a/tests/qemucapabilitiesdata/caps_1.2.2-1.caps b/tests/qemucapabilitiesdata/caps_1.2.2-1.caps
index 2e452ea..5fdc791 100644
--- a/tests/qemucapabilitiesdata/caps_1.2.2-1.caps
+++ b/tests/qemucapabilitiesdata/caps_1.2.2-1.caps
@@ -114,4 +114,5 @@
<flag name='virtio-net'/>
<flag name='qxl.vram64_size_mb'/>
<flag name='qxl-vga.vram64_size_mb'/>
+ <flag name='device-tray-moved-event'/>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_1.3.1-1.caps b/tests/qemucapabilitiesdata/caps_1.3.1-1.caps
index 5ad56aa..9402e68 100644
--- a/tests/qemucapabilitiesdata/caps_1.3.1-1.caps
+++ b/tests/qemucapabilitiesdata/caps_1.3.1-1.caps
@@ -129,4 +129,5 @@
<flag name='virtio-net'/>
<flag name='qxl.vram64_size_mb'/>
<flag name='qxl-vga.vram64_size_mb'/>
+ <flag name='device-tray-moved-event'/>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_1.4.2-1.caps b/tests/qemucapabilitiesdata/caps_1.4.2-1.caps
index d0341fd..1944dc3 100644
--- a/tests/qemucapabilitiesdata/caps_1.4.2-1.caps
+++ b/tests/qemucapabilitiesdata/caps_1.4.2-1.caps
@@ -130,4 +130,5 @@
<flag name='virtio-net'/>
<flag name='qxl.vram64_size_mb'/>
<flag name='qxl-vga.vram64_size_mb'/>
+ <flag name='device-tray-moved-event'/>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_1.5.3-1.caps b/tests/qemucapabilitiesdata/caps_1.5.3-1.caps
index 93ea687..d9d35ce 100644
--- a/tests/qemucapabilitiesdata/caps_1.5.3-1.caps
+++ b/tests/qemucapabilitiesdata/caps_1.5.3-1.caps
@@ -139,4 +139,5 @@
<flag name='virtio-net'/>
<flag name='qxl.vram64_size_mb'/>
<flag name='qxl-vga.vram64_size_mb'/>
+ <flag name='device-tray-moved-event'/>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_1.6.0-1.caps b/tests/qemucapabilitiesdata/caps_1.6.0-1.caps
index c25b076..1a52a6f 100644
--- a/tests/qemucapabilitiesdata/caps_1.6.0-1.caps
+++ b/tests/qemucapabilitiesdata/caps_1.6.0-1.caps
@@ -145,4 +145,5 @@
<flag name='virtio-net'/>
<flag name='qxl.vram64_size_mb'/>
<flag name='qxl-vga.vram64_size_mb'/>
+ <flag name='device-tray-moved-event'/>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_1.6.50-1.caps b/tests/qemucapabilitiesdata/caps_1.6.50-1.caps
index 30b70e9..973bdf5 100644
--- a/tests/qemucapabilitiesdata/caps_1.6.50-1.caps
+++ b/tests/qemucapabilitiesdata/caps_1.6.50-1.caps
@@ -145,4 +145,5 @@
<flag name='virtio-net'/>
<flag name='qxl.vram64_size_mb'/>
<flag name='qxl-vga.vram64_size_mb'/>
+ <flag name='device-tray-moved-event'/>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_2.1.1-1.caps b/tests/qemucapabilitiesdata/caps_2.1.1-1.caps
index 59d0323..254eb2a 100644
--- a/tests/qemucapabilitiesdata/caps_2.1.1-1.caps
+++ b/tests/qemucapabilitiesdata/caps_2.1.1-1.caps
@@ -163,4 +163,5 @@
<flag name='qxl.vram64_size_mb'/>
<flag name='qxl-vga.vram64_size_mb'/>
<flag name='debug-threads'/>
+ <flag name='device-tray-moved-event'/>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_2.4.0-1.caps b/tests/qemucapabilitiesdata/caps_2.4.0-1.caps
index efbf9af..bb76ddb 100644
--- a/tests/qemucapabilitiesdata/caps_2.4.0-1.caps
+++ b/tests/qemucapabilitiesdata/caps_2.4.0-1.caps
@@ -174,4 +174,5 @@
<flag name='qxl.vram64_size_mb'/>
<flag name='qxl-vga.vram64_size_mb'/>
<flag name='debug-threads'/>
+ <flag name='device-tray-moved-event'/>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_2.5.0-1.caps b/tests/qemucapabilitiesdata/caps_2.5.0-1.caps
index 5fd3bce..0734fbd 100644
--- a/tests/qemucapabilitiesdata/caps_2.5.0-1.caps
+++ b/tests/qemucapabilitiesdata/caps_2.5.0-1.caps
@@ -175,4 +175,5 @@
<flag name='qxl.vram64_size_mb'/>
<flag name='qxl-vga.vram64_size_mb'/>
<flag name='debug-threads'/>
+ <flag name='device-tray-moved-event'/>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_2.6.0-1.caps b/tests/qemucapabilitiesdata/caps_2.6.0-1.caps
index 549759c..7c9eb13 100644
--- a/tests/qemucapabilitiesdata/caps_2.6.0-1.caps
+++ b/tests/qemucapabilitiesdata/caps_2.6.0-1.caps
@@ -178,4 +178,5 @@
<flag name='qxl.vram64_size_mb'/>
<flag name='qxl-vga.vram64_size_mb'/>
<flag name='debug-threads'/>
+ <flag name='device-tray-moved-event'/>
</qemuCaps>

View File

@ -0,0 +1,31 @@
From: Cole Robinson <crobinso@redhat.com>
Date: Mon, 2 May 2016 19:07:34 -0400
Subject: [PATCH] qemu: hotplug: Report error if we hit tray status timeout
If we exceed the timeout waiting for the tray status to change,
we don't report an error. Fix it
(cherry picked from commit 1fad65d49aae364576bd91352a001249510f8d4e)
---
src/qemu/qemu_hotplug.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 40d5683..12653e3 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -225,7 +225,13 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
goto error;
while (disk->tray_status != VIR_DOMAIN_DISK_TRAY_OPEN) {
- if (virDomainObjWaitUntil(vm, now + CHANGE_MEDIA_TIMEOUT) != 0)
+ 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);

View File

@ -0,0 +1,123 @@
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)

View File

@ -0,0 +1,40 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 23 May 2016 16:32:06 +0200
Subject: [PATCH] qemu: hotplug: Fix error reported when cdrom tray is locked
Commit 1fad65d49aae364576bd91352a001249510f8d4e used a really big hammer
and overwrote the error message that might be reported by qemu if the
tray is locked. Fix it by reporting the error only if no error is
currently set.
Error after commit mentioned above:
error: internal error: timed out waiting for disk tray status update
New error:
error: internal error: unable to execute QEMU command 'eject': Tray of
device 'drive-ide0-0-0' is not open
(cherry picked from commit 2e75da42e41af0cd48ca6f75d0606b40a366cc54)
---
src/qemu/qemu_hotplug.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index d180b38..9f42e94 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -162,8 +162,12 @@ qemuHotplugWaitForTrayEject(virQEMUDriverPtr driver,
return -1;
if (rc > 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("timed out waiting for disk tray status update"));
+ /* the caller called qemuMonitorEjectMedia which usually reports an
+ * error. Report the failure in an off-chance that it didn't. */
+ if (!virGetLastError()) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("timed out waiting for disk tray status update"));
+ }
return -1;
}
}

View File

@ -0,0 +1,45 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 19 May 2016 15:30:12 +0200
Subject: [PATCH] qemu: hotplug: wait for the tray to eject only for drives
with a tray
Use the detected tray presence flag to trigger the tray waiting code
only if the given storage device in qemu reports to have a tray.
This is necessary as the floppy device lost it's tray as of qemu commit:
commit abb3e55b5b718d6392441f56ba0729a62105ac56
Author: Max Reitz <mreitz@redhat.com>
Date: Fri Jan 29 20:49:12 2016 +0100
Revert "hw/block/fdc: Implement tray status"
(cherry picked from commit 72a7ff6b507bcf389cc493ac0ba07d32de266d6e)
---
src/qemu/qemu_hotplug.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 9f42e94..4db180b 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -209,6 +209,7 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
int ret = -1, rc;
char *driveAlias = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
+ qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
const char *format = NULL;
char *sourcestr = NULL;
@@ -237,8 +238,9 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
if (qemuDomainObjExitMonitor(driver, vm) < 0)
goto cleanup;
- /* If the tray change event is supported wait for it to open. */
- if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_TRAY_MOVED)) {
+ /* If the tray is present and tray change event is supported wait for it to open. */
+ if (diskPriv->tray &&
+ virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_TRAY_MOVED)) {
if (qemuHotplugWaitForTrayEject(driver, vm, disk, driveAlias, force) < 0)
goto error;
} else {

View File

@ -373,7 +373,7 @@
Summary: Library providing a simple virtualization API
Name: libvirt
Version: 1.3.3.1
Release: 3%{?dist}%{?extra_release}
Release: 4%{?dist}%{?extra_release}
License: LGPLv2+
Group: Development/Libraries
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
@ -396,6 +396,22 @@ Patch0008: 0008-xlconfigtests-use-qemu-xen-in-all-test-data-files.patch
# Advertise fedora edk2 firmware builds to apps (bz #1335395)
Patch0101: 0101-spec-Advertise-nvram-paths-of-official-fedora-edk2-b.patch
# Don't disable auto_login of non-libvirt-managed iscsi (bz #1331552)
Patch0102: 0102-util-Add-exitstatus-parameter-to-virCommandRunRegex.patch
Patch0103: 0103-iscsi-Add-exit-status-checking-for-virISCSIGetSessio.patch
Patch0104: 0104-util-Remove-disabling-of-autologin-for-iscsi-targets.patch
Patch0105: 0105-iscsi-Remove-initiatoriqn-from-virISCSIScanTargets.patch
# Fix floppy media change (bz #1341998)
Patch0106: 0106-qemu-process-Refresh-ejectable-media-tray-state-on-V.patch
Patch0107: 0107-qemu-Move-struct-qemuDomainDiskInfo-to-qemu_domain.h.patch
Patch0108: 0108-qemu-Extract-more-information-about-qemu-drives.patch
Patch0109: 0109-qemu-Move-and-rename-qemuDomainCheckEjectableMedia-t.patch
Patch0110: 0110-qemu-process-Fix-and-improve-disk-data-extraction.patch
Patch0111: 0111-qemu-hotplug-Skip-waiting-for-tray-opening-if-qemu-d.patch
Patch0112: 0112-qemu-hotplug-Report-error-if-we-hit-tray-status-time.patch
Patch0113: 0113-qemu-hotplug-Extract-code-for-waiting-for-tray-eject.patch
Patch0114: 0114-qemu-hotplug-Fix-error-reported-when-cdrom-tray-is-l.patch
Patch0115: 0115-qemu-hotplug-wait-for-the-tray-to-eject-only-for-dri.patch
%if %{with_libvirtd}
Requires: libvirt-daemon = %{version}-%{release}
@ -2422,6 +2438,10 @@ exit 0
%changelog
* Thu Jun 23 2016 Cole Robinson <crobinso@redhat.com> - 1.3.3.1-4
- Don't disable auto_login of non-libvirt-managed iscsi (bz #1331552)
- Fix floppy media change (bz #1341998)
* Wed Jun 08 2016 Cole Robinson <crobinso@redhat.com> - 1.3.3.1-3
- Fix advertising fedora edk2 firmware builds