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