Originally, qemuDomainCheckEjectableMedia was entering monitor with qemu
driver lock. Commit 2067e31bf97667eab9f111b496f5e9a44e827c5b, which I
made to fix that, revealed another issue we had (but didn't notice it
since the driver was locked): we didn't set nested job when
qemuDomainCheckEjectableMedia is called during migration. Thus the
original fix I made was wrong.
---
I'll try to come up with something to help avoid such issues in the future.
src/qemu/qemu_driver.c | 5 ++++-
src/qemu/qemu_hotplug.c | 12 +++++++-----
src/qemu/qemu_hotplug.h | 4 +++-
src/qemu/qemu_process.c | 2 +-
4 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 7e6d59c..dd79973 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8816,6 +8816,7 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
struct qemud_driver *driver = domain->conn->privateData;
virDomainObjPtr vm;
char *xml = NULL;
+ enum qemuDomainAsyncJob asyncJob;
virCheckFlags(QEMU_MIGRATION_FLAGS, NULL);
@@ -8832,9 +8833,11 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) {
if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
goto cleanup;
+ asyncJob = QEMU_ASYNC_JOB_MIGRATION_OUT;
} else {
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
goto cleanup;
+ asyncJob = QEMU_ASYNC_JOB_NONE;
}
if (!virDomainObjIsActive(vm)) {
@@ -8847,7 +8850,7 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
* We don't want to require them on the destination.
*/
- if (qemuDomainCheckEjectableMedia(driver, vm) < 0)
+ if (qemuDomainCheckEjectableMedia(driver, vm, asyncJob) < 0)
goto endjob;
if (!(xml = qemuMigrationBegin(driver, vm, xmlin, dname,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 3b6eb9d..857b980 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -155,16 +155,18 @@ error:
int
qemuDomainCheckEjectableMedia(struct qemud_driver *driver,
- virDomainObjPtr vm)
+ virDomainObjPtr vm,
+ enum qemuDomainAsyncJob asyncJob)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
- virHashTablePtr table;
+ virHashTablePtr table = NULL;
int ret = -1;
int i;
- qemuDomainObjEnterMonitorWithDriver(driver, vm);
- table = qemuMonitorGetBlockInfo(priv->mon);
- qemuDomainObjExitMonitorWithDriver(driver, vm);
+ if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
+ table = qemuMonitorGetBlockInfo(priv->mon);
+ qemuDomainObjExitMonitorWithDriver(driver, vm);
+ }
if (!table)
goto cleanup;
diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h
index 0310361..e6d7843 100644
--- a/src/qemu/qemu_hotplug.h
+++ b/src/qemu/qemu_hotplug.h
@@ -25,6 +25,7 @@
# define __QEMU_HOTPLUG_H__
# include "qemu_conf.h"
+# include "qemu_domain.h"
# include "domain_conf.h"
int qemuDomainChangeEjectableMedia(struct qemud_driver *driver,
@@ -32,7 +33,8 @@ int qemuDomainChangeEjectableMedia(struct qemud_driver *driver,
virDomainDiskDefPtr disk,
bool force);
int qemuDomainCheckEjectableMedia(struct qemud_driver *driver,
- virDomainObjPtr vm);
+ virDomainObjPtr vm,
+ enum qemuDomainAsyncJob asyncJob);
int qemuDomainAttachPciDiskDevice(virConnectPtr conn,
struct qemud_driver *driver,
virDomainObjPtr vm,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 0667a03..622739c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3106,7 +3106,7 @@ qemuProcessReconnect(void *opaque)
if (qemuProcessFiltersInstantiate(conn, obj->def))
goto error;
- if (qemuDomainCheckEjectableMedia(driver, obj) < 0)
+ if (qemuDomainCheckEjectableMedia(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
goto error;
if (qemuProcessRecoverJob(driver, obj, conn, &oldjob) < 0)
--
1.7.8.5