diff options
Diffstat (limited to 'migration/colo.c')
| -rw-r--r-- | migration/colo.c | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/migration/colo.c b/migration/colo.c index a688ac553a..72f4f7b37e 100644 --- a/migration/colo.c +++ b/migration/colo.c @@ -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; +} |