---
Makefile.objs | 2 +-
block.c | 7 ++-
block.h | 1 +
block/repagent/repagent_drv.c | 197 +++++++++++++++++++++++++++++++++++++++++
blockdev.c | 6 ++
vl.c | 15 +++
6 files changed, 226 insertions(+), 2 deletions(-)
create mode 100644 block/repagent/repagent_drv.c
diff --git a/Makefile.objs b/Makefile.objs
index 86fad8a..36165ae 100755
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -31,7 +31,7 @@ block-obj-$(CONFIG_POSIX) += posix-aio-compat.o
block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
# Replication agent block driver - repagent
-repagent-nested-y = repagent_client.o repagent.o repcmd_listener.o
+repagent-nested-y = repagent_client.o repagent.o repcmd_listener.o repagent_drv.o
repagent-obj-y = $(addprefix block/repagent/, $(repagent-nested-y))
block-obj-y += $(repagent-obj-y)
diff --git a/block.c b/block.c
index 78756d8..6612af1 100644
--- a/block.c
+++ b/block.c
@@ -607,7 +607,8 @@ static int bdrv_open_common(BlockDriverState *bs, const char *filename,
* Clear flags that are internal to the block layer before opening the
* image.
*/
- open_flags = flags & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
+ open_flags = flags
+ & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING | BDRV_O_REPAGENT);
/*
* Snapshots should be writable.
@@ -689,6 +690,10 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
int ret;
char tmp_filename[PATH_MAX];
+ if (flags & BDRV_O_REPAGENT) {
+ drv = bdrv_find_format("repagent");
+ }
+
if (flags & BDRV_O_SNAPSHOT) {
BlockDriverState *bs1;
int64_t total_size;
diff --git a/block.h b/block.h
index 48d0bf3..d4a8257 100644
--- a/block.h
+++ b/block.h
@@ -71,6 +71,7 @@ typedef struct BlockDevOps {
#define BDRV_O_NO_BACKING 0x0100 /* don't open the backing file */
#define BDRV_O_NO_FLUSH 0x0200 /* disable flushing on this disk */
#define BDRV_O_COPY_ON_READ 0x0400 /* copy read backing sectors into image */
+#define BDRV_O_REPAGENT 0x0800 /* Use replication - temporary flag */
#define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH)
diff --git a/block/repagent/repagent_drv.c b/block/repagent/repagent_drv.c
new file mode 100644
index 0000000..49e110d
--- /dev/null
+++ b/block/repagent/repagent_drv.c
@@ -0,0 +1,197 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <stdint.h>
+
+#include "block.h"
+#include "rephub_defs.h"
+#include "block_int.h"
+#include "repagent_client.h"
+#include "repagent.h"
+#include "rephub_cmds.h"
+
+#define ZERO_MEM_OBJ(pObj) memset(pObj, 0, sizeof(*pObj))
+
+typedef struct BDRVRepagentState {
+} BDRVRepagentState;
+
+static int repagent_probe(const uint8_t *buf, int buf_size,
+ const char *filename)
+{
+ return 0;
+}
+
+
+static int repagent_open(BlockDriverState *bs, int flags)
+{
+ int ret;
+ /* BDRVRepagentState *s = bs->opaque */
+ bs->file = bdrv_new("repagent_file");
+ ret = bdrv_open(bs->file, bs->filename, flags, NULL);
+ if (ret < 0) {
+ printf("Error opening repagent inner file\n");
+ bdrv_delete(bs->file);
+ }
+
+ return ret;
+}
+
+static int repagent_set_key(BlockDriverState *bs, const char *key)
+{
+ return bs->file->drv->bdrv_set_key(bs->file, key);
+}
+
+static int coroutine_fn repagent_co_is_allocated(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors, int *pnum)
+{
+ return bs->file->drv->bdrv_co_is_allocated(bs->file, sector_num,
+ nb_sectors, pnum);
+}
+
+static coroutine_fn int repagent_co_readv(BlockDriverState *bs,
+ int64_t sector_num, int remaining_sectors, QEMUIOVector *qiov)
+{
+ return bs->file->drv->bdrv_co_readv(bs->file, sector_num,
+ remaining_sectors, qiov);
+}
+
+static coroutine_fn int repagent_co_writev(BlockDriverState *bs,
+ int64_t sector_num,
+ int remaining_sectors,
+ QEMUIOVector *qiov)
+{
+ return bs->file->drv->bdrv_co_writev(bs->file, sector_num,
+ remaining_sectors, qiov);
+}
+
+static void repagent_close(BlockDriverState *bs)
+{
+ return bs->file->drv->bdrv_close(bs->file);
+}
+
+static void repagent_invalidate_cache(BlockDriverState *bs)
+{
+ bs->file->drv->bdrv_invalidate_cache(bs->file);
+}
+
+static int repagent_change_backing_file(BlockDriverState *bs,
+ const char *backing_file, const char *backing_fmt) {
+ return bs->file->drv->bdrv_change_backing_file(bs->file, backing_file,
+ backing_fmt);
+}
+
+static int repagent_create(const char *filename, QEMUOptionParameter *options)
+{
+ /* return bs->file->drv->bdrv_create(const char *filename,
+ * QEMUOptionParameter *options);
+ orim - create?
+ */
+ return 0;
+}
+
+static int repagent_make_empty(BlockDriverState *bs)
+{
+ return bs->file->drv->bdrv_make_empty(bs->file);
+}
+
+static coroutine_fn int repagent_co_discard(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors)
+{
+ return bs->file->drv->bdrv_make_empty(bs->file);
+}
+
+static int repagent_truncate(BlockDriverState *bs, int64_t offset)
+{
+ return bs->file->drv->bdrv_truncate(bs->file, offset);
+}
+
+static int repagent_write_compressed(BlockDriverState *bs, int64_t sector_num,
+ const uint8_t *buf, int nb_sectors)
+{
+ return bs->file->drv->bdrv_write_compressed(bs->file, sector_num,
+ buf, nb_sectors);
+}
+
+static coroutine_fn int repagent_co_flush_to_os(BlockDriverState *bs)
+{
+ return bs->file->drv->bdrv_co_flush_to_os(bs->file);
+}
+
+static coroutine_fn int repagent_co_flush_to_disk(BlockDriverState *bs)
+{
+ return bs->file->drv->bdrv_co_flush_to_disk(bs->file);
+}
+
+static int repagent_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
+{
+ return bs->file->drv->bdrv_get_info(bs->file, bdi);
+}
+
+
+static int repagent_check(BlockDriverState *bs, BdrvCheckResult *result)
+{
+ return bs->file->drv->bdrv_check(bs->file, result);
+}
+
+static int repagent_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
+ int64_t pos, int size)
+{
+ return bs->file->drv->bdrv_save_vmstate(bs->file, buf, pos, size);
+}
+
+static int repagent_load_vmstate(BlockDriverState *bs, uint8_t *buf,
+ int64_t pos, int size)
+{
+ return bs->file->drv->bdrv_load_vmstate(bs->file, buf, pos, size);
+}
+
+
+static QEMUOptionParameter repagent_create_options[] = {
+ { NULL }
+};
+
+static BlockDriver bdrv_repagent = {
+ .format_name = "repagent",
+ .instance_size = sizeof(BDRVRepagentState),
+ .bdrv_probe = repagent_probe,
+ .bdrv_open = repagent_open,
+ .bdrv_close = repagent_close,
+ .bdrv_create = repagent_create,
+ .bdrv_co_is_allocated = repagent_co_is_allocated,
+ .bdrv_set_key = repagent_set_key,
+ .bdrv_make_empty = repagent_make_empty,
+
+ .bdrv_co_readv = repagent_co_readv,
+ .bdrv_co_writev = repagent_co_writev,
+ .bdrv_co_flush_to_os = repagent_co_flush_to_os,
+ .bdrv_co_flush_to_disk = repagent_co_flush_to_disk,
+
+ .bdrv_co_discard = repagent_co_discard,
+ .bdrv_truncate = repagent_truncate,
+ .bdrv_write_compressed = repagent_write_compressed,
+
+ .bdrv_snapshot_create = NULL,
+ .bdrv_snapshot_goto = NULL,
+ .bdrv_snapshot_delete = NULL,
+ .bdrv_snapshot_list = NULL,
+ .bdrv_snapshot_load_tmp = NULL,
+ .bdrv_get_info = repagent_get_info,
+
+ .bdrv_save_vmstate = repagent_save_vmstate,
+ .bdrv_load_vmstate = repagent_load_vmstate,
+
+ .bdrv_change_backing_file = repagent_change_backing_file,
+
+ .bdrv_invalidate_cache = repagent_invalidate_cache,
+
+ .create_options = repagent_create_options,
+ .bdrv_check = repagent_check,
+};
+
+static void bdrv_repagent_init(void)
+{
+ bdrv_register(&bdrv_repagent);
+}
+
+block_init(bdrv_repagent_init);
diff --git a/blockdev.c b/blockdev.c
index d78aa51..a75cee3 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -292,6 +292,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
DriveInfo *dinfo;
BlockIOLimit io_limits;
int snapshot = 0;
+ int repagent = 0;
bool copy_on_read;
int ret;
@@ -308,6 +309,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
secs = qemu_opt_get_number(opts, "secs", 0);
snapshot = qemu_opt_get_bool(opts, "snapshot", 0);
+ repagent = qemu_opt_get_bool(opts, "repagent", 0);
ro = qemu_opt_get_bool(opts, "readonly", 0);
copy_on_read = qemu_opt_get_bool(opts, "copy-on-read", false);
@@ -587,6 +589,10 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
bdrv_flags |= (BDRV_O_SNAPSHOT|BDRV_O_CACHE_WB|BDRV_O_NO_FLUSH);
}
+ if (repagent) {
+ bdrv_flags |= BDRV_O_REPAGENT;
+ }
+
if (copy_on_read) {
bdrv_flags |= BDRV_O_COPY_ON_READ;
}
diff --git a/vl.c b/vl.c
index 17cf6ce..7d381ea 100644
--- a/vl.c
+++ b/vl.c
@@ -775,6 +775,14 @@ static int drive_enable_snapshot(QemuOpts *opts, void *opaque)
return 0;
}
+static int drive_enable_repagent(QemuOpts *opts, void *opaque)
+{
+ if (NULL == qemu_opt_get(opts, "repagent")) {
+ qemu_opt_set(opts, "repagent", "on");
+ }
+ return 0;
+}
+
static void default_drive(int enable, int snapshot, int use_scsi,
BlockInterfaceType type, int index,
const char *optstr)
@@ -2287,6 +2295,7 @@ int main(int argc, char **argv, char **envp)
const char *trace_events = NULL;
const char *trace_file = NULL;
+ int enable_repagent = 0;
atexit(qemu_run_exit_notifiers);
error_set_progname(argv[0]);
@@ -2415,6 +2424,8 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_repagent:
#ifdef CONFIG_REPAGENT
repagent_init(optarg, 0);
+ enable_repagent = 1;
+
#else
fprintf(stderr, "Repagent support is disabled. "
"Don't use -repagent option.\n");
@@ -3400,6 +3411,10 @@ int main(int argc, char **argv, char **envp)
blk_mig_init();
/* open the virtual block devices */
+ if (enable_repagent) {
+ qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_repagent,
+ NULL, 0);
+ }
if (snapshot)
qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot, NULL, 0);
if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func, &machine->use_scsi, 1) != 0)
--
1.7.6.5