diff options
-rw-r--r-- | migration/migration.c | 51 | ||||
-rw-r--r-- | trace-events | 6 |
2 files changed, 42 insertions, 15 deletions
diff --git a/migration/migration.c b/migration/migration.c index 064986b527..3cdb4f7257 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -1258,7 +1258,6 @@ static int open_return_path_on_source(MigrationState *ms) return 0; } -__attribute__ (( unused )) /* Until later in patch series */ /* Returns 0 if the RP was ok, otherwise there was an error on the RP */ static int await_return_path_close_on_source(MigrationState *ms) { @@ -1399,23 +1398,47 @@ static void migration_completion(MigrationState *s, int current_active_state, { int ret; - qemu_mutex_lock_iothread(); - *start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); - qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); - *old_vm_running = runstate_is_running(); + if (s->state == MIGRATION_STATUS_ACTIVE) { + qemu_mutex_lock_iothread(); + *start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); + qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); + *old_vm_running = runstate_is_running(); + ret = global_state_store(); + + if (!ret) { + ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); + if (ret >= 0) { + qemu_file_set_rate_limit(s->file, INT64_MAX); + qemu_savevm_state_complete_precopy(s->file); + } + } + qemu_mutex_unlock_iothread(); - ret = global_state_store(); - if (!ret) { - ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); - if (ret >= 0) { - qemu_file_set_rate_limit(s->file, INT64_MAX); - qemu_savevm_state_complete_precopy(s->file); + if (ret < 0) { + goto fail; } + } else if (s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE) { + trace_migration_completion_postcopy_end(); + + qemu_savevm_state_complete_postcopy(s->file); + trace_migration_completion_postcopy_end_after_complete(); } - qemu_mutex_unlock_iothread(); - if (ret < 0) { - goto fail; + /* + * If rp was opened we must clean up the thread before + * cleaning everything else up (since if there are no failures + * it will wait for the destination to send it's status in + * a SHUT command). + * Postcopy opens rp if enabled (even if it's not avtivated) + */ + if (migrate_postcopy_ram()) { + int rp_error; + trace_migration_completion_postcopy_end_before_rp(); + rp_error = await_return_path_close_on_source(s); + trace_migration_completion_postcopy_end_after_rp(rp_error); + if (rp_error) { + goto fail; + } } if (qemu_file_get_error(s->file)) { diff --git a/trace-events b/trace-events index 9b7876eb8e..401d4c3a54 100644 --- a/trace-events +++ b/trace-events @@ -1453,6 +1453,11 @@ migrate_fd_error(void) "" migrate_fd_cancel(void) "" migrate_pending(uint64_t size, uint64_t max, uint64_t post, uint64_t nonpost) "pending size %" PRIu64 " max %" PRIu64 " (post=%" PRIu64 " nonpost=%" PRIu64 ")" migrate_send_rp_message(int msg_type, uint16_t len) "%d: len %d" +migration_completion_file_err(void) "" +migration_completion_postcopy_end(void) "" +migration_completion_postcopy_end_after_complete(void) "" +migration_completion_postcopy_end_before_rp(void) "" +migration_completion_postcopy_end_after_rp(int rp_error) "%d" migration_thread_after_loop(void) "" migration_thread_file_err(void) "" migration_thread_setup_complete(void) "" @@ -1470,7 +1475,6 @@ migrate_transferred(uint64_t tranferred, uint64_t time_spent, double bandwidth, migrate_state_too_big(void) "" migrate_global_state_post_load(const char *state) "loaded state: %s" migrate_global_state_pre_save(const char *state) "saved state: %s" -migration_completion_file_err(void) "" migration_thread_low_pending(uint64_t pending) "%" PRIu64 # migration/rdma.c |