diff options
Diffstat (limited to 'migration/colo.c')
| -rw-r--r-- | migration/colo.c | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/migration/colo.c b/migration/colo.c index 6c7c313956..72f4f7b37e 100644 --- a/migration/colo.c +++ b/migration/colo.c @@ -145,8 +145,8 @@ static void secondary_vm_do_failover(void) qemu_sem_post(&mis->colo_incoming_sem); /* For Secondary VM, jump to incoming co */ - if (mis->migration_incoming_co) { - qemu_coroutine_enter(mis->migration_incoming_co); + if (mis->colo_incoming_co) { + qemu_coroutine_enter(mis->colo_incoming_co); } } @@ -817,7 +817,7 @@ void colo_shutdown(void) } } -void *colo_process_incoming_thread(void *opaque) +static void *colo_process_incoming_thread(void *opaque) { MigrationIncomingState *mis = opaque; QEMUFile *fb = NULL; @@ -918,3 +918,40 @@ out: rcu_unregister_thread(); return NULL; } + +int coroutine_fn colo_incoming_co(void) +{ + MigrationIncomingState *mis = migration_incoming_get_current(); + Error *local_err = NULL; + QemuThread th; + + assert(qemu_mutex_iothread_locked()); + + if (!migration_incoming_colo_enabled()) { + return 0; + } + + /* Make sure all file formats throw away their mutable metadata */ + bdrv_activate_all(&local_err); + if (local_err) { + error_report_err(local_err); + return -EINVAL; + } + + qemu_thread_create(&th, "COLO incoming", colo_process_incoming_thread, + mis, QEMU_THREAD_JOINABLE); + + mis->colo_incoming_co = qemu_coroutine_self(); + qemu_coroutine_yield(); + mis->colo_incoming_co = NULL; + + qemu_mutex_unlock_iothread(); + /* Wait checkpoint incoming thread exit before free resource */ + qemu_thread_join(&th); + qemu_mutex_lock_iothread(); + + /* We hold the global iothread lock, so it is safe here */ + colo_release_ram_cache(); + + return 0; +} |