The hook is only defined in two vmstate users ("ram" and "block dirty
bitmap"), meanwhile both of them define the hook exactly the same as the
precopy version. Hence, this postcopy version isn't needed.
No functional change intended.
Reviewed-by: Juraj Marcin <jmarcin@redhat.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Link: https://lore.kernel.org/r/20250613140801.474264-6-peterx@redhat.com
Signed-off-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
361 lines
12 KiB
C
361 lines
12 KiB
C
/*
|
|
* QEMU migration vmstate registration
|
|
*
|
|
* Copyright IBM, Corp. 2008
|
|
*
|
|
* Authors:
|
|
* Anthony Liguori <aliguori@us.ibm.com>
|
|
*
|
|
* This work is licensed under the terms of the GNU GPL, version 2. See
|
|
* the COPYING file in the top-level directory.
|
|
*
|
|
*/
|
|
|
|
#ifndef MIGRATION_REGISTER_H
|
|
#define MIGRATION_REGISTER_H
|
|
|
|
#include "hw/vmstate-if.h"
|
|
|
|
/**
|
|
* struct SaveVMHandlers: handler structure to finely control
|
|
* migration of complex subsystems and devices, such as RAM, block and
|
|
* VFIO.
|
|
*/
|
|
typedef struct SaveVMHandlers {
|
|
|
|
/* The following handlers run inside the BQL. */
|
|
|
|
/**
|
|
* @save_state
|
|
*
|
|
* Saves state section on the source using the latest state format
|
|
* version.
|
|
*
|
|
* Legacy method. Should be deprecated when all users are ported
|
|
* to VMStateDescription.
|
|
*
|
|
* @f: QEMUFile where to send the data
|
|
* @opaque: data pointer passed to register_savevm_live()
|
|
*/
|
|
void (*save_state)(QEMUFile *f, void *opaque);
|
|
|
|
/**
|
|
* @save_prepare
|
|
*
|
|
* Called early, even before migration starts, and can be used to
|
|
* perform early checks.
|
|
*
|
|
* @opaque: data pointer passed to register_savevm_live()
|
|
* @errp: pointer to Error*, to store an error if it happens.
|
|
*
|
|
* Returns zero to indicate success and negative for error
|
|
*/
|
|
int (*save_prepare)(void *opaque, Error **errp);
|
|
|
|
/**
|
|
* @save_setup
|
|
*
|
|
* Initializes the data structures on the source and transmits
|
|
* first section containing information on the device
|
|
*
|
|
* @f: QEMUFile where to send the data
|
|
* @opaque: data pointer passed to register_savevm_live()
|
|
* @errp: pointer to Error*, to store an error if it happens.
|
|
*
|
|
* Returns zero to indicate success and negative for error
|
|
*/
|
|
int (*save_setup)(QEMUFile *f, void *opaque, Error **errp);
|
|
|
|
/**
|
|
* @save_cleanup
|
|
*
|
|
* Uninitializes the data structures on the source.
|
|
* Note that this handler can be called even if save_setup
|
|
* wasn't called earlier.
|
|
*
|
|
* @opaque: data pointer passed to register_savevm_live()
|
|
*/
|
|
void (*save_cleanup)(void *opaque);
|
|
|
|
/**
|
|
* @save_live_complete_precopy
|
|
*
|
|
* Transmits the last section for the device containing any
|
|
* remaining data at the end phase of migration.
|
|
*
|
|
* For precopy, this will be invoked _during_ the switchover phase
|
|
* after source VM is stopped.
|
|
*
|
|
* For postcopy, this will be invoked _after_ the switchover phase
|
|
* (except some very unusual cases, like PMEM ramblocks), while
|
|
* destination VM can be running.
|
|
*
|
|
* @f: QEMUFile where to send the data
|
|
* @opaque: data pointer passed to register_savevm_live()
|
|
*
|
|
* Returns zero to indicate success and negative for error
|
|
*/
|
|
int (*save_live_complete_precopy)(QEMUFile *f, void *opaque);
|
|
|
|
/**
|
|
* @save_live_complete_precopy_thread (invoked in a separate thread)
|
|
*
|
|
* Called at the end of a precopy phase from a separate worker thread
|
|
* in configurations where multifd device state transfer is supported
|
|
* in order to perform asynchronous transmission of the remaining data in
|
|
* parallel with @save_live_complete_precopy handlers.
|
|
* When postcopy is enabled, devices that support postcopy will skip this
|
|
* step.
|
|
*
|
|
* @d: a #SaveLiveCompletePrecopyThreadData containing parameters that the
|
|
* handler may need, including this device section idstr and instance_id,
|
|
* and opaque data pointer passed to register_savevm_live().
|
|
* @errp: pointer to Error*, to store an error if it happens.
|
|
*
|
|
* Returns true to indicate success and false for errors.
|
|
*/
|
|
SaveLiveCompletePrecopyThreadHandler save_live_complete_precopy_thread;
|
|
|
|
/* This runs both outside and inside the BQL. */
|
|
|
|
/**
|
|
* @is_active
|
|
*
|
|
* Will skip a state section if not active
|
|
*
|
|
* @opaque: data pointer passed to register_savevm_live()
|
|
*
|
|
* Returns true if state section is active else false
|
|
*/
|
|
bool (*is_active)(void *opaque);
|
|
|
|
/**
|
|
* @has_postcopy
|
|
*
|
|
* Checks if a device supports postcopy
|
|
*
|
|
* @opaque: data pointer passed to register_savevm_live()
|
|
*
|
|
* Returns true for postcopy support else false
|
|
*/
|
|
bool (*has_postcopy)(void *opaque);
|
|
|
|
/**
|
|
* @is_active_iterate
|
|
*
|
|
* As #SaveVMHandlers.is_active(), will skip an inactive state
|
|
* section in qemu_savevm_state_iterate.
|
|
*
|
|
* For example, it is needed for only-postcopy-states, which needs
|
|
* to be handled by qemu_savevm_state_setup() and
|
|
* qemu_savevm_state_pending(), but do not need iterations until
|
|
* not in postcopy stage.
|
|
*
|
|
* @opaque: data pointer passed to register_savevm_live()
|
|
*
|
|
* Returns true if state section is active else false
|
|
*/
|
|
bool (*is_active_iterate)(void *opaque);
|
|
|
|
/* This runs outside the BQL in the migration case, and
|
|
* within the lock in the savevm case. The callback had better only
|
|
* use data that is local to the migration thread or protected
|
|
* by other locks.
|
|
*/
|
|
|
|
/**
|
|
* @save_live_iterate
|
|
*
|
|
* Should send a chunk of data until the point that stream
|
|
* bandwidth limits tell it to stop. Each call generates one
|
|
* section.
|
|
*
|
|
* @f: QEMUFile where to send the data
|
|
* @opaque: data pointer passed to register_savevm_live()
|
|
*
|
|
* Returns 0 to indicate that there is still more data to send,
|
|
* 1 that there is no more data to send and
|
|
* negative to indicate an error.
|
|
*/
|
|
int (*save_live_iterate)(QEMUFile *f, void *opaque);
|
|
|
|
/* This runs outside the BQL! */
|
|
|
|
/**
|
|
* @save_postcopy_prepare
|
|
*
|
|
* This hook will be invoked on the source side right before switching
|
|
* to postcopy (before VM stopped).
|
|
*
|
|
* @f: QEMUFile where to send the data
|
|
* @opaque: Data pointer passed to register_savevm_live()
|
|
* @errp: Error** used to report error message
|
|
*
|
|
* Returns: true if succeeded, false if error occured. When false is
|
|
* returned, @errp must be set.
|
|
*/
|
|
bool (*save_postcopy_prepare)(QEMUFile *f, void *opaque, Error **errp);
|
|
|
|
/**
|
|
* @state_pending_estimate
|
|
*
|
|
* This estimates the remaining data to transfer
|
|
*
|
|
* Sum of @can_postcopy and @must_postcopy is the whole amount of
|
|
* pending data.
|
|
*
|
|
* @opaque: data pointer passed to register_savevm_live()
|
|
* @must_precopy: amount of data that must be migrated in precopy
|
|
* or in stopped state, i.e. that must be migrated
|
|
* before target start.
|
|
* @can_postcopy: amount of data that can be migrated in postcopy
|
|
* or in stopped state, i.e. after target start.
|
|
* Some can also be migrated during precopy (RAM).
|
|
* Some must be migrated after source stops
|
|
* (block-dirty-bitmap)
|
|
*/
|
|
void (*state_pending_estimate)(void *opaque, uint64_t *must_precopy,
|
|
uint64_t *can_postcopy);
|
|
|
|
/**
|
|
* @state_pending_exact
|
|
*
|
|
* This calculates the exact remaining data to transfer
|
|
*
|
|
* Sum of @can_postcopy and @must_postcopy is the whole amount of
|
|
* pending data.
|
|
*
|
|
* @opaque: data pointer passed to register_savevm_live()
|
|
* @must_precopy: amount of data that must be migrated in precopy
|
|
* or in stopped state, i.e. that must be migrated
|
|
* before target start.
|
|
* @can_postcopy: amount of data that can be migrated in postcopy
|
|
* or in stopped state, i.e. after target start.
|
|
* Some can also be migrated during precopy (RAM).
|
|
* Some must be migrated after source stops
|
|
* (block-dirty-bitmap)
|
|
*/
|
|
void (*state_pending_exact)(void *opaque, uint64_t *must_precopy,
|
|
uint64_t *can_postcopy);
|
|
|
|
/**
|
|
* @load_state
|
|
*
|
|
* Load sections generated by any of the save functions that
|
|
* generate sections.
|
|
*
|
|
* Legacy method. Should be deprecated when all users are ported
|
|
* to VMStateDescription.
|
|
*
|
|
* @f: QEMUFile where to receive the data
|
|
* @opaque: data pointer passed to register_savevm_live()
|
|
* @version_id: the maximum version_id supported
|
|
*
|
|
* Returns zero to indicate success and negative for error
|
|
*/
|
|
int (*load_state)(QEMUFile *f, void *opaque, int version_id);
|
|
|
|
/**
|
|
* @load_state_buffer (invoked outside the BQL)
|
|
*
|
|
* Load device state buffer provided to qemu_loadvm_load_state_buffer().
|
|
*
|
|
* @opaque: data pointer passed to register_savevm_live()
|
|
* @buf: the data buffer to load
|
|
* @len: the data length in buffer
|
|
* @errp: pointer to Error*, to store an error if it happens.
|
|
*
|
|
* Returns true to indicate success and false for errors.
|
|
*/
|
|
bool (*load_state_buffer)(void *opaque, char *buf, size_t len,
|
|
Error **errp);
|
|
|
|
/**
|
|
* @load_setup
|
|
*
|
|
* Initializes the data structures on the destination.
|
|
*
|
|
* @f: QEMUFile where to receive the data
|
|
* @opaque: data pointer passed to register_savevm_live()
|
|
* @errp: pointer to Error*, to store an error if it happens.
|
|
*
|
|
* Returns zero to indicate success and negative for error
|
|
*/
|
|
int (*load_setup)(QEMUFile *f, void *opaque, Error **errp);
|
|
|
|
/**
|
|
* @load_cleanup
|
|
*
|
|
* Uninitializes the data structures on the destination.
|
|
* Note that this handler can be called even if load_setup
|
|
* wasn't called earlier.
|
|
*
|
|
* @opaque: data pointer passed to register_savevm_live()
|
|
*
|
|
* Returns zero to indicate success and negative for error
|
|
*/
|
|
int (*load_cleanup)(void *opaque);
|
|
|
|
/**
|
|
* @resume_prepare
|
|
*
|
|
* Called when postcopy migration wants to resume from failure
|
|
*
|
|
* @s: Current migration state
|
|
* @opaque: data pointer passed to register_savevm_live()
|
|
*
|
|
* Returns zero to indicate success and negative for error
|
|
*/
|
|
int (*resume_prepare)(MigrationState *s, void *opaque);
|
|
|
|
/**
|
|
* @switchover_ack_needed
|
|
*
|
|
* Checks if switchover ack should be used. Called only on
|
|
* destination.
|
|
*
|
|
* @opaque: data pointer passed to register_savevm_live()
|
|
*
|
|
* Returns true if switchover ack should be used and false
|
|
* otherwise
|
|
*/
|
|
bool (*switchover_ack_needed)(void *opaque);
|
|
|
|
/**
|
|
* @switchover_start
|
|
*
|
|
* Notifies that the switchover has started. Called only on
|
|
* the destination.
|
|
*
|
|
* @opaque: data pointer passed to register_savevm_live()
|
|
*
|
|
* Returns zero to indicate success and negative for error
|
|
*/
|
|
int (*switchover_start)(void *opaque);
|
|
} SaveVMHandlers;
|
|
|
|
/**
|
|
* register_savevm_live: Register a set of custom migration handlers
|
|
*
|
|
* @idstr: state section identifier
|
|
* @instance_id: instance id
|
|
* @version_id: version id supported
|
|
* @ops: SaveVMHandlers structure
|
|
* @opaque: data pointer passed to SaveVMHandlers handlers
|
|
*/
|
|
int register_savevm_live(const char *idstr,
|
|
uint32_t instance_id,
|
|
int version_id,
|
|
const SaveVMHandlers *ops,
|
|
void *opaque);
|
|
|
|
/**
|
|
* unregister_savevm: Unregister custom migration handlers
|
|
*
|
|
* @obj: object associated with state section
|
|
* @idstr: state section identifier
|
|
* @opaque: data pointer passed to register_savevm_live()
|
|
*/
|
|
void unregister_savevm(VMStateIf *obj, const char *idstr, void *opaque);
|
|
|
|
#endif
|