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