migration: Perform vmsd structure check during tests

Perform a check on vmsd structures during test runs in the hope
of catching any missing terminators and other simple screwups.

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
This commit is contained in:
Dr. David Alan Gilbert 2022-01-13 19:44:52 +00:00 committed by Juan Quintela
parent 89c5684891
commit bb25a72895

View File

@ -66,6 +66,7 @@
#include "net/announce.h"
#include "qemu/yank.h"
#include "yank_functions.h"
#include "sysemu/qtest.h"
const unsigned int postcopy_ram_discard_version;
@ -804,6 +805,42 @@ void unregister_savevm(VMStateIf *obj, const char *idstr, void *opaque)
}
}
/*
* Perform some basic checks on vmsd's at registration
* time.
*/
static void vmstate_check(const VMStateDescription *vmsd)
{
const VMStateField *field = vmsd->fields;
const VMStateDescription **subsection = vmsd->subsections;
if (field) {
while (field->name) {
if (field->flags & (VMS_STRUCT | VMS_VSTRUCT)) {
/* Recurse to sub structures */
vmstate_check(field->vmsd);
}
/* Carry on */
field++;
}
/* Check for the end of field list canary */
if (field->flags != VMS_END) {
error_report("VMSTATE not ending with VMS_END: %s", vmsd->name);
g_assert_not_reached();
}
}
while (subsection && *subsection) {
/*
* The name of a subsection should start with the name of the
* current object.
*/
assert(!strncmp(vmsd->name, (*subsection)->name, strlen(vmsd->name)));
vmstate_check(*subsection);
subsection++;
}
}
int vmstate_register_with_alias_id(VMStateIf *obj, uint32_t instance_id,
const VMStateDescription *vmsd,
void *opaque, int alias_id,
@ -849,6 +886,11 @@ int vmstate_register_with_alias_id(VMStateIf *obj, uint32_t instance_id,
} else {
se->instance_id = instance_id;
}
/* Perform a recursive sanity check during the test runs */
if (qtest_enabled()) {
vmstate_check(vmsd);
}
assert(!se->compat || se->instance_id == 0);
savevm_state_handler_insert(se);
return 0;