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/queue.h" 20 21typedef struct ReplicationOps ReplicationOps; 22typedef struct ReplicationState ReplicationState; 23 24/** 25 * SECTION:replication.h 26 * @title:Base Replication System 27 * @short_description: interfaces for handling replication 28 * 29 * The Replication Model provides a framework for handling Replication 30 * 31 * <example> 32 * <title>How to use replication interfaces</title> 33 * <programlisting> 34 * #include "replication.h" 35 * 36 * typedef struct BDRVReplicationState { 37 * ReplicationState *rs; 38 * } BDRVReplicationState; 39 * 40 * static void replication_start(ReplicationState *rs, ReplicationMode mode, 41 * Error **errp); 42 * static void replication_do_checkpoint(ReplicationState *rs, Error **errp); 43 * static void replication_get_error(ReplicationState *rs, Error **errp); 44 * static void replication_stop(ReplicationState *rs, bool failover, 45 * Error **errp); 46 * 47 * static ReplicationOps replication_ops = { 48 * .start = replication_start, 49 * .checkpoint = replication_do_checkpoint, 50 * .get_error = replication_get_error, 51 * .stop = replication_stop, 52 * } 53 * 54 * static int replication_open(BlockDriverState *bs, QDict *options, 55 * int flags, Error **errp) 56 * { 57 * BDRVReplicationState *s = bs->opaque; 58 * s->rs = replication_new(bs, &replication_ops); 59 * return 0; 60 * } 61 * 62 * static void replication_close(BlockDriverState *bs) 63 * { 64 * BDRVReplicationState *s = bs->opaque; 65 * replication_remove(s->rs); 66 * } 67 * 68 * BlockDriver bdrv_replication = { 69 * .format_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