[RFC 02/22] migration: VMStateInfo: introduce new handlers with errp

Vladimir Sementsov-Ogievskiy posted 22 patches 2 weeks, 2 days ago
[RFC 02/22] migration: VMStateInfo: introduce new handlers with errp
Posted by Vladimir Sementsov-Ogievskiy 2 weeks, 2 days ago
Add new APIs with errp, to allow handlers report good
error messages. We'll convert existing handlers soon.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 include/migration/vmstate.h |  7 +++++++
 migration/vmstate.c         | 37 +++++++++++++++++++++++++++----------
 2 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index 0aac3b7a66..f0ffd8f9c5 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -46,6 +46,13 @@ struct VMStateInfo {
     int coroutine_mixed_fn (*put)(QEMUFile *f, void *pv, size_t size,
                                   const VMStateField *field,
                                   JSONWriter *vmdesc);
+    bool coroutine_mixed_fn (*load)(QEMUFile *f, void *pv, size_t size,
+                                    const VMStateField *field,
+                                    Error **errp);
+    bool coroutine_mixed_fn (*save)(QEMUFile *f, void *pv, size_t size,
+                                    const VMStateField *field,
+                                    JSONWriter *vmdesc,
+                                    Error **errp);
 };
 
 enum VMStateFlags {
diff --git a/migration/vmstate.c b/migration/vmstate.c
index 4d28364f7b..1d291ff556 100644
--- a/migration/vmstate.c
+++ b/migration/vmstate.c
@@ -212,13 +212,22 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
                                              inner_field->struct_version_id,
                                              errp);
                 } else {
-                    ret = inner_field->info->get(f, curr_elem, size,
-                                                 inner_field);
-                    if (ret < 0) {
-                        error_setg(errp,
-                                   "Failed to load element of type %s for %s: "
-                                   "%d", inner_field->info->name,
-                                   inner_field->name, ret);
+                    if (inner_field->info->get) {
+                        ret = inner_field->info->get(f, curr_elem, size,
+                                                     inner_field);
+                        if (ret < 0) {
+                            error_setg(errp,
+                                       "Failed to load element of type %s for %s: "
+                                       "%d", inner_field->info->name,
+                                       inner_field->name, ret);
+                        }
+                    } else if (!inner_field->info->load(
+                        f, curr_elem, size, inner_field, errp)) {
+                            error_prepend(
+                                errp,
+                                "Failed to load element of type %s for %s: ",
+                                inner_field->info->name, inner_field->name);
+                            ret = -EINVAL;
                     }
                 }
 
@@ -536,9 +545,12 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
                                                curr_elem, vmdesc_loop,
                                                inner_field->struct_version_id,
                                                errp);
-                } else {
+                } else if (inner_field->info->put) {
                     ret = inner_field->info->put(f, curr_elem, size,
                                                  inner_field, vmdesc_loop);
+                } else if (!inner_field->info->save(
+                    f, curr_elem, size, inner_field, vmdesc_loop, errp)) {
+                    ret = -EINVAL;
                 }
 
                 written_bytes = qemu_file_transferred(f) - old_offset;
@@ -551,8 +563,13 @@ 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 (*errp) {
+                        error_prepend(errp, "Save of field %s/%s failed: ",
+                                      vmsd->name, field->name);
+                    } else {
+                        error_setg(errp, "Save of field %s/%s failed",
+                                   vmsd->name, field->name);
+                    }
                     if (vmsd->post_save) {
                         vmsd->post_save(opaque);
                     }
-- 
2.48.1