| 
									
										
										
										
											2016-07-27 15:01:49 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * 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
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-11 10:36:01 +01:00
										 |  |  | #include "qapi/qapi-types-block-core.h"
 | 
					
						
							| 
									
										
										
										
											2019-05-23 16:35:07 +02:00
										 |  |  | #include "qemu/module.h"
 | 
					
						
							| 
									
										
										
										
											2016-07-27 15:01:49 +08:00
										 |  |  | #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 */
 |