migration: Support gtree migration

Introduce support for GTree migration. A custom save/restore
is implemented. Each item is made of a key and a data.

If the key is a pointer to an object, 2 VMSDs are passed into
the GTree VMStateField.

When putting the items, the tree is traversed in sorted order by
g_tree_foreach.

On the get() path, gtrees must be allocated using the proper
key compare, key destroy and value destroy. This must be handled
beforehand, for example in a pre_load method.

Tests are added to test save/dump of structs containing gtrees
including the virtio-iommu domain/mappings scenario.

Signed-off-by: Eric Auger <eric.auger@redhat.com>

Message-Id: <20191011121724.433-1-eric.auger@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
  uintptr_t fixup for test on 32bit
This commit is contained in:
Eric Auger 2019-10-11 14:17:24 +02:00 committed by Dr. David Alan Gilbert
parent aff66d2ef0
commit 9a85e4b8f6
4 changed files with 618 additions and 0 deletions

View file

@ -224,6 +224,7 @@ extern const VMStateInfo vmstate_info_unused_buffer;
extern const VMStateInfo vmstate_info_tmp;
extern const VMStateInfo vmstate_info_bitmap;
extern const VMStateInfo vmstate_info_qtailq;
extern const VMStateInfo vmstate_info_gtree;
#define type_check_2darray(t1,t2,n,m) ((t1(*)[n][m])0 - (t2*)0)
/*
@ -754,6 +755,45 @@ extern const VMStateInfo vmstate_info_qtailq;
.start = offsetof(_type, _next), \
}
/*
* For migrating a GTree whose key is a pointer to _key_type and the
* value, a pointer to _val_type
* The target tree must have been properly initialized
* _vmsd: Start address of the 2 element array containing the data vmsd
* and the key vmsd, in that order
* _key_type: type of the key
* _val_type: type of the value
*/
#define VMSTATE_GTREE_V(_field, _state, _version, _vmsd, \
_key_type, _val_type) \
{ \
.name = (stringify(_field)), \
.version_id = (_version), \
.vmsd = (_vmsd), \
.info = &vmstate_info_gtree, \
.start = sizeof(_key_type), \
.size = sizeof(_val_type), \
.offset = offsetof(_state, _field), \
}
/*
* For migrating a GTree with direct key and the value a pointer
* to _val_type
* The target tree must have been properly initialized
* _vmsd: data vmsd
* _val_type: type of the value
*/
#define VMSTATE_GTREE_DIRECT_KEY_V(_field, _state, _version, _vmsd, _val_type) \
{ \
.name = (stringify(_field)), \
.version_id = (_version), \
.vmsd = (_vmsd), \
.info = &vmstate_info_gtree, \
.start = 0, \
.size = sizeof(_val_type), \
.offset = offsetof(_state, _field), \
}
/* _f : field name
_f_n : num of elements field_name
_n : num of elements