xref: /qemu/include/migration/register.h (revision b6f568262b48ca0cb3dc018909908017551b5679)
1f2a8f0a6SJuan Quintela /*
2f2a8f0a6SJuan Quintela  * QEMU migration vmstate registration
3f2a8f0a6SJuan Quintela  *
4f2a8f0a6SJuan Quintela  * Copyright IBM, Corp. 2008
5f2a8f0a6SJuan Quintela  *
6f2a8f0a6SJuan Quintela  * Authors:
7f2a8f0a6SJuan Quintela  *  Anthony Liguori   <aliguori@us.ibm.com>
8f2a8f0a6SJuan Quintela  *
9f2a8f0a6SJuan Quintela  * This work is licensed under the terms of the GNU GPL, version 2.  See
10f2a8f0a6SJuan Quintela  * the COPYING file in the top-level directory.
11f2a8f0a6SJuan Quintela  *
12f2a8f0a6SJuan Quintela  */
13f2a8f0a6SJuan Quintela 
14f2a8f0a6SJuan Quintela #ifndef MIGRATION_REGISTER_H
15f2a8f0a6SJuan Quintela #define MIGRATION_REGISTER_H
16f2a8f0a6SJuan Quintela 
17107b5969SMarc-André Lureau #include "hw/vmstate-if.h"
18107b5969SMarc-André Lureau 
19ee8bb867SCédric Le Goater /**
20ee8bb867SCédric Le Goater  * struct SaveVMHandlers: handler structure to finely control
21ee8bb867SCédric Le Goater  * migration of complex subsystems and devices, such as RAM, block and
22ee8bb867SCédric Le Goater  * VFIO.
23ee8bb867SCédric Le Goater  */
24f2a8f0a6SJuan Quintela typedef struct SaveVMHandlers {
25ee8bb867SCédric Le Goater 
26ee8bb867SCédric Le Goater     /* The following handlers run inside the BQL. */
27ee8bb867SCédric Le Goater 
28ee8bb867SCédric Le Goater     /**
29ee8bb867SCédric Le Goater      * @save_state
30ee8bb867SCédric Le Goater      *
31ee8bb867SCédric Le Goater      * Saves state section on the source using the latest state format
32ee8bb867SCédric Le Goater      * version.
33ee8bb867SCédric Le Goater      *
34ee8bb867SCédric Le Goater      * Legacy method. Should be deprecated when all users are ported
35ee8bb867SCédric Le Goater      * to VMStateDescription.
36ee8bb867SCédric Le Goater      *
37ee8bb867SCédric Le Goater      * @f: QEMUFile where to send the data
38ee8bb867SCédric Le Goater      * @opaque: data pointer passed to register_savevm_live()
39ee8bb867SCédric Le Goater      */
40f61efdeeSCédric Le Goater     void (*save_state)(QEMUFile *f, void *opaque);
41f2a8f0a6SJuan Quintela 
42ee8bb867SCédric Le Goater     /**
43ee8bb867SCédric Le Goater      * @save_prepare
44ee8bb867SCédric Le Goater      *
45ee8bb867SCédric Le Goater      * Called early, even before migration starts, and can be used to
46ee8bb867SCédric Le Goater      * perform early checks.
47ee8bb867SCédric Le Goater      *
48ee8bb867SCédric Le Goater      * @opaque: data pointer passed to register_savevm_live()
49ee8bb867SCédric Le Goater      * @errp: pointer to Error*, to store an error if it happens.
50ee8bb867SCédric Le Goater      *
51ee8bb867SCédric Le Goater      * Returns zero to indicate success and negative for error
5208fc4cb5SAvihai Horon      */
5308fc4cb5SAvihai Horon     int (*save_prepare)(void *opaque, Error **errp);
54ee8bb867SCédric Le Goater 
55ee8bb867SCédric Le Goater     /**
56ee8bb867SCédric Le Goater      * @save_setup
57ee8bb867SCédric Le Goater      *
58ee8bb867SCédric Le Goater      * Initializes the data structures on the source and transmits
59ee8bb867SCédric Le Goater      * first section containing information on the device
60ee8bb867SCédric Le Goater      *
61ee8bb867SCédric Le Goater      * @f: QEMUFile where to send the data
62ee8bb867SCédric Le Goater      * @opaque: data pointer passed to register_savevm_live()
6301c3ac68SCédric Le Goater      * @errp: pointer to Error*, to store an error if it happens.
64ee8bb867SCédric Le Goater      *
65ee8bb867SCédric Le Goater      * Returns zero to indicate success and negative for error
66ee8bb867SCédric Le Goater      */
6701c3ac68SCédric Le Goater     int (*save_setup)(QEMUFile *f, void *opaque, Error **errp);
68ee8bb867SCédric Le Goater 
69ee8bb867SCédric Le Goater     /**
70ee8bb867SCédric Le Goater      * @save_cleanup
71ee8bb867SCédric Le Goater      *
72d3237d0dSMaciej S. Szmigiero      * Uninitializes the data structures on the source.
73d3237d0dSMaciej S. Szmigiero      * Note that this handler can be called even if save_setup
74d3237d0dSMaciej S. Szmigiero      * wasn't called earlier.
75ee8bb867SCédric Le Goater      *
76ee8bb867SCédric Le Goater      * @opaque: data pointer passed to register_savevm_live()
77ee8bb867SCédric Le Goater      */
7870f794fcSJuan Quintela     void (*save_cleanup)(void *opaque);
79ee8bb867SCédric Le Goater 
80ee8bb867SCédric Le Goater     /**
81ee8bb867SCédric Le Goater      * @save_live_complete_postcopy
82ee8bb867SCédric Le Goater      *
83ee8bb867SCédric Le Goater      * Called at the end of postcopy for all postcopyable devices.
84ee8bb867SCédric Le Goater      *
85ee8bb867SCédric Le Goater      * @f: QEMUFile where to send the data
86ee8bb867SCédric Le Goater      * @opaque: data pointer passed to register_savevm_live()
87ee8bb867SCédric Le Goater      *
88ee8bb867SCédric Le Goater      * Returns zero to indicate success and negative for error
89ee8bb867SCédric Le Goater      */
90f2a8f0a6SJuan Quintela     int (*save_live_complete_postcopy)(QEMUFile *f, void *opaque);
91ee8bb867SCédric Le Goater 
92ee8bb867SCédric Le Goater     /**
93ee8bb867SCédric Le Goater      * @save_live_complete_precopy
94ee8bb867SCédric Le Goater      *
95ee8bb867SCédric Le Goater      * Transmits the last section for the device containing any
96ee8bb867SCédric Le Goater      * remaining data at the end of a precopy phase. When postcopy is
97ee8bb867SCédric Le Goater      * enabled, devices that support postcopy will skip this step,
98ee8bb867SCédric Le Goater      * where the final data will be flushed at the end of postcopy via
99ee8bb867SCédric Le Goater      * @save_live_complete_postcopy instead.
100ee8bb867SCédric Le Goater      *
101ee8bb867SCédric Le Goater      * @f: QEMUFile where to send the data
102ee8bb867SCédric Le Goater      * @opaque: data pointer passed to register_savevm_live()
103ee8bb867SCédric Le Goater      *
104ee8bb867SCédric Le Goater      * Returns zero to indicate success and negative for error
105ee8bb867SCédric Le Goater      */
106f2a8f0a6SJuan Quintela     int (*save_live_complete_precopy)(QEMUFile *f, void *opaque);
107f2a8f0a6SJuan Quintela 
1088305921aSMaciej S. Szmigiero     /**
1098305921aSMaciej S. Szmigiero      * @save_live_complete_precopy_thread (invoked in a separate thread)
1108305921aSMaciej S. Szmigiero      *
1118305921aSMaciej S. Szmigiero      * Called at the end of a precopy phase from a separate worker thread
1128305921aSMaciej S. Szmigiero      * in configurations where multifd device state transfer is supported
1138305921aSMaciej S. Szmigiero      * in order to perform asynchronous transmission of the remaining data in
1148305921aSMaciej S. Szmigiero      * parallel with @save_live_complete_precopy handlers.
1158305921aSMaciej S. Szmigiero      * When postcopy is enabled, devices that support postcopy will skip this
1168305921aSMaciej S. Szmigiero      * step.
1178305921aSMaciej S. Szmigiero      *
1188305921aSMaciej S. Szmigiero      * @d: a #SaveLiveCompletePrecopyThreadData containing parameters that the
1198305921aSMaciej S. Szmigiero      * handler may need, including this device section idstr and instance_id,
1208305921aSMaciej S. Szmigiero      * and opaque data pointer passed to register_savevm_live().
1218305921aSMaciej S. Szmigiero      * @errp: pointer to Error*, to store an error if it happens.
1228305921aSMaciej S. Szmigiero      *
1238305921aSMaciej S. Szmigiero      * Returns true to indicate success and false for errors.
1248305921aSMaciej S. Szmigiero      */
1258305921aSMaciej S. Szmigiero     SaveLiveCompletePrecopyThreadHandler save_live_complete_precopy_thread;
1268305921aSMaciej S. Szmigiero 
127a4a411fbSStefan Hajnoczi     /* This runs both outside and inside the BQL.  */
128ee8bb867SCédric Le Goater 
129ee8bb867SCédric Le Goater     /**
130ee8bb867SCédric Le Goater      * @is_active
131ee8bb867SCédric Le Goater      *
132ee8bb867SCédric Le Goater      * Will skip a state section if not active
133ee8bb867SCédric Le Goater      *
134ee8bb867SCédric Le Goater      * @opaque: data pointer passed to register_savevm_live()
135ee8bb867SCédric Le Goater      *
136ee8bb867SCédric Le Goater      * Returns true if state section is active else false
137ee8bb867SCédric Le Goater      */
138f2a8f0a6SJuan Quintela     bool (*is_active)(void *opaque);
139ee8bb867SCédric Le Goater 
140ee8bb867SCédric Le Goater     /**
141ee8bb867SCédric Le Goater      * @has_postcopy
142ee8bb867SCédric Le Goater      *
143ee8bb867SCédric Le Goater      * Checks if a device supports postcopy
144ee8bb867SCédric Le Goater      *
145ee8bb867SCédric Le Goater      * @opaque: data pointer passed to register_savevm_live()
146ee8bb867SCédric Le Goater      *
147ee8bb867SCédric Le Goater      * Returns true for postcopy support else false
148ee8bb867SCédric Le Goater      */
149c6467627SVladimir Sementsov-Ogievskiy     bool (*has_postcopy)(void *opaque);
150f2a8f0a6SJuan Quintela 
151ee8bb867SCédric Le Goater     /**
152ee8bb867SCédric Le Goater      * @is_active_iterate
153ee8bb867SCédric Le Goater      *
154ee8bb867SCédric Le Goater      * As #SaveVMHandlers.is_active(), will skip an inactive state
155ee8bb867SCédric Le Goater      * section in qemu_savevm_state_iterate.
156ee8bb867SCédric Le Goater      *
157ee8bb867SCédric Le Goater      * For example, it is needed for only-postcopy-states, which needs
158ee8bb867SCédric Le Goater      * to be handled by qemu_savevm_state_setup() and
159ee8bb867SCédric Le Goater      * qemu_savevm_state_pending(), but do not need iterations until
160ee8bb867SCédric Le Goater      * not in postcopy stage.
161ee8bb867SCédric Le Goater      *
162ee8bb867SCédric Le Goater      * @opaque: data pointer passed to register_savevm_live()
163ee8bb867SCédric Le Goater      *
164ee8bb867SCédric Le Goater      * Returns true if state section is active else false
165c865d848SVladimir Sementsov-Ogievskiy      */
166c865d848SVladimir Sementsov-Ogievskiy     bool (*is_active_iterate)(void *opaque);
167c865d848SVladimir Sementsov-Ogievskiy 
168a4a411fbSStefan Hajnoczi     /* This runs outside the BQL in the migration case, and
169f2a8f0a6SJuan Quintela      * within the lock in the savevm case.  The callback had better only
170f2a8f0a6SJuan Quintela      * use data that is local to the migration thread or protected
171f2a8f0a6SJuan Quintela      * by other locks.
172f2a8f0a6SJuan Quintela      */
173ee8bb867SCédric Le Goater 
174ee8bb867SCédric Le Goater     /**
175ee8bb867SCédric Le Goater      * @save_live_iterate
176ee8bb867SCédric Le Goater      *
177ee8bb867SCédric Le Goater      * Should send a chunk of data until the point that stream
178ee8bb867SCédric Le Goater      * bandwidth limits tell it to stop. Each call generates one
179ee8bb867SCédric Le Goater      * section.
180ee8bb867SCédric Le Goater      *
181ee8bb867SCédric Le Goater      * @f: QEMUFile where to send the data
182ee8bb867SCédric Le Goater      * @opaque: data pointer passed to register_savevm_live()
183ee8bb867SCédric Le Goater      *
184ee8bb867SCédric Le Goater      * Returns 0 to indicate that there is still more data to send,
185ee8bb867SCédric Le Goater      *         1 that there is no more data to send and
186ee8bb867SCédric Le Goater      *         negative to indicate an error.
187ee8bb867SCédric Le Goater      */
188f2a8f0a6SJuan Quintela     int (*save_live_iterate)(QEMUFile *f, void *opaque);
189f2a8f0a6SJuan Quintela 
190a4a411fbSStefan Hajnoczi     /* This runs outside the BQL!  */
191ee8bb867SCédric Le Goater 
192ee8bb867SCédric Le Goater     /**
193*1d481116SPeter Xu      * @save_postcopy_prepare
194*1d481116SPeter Xu      *
195*1d481116SPeter Xu      * This hook will be invoked on the source side right before switching
196*1d481116SPeter Xu      * to postcopy (before VM stopped).
197*1d481116SPeter Xu      *
198*1d481116SPeter Xu      * @f:      QEMUFile where to send the data
199*1d481116SPeter Xu      * @opaque: Data pointer passed to register_savevm_live()
200*1d481116SPeter Xu      * @errp:   Error** used to report error message
201*1d481116SPeter Xu      *
202*1d481116SPeter Xu      * Returns: true if succeeded, false if error occured.  When false is
203*1d481116SPeter Xu      * returned, @errp must be set.
204*1d481116SPeter Xu      */
205*1d481116SPeter Xu     bool (*save_postcopy_prepare)(QEMUFile *f, void *opaque, Error **errp);
206*1d481116SPeter Xu 
207*1d481116SPeter Xu     /**
208ee8bb867SCédric Le Goater      * @state_pending_estimate
20947995026SVladimir Sementsov-Ogievskiy      *
210ee8bb867SCédric Le Goater      * This estimates the remaining data to transfer
21124beea4eSJuan Quintela      *
212ee8bb867SCédric Le Goater      * Sum of @can_postcopy and @must_postcopy is the whole amount of
21324beea4eSJuan Quintela      * pending data.
214ee8bb867SCédric Le Goater      *
215ee8bb867SCédric Le Goater      * @opaque: data pointer passed to register_savevm_live()
216ee8bb867SCédric Le Goater      * @must_precopy: amount of data that must be migrated in precopy
217ee8bb867SCédric Le Goater      *                or in stopped state, i.e. that must be migrated
218ee8bb867SCédric Le Goater      *                before target start.
219ee8bb867SCédric Le Goater      * @can_postcopy: amount of data that can be migrated in postcopy
220ee8bb867SCédric Le Goater      *                or in stopped state, i.e. after target start.
221ee8bb867SCédric Le Goater      *                Some can also be migrated during precopy (RAM).
222ee8bb867SCédric Le Goater      *                Some must be migrated after source stops
223ee8bb867SCédric Le Goater      *                (block-dirty-bitmap)
22447995026SVladimir Sementsov-Ogievskiy      */
22524beea4eSJuan Quintela     void (*state_pending_estimate)(void *opaque, uint64_t *must_precopy,
22624beea4eSJuan Quintela                                    uint64_t *can_postcopy);
227ee8bb867SCédric Le Goater 
228ee8bb867SCédric Le Goater     /**
229ee8bb867SCédric Le Goater      * @state_pending_exact
230ee8bb867SCédric Le Goater      *
231ee8bb867SCédric Le Goater      * This calculates the exact remaining data to transfer
232ee8bb867SCédric Le Goater      *
233ee8bb867SCédric Le Goater      * Sum of @can_postcopy and @must_postcopy is the whole amount of
234ee8bb867SCédric Le Goater      * pending data.
235ee8bb867SCédric Le Goater      *
236ee8bb867SCédric Le Goater      * @opaque: data pointer passed to register_savevm_live()
237ee8bb867SCédric Le Goater      * @must_precopy: amount of data that must be migrated in precopy
238ee8bb867SCédric Le Goater      *                or in stopped state, i.e. that must be migrated
239ee8bb867SCédric Le Goater      *                before target start.
240ee8bb867SCédric Le Goater      * @can_postcopy: amount of data that can be migrated in postcopy
241ee8bb867SCédric Le Goater      *                or in stopped state, i.e. after target start.
242ee8bb867SCédric Le Goater      *                Some can also be migrated during precopy (RAM).
243ee8bb867SCédric Le Goater      *                Some must be migrated after source stops
244ee8bb867SCédric Le Goater      *                (block-dirty-bitmap)
245ee8bb867SCédric Le Goater      */
24624beea4eSJuan Quintela     void (*state_pending_exact)(void *opaque, uint64_t *must_precopy,
24724beea4eSJuan Quintela                                 uint64_t *can_postcopy);
248ee8bb867SCédric Le Goater 
249ee8bb867SCédric Le Goater     /**
250ee8bb867SCédric Le Goater      * @load_state
251ee8bb867SCédric Le Goater      *
252ee8bb867SCédric Le Goater      * Load sections generated by any of the save functions that
253ee8bb867SCédric Le Goater      * generate sections.
254ee8bb867SCédric Le Goater      *
255ee8bb867SCédric Le Goater      * Legacy method. Should be deprecated when all users are ported
256ee8bb867SCédric Le Goater      * to VMStateDescription.
257ee8bb867SCédric Le Goater      *
258ee8bb867SCédric Le Goater      * @f: QEMUFile where to receive the data
259ee8bb867SCédric Le Goater      * @opaque: data pointer passed to register_savevm_live()
260ee8bb867SCédric Le Goater      * @version_id: the maximum version_id supported
261ee8bb867SCédric Le Goater      *
262ee8bb867SCédric Le Goater      * Returns zero to indicate success and negative for error
263ee8bb867SCédric Le Goater      */
264f61efdeeSCédric Le Goater     int (*load_state)(QEMUFile *f, void *opaque, int version_id);
265ee8bb867SCédric Le Goater 
266ee8bb867SCédric Le Goater     /**
267a30363dbSMaciej S. Szmigiero      * @load_state_buffer (invoked outside the BQL)
268a30363dbSMaciej S. Szmigiero      *
269a30363dbSMaciej S. Szmigiero      * Load device state buffer provided to qemu_loadvm_load_state_buffer().
270a30363dbSMaciej S. Szmigiero      *
271a30363dbSMaciej S. Szmigiero      * @opaque: data pointer passed to register_savevm_live()
272a30363dbSMaciej S. Szmigiero      * @buf: the data buffer to load
273a30363dbSMaciej S. Szmigiero      * @len: the data length in buffer
274a30363dbSMaciej S. Szmigiero      * @errp: pointer to Error*, to store an error if it happens.
275a30363dbSMaciej S. Szmigiero      *
276a30363dbSMaciej S. Szmigiero      * Returns true to indicate success and false for errors.
277a30363dbSMaciej S. Szmigiero      */
278a30363dbSMaciej S. Szmigiero     bool (*load_state_buffer)(void *opaque, char *buf, size_t len,
279a30363dbSMaciej S. Szmigiero                               Error **errp);
280a30363dbSMaciej S. Szmigiero 
281a30363dbSMaciej S. Szmigiero     /**
282ee8bb867SCédric Le Goater      * @load_setup
283ee8bb867SCédric Le Goater      *
284ee8bb867SCédric Le Goater      * Initializes the data structures on the destination.
285ee8bb867SCédric Le Goater      *
286ee8bb867SCédric Le Goater      * @f: QEMUFile where to receive the data
287ee8bb867SCédric Le Goater      * @opaque: data pointer passed to register_savevm_live()
288e4fa064dSCédric Le Goater      * @errp: pointer to Error*, to store an error if it happens.
289ee8bb867SCédric Le Goater      *
290ee8bb867SCédric Le Goater      * Returns zero to indicate success and negative for error
291ee8bb867SCédric Le Goater      */
292e4fa064dSCédric Le Goater     int (*load_setup)(QEMUFile *f, void *opaque, Error **errp);
293ee8bb867SCédric Le Goater 
294ee8bb867SCédric Le Goater     /**
295ee8bb867SCédric Le Goater      * @load_cleanup
296ee8bb867SCédric Le Goater      *
297ee8bb867SCédric Le Goater      * Uninitializes the data structures on the destination.
298d3237d0dSMaciej S. Szmigiero      * Note that this handler can be called even if load_setup
299d3237d0dSMaciej S. Szmigiero      * wasn't called earlier.
300ee8bb867SCédric Le Goater      *
301ee8bb867SCédric Le Goater      * @opaque: data pointer passed to register_savevm_live()
302ee8bb867SCédric Le Goater      *
303ee8bb867SCédric Le Goater      * Returns zero to indicate success and negative for error
304ee8bb867SCédric Le Goater      */
305acb5ea86SJuan Quintela     int (*load_cleanup)(void *opaque);
306ee8bb867SCédric Le Goater 
307ee8bb867SCédric Le Goater     /**
308ee8bb867SCédric Le Goater      * @resume_prepare
309ee8bb867SCédric Le Goater      *
310ee8bb867SCédric Le Goater      * Called when postcopy migration wants to resume from failure
311ee8bb867SCédric Le Goater      *
312ee8bb867SCédric Le Goater      * @s: Current migration state
313ee8bb867SCédric Le Goater      * @opaque: data pointer passed to register_savevm_live()
314ee8bb867SCédric Le Goater      *
315ee8bb867SCédric Le Goater      * Returns zero to indicate success and negative for error
316ee8bb867SCédric Le Goater      */
317d1b8eadbSPeter Xu     int (*resume_prepare)(MigrationState *s, void *opaque);
318ee8bb867SCédric Le Goater 
319ee8bb867SCédric Le Goater     /**
320ee8bb867SCédric Le Goater      * @switchover_ack_needed
321ee8bb867SCédric Le Goater      *
322ee8bb867SCédric Le Goater      * Checks if switchover ack should be used. Called only on
323ee8bb867SCédric Le Goater      * destination.
324ee8bb867SCédric Le Goater      *
325ee8bb867SCédric Le Goater      * @opaque: data pointer passed to register_savevm_live()
326ee8bb867SCédric Le Goater      *
327ee8bb867SCédric Le Goater      * Returns true if switchover ack should be used and false
328ee8bb867SCédric Le Goater      * otherwise
329ee8bb867SCédric Le Goater      */
3301b4adb10SAvihai Horon     bool (*switchover_ack_needed)(void *opaque);
3314e55cb3cSMaciej S. Szmigiero 
3324e55cb3cSMaciej S. Szmigiero     /**
3334e55cb3cSMaciej S. Szmigiero      * @switchover_start
3344e55cb3cSMaciej S. Szmigiero      *
3354e55cb3cSMaciej S. Szmigiero      * Notifies that the switchover has started. Called only on
3364e55cb3cSMaciej S. Szmigiero      * the destination.
3374e55cb3cSMaciej S. Szmigiero      *
3384e55cb3cSMaciej S. Szmigiero      * @opaque: data pointer passed to register_savevm_live()
3394e55cb3cSMaciej S. Szmigiero      *
3404e55cb3cSMaciej S. Szmigiero      * Returns zero to indicate success and negative for error
3414e55cb3cSMaciej S. Szmigiero      */
3424e55cb3cSMaciej S. Szmigiero     int (*switchover_start)(void *opaque);
343f2a8f0a6SJuan Quintela } SaveVMHandlers;
344f2a8f0a6SJuan Quintela 
345ee8bb867SCédric Le Goater /**
346ee8bb867SCédric Le Goater  * register_savevm_live: Register a set of custom migration handlers
347ee8bb867SCédric Le Goater  *
348ee8bb867SCédric Le Goater  * @idstr: state section identifier
349ee8bb867SCédric Le Goater  * @instance_id: instance id
350ee8bb867SCédric Le Goater  * @version_id: version id supported
351ee8bb867SCédric Le Goater  * @ops: SaveVMHandlers structure
352ee8bb867SCédric Le Goater  * @opaque: data pointer passed to SaveVMHandlers handlers
353ee8bb867SCédric Le Goater  */
354ce62df53SDr. David Alan Gilbert int register_savevm_live(const char *idstr,
35593062e23SPeter Xu                          uint32_t instance_id,
356f2a8f0a6SJuan Quintela                          int version_id,
357de22ded0SMarc-André Lureau                          const SaveVMHandlers *ops,
358f2a8f0a6SJuan Quintela                          void *opaque);
359f2a8f0a6SJuan Quintela 
360ee8bb867SCédric Le Goater /**
361ee8bb867SCédric Le Goater  * unregister_savevm: Unregister custom migration handlers
362ee8bb867SCédric Le Goater  *
363ee8bb867SCédric Le Goater  * @obj: object associated with state section
364ee8bb867SCédric Le Goater  * @idstr:  state section identifier
365ee8bb867SCédric Le Goater  * @opaque: data pointer passed to register_savevm_live()
366ee8bb867SCédric Le Goater  */
3673cad405bSMarc-André Lureau void unregister_savevm(VMStateIf *obj, const char *idstr, void *opaque);
368f2a8f0a6SJuan Quintela 
369f2a8f0a6SJuan Quintela #endif
370