| /* |
| * 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 */ |