On Wed, Apr 22, 2026 at 11:34:27 +0200, Denis V. Lunev wrote:
When libvirtd reconnects to a running QEMU process that had an in-progress migration, qemuProcessReconnect first connects the monitor and only later recovers the migration job. During this window the async job is VIR_ASYNC_JOB_NONE, so any MIGRATION status events from QEMU are silently dropped by qemuProcessHandleMigrationStatus.
If the migration was already cancelled or completed by QEMU during this window, no further events will be emitted. When qemuMigrationSrcCancelUnattended later restores the async job and calls qemuMigrationSrcCancel with wait=true, the wait loop calls qemuDomainObjWait (virCondWait with no timeout) and blocks forever waiting for an event that will never arrive.
qemuProcessRecoverMigration already queries QEMU for the current migration state via qemuMigrationAnyRefreshStatus and passes the result to qemuProcessRecoverMigrationOut as migStatus. Plumb that value one level further into qemuMigrationSrcCancelUnattended and, when it indicates the migration has already reached a terminal state (VIR_DOMAIN_JOB_STATUS_CANCELED), skip restoring the async job and the qemuMigrationSrcCancel/virDomainObjEndAsyncJob pair entirely.
Signed-off-by: Denis V. Lunev <den@openvz.org> Suggested-by: Jiri Denemark <jdenemar@redhat.com> CC: Peter Krempa <pkrempa@redhat.com> CC: Michal Privoznik <mprivozn@redhat.com>
Thanks. Indeed the patch ended up in my spam box again :-( Reviewed-by: Jiri Denemark <jdenemar@redhat.com> and pushed.