- We need to have good error reporting in the callbacks in VMStateDescription struct. Specifically pre_save, post_save, pre_load and post_load callbacks. - It is not possible to change these functions everywhere in one patch, therefore, we introduce a duplicate set of callbacks with Error object passed to them. - So, in this commit, we implement 'errp' variants of these callbacks, introducing an explicit Error object parameter. - This is a functional step towards transitioning the entire codebase to the new error-parameterized functions. - Deliberately called in mutual exclusion from their counterparts, to prevent conflicts during the transition. - New impls should preferentally use 'errp' variants of these methods, and existing impls incrementally converted. The variants without 'errp' are intended to be removed once all usage is converted.
Signed-off-by: Arun Menon <arme...@redhat.com> --- include/migration/vmstate.h | 11 +++++++++++ migration/vmstate.c | 36 +++++++++++++++++++++++++++++++----- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index 056781b1c21e737583f081594d9f88b32adfd674..53fa72c1bbde399be02c88fc8745fdbb79bfd7c8 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -200,15 +200,26 @@ struct VMStateDescription { * exclusive. For this reason, also early_setup VMSDs are migrated in a * QEMU_VM_SECTION_FULL section, while save_setup() data is migrated in * a QEMU_VM_SECTION_START section. + * + * There are duplicate impls of the post/pre save/load hooks. + * New impls should preferentally use 'errp' variants of these + * methods and existing impls incrementally converted. + * The variants without 'errp' are intended to be removed + * once all usage is converted. */ + bool early_setup; int version_id; int minimum_version_id; MigrationPriority priority; int (*pre_load)(void *opaque); + int (*pre_load_errp)(void *opaque, Error **errp); int (*post_load)(void *opaque, int version_id); + int (*post_load_errp)(void *opaque, int version_id, Error **errp); int (*pre_save)(void *opaque); + int (*pre_save_errp)(void *opaque, Error **errp); int (*post_save)(void *opaque); + int (*post_save_errp)(void *opaque, Error **errp); bool (*needed)(void *opaque); bool (*dev_unplug_pending)(void *opaque); diff --git a/migration/vmstate.c b/migration/vmstate.c index 078a00003023cc248fb16f05017d4c4251fd86df..bff4539cbe526c5a0718678d4e1f32ba9ac57889 100644 --- a/migration/vmstate.c +++ b/migration/vmstate.c @@ -152,7 +152,13 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd, trace_vmstate_load_state_end(vmsd->name, "too old", -EINVAL); return -EINVAL; } - if (vmsd->pre_load) { + if (vmsd->pre_load_errp) { + ret = vmsd->pre_load_errp(opaque, errp); + if (ret) { + error_prepend(errp, "VM pre load failed : %d ", ret); + return ret; + } + } else if (vmsd->pre_load) { ret = vmsd->pre_load(opaque); if (ret) { error_setg(errp, "VM pre load failed : %d", ret); @@ -238,7 +244,12 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd, qemu_file_set_error(f, ret); return ret; } - if (vmsd->post_load) { + if (vmsd->post_load_errp) { + ret = vmsd->post_load_errp(opaque, version_id, errp); + if (ret < 0) { + error_prepend(errp, "VM Post load failed : %d ", ret); + } + } else if (vmsd->post_load) { ret = vmsd->post_load(opaque, version_id); if (ret < 0) { error_setg(errp, "VM Post load failed : %d", ret); @@ -414,7 +425,14 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd, trace_vmstate_save_state_top(vmsd->name); - if (vmsd->pre_save) { + if (vmsd->pre_save_errp) { + ret = vmsd->pre_save_errp(opaque, errp); + trace_vmstate_save_state_pre_save_res(vmsd->name, ret); + if (ret) { + error_prepend(errp, "pre-save failed: %s ", vmsd->name); + return ret; + } + } else if (vmsd->pre_save) { ret = vmsd->pre_save(opaque); trace_vmstate_save_state_pre_save_res(vmsd->name, ret); if (ret) { @@ -524,7 +542,9 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd, if (ret) { error_setg(errp, "Save of field %s/%s failed", vmsd->name, field->name); - if (vmsd->post_save) { + if (vmsd->post_save_errp) { + vmsd->post_save_errp(opaque, errp); + } else if (vmsd->post_save) { vmsd->post_save(opaque); } return ret; @@ -552,7 +572,13 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd, ret = vmstate_subsection_save(f, vmsd, opaque, vmdesc, errp); - if (vmsd->post_save) { + if (vmsd->post_save_errp) { + int ps_ret = vmsd->post_save_errp(opaque, errp); + if (!ret && ps_ret) { + ret = ps_ret; + error_prepend(errp, "post-save failed: %s ", vmsd->name); + } + } else if (vmsd->post_save) { int ps_ret = vmsd->post_save(opaque); if (!ret && ps_ret) { ret = ps_ret; -- 2.50.0