1/* 2 * Replication filter 3 * 4 * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. 5 * Copyright (c) 2016 Intel Corporation 6 * Copyright (c) 2016 FUJITSU LIMITED 7 * 8 * Author: 9 * Changlong Xie <xiecl.fnst@cn.fujitsu.com> 10 * 11 * This work is licensed under the terms of the GNU GPL, version 2 or later. 12 * See the COPYING file in the top-level directory. 13 */ 14 15#ifndef REPLICATION_H 16#define REPLICATION_H 17 18#include "qemu/queue.h" 19 20typedef struct ReplicationOps ReplicationOps; 21typedef struct ReplicationState ReplicationState; 22 23/** 24 * SECTION:replication.h 25 * @title:Base Replication System 26 * @short_description: interfaces for handling replication 27 * 28 * The Replication Model provides a framework for handling Replication 29 * 30 * <example> 31 * <title>How to use replication interfaces</title> 32 * <programlisting> 33 * #include "replication.h" 34 * 35 * typedef struct BDRVReplicationState { 36 * ReplicationState *rs; 37 * } BDRVReplicationState; 38 * 39 * static void replication_start(ReplicationState *rs, ReplicationMode mode, 40 * Error **errp); 41 * static void replication_do_checkpoint(ReplicationState *rs, Error **errp); 42 * static void replication_get_error(ReplicationState *rs, Error **errp); 43 * static void replication_stop(ReplicationState *rs, bool failover, 44 * Error **errp); 45 * 46 * static ReplicationOps replication_ops = { 47 * .start = replication_start, 48 * .checkpoint = replication_do_checkpoint, 49 * .get_error = replication_get_error, 50 * .stop = replication_stop, 51 * } 52 * 53 * static int replication_open(BlockDriverState *bs, QDict *options, 54 * int flags, Error **errp) 55 * { 56 * BDRVReplicationState *s = bs->opaque; 57 * s->rs = replication_new(bs, &replication_ops); 58 * return 0; 59 * } 60 * 61 * static void replication_close(BlockDriverState *bs) 62 * { 63 * BDRVReplicationState *s = bs->opaque; 64 * replication_remove(s->rs); 65 * } 66 * 67 * BlockDriver bdrv_replication = { 68 * .format_name = "replication", 69 * .protocol_name = "replication", 70 * .instance_size = sizeof(BDRVReplicationState), 71 * 72 * .bdrv_open = replication_open, 73 * .bdrv_close = replication_close, 74 * }; 75 * 76 * static void bdrv_replication_init(void) 77 * { 78 * bdrv_register(&bdrv_replication); 79 * } 80 * 81 * block_init(bdrv_replication_init); 82 * </programlisting> 83 * </example> 84 * 85 * We create an example about how to use replication interfaces in above. 86 * Then in migration, we can use replication_(start/stop/do_checkpoint/ 87 * get_error)_all to handle all replication operations. 88 */ 89 90/** 91 * ReplicationState: 92 * @opaque: opaque pointer value passed to this ReplicationState 93 * @ops: replication operation of this ReplicationState 94 * @node: node that we will insert into @replication_states QLIST 95 */ 96struct ReplicationState { 97 void *opaque; 98 ReplicationOps *ops; 99 QLIST_ENTRY(ReplicationState) node; 100}; 101 102/** 103 * ReplicationOps: 104 * @start: callback to start replication 105 * @stop: callback to stop replication 106 * @checkpoint: callback to do checkpoint 107 * @get_error: callback to check if error occurred during replication 108 */ 109struct ReplicationOps { 110 void (*start)(ReplicationState *rs, ReplicationMode mode, Error **errp); 111 void (*stop)(ReplicationState *rs, bool failover, Error **errp); 112 void (*checkpoint)(ReplicationState *rs, Error **errp); 113 void (*get_error)(ReplicationState *rs, Error **errp); 114}; 115 116/** 117 * replication_new: 118 * @opaque: opaque pointer value passed to ReplicationState 119 * @ops: replication operation of the new relevant ReplicationState 120 * 121 * Called to create a new ReplicationState instance, and then insert it 122 * into @replication_states QLIST 123 * 124 * Returns: the new ReplicationState instance 125 */ 126ReplicationState *replication_new(void *opaque, ReplicationOps *ops); 127 128/** 129 * replication_remove: 130 * @rs: the ReplicationState instance to remove 131 * 132 * Called to remove a ReplicationState instance, and then delete it from 133 * @replication_states QLIST 134 */ 135void replication_remove(ReplicationState *rs); 136 137/** 138 * replication_start_all: 139 * @mode: replication mode that could be "primary" or "secondary" 140 * @errp: returns an error if this function fails 141 * 142 * Start replication, called in migration/checkpoint thread 143 * 144 * Note: the caller of the function MUST make sure vm stopped 145 */ 146void replication_start_all(ReplicationMode mode, Error **errp); 147 148/** 149 * replication_do_checkpoint_all: 150 * @errp: returns an error if this function fails 151 * 152 * This interface is called after all VM state is transferred to Secondary QEMU 153 */ 154void replication_do_checkpoint_all(Error **errp); 155 156/** 157 * replication_get_error_all: 158 * @errp: returns an error if this function fails 159 * 160 * This interface is called to check if error occurred during replication 161 */ 162void replication_get_error_all(Error **errp); 163 164/** 165 * replication_stop_all: 166 * @failover: boolean value that indicates if we need do failover or not 167 * @errp: returns an error if this function fails 168 * 169 * It is called on failover. The vm should be stopped before calling it, if you 170 * use this API to shutdown the guest, or other things except failover 171 */ 172void replication_stop_all(bool failover, Error **errp); 173 174#endif /* REPLICATION_H */ 175