From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:57813) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SFldv-0004uv-4C for qemu-devel@nongnu.org; Thu, 05 Apr 2012 08:18:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SFldj-0002ff-JP for qemu-devel@nongnu.org; Thu, 05 Apr 2012 08:18:18 -0400 Received: from mail-qc0-f173.google.com ([209.85.216.173]:40254) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SFldj-0002f6-Di for qemu-devel@nongnu.org; Thu, 05 Apr 2012 08:18:11 -0400 Received: by qcsc20 with SMTP id c20so791325qcs.4 for ; Thu, 05 Apr 2012 05:18:04 -0700 (PDT) From: Ori Mamluk MIME-Version: 1.0 Date: Thu, 5 Apr 2012 15:17:54 +0300 Message-ID: <1aa50d55ff34d06fd6eb52194ade5e5c@mail.gmail.com> Content-Type: multipart/alternative; boundary=00248c71179526116604bced88c2 Subject: [Qemu-devel] [RFC PATCH v3 4/9] repagent: started writing repagent as a bdrv. Finished driver empty template. List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , Roni Luxenberg , Stefan Hajnoczi , dlaor@redhat.com, Anthony Liguori , Oded Kedem , Yair Kuszpet , Paolo Bonzini --00248c71179526116604bced88c2 Content-Type: text/plain; charset=ISO-8859-1 --- 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 +#include +#include +#include +#include + +#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 --00248c71179526116604bced88c2 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable

=A0

---

Makefile.objs=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0 |=A0=A0=A0 2 +-

block.c=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 = |=A0=A0=A0 7 ++-

block.h=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 |=A0=A0=A0 1 +

block/repagent/repagent_drv.c |=A0 197 ++++++++++++++++++++++++++= +++++++++++++++

blockdev.c=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =A0=A0|=A0= =A0=A0 6 ++

vl.c=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 |=A0=A0 15 +++

6 files changed, 226 insertions(+), 2 deletions(-)

create mode 100644 block/repagent/repagent_drv.c

=A0

diff --git a/Makefile.= objs b/Makefile.objs

index 86fad8a..36165ae 10075= 5

--- a/Makefile.objs

+= ++ b/Makefile.objs

@@ -31,7 +31,7 @@ block-obj-$(CONFIG_POSIX) +=3D pos= ix-aio-compat.o

block-obj-$(CONFIG_LINUX_AIO) += =3D linux-aio.o

=A0# = Replication agent block driver - repagent

-repagent-nested-y =3D repagent_client.o=A0 repagent= .o=A0 repcmd_listener.o

+repagent-nested-y =3D re= pagent_client.o=A0 repagent.o=A0 repcmd_listener.o repagent_drv.o

repagent-obj-y =3D $(addprefix block/repagent/, $(repagent-nested-y))

<= p class=3D"MsoNormal"> block-obj-y +=3D $(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 *filenam= e,

=A0=A0=A0=A0=A0 * Clear flags that are internal to t= he block layer before opening the

=A0=A0=A0=A0=A0= * image.

=A0=A0=A0=A0=A0 */

-=A0=A0=A0 open_flags =3D flags & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_B= ACKING);

+=A0=A0=A0 open_flags =3D flags

+=A0=A0=A0=A0=A0=A0=A0=A0 & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING= | BDRV_O_REPAGENT);

= =A0=A0=A0=A0=A0/*

=A0=A0=A0=A0=A0 * Snapshots should be writable.

@= @ -689,6 +690,10 @@ int bdrv_open(BlockDriverState *bs, const char *filenam= e, int flags,

=A0=A0=A0=A0 int ret;

=A0=A0=A0=A0 char tmp_filename[PATH_MAX];

+=A0=A0=A0 if (flags &am= p; BDRV_O_REPAGENT) {

+=A0=A0=A0=A0=A0=A0=A0 drv = =3D bdrv_find_format("repagent");

+=A0= =A0=A0 }

+

=A0=A0=A0=A0 if (flags & BDRV_O_SNAPSHOT) {=

=A0=A0=A0=A0=A0=A0=A0=A0 BlockDriverState *bs1;<= /p>

=A0=A0=A0=A0=A0=A0=A0=A0 int64_t total_size;

<= p class=3D"MsoNormal">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=A0 0x0100 /* don't open the backing file */<= /p>

#define BDRV_O_NO_FLUSH=A0=A0=A0 0x0200 /* disab= le flushing on this disk */

#define BDRV_O_COPY_= ON_READ 0x0400 /* copy read backing sectors into image */

+#define BDRV_O_REPAGENT=A0=A0=A0 0x0800 /* Use repl= ication - temporary flag */

=A0#define BDRV_O_CACHE_MASK=A0 (BDRV_O_NOCACHE | BDRV_O_CACHE_WB | = BDRV_O_NO_FLUSH)

diff --git a/block/repag= ent/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 @@

+#in= clude <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"

+#inc= lude "repagent_client.h"

+#include &quo= t;repagent.h"

+#include "rephub_cmds.h"

+

+#define ZERO_MEM_OBJ(pObj) memset(pO= bj, 0, sizeof(*pObj))

+

+typedef struct BDRVRepagentState {

+} BDRVRepagentState;

+

+static int repagent_probe(const uint8_t *buf, int = buf_size,

+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0 const char *filename)

+{

+=A0=A0=A0 return 0;

+}

+

+

+static int repagent_open(BlockDriverStat= e *bs, int flags)

+{

+=A0=A0=A0 int ret;

=

+=A0=A0=A0 /* BDRVRepagentState *s =3D bs->opaque= */

+=A0=A0=A0 bs->file =3D bdrv_new("rep= agent_file");

+=A0=A0=A0 ret =3D bdrv_open(bs->file, bs->filename, flags, NULL);

+=A0=A0=A0 if (ret < 0) {

+=A0=A0=A0=A0=A0=A0=A0 printf("Error opening repagent inner file\n= ");

+=A0=A0=A0=A0=A0=A0=A0 bdrv_delete(bs->file);

= +=A0=A0=A0 }

+

+=A0=A0= =A0 return ret;

+}

+

+static int repagent_set_key(BlockDriverState *bs, = const char *key)

+{

+=A0=A0=A0 return bs-&g= t;file->drv->bdrv_set_key(bs->file, key);

+}

+

+static int coro= utine_fn repagent_co_is_allocated(BlockDriverState *bs,

+=A0=A0=A0=A0=A0=A0=A0 int64_t sector_num, int nb_se= ctors, int *pnum)

+{

+= =A0=A0=A0 return bs->file->drv->bdrv_co_is_allocated(bs->file, = sector_num,

+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 nb_sectors, pnum);

+}

+

+= static coroutine_fn int repagent_co_readv(BlockDriverState *bs,

+=A0=A0=A0=A0=A0=A0=A0=A0=A0 int64_t sector_num, int remaini= ng_sectors, QEMUIOVector *qiov)

+{

+=A0=A0=A0 return bs-&g= t;file->drv->bdrv_co_readv(bs->file, sector_num,

+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 remaini= ng_sectors, qiov);

+}

+

+static coroutine_fn int= repagent_co_writev(BlockDriverState *bs,

+=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =A0=A0=A0=A0=A0=A0=A0=A0=A0in= t64_t sector_num,

+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 int remaining_sectors,

+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0 QEMUIOVector *qiov)

+= {

+=A0=A0=A0 return bs->file->drv->bdrv_= co_writev(bs->file, sector_num,

+=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0 remaining_sectors, qiov);

+}

+

+static void repagent_close(BlockDriverState *bs)

+{

+=A0=A0=A0 return bs->file->drv-&g= t;bdrv_close(bs->file);

+}

+

+static void repagent_invalidate_cache(BlockDriverState *bs)

+{

+=A0=A0=A0 bs->file->dr= v->bdrv_invalidate_cache(bs->file);

+}

+

+static int repagent_change_backing_file(BlockDriverState *bs,

+=A0=A0=A0=A0=A0=A0=A0 const char *backing_file, const c= har *backing_fmt) {

+=A0=A0=A0 return bs->file->drv->bdrv_chang= e_backing_file(bs->file, backing_file,

+=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0 backing_fmt);

+}

<= p class=3D"MsoNormal">+

+static int repagent_create(const char *filename, QEMUOptionParameter *opti= ons)

+{

+=A0=A0=A0 /*= =A0=A0=A0 return bs->file->drv->bdrv_create(const char *filename,<= /p>

+=A0=A0=A0=A0 * QEMUOptionParameter *options);

+= =A0=A0=A0=A0 orim - create?

+=A0=A0=A0=A0 */

<= p class=3D"MsoNormal">+=A0=A0=A0 return 0;

+}

=

+

+static int repagent_make_empty(BlockDriverState *bs)

+{

+=A0=A0=A0 return bs->file->drv->= ;bdrv_make_empty(bs->file);

+}

+

+static coroutine_fn int repagent_co_discard(Bl= ockDriverState *bs,

+=A0=A0=A0 int64_t sector_num= , int nb_sectors)

+{

+= =A0=A0=A0 return bs->file->drv->bdrv_make_empty(bs->file);

+}

+

+static int repagent_truncate(BlockDriverState *bs, int64_t offset)

+{

+=A0=A0=A0 return bs-&= gt;file->drv->bdrv_truncate(bs->file, offset);

+}

+

+static int repagent_write_compressed(BlockDriverState *bs, int64_t se= ctor_num,

+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 const uint8= _t *buf, int nb_sectors)

+{

+=A0=A0=A0 return bs-&g= t;file->drv->bdrv_write_compressed(bs->file, sector_num,

+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= buf, nb_sectors);

+}

+

+static coroutine_fn int= repagent_co_flush_to_os(BlockDriverState *bs)

+{=

+=A0=A0=A0 return bs->file->drv->bdrv_c= o_flush_to_os(bs->file);

+}

+

+static coroutine_fn int repagent_co_flush_to_disk(BlockDriverState *b= s)

+{

+=A0=A0=A0 return= bs->file->drv->bdrv_co_flush_to_disk(bs->file);

+}

+

+static int repagent_get_info(BlockDriverState *bs, BlockDriverInfo *b= di)

+{

+=A0=A0=A0 retur= n bs->file->drv->bdrv_get_info(bs->file, bdi);

+}

+

+

+static int repagent_check(BlockDriverStat= e *bs, BdrvCheckResult *result)

+{

+=A0=A0=A0 return bs->file->drv->bdrv_check(bs->file, result);<= /p>

+}

+

+static int repagent_save_vmstate(BlockDriverState *bs, const uint8= _t *buf,

+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 int64_t pos, int size)

+{

+=A0=A0=A0 return bs->file->d= rv->bdrv_save_vmstate(bs->file, buf, pos, size);

+}

+

+static int repage= nt_load_vmstate(BlockDriverState *bs, uint8_t *buf,

+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0 =A0=A0int64_t pos, int size)

+{

+=A0=A0=A0 return bs->file->drv->bdrv= _load_vmstate(bs->file, buf, pos, size);

+}

+

+

+static QEMUOptionParameter repagent_create_options[] =3D {

+=A0=A0=A0 { NULL }

+};

+

+static BlockDriver bdr= v_repagent =3D {

+=A0=A0=A0 .format_name=A0=A0=A0= =A0=A0=A0=A0 =3D "repagent",

+=A0=A0=A0 .instance_size=A0=A0=A0=A0=A0 =3D sizeof(= BDRVRepagentState),

+=A0=A0=A0 .bdrv_probe=A0=A0= =A0=A0=A0=A0=A0=A0 =3D repagent_probe,

+=A0=A0=A0= .bdrv_open=A0=A0=A0=A0=A0=A0=A0=A0=A0 =3D repagent_open,

+=A0=A0=A0 .bdrv_close=A0=A0=A0=A0=A0=A0=A0=A0 =3D repagent_close,

+=A0=A0=A0 .bdrv_create=A0=A0=A0=A0=A0=A0=A0 =3D repagent= _create,

+=A0=A0=A0 .bdrv_co_is_allocated =3D rep= agent_co_is_allocated,

+=A0=A0=A0 .bdrv_set_key= =A0=A0=A0=A0=A0=A0 =3D repagent_set_key,

+=A0=A0=A0 .bdrv_make_empty=A0=A0=A0 =3D repagent_ma= ke_empty,

+

+=A0=A0=A0 = .bdrv_co_readv=A0=A0=A0=A0=A0=A0=A0=A0=A0 =3D repagent_co_readv,

+=A0=A0=A0 .bdrv_co_writev=A0=A0=A0=A0=A0=A0=A0=A0 =3D repa= gent_co_writev,

+=A0=A0=A0 .bdrv_co_flush_to_os=A0=A0=A0 =3D repagen= t_co_flush_to_os,

+=A0=A0=A0 .bdrv_co_flush_to_di= sk=A0 =3D repagent_co_flush_to_disk,

+

+=A0=A0=A0 .bdrv_co_discard=A0=A0=A0=A0=A0=A0=A0 =3D repage= nt_co_discard,

+=A0=A0=A0 .bdrv_truncate=A0=A0=A0=A0=A0=A0=A0=A0=A0= =3D repagent_truncate,

+=A0=A0=A0 .bdrv_write_co= mpressed=A0 =3D repagent_write_compressed,

+

<= p class=3D"MsoNormal">+=A0=A0=A0 .bdrv_snapshot_create=A0=A0 =3D NULL,

+=A0=A0=A0 .bdrv_snapshot_goto=A0=A0=A0=A0 =3D NULL,=

+=A0=A0=A0 .bdrv_snapshot_delete=A0=A0 =3D NULL,=

+=A0=A0=A0 .bdrv_snapshot_list=A0=A0=A0=A0 =3D N= ULL,

+=A0=A0=A0 .bdrv_snapshot_load_tmp=A0=A0=A0= =A0 =3D NULL,

+=A0=A0=A0 .bdrv_get_info=A0=A0=A0=A0=A0 =3D repagen= t_get_info,

+

+=A0=A0= =A0 .bdrv_save_vmstate=A0=A0=A0 =3D repagent_save_vmstate,

+=A0=A0=A0 .bdrv_load_vmstate=A0=A0=A0 =3D repagent_load_vmstate,=

+

+=A0=A0=A0 .bdrv_change_= backing_file=A0=A0 =3D repagent_change_backing_file,

+

+=A0=A0=A0 .bdrv_invalidate_cache=A0=A0=A0= =A0=A0 =3D repagent_invalidate_cache,

+

+=A0=A0=A0 .create_optio= ns =3D repagent_create_options,

+=A0=A0=A0 .bdrv_= check =3D repagent_check,

+};

+

+static void bdrv_repagent_init(void)

+{

+=A0=A0=A0 bdrv_register(&bdrv_repagent);

+}

+

+bl= ock_init(bdrv_repagent_init);

diff --git a/blockdev.c b/blockdev.c

index d78aa51..a75cee3 100644

--- a/bl= ockdev.c

+++ b/blockdev.c

@@ -292,6 +292,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to= _scsi)

=A0=A0=A0=A0 DriveInfo *dinfo;

=A0=A0=A0=A0 BlockIOLimit io_limits;

=A0=A0= =A0=A0 int snapshot =3D 0;

+=A0=A0=A0 int repagen= t =3D 0;

=A0=A0=A0=A0 bool copy_on_read;

=A0=A0=A0=A0 int ret;

@@ -308,6 +309,7 @@ DriveInfo *drive_init(QemuOpts = *opts, int default_to_scsi)

=A0=A0=A0=A0 secs=A0 = =3D qemu_opt_get_number(opts, "secs", 0);

=A0=A0=A0=A0=A0snapshot = =3D qemu_opt_get_bool(opts, "snapshot", 0);

+=A0=A0=A0 repagent =3D qemu_opt_get_bool(opts, "repagent", = 0);

=A0=A0=A0=A0 ro =3D qemu_opt_get_bool(opts, "readonly", 0);

=A0=A0=A0=A0 copy_on_read =3D qemu_opt_get_bool(opts, = "copy-on-read", false);

@@ -587,6 +589,10 @@ DriveInfo *drive_init(QemuOpts *opts, i= nt default_to_scsi)

=A0=A0=A0=A0=A0=A0=A0=A0 bdrv_flags |=3D (BDRV_O_SNA= PSHOT|BDRV_O_CACHE_WB|BDRV_O_NO_FLUSH);

=A0=A0=A0= =A0 }

+=A0=A0=A0 if (= repagent) {

+=A0=A0=A0=A0=A0=A0=A0 bdrv_flags |=3D BDRV_O_REPAGENT;

+=A0=A0=A0 }

+

= =A0=A0=A0=A0 if (copy_on_read) {

=A0=A0=A0=A0=A0= =A0=A0=A0 bdrv_flags |=3D BDRV_O_COPY_ON_READ;

=A0=A0=A0=A0 }

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 *op= aque)

=A0=A0=A0=A0 return 0;

}<= /p>

+static int drive_ena= ble_repagent(QemuOpts *opts, void *opaque)

+{

=

+=A0=A0=A0 if (NULL =3D=3D qemu_opt_get(opts, "repagent")) {

<= p class=3D"MsoNormal">+=A0=A0=A0=A0=A0=A0=A0 qemu_opt_set(opts, "repag= ent", "on");

+=A0=A0=A0 }

+=A0=A0=A0 return 0;

+}

+

static void default_drive(int enable, int snapshot, int use_scsi,

=

=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0 BlockInterfaceType type, int index,

=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0 const char *optstr)

@= @ -2287,6 +2295,7 @@ int main(int argc, char **argv, char **envp)

=A0=A0=A0=A0 const char *trace_events =3D NULL;

=A0=A0=A0=A0 const char *trace_file =3D NULL;

+=A0=A0=A0 int enable_repag= ent =3D 0;

=A0=A0=A0=A0 atexit(qemu_run_exit_noti= fiers);

=A0=A0=A0=A0 error_set_progname(argv[0]);

@@ -2415,6 +2424,8 @@ int main(int argc, char **argv, = char **envp)

=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= case QEMU_OPTION_repagent:

#ifdef CONFIG_REPAGENT

=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0 repagent_init(optarg, 0);

+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 enable_repagent =3D 1;

=

+

#else

=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 fprintf(stderr, "Repa= gent support is disabled. "

=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 "Don't use -repagent= option.\n");

@@ -3400,6 +3411,10 @@ int mai= n(int argc, char **argv, char **envp)

=A0=A0=A0=A0 blk_mig_init();

=A0=A0=A0=A0=A0/* open the virtual block dev= ices */

+=A0=A0=A0 if (enable_repagent) {

+=A0=A0=A0=A0=A0=A0=A0 qemu_opts_foreach(qemu_find_opts(= "drive"), drive_enable_repagent,

+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 NULL, 0);

+=A0=A0=A0 }

=A0=A0=A0=A0 if (= snapshot)

=A0=A0=A0=A0=A0=A0=A0=A0 qemu_opts_fore= ach(qemu_find_opts("drive"), drive_enable_snapshot, NULL, 0);

=A0=A0=A0=A0 if (qemu_opts_foreach(qemu_find_opts(&q= uot;drive"), drive_init_func, &machine->use_scsi, 1) !=3D 0)

--

1.7.6.5

--00248c71179526116604bced88c2--