diff options
author | Dr. David Alan Gilbert | 2017-02-03 17:06:49 +0100 |
---|---|---|
committer | Dr. David Alan Gilbert | 2017-02-13 18:27:14 +0100 |
commit | bcf45131293664118355df03d2ce5458156deaad (patch) | |
tree | 76da0209b74a753d4cabed500f7a9689358da85d /migration/vmstate.c | |
parent | migration: Add VMSTATE_UNUSED_VARRAY_UINT32 (diff) | |
download | qemu-bcf45131293664118355df03d2ce5458156deaad.tar.gz qemu-bcf45131293664118355df03d2ce5458156deaad.tar.xz qemu-bcf45131293664118355df03d2ce5458156deaad.zip |
migration: Add VMSTATE_WITH_TMP
VMSTATE_WITH_TMP is for handling structures where some calculation
or rearrangement of the data needs to be performed before the data
hits the wire.
For example, where the value on the wire is an offset from a
non-migrated base, but the data in the structure is the actual pointer.
To use it, a temporary type is created and a vmsd used on that type.
The first element of the type must be 'parent' a pointer back to the
type of the main structure. VMSTATE_WITH_TMP takes care of allocating
and freeing the temporary before running the child vmsd.
The post_load/pre_save on the child vmsd can copy things from the parent
to the temporary using the parent pointer and do any other calculations
needed; it can then use normal VMSD entries to do the actual data
storage without having to fiddle around with qemu_get_*/qemu_put_*
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Message-Id: <20170203160651.19917-3-dgilbert@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Diffstat (limited to 'migration/vmstate.c')
-rw-r--r-- | migration/vmstate.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/migration/vmstate.c b/migration/vmstate.c index 520341a2de..b4d8ae982a 100644 --- a/migration/vmstate.c +++ b/migration/vmstate.c @@ -935,6 +935,46 @@ const VMStateInfo vmstate_info_unused_buffer = { .put = put_unused_buffer, }; +/* vmstate_info_tmp, see VMSTATE_WITH_TMP, the idea is that we allocate + * a temporary buffer and the pre_load/pre_save methods in the child vmsd + * copy stuff from the parent into the child and do calculations to fill + * in fields that don't really exist in the parent but need to be in the + * stream. + */ +static int get_tmp(QEMUFile *f, void *pv, size_t size, VMStateField *field) +{ + int ret; + const VMStateDescription *vmsd = field->vmsd; + int version_id = field->version_id; + void *tmp = g_malloc(size); + + /* Writes the parent field which is at the start of the tmp */ + *(void **)tmp = pv; + ret = vmstate_load_state(f, vmsd, tmp, version_id); + g_free(tmp); + return ret; +} + +static int put_tmp(QEMUFile *f, void *pv, size_t size, VMStateField *field, + QJSON *vmdesc) +{ + const VMStateDescription *vmsd = field->vmsd; + void *tmp = g_malloc(size); + + /* Writes the parent field which is at the start of the tmp */ + *(void **)tmp = pv; + vmstate_save_state(f, vmsd, tmp, vmdesc); + g_free(tmp); + + return 0; +} + +const VMStateInfo vmstate_info_tmp = { + .name = "tmp", + .get = get_tmp, + .put = put_tmp, +}; + /* bitmaps (as defined by bitmap.h). Note that size here is the size * of the bitmap in bits. The on-the-wire format of a bitmap is 64 * bit words with the bits in big endian order. The in-memory format |