 cb83d2efe1
			
		
	
	
		cb83d2efe1
		
	
	
	
	
		
			
			The protocol_name field is used when selecting a driver via protocol syntax (i.e. <protocol_name>:<filename:options:...>). Drivers that are only selected explicitly (e.g. driver=replication,mode=primary,...) should not have a protocol_name. This patch removes the protocol_name field from the brdv_replication structure so that attempts to invoke this driver using protocol syntax will fail gracefully: $ qemu-img info replication:foo qemu-img: Could not open 'replication:': Unknown protocol 'replication' Buglink: https://bugs.launchpad.net/qemu/+bug/1726733 Signed-off-by: Fabiano Rosas <farosas@linux.vnet.ibm.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
		
			
				
	
	
		
			175 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * 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
 | |
| 
 | |
| #include "qapi/qapi-types-block-core.h"
 | |
| #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 */
 |