--- 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