|
@@ -0,0 +1,174 @@
|
|
|
+/*
|
|
|
+ * 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 "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",
|
|
|
+ * .protocol_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 */
|