aboutsummaryrefslogtreecommitdiff
path: root/migration/vmstate-types.c
diff options
context:
space:
mode:
authorEric Auger <eric.auger@redhat.com>2020-01-13 14:48:23 +0100
committerJuan Quintela <quintela@redhat.com>2020-01-20 09:10:23 +0100
commit4746dbf8a98d560e20dbd22d0e8405b38478b409 (patch)
tree3bc9f98a1ccb539c72fa1f6efb81ca998224e077 /migration/vmstate-types.c
parent0ab994867c365db21e15f9503922c79234d8e40e (diff)
downloadqemu-4746dbf8a98d560e20dbd22d0e8405b38478b409.zip
qemu-4746dbf8a98d560e20dbd22d0e8405b38478b409.tar.gz
qemu-4746dbf8a98d560e20dbd22d0e8405b38478b409.tar.bz2
migration: Support QLIST migration
Support QLIST migration using the same principle as QTAILQ: 94869d5c52 ("migration: migrate QTAILQ"). The VMSTATE_QLIST_V macro has the same proto as VMSTATE_QTAILQ_V. The change mainly resides in QLIST RAW macros: QLIST_RAW_INSERT_HEAD and QLIST_RAW_REVERSE. Tests also are provided. Signed-off-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Reviewed-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com>
Diffstat (limited to 'migration/vmstate-types.c')
-rw-r--r--migration/vmstate-types.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/migration/vmstate-types.c b/migration/vmstate-types.c
index 7236cf9..1eee367 100644
--- a/migration/vmstate-types.c
+++ b/migration/vmstate-types.c
@@ -843,3 +843,73 @@ const VMStateInfo vmstate_info_gtree = {
.get = get_gtree,
.put = put_gtree,
};
+
+static int put_qlist(QEMUFile *f, void *pv, size_t unused_size,
+ const VMStateField *field, QJSON *vmdesc)
+{
+ const VMStateDescription *vmsd = field->vmsd;
+ /* offset of the QTAILQ entry in a QTAILQ element*/
+ size_t entry_offset = field->start;
+ void *elm;
+ int ret;
+
+ trace_put_qlist(field->name, vmsd->name, vmsd->version_id);
+ QLIST_RAW_FOREACH(elm, pv, entry_offset) {
+ qemu_put_byte(f, true);
+ ret = vmstate_save_state(f, vmsd, elm, vmdesc);
+ if (ret) {
+ error_report("%s: failed to save %s (%d)", field->name,
+ vmsd->name, ret);
+ return ret;
+ }
+ }
+ qemu_put_byte(f, false);
+ trace_put_qlist_end(field->name, vmsd->name);
+
+ return 0;
+}
+
+static int get_qlist(QEMUFile *f, void *pv, size_t unused_size,
+ const VMStateField *field)
+{
+ int ret = 0;
+ const VMStateDescription *vmsd = field->vmsd;
+ /* size of a QLIST element */
+ size_t size = field->size;
+ /* offset of the QLIST entry in a QLIST element */
+ size_t entry_offset = field->start;
+ int version_id = field->version_id;
+ void *elm;
+
+ trace_get_qlist(field->name, vmsd->name, vmsd->version_id);
+ if (version_id > vmsd->version_id) {
+ error_report("%s %s", vmsd->name, "too new");
+ return -EINVAL;
+ }
+ if (version_id < vmsd->minimum_version_id) {
+ error_report("%s %s", vmsd->name, "too old");
+ return -EINVAL;
+ }
+
+ while (qemu_get_byte(f)) {
+ elm = g_malloc(size);
+ ret = vmstate_load_state(f, vmsd, elm, version_id);
+ if (ret) {
+ error_report("%s: failed to load %s (%d)", field->name,
+ vmsd->name, ret);
+ g_free(elm);
+ return ret;
+ }
+ QLIST_RAW_INSERT_HEAD(pv, elm, entry_offset);
+ }
+ QLIST_RAW_REVERSE(pv, elm, entry_offset);
+ trace_get_qlist_end(field->name, vmsd->name);
+
+ return ret;
+}
+
+const VMStateInfo vmstate_info_qlist = {
+ .name = "qlist",
+ .get = get_qlist,
+ .put = put_qlist,
+};