From deecb4e7133c573a85558e29dff61ae428a9cfe8 Mon Sep 17 00:00:00 2001 From: Arun Menon Date: Thu, 18 Sep 2025 20:53:26 +0530 Subject: [PATCH] migration: push Error **errp into qemu_loadvm_state_main() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This is an incremental step in converting vmstate loading code to report error via Error objects instead of directly printing it to console/monitor. It is ensured that qemu_loadvm_state_main() must report an error in errp, in case of failure. Set errp explicitly if it is NULL in case of failure in the out section. This will be removed in the subsequent patch when all of the calls are converted to passing errp. The error message in the default case of qemu_loadvm_state_main() has the word "savevm". This is removed because it can confuse the user while reading destination side error logs. Reviewed-by: Daniel P. Berrangé Reviewed-by: Fabiano Rosas Signed-off-by: Arun Menon Tested-by: Fabiano Rosas Reviewed-by: Akihiko Odaki Link: https://lore.kernel.org/r/20250918-propagate_tpm_error-v14-9-36f11a6fb9d3@redhat.com Signed-off-by: Peter Xu --- migration/colo.c | 3 +-- migration/savevm.c | 36 +++++++++++++++++------------------- migration/savevm.h | 3 ++- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/migration/colo.c b/migration/colo.c index a426ec5b60b..ad50a3abc9c 100644 --- a/migration/colo.c +++ b/migration/colo.c @@ -686,11 +686,10 @@ static void colo_incoming_process_checkpoint(MigrationIncomingState *mis, bql_lock(); cpu_synchronize_all_states(); - ret = qemu_loadvm_state_main(mis->from_src_file, mis); + ret = qemu_loadvm_state_main(mis->from_src_file, mis, errp); bql_unlock(); if (ret < 0) { - error_setg(errp, "Load VM's live state (ram) error"); return; } diff --git a/migration/savevm.c b/migration/savevm.c index 9e30718995e..f1338f5cf6d 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2105,7 +2105,7 @@ static void *postcopy_ram_listen_thread(void *opaque) qemu_file_set_blocking(f, true, &error_fatal); /* TODO: sanity check that only postcopiable data will be loaded here */ - load_res = qemu_loadvm_state_main(f, mis); + load_res = qemu_loadvm_state_main(f, mis, &error_fatal); /* * This is tricky, but, mis->from_src_file can change after it @@ -2456,10 +2456,7 @@ static int loadvm_handle_cmd_packaged(MigrationIncomingState *mis, Error **errp) qemu_coroutine_yield(); } while (1); - ret = qemu_loadvm_state_main(packf, mis); - if (ret < 0) { - error_setg(errp, "VM state load failed: %d", ret); - } + ret = qemu_loadvm_state_main(packf, mis, errp); trace_loadvm_handle_cmd_packaged_main(ret); qemu_fclose(packf); object_unref(OBJECT(bioc)); @@ -3080,18 +3077,22 @@ static bool postcopy_pause_incoming(MigrationIncomingState *mis) return true; } -int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis) +int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis, + Error **errp) { + ERRP_GUARD(); uint8_t section_type; int ret = 0; - Error *local_err = NULL; retry: while (true) { section_type = qemu_get_byte(f); - ret = qemu_file_get_error_obj_any(f, mis->postcopy_qemufile_dst, NULL); + ret = qemu_file_get_error_obj_any(f, mis->postcopy_qemufile_dst, errp); if (ret) { + error_prepend(errp, + "Failed to load section ID: stream error: %d: ", + ret); break; } @@ -3112,10 +3113,7 @@ retry: } break; case QEMU_VM_COMMAND: - ret = loadvm_process_command(f, &local_err); - if (ret < 0) { - error_report_err(local_err); - } + ret = loadvm_process_command(f, errp); trace_qemu_loadvm_state_section_command(ret); if ((ret < 0) || (ret == LOADVM_QUIT)) { goto out; @@ -3125,7 +3123,7 @@ retry: /* This is the end of migration */ goto out; default: - error_report("Unknown savevm section type %d", section_type); + error_setg(errp, "Unknown section type %d", section_type); ret = -EINVAL; goto out; } @@ -3133,6 +3131,9 @@ retry: out: if (ret < 0) { + if (*errp == NULL) { + error_setg(errp, "Loading VM state failed: %d", ret); + } qemu_file_set_error(f, ret); /* Cancel bitmaps incoming regardless of recovery */ @@ -3153,6 +3154,7 @@ out: migrate_postcopy_ram() && postcopy_pause_incoming(mis)) { /* Reset f to point to the newly created channel */ f = mis->from_src_file; + error_free_or_abort(errp); goto retry; } } @@ -3186,10 +3188,7 @@ int qemu_loadvm_state(QEMUFile *f, Error **errp) cpu_synchronize_all_pre_loadvm(); - ret = qemu_loadvm_state_main(f, mis); - if (ret < 0) { - error_setg(errp, "Load VM state failed: %d", ret); - } + ret = qemu_loadvm_state_main(f, mis, errp); qemu_event_set(&mis->main_thread_load_event); trace_qemu_loadvm_state_post_main(ret); @@ -3270,9 +3269,8 @@ int qemu_load_device_state(QEMUFile *f, Error **errp) int ret; /* Load QEMU_VM_SECTION_FULL section */ - ret = qemu_loadvm_state_main(f, mis); + ret = qemu_loadvm_state_main(f, mis, errp); if (ret < 0) { - error_setg(errp, "Failed to load device state: %d", ret); return ret; } diff --git a/migration/savevm.h b/migration/savevm.h index b12681839f0..c337e3e3d11 100644 --- a/migration/savevm.h +++ b/migration/savevm.h @@ -66,7 +66,8 @@ int qemu_save_device_state(QEMUFile *f); int qemu_loadvm_state(QEMUFile *f, Error **errp); void qemu_loadvm_state_cleanup(MigrationIncomingState *mis); -int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis); +int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis, + Error **errp); int qemu_load_device_state(QEMUFile *f, Error **errp); int qemu_loadvm_approve_switchover(void); int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f, -- 2.47.3