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