From ed1c45b0ba92535a48ba89207ed5cadf3ec1b42d Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Fri, 27 Apr 2018 16:20:15 +0200 Subject: [PATCH] qemu: migration: Don't crash on access to 'current' job When a VM is destroyed while being migrated (waiting in qemuMigrationSrcWaitForCompletion) the private object cleanup code frees the 'current' job info. Since the migration code attempts to setup various aspects of the current job even on failure this results into a crash. Job data is cleared in qemuDomainObjPrivateDataClear since commit 888aa4b6b9db Fix this by skipping all of the code which requires the qemu process to be alive if the VM is not active any more. Signed-off-by: Peter Krempa Reviewed-by: Jiri Denemark --- src/qemu/qemu_migration.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index b913e99928..1a857329ec 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -3561,27 +3561,28 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, error: orig_err = virSaveLastError(); - if (cancel && - priv->job.current->status != QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED && - virDomainObjIsActive(vm) && - qemuDomainObjEnterMonitorAsync(driver, vm, - QEMU_ASYNC_JOB_MIGRATION_OUT) == 0) { - qemuMonitorMigrateCancel(priv->mon); - ignore_value(qemuDomainObjExitMonitor(driver, vm)); - } + if (virDomainObjIsActive(vm)) { + if (cancel && + priv->job.current->status != QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED && + qemuDomainObjEnterMonitorAsync(driver, vm, + QEMU_ASYNC_JOB_MIGRATION_OUT) == 0) { + qemuMonitorMigrateCancel(priv->mon); + ignore_value(qemuDomainObjExitMonitor(driver, vm)); + } - /* cancel any outstanding NBD jobs */ - if (mig && mig->nbd) - qemuMigrationSrcCancelDriveMirror(driver, vm, false, - QEMU_ASYNC_JOB_MIGRATION_OUT, - dconn); + /* cancel any outstanding NBD jobs */ + if (mig && mig->nbd) + qemuMigrationSrcCancelDriveMirror(driver, vm, false, + QEMU_ASYNC_JOB_MIGRATION_OUT, + dconn); + + if (priv->job.current->status != QEMU_DOMAIN_JOB_STATUS_CANCELED) + priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_FAILED; + } if (iothread) qemuMigrationSrcStopTunnel(iothread, true); - if (priv->job.current->status != QEMU_DOMAIN_JOB_STATUS_CANCELED) - priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_FAILED; - goto cleanup; exit_monitor: -- GitLab