/* * Replication filter * * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. * Copyright (c) 2016 Intel Corporation * Copyright (c) 2016 FUJITSU LIMITED * * Author: * Changlong Xie <xiecl.fnst@cn.fujitsu.com> * * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. */ #ifndef REPLICATION_H #define REPLICATION_H #include "qapi/qapi-types-block-core.h" #include "qemu/queue.h" typedef struct ReplicationOps ReplicationOps; typedef struct ReplicationState ReplicationState; /** * SECTION:replication.h * @title:Base Replication System * @short_description: interfaces for handling replication * * The Replication Model provides a framework for handling Replication * * <example> * <title>How to use replication interfaces</title> * <programlisting> * #include "replication.h" * * typedef struct BDRVReplicationState { * ReplicationState *rs; * } BDRVReplicationState; * * static void replication_start(ReplicationState *rs, ReplicationMode mode, * Error **errp); * static void replication_do_checkpoint(ReplicationState *rs, Error **errp); * static void replication_get_error(ReplicationState *rs, Error **errp); * static void replication_stop(ReplicationState *rs, bool failover, * Error **errp); * * static ReplicationOps replication_ops = { * .start = replication_start, * .checkpoint = replication_do_checkpoint, * .get_error = replication_get_error, * .stop = replication_stop, * } * * static int replication_open(BlockDriverState *bs, QDict *options, * int flags, Error **errp) * { * BDRVReplicationState *s = bs->opaque; * s->rs = replication_new(bs, &replication_ops); * return 0; * } * * static void replication_close(BlockDriverState *bs) * { * BDRVReplicationState *s = bs->opaque; * replication_remove(s->rs); * } * * BlockDriver bdrv_replication = { * .format_name = "replication", * .instance_size = sizeof(BDRVReplicationState), * * .bdrv_open = replication_open, * .bdrv_close = replication_close, * }; * * static void bdrv_replication_init(void) * { * bdrv_register(&bdrv_replication); * } * * block_init(bdrv_replication_init); * </programlisting> * </example> * * We create an example about how to use replication interfaces in above. * Then in migration, we can use replication_(start/stop/do_checkpoint/ * get_error)_all to handle all replication operations. */ /** * ReplicationState: * @opaque: opaque pointer value passed to this ReplicationState * @ops: replication operation of this ReplicationState * @node: node that we will insert into @replication_states QLIST */ struct ReplicationState { void *opaque; ReplicationOps *ops; QLIST_ENTRY(ReplicationState) node; }; /** * ReplicationOps: * @start: callback to start replication * @stop: callback to stop replication * @checkpoint: callback to do checkpoint * @get_error: callback to check if error occurred during replication */ struct ReplicationOps { void (*start)(ReplicationState *rs, ReplicationMode mode, Error **errp); void (*stop)(ReplicationState *rs, bool failover, Error **errp); void (*checkpoint)(ReplicationState *rs, Error **errp); void (*get_error)(ReplicationState *rs, Error **errp); }; /** * replication_new: * @opaque: opaque pointer value passed to ReplicationState * @ops: replication operation of the new relevant ReplicationState * * Called to create a new ReplicationState instance, and then insert it * into @replication_states QLIST * * Returns: the new ReplicationState instance */ ReplicationState *replication_new(void *opaque, ReplicationOps *ops); /** * replication_remove: * @rs: the ReplicationState instance to remove * * Called to remove a ReplicationState instance, and then delete it from * @replication_states QLIST */ void replication_remove(ReplicationState *rs); /** * replication_start_all: * @mode: replication mode that could be "primary" or "secondary" * @errp: returns an error if this function fails * * Start replication, called in migration/checkpoint thread * * Note: the caller of the function MUST make sure vm stopped */ void replication_start_all(ReplicationMode mode, Error **errp); /** * replication_do_checkpoint_all: * @errp: returns an error if this function fails * * This interface is called after all VM state is transferred to Secondary QEMU */ void replication_do_checkpoint_all(Error **errp); /** * replication_get_error_all: * @errp: returns an error if this function fails * * This interface is called to check if error occurred during replication */ void replication_get_error_all(Error **errp); /** * replication_stop_all: * @failover: boolean value that indicates if we need do failover or not * @errp: returns an error if this function fails * * It is called on failover. The vm should be stopped before calling it, if you * use this API to shutdown the guest, or other things except failover */ void replication_stop_all(bool failover, Error **errp); #endif /* REPLICATION_H */