qemuProcessStart expects to be run with a job already set and every caller except for qemuMigrationPrepareAny use it correctly. This bug can be observed in libvirtd logs during incoming migration as warning : qemuDomainObjEnterMonitorInternal:979 : This thread seems to be the async job owner; entering monitor without asking for a nested job is dangerous --- src/qemu/qemu_domain.c | 35 ++++++++++++++++++++++++----------- src/qemu/qemu_domain.h | 4 ++++ src/qemu/qemu_migration.c | 11 +++++++---- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index eca85fc..0e56596 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -881,6 +881,29 @@ int qemuDomainObjBeginAsyncJob(virQEMUDriverPtr driver, asyncJob); } +int +qemuDomainObjBeginNestedJob(virQEMUDriverPtr driver, + virDomainObjPtr obj, + enum qemuDomainAsyncJob asyncJob) +{ + qemuDomainObjPrivatePtr priv = obj->privateData; + + if (asyncJob != priv->job.asyncJob) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected async job %d"), asyncJob); + return -1; + } + + if (priv->job.asyncOwner != virThreadSelfID()) { + VIR_WARN("This thread doesn't seem to be the async job owner: %d", + priv->job.asyncOwner); + } + + return qemuDomainObjBeginJobInternal(driver, obj, + QEMU_JOB_ASYNC_NESTED, + QEMU_ASYNC_JOB_NONE); +} + /* * obj must be locked before calling @@ -955,17 +978,7 @@ qemuDomainObjEnterMonitorInternal(virQEMUDriverPtr driver, qemuDomainObjPrivatePtr priv = obj->privateData; if (asyncJob != QEMU_ASYNC_JOB_NONE) { - if (asyncJob != priv->job.asyncJob) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("unexpected async job %d"), asyncJob); - return -1; - } - if (priv->job.asyncOwner != virThreadSelfID()) - VIR_WARN("This thread doesn't seem to be the async job owner: %d", - priv->job.asyncOwner); - if (qemuDomainObjBeginJobInternal(driver, obj, - QEMU_JOB_ASYNC_NESTED, - QEMU_ASYNC_JOB_NONE) < 0) + if (qemuDomainObjBeginNestedJob(driver, obj, asyncJob) < 0) return -1; if (!virDomainObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 30e6b97..e114f89 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -192,6 +192,10 @@ int qemuDomainObjBeginAsyncJob(virQEMUDriverPtr driver, virDomainObjPtr obj, enum qemuDomainAsyncJob asyncJob) ATTRIBUTE_RETURN_CHECK; +int qemuDomainObjBeginNestedJob(virQEMUDriverPtr driver, + virDomainObjPtr obj, + enum qemuDomainAsyncJob asyncJob) + ATTRIBUTE_RETURN_CHECK; bool qemuDomainObjEndJob(virQEMUDriverPtr driver, virDomainObjPtr obj) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index a58a79d..4c6d7e1 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2118,6 +2118,10 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, goto endjob; } + if (qemuDomainObjBeginNestedJob(driver, vm, + QEMU_ASYNC_JOB_MIGRATION_IN) < 0) + goto endjob; + /* Start the QEMU daemon, with the same command-line arguments plus * -incoming $migrateFrom */ @@ -2126,9 +2130,8 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, VIR_QEMU_PROCESS_START_PAUSED | VIR_QEMU_PROCESS_START_AUTODESTROY) < 0) { virDomainAuditStart(vm, "migrated", false); - /* Note that we don't set an error here because qemuProcessStart - * should have already done that. - */ + if (qemuDomainObjEndJob(driver, vm) < 0) + vm = NULL; goto endjob; } @@ -2235,7 +2238,7 @@ stop: qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, 0); endjob: - if (!qemuMigrationJobFinish(driver, vm)) { + if (vm && !qemuMigrationJobFinish(driver, vm)) { vm = NULL; } goto cleanup; -- 1.8.1.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list