Define vmstate_register_init to statically declare that a vmstate object
should be registered during qemu initialization, specifically, in the
call to vmstate_register_init_all. This is needed to register objects
that are not Objects (and hence cannot use the DeviceClass vmsd hook),
without requiring that qemu call an object-specific initialization function.
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
include/migration/vmstate.h | 18 ++++++++++++++++++
migration/savevm.c | 32 ++++++++++++++++++++++++++++++++
system/vl.c | 3 +++
3 files changed, 53 insertions(+)
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index 3d71b34..8cb3d2b 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -1255,6 +1255,24 @@ static inline int vmstate_register(VMStateIf *obj, int instance_id,
}
/**
+ * vmstate_register_init() - statically declare a VMSD to be registered when
+ * QEMU calls vmstate_register_init_all. This is useful for registering
+ * objects that are not Objects (and hence cannot use the DeviceClass vmsd
+ * hook).
+ */
+#define vmstate_register_init(_obj, _id, _vmsd, _opaque) \
+static void __attribute__((constructor)) vmstate_register_ ## _vmsd(void) \
+{ \
+ vmstate_register_init_add(_obj, _id, &_vmsd, _opaque); \
+}
+
+void vmstate_register_init_add(VMStateIf *obj, int instance_id,
+ const VMStateDescription *vmsd, void *opaque);
+
+void vmstate_register_init_all(void);
+
+
+/**
* vmstate_replace_hack_for_ppc() - ppc used to abuse vmstate_register
*
* Don't even think about using this function in new code.
diff --git a/migration/savevm.c b/migration/savevm.c
index cd2eabe..ec48da9 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -957,6 +957,38 @@ err:
return -1;
}
+typedef struct VMStateInit {
+ VMStateIf *obj;
+ int instance_id;
+ const VMStateDescription *vmsd;
+ void *opaque;
+ QLIST_ENTRY(VMStateInit) next;
+} VMStateInit;
+
+static QLIST_HEAD(, VMStateInit) vmstate_inits;
+
+void vmstate_register_init_add(VMStateIf *obj, int instance_id,
+ const VMStateDescription *vmsd, void *opaque)
+{
+ VMStateInit *v = g_new0(VMStateInit, 1);
+
+ v->obj = obj;
+ v->instance_id = instance_id;
+ v->vmsd = vmsd;
+ v->opaque = opaque;
+ QLIST_INSERT_HEAD(&vmstate_inits, v, next);
+}
+
+void vmstate_register_init_all(void)
+{
+ VMStateInit *v, *tmp;
+
+ QLIST_FOREACH_SAFE(v, &vmstate_inits, next, tmp) {
+ vmstate_register(v->obj, v->instance_id, v->vmsd, v->opaque);
+ QLIST_REMOVE(v, next);
+ }
+}
+
void vmstate_unregister(VMStateIf *obj, const VMStateDescription *vmsd,
void *opaque)
{
diff --git a/system/vl.c b/system/vl.c
index c644222..7797206 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -78,6 +78,7 @@
#include "hw/i386/pc.h"
#include "migration/misc.h"
#include "migration/snapshot.h"
+#include "migration/vmstate.h"
#include "sysemu/tpm.h"
#include "sysemu/dma.h"
#include "hw/audio/soundhw.h"
@@ -3663,6 +3664,8 @@ void qemu_init(int argc, char **argv)
qemu_create_machine(machine_opts_dict);
+ vmstate_register_init_all();
+
suspend_mux_open();
qemu_disable_default_devices();
--
1.8.3.1