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.sist...@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


Reply via email to