2016-07-27 09:01:49 +02: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"
|
2016-07-27 09:01:49 +02: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 */
|