Hi! VMStateDescription supports enclosed VMStateDescription's via .vmsd. This is used in multiple places and VMStateDescription definitions look the same way - name, version_id, minimum_version_id, etc.
QEMU handles first level VMStateDescription and enclosed VMStateDescription slightly different - for the latter it ignores the version_id from the source and always uses the version_id on the destination side so version fields are useless (code is below). Is that by design? Or a bug? I cannot see how we could fix it without breaking backward compatibility but I am sure the community does know that :) If this is by design, it probably makes sense to remove unused version_id/minimum_version_id fields completely for vmsd's which we know are enclosed (or embedded?). What do I miss here? Thanks! int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd, void *opaque, int version_id) { VMStateField *field = vmsd->fields; int ret; if (version_id > vmsd->version_id) { return -EINVAL; } if (version_id < vmsd->minimum_version_id) { if (vmsd->load_state_old && version_id >= vmsd->minimum_version_id_old) { return vmsd->load_state_old(f, opaque, version_id); } return -EINVAL; } if (vmsd->pre_load) { int ret = vmsd->pre_load(opaque); if (ret) { return ret; } } while (field->name) { if ((field->field_exists && field->field_exists(opaque, version_id)) || (!field->field_exists && field->version_id <= version_id)) { void *base_addr = vmstate_base_addr(opaque, field, true); int i, n_elems = vmstate_n_elems(opaque, field); int size = vmstate_size(opaque, field); for (i = 0; i < n_elems; i++) { void *addr = base_addr + size * i; if (field->flags & VMS_ARRAY_OF_POINTER) { addr = *(void **)addr; } if (field->flags & VMS_STRUCT) { ret = vmstate_load_state(f, field->vmsd, addr, field->vmsd->version_id); -- Alexey