Hi Akihiko, Thanks for the review.
On Fri, Aug 01, 2025 at 04:17:04PM +0900, Akihiko Odaki wrote: > On 2025/07/31 22:20, Arun Menon wrote: > > 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. > > loadvm_process_command also sets the errp object explicitly. > > > > Reviewed-by: Daniel P. Berrangé <berra...@redhat.com> > > Signed-off-by: Arun Menon <arme...@redhat.com> > > --- > > migration/colo.c | 5 +++-- > > migration/savevm.c | 27 ++++++++++++++++----------- > > migration/savevm.h | 3 ++- > > 3 files changed, 21 insertions(+), 14 deletions(-) > > > > diff --git a/migration/colo.c b/migration/colo.c > > index > > 981bd4bf9ced8b45b4c5d494acae119a174ee974..529794dfc8d943b8ba3a25391ee2132c0c3f312e > > 100644 > > --- a/migration/colo.c > > +++ b/migration/colo.c > > @@ -659,6 +659,7 @@ void migrate_start_colo_process(MigrationState *s) > > static void colo_incoming_process_checkpoint(MigrationIncomingState *mis, > > QEMUFile *fb, QIOChannelBuffer *bioc, Error **errp) > > { > > + ERRP_GUARD(); > > uint64_t total_size; > > uint64_t value; > > Error *local_err = NULL; > > @@ -686,11 +687,11 @@ 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"); > > + error_prepend(errp, "Load VM's live state (ram) error: "); > > return; > > } > > diff --git a/migration/savevm.c b/migration/savevm.c > > index > > e885f1724f223771d60081fea199320abc549d2f..f5903995edd2b4c4f6c1a214c7126d831f10c9f1 > > 100644 > > --- a/migration/savevm.c > > +++ b/migration/savevm.c > > @@ -2111,7 +2111,7 @@ static void *postcopy_ram_listen_thread(void *opaque) > > qemu_file_set_blocking(f, true); > > /* 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, NULL); > > /* > > * This is tricky, but, mis->from_src_file can change after it > > @@ -2412,6 +2412,7 @@ static void > > loadvm_postcopy_handle_resume(MigrationIncomingState *mis) > > */ > > static int loadvm_handle_cmd_packaged(MigrationIncomingState *mis, Error > > **errp) > > { > > + ERRP_GUARD(); > > int ret; > > size_t length; > > QIOChannelBuffer *bioc; > > @@ -2461,9 +2462,9 @@ static int > > loadvm_handle_cmd_packaged(MigrationIncomingState *mis, Error **errp) > > qemu_coroutine_yield(); > > } while (1); > > - ret = qemu_loadvm_state_main(packf, mis); > > + ret = qemu_loadvm_state_main(packf, mis, errp); > > if (ret < 0) { > > - error_setg(errp, "VM state load failed: %d", ret); > > + error_prepend(errp, "Loading VM state failed: %d: ", ret); > > } > > trace_loadvm_handle_cmd_packaged_main(ret); > > qemu_fclose(packf); > > @@ -3066,8 +3067,10 @@ 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; > > @@ -3075,8 +3078,10 @@ 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 device state section ID: > > %d: ", > > + ret); > > I noticed this is after the "retry" label; errp already contains an error > when retried so the error needs to be properly reported and freed. Yes, I shall check how to report error, because there is an error_report() in the default case. And yes, errp needs to be freed and set to NULL before retry. > > > break; > > } > > @@ -3084,20 +3089,20 @@ retry: > > switch (section_type) { > > case QEMU_VM_SECTION_START: > > case QEMU_VM_SECTION_FULL: > > - ret = qemu_loadvm_section_start_full(f, section_type, NULL); > > + ret = qemu_loadvm_section_start_full(f, section_type, errp); > > if (ret < 0) { > > goto out; > > } > > break; > > case QEMU_VM_SECTION_PART: > > case QEMU_VM_SECTION_END: > > - ret = qemu_loadvm_section_part_end(f, section_type, NULL); > > + ret = qemu_loadvm_section_part_end(f, section_type, errp); > > if (ret < 0) { > > goto out; > > } > > break; > > case QEMU_VM_COMMAND: > > - ret = loadvm_process_command(f, NULL); > > + ret = loadvm_process_command(f, errp); > > trace_qemu_loadvm_state_section_command(ret); > > if ((ret < 0) || (ret == LOADVM_QUIT)) { > > goto out; > > @@ -3107,7 +3112,7 @@ retry: > > /* This is the end of migration */ > > goto out; > > default: > > - error_report("Unknown savevm section type %d", section_type); > > + error_setg(errp, "Unknown savevm section type %d", > > section_type); > > ret = -EINVAL; > > goto out; > > } > > @@ -3171,7 +3176,7 @@ int qemu_loadvm_state(QEMUFile *f) > > cpu_synchronize_all_pre_loadvm(); > > - ret = qemu_loadvm_state_main(f, mis); > > + ret = qemu_loadvm_state_main(f, mis, NULL); > > qemu_event_set(&mis->main_thread_load_event); > > trace_qemu_loadvm_state_post_main(ret); > > @@ -3245,7 +3250,7 @@ int qemu_load_device_state(QEMUFile *f) > > int ret; > > /* Load QEMU_VM_SECTION_FULL section */ > > - ret = qemu_loadvm_state_main(f, mis); > > + ret = qemu_loadvm_state_main(f, mis, NULL); > > if (ret < 0) { > > error_report("Failed to load device state: %d", ret); > > return ret; > > diff --git a/migration/savevm.h b/migration/savevm.h > > index > > 2d5e9c716686f06720325e82fe90c75335ced1de..fd7419e6ff90062970ed246b3ea71e6d49a6e372 > > 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); > > 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); > > int qemu_loadvm_approve_switchover(void); > > int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f, > > > Regards, Arun