On Fri, Mar 20, 2026 at 18:34:02 +0100, 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.
Fix this by re-querying QEMU migration state with qemuMigrationAnyRefreshStatus after restoring the async job but before calling qemuMigrationSrcCancel. If QEMU has already reached a terminal state, the cancel is skipped.
Signed-off-by: Denis V. Lunev <den@openvz.org> CC: Jiri Denemark <jdenemar@redhat.com> CC: Peter Krempa <pkrempa@redhat.com> CC: Michal Privoznik <mprivozn@redhat.com> CC: Efim Shevrin <efim.shevrin@virtuozzo.com> --- v1 -> v2: Instead of querying QEMU with query-migrate inside qemuMigrationSrcCancel, use qemuMigrationAnyRefreshStatus in qemuMigrationSrcCancelUnattended after restoring the async job to re-check migration state before the actual cancel.
src/qemu/qemu_migration.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
I apologize for the delay, for some reason your patch ended up in my spam folder (although v1 went in just fine). I'll look at this tomorrow. Jirka