From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:57844) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SFle6-00050v-9L for qemu-devel@nongnu.org; Thu, 05 Apr 2012 08:18:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SFldp-0002gA-Qd for qemu-devel@nongnu.org; Thu, 05 Apr 2012 08:18:30 -0400 Received: from mail-qc0-f173.google.com ([209.85.216.173]:60323) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SFldp-0002fJ-IJ for qemu-devel@nongnu.org; Thu, 05 Apr 2012 08:18:17 -0400 Received: by qcsc20 with SMTP id c20so791342qcs.4 for ; Thu, 05 Apr 2012 05:18:06 -0700 (PDT) From: Ori Mamluk MIME-Version: 1.0 Date: Thu, 5 Apr 2012 15:17:57 +0300 Message-ID: <9509408278c87462255946a21ac377f0@mail.gmail.com> Content-Type: multipart/alternative; boundary=20cf306f779e4a32c004bced8851 Subject: [Qemu-devel] [RFC PATCH v3 5/9] repagent: Changed repagent to be a block driver 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 --20cf306f779e4a32c004bced8851 Content-Type: text/plain; charset=ISO-8859-1 Driver functions are in repagent_drv.c, it is basd on raw.c Qemu runs and is able to boot --- block.c | 33 +++++-- block.h | 1 - block/repagent/repagent.c | 53 ++++++++---- block/repagent/repagent.h | 6 ++ block/repagent/repagent_drv.c | 198 ++++++++++++++++++---------------------- block/repagent/rephub_cmds.h | 2 +- blockdev.c | 7 +-- vl.c | 17 +--- 8 files changed, 160 insertions(+), 157 deletions(-) diff --git a/block.c b/block.c index 6612af1..8e11c03 100644 --- a/block.c +++ b/block.c @@ -57,6 +57,7 @@ typedef enum { BDRV_REQ_ZERO_WRITE = 0x2, } BdrvRequestFlags; + static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load); static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, @@ -104,6 +105,9 @@ static BlockDriverState *bs_snapshots; /* If non-zero, use only whitelisted block drivers */ static int use_bdrv_whitelist; +/* orim temporary */ +int use_repagent; + #ifdef _WIN32 static int is_windows_drive_prefix(const char *filename) { @@ -607,8 +611,7 @@ 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 | BDRV_O_REPAGENT); + open_flags = flags & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); /* * Snapshots should be writable. @@ -690,8 +693,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 (use_repagent && bs->device_name[0] != '\0' && strcmp( + bs->device_name, "pflash0") != 0) { + BlockDriver *bdrv_repagent = bdrv_find_format("repagent"); + drv = bdrv_repagent; } if (flags & BDRV_O_SNAPSHOT) { @@ -759,7 +764,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags, } #ifdef CONFIG_REPAGENT - repagent_register_drive(filename, bs); +/* repagent_register_drive(filename, bs); */ #endif /* Open the image */ ret = bdrv_open_common(bs, filename, flags, drv); @@ -1481,6 +1486,13 @@ static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, qemu_aio_wait(); } } + /* orim todo remove */ + printf("IO done. is_write %d sec %lld size %d ", is_write, + (long long int) sector_num, nb_sectors); + if (bs->drv != NULL) { + printf("Drv %s, ", bs->drv->format_name); + } + printf("file %s, ret %d\n", bs->filename, rwco.ret); return rwco.ret; } @@ -1861,8 +1873,9 @@ static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs, Currently we know that by checking device_name - only highest level (closest to the guest) has that name. */ - repagent_handle_protected_write(bs, sector_num, +/* repagent_handle_protected_write(bs, sector_num, nb_sectors, qiov, ret); +*/ } #endif if (bs->dirty_bitmap) { @@ -1942,16 +1955,20 @@ int64_t bdrv_get_allocated_file_size(BlockDriverState *bs) */ int64_t bdrv_getlength(BlockDriverState *bs) { + int64_t ret = 0; BlockDriver *drv = bs->drv; if (!drv) return -ENOMEDIUM; + ret = bs->total_sectors * BDRV_SECTOR_SIZE; if (bs->growable || bdrv_dev_has_removable_media(bs)) { if (drv->bdrv_getlength) { - return drv->bdrv_getlength(bs); + ret = drv->bdrv_getlength(bs); } } - return bs->total_sectors * BDRV_SECTOR_SIZE; + /* orim todo remove */ + printf("bdrv_getlength returned %d", (int)ret); + return ret; } /* return 0 as number of sectors if no device present or error */ diff --git a/block.h b/block.h index d4a8257..48d0bf3 100644 --- a/block.h +++ b/block.h @@ -71,7 +71,6 @@ 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.c b/block/repagent/repagent.c index c291915..c3dd593 100644 --- a/block/repagent/repagent.c +++ b/block/repagent/repagent.c @@ -34,6 +34,8 @@ typedef struct RepagentReadVolIo { struct timeval start_time; } RepagentReadVolIo; +static int repagent_get_volume_by_driver( + BlockDriverState *bs); static int repagent_get_volume_by_name(const char *name); static void repagent_report_volumes_to_hub(void); static void repagent_vol_read_done(void *opaque, int ret); @@ -67,18 +69,16 @@ void repagent_init(const char *hubname, int port) void repagent_register_drive(const char *drive_path, BlockDriverState *driver_ptr) { - int i; - for (i = 0; i < g_rep_agent.num_volumes ; i++) { - RepagentVolume *vol = g_rep_agent.volumes[i]; - if (vol != NULL) { - assert( - strcmp(drive_path, vol->vol_path) != 0 - && driver_ptr != vol->driver_ptr); - } - } + /* Assert that the volume is not registered yet */ + int i = repagent_get_volume_by_name(drive_path); + assert(i == -1); + /*Add the volume at the last place*/ assert(g_rep_agent.num_volumes < REPAGENT_MAX_NUM_VOLUMES); + i = g_rep_agent.num_volumes; + g_rep_agent.num_volumes++; + printf("zerto repagent: Registering drive. Num drives %d, path %s\n", g_rep_agent.num_volumes, drive_path); g_rep_agent.volumes[i] = @@ -93,9 +93,25 @@ void repagent_register_drive(const char *drive_path, repagent_report_volumes_to_hub(); } +void repagent_deregister_drive(const char *drive_path, + BlockDriverState *driver_ptr) +{ + /* Orim todo thread-safety? */ + int i = repagent_get_volume_by_driver(driver_ptr); + assert(i != -1); + + RepagentVolume *vol = g_rep_agent.volumes[i]; + /* Put the last volume in the cell of the removed volume to maintain a + * contiguous array */ + g_rep_agent.volumes[i] = g_rep_agent.volumes[g_rep_agent.num_volumes - 1]; + g_rep_agent.volumes[g_rep_agent.num_volumes - 1] = NULL; + g_rep_agent.num_volumes--; + g_free(vol); + +} /* orim todo destruction? */ -static RepagentVolume *repagent_get_protected_volume_by_driver( +static int repagent_get_volume_by_driver( BlockDriverState *bs) { /* orim todo optimize search */ @@ -103,10 +119,10 @@ static RepagentVolume *repagent_get_protected_volume_by_driver( for (i = 0; i < g_rep_agent.num_volumes ; i++) { RepagentVolume *p_vol = g_rep_agent.volumes[i]; if (p_vol != NULL && p_vol->driver_ptr == (void *) bs) { - return p_vol; + return i; } } - return NULL; + return -1; } void repagent_handle_protected_write(BlockDriverState *bs, int64_t sector_num, @@ -120,13 +136,16 @@ void repagent_handle_protected_write(BlockDriverState *bs, int64_t sector_num, printf("\n"); - RepagentVolume *p_vol = repagent_get_protected_volume_by_driver(bs); - if (p_vol == NULL || p_vol->vol_id == REPAGENT_VOLUME_ID_NONE) { + /* orim todo thread safety? */ + int i = repagent_get_volume_by_driver(bs); + if (i == -1 || g_rep_agent.volumes[i]->vol_id == REPAGENT_VOLUME_ID_NONE) { /* Unprotected */ printf("Got a write to an unprotected volume.\n"); return; } + RepagentVolume *p_vol = g_rep_agent.volumes[i]; + /* Report IO to rephub */ int data_size = qiov->size; @@ -234,7 +253,7 @@ int repaget_read_vol(RepCmdReadVolReq *pcmd, uint8_t *pdata) REPHUB_CMD_READ_VOL_RES, 0, NULL); p_res_cmd->req_id = pcmd->req_id; p_res_cmd->volume_id = pcmd->volume_id; - p_res_cmd->is_status_success = FALSE; + p_res_cmd->io_status = -1; repagent_client_send((RepCmd *) p_res_cmd); return TRUE; } @@ -280,7 +299,7 @@ static void repagent_vol_read_done(void *opaque, int ret) &pdata); pcmd->req_id = read_xact->rep_cmd.req_id; pcmd->volume_id = read_xact->rep_cmd.volume_id; - pcmd->is_status_success = FALSE; + pcmd->io_status = -1; printf("Protected vol read - volId %llu, offset %llu, size %u\n", (unsigned long long int) read_xact->rep_cmd.volume_id, @@ -294,7 +313,7 @@ static void repagent_vol_read_done(void *opaque, int ret) printf("Read prot vol done. Took %u seconds, %u us.", (uint32_t) t2.tv_sec, (uint32_t) t2.tv_usec); - pcmd->is_status_success = TRUE; + pcmd->io_status = 0; /* Success */ /* orim todo optimize - don't copy, use the qiov buffer */ qemu_iovec_to_buffer(&read_xact->qiov, pdata); } else { diff --git a/block/repagent/repagent.h b/block/repagent/repagent.h index 98ccbf2..310db0f 100644 --- a/block/repagent/repagent.h +++ b/block/repagent/repagent.h @@ -32,11 +32,17 @@ typedef struct RepCmdStartProtect RepCmdStartProtect; typedef struct RepCmdDataStartProtect RepCmdDataStartProtect; struct RepCmdReadVolReq; +/* orim temporary */ +extern int use_repagent; + + void repagent_init(const char *hubname, int port); void repagent_handle_protected_write(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, int ret_status); void repagent_register_drive(const char *drive_path, BlockDriverState *driver_ptr); +void repagent_deregister_drive(const char *drive_path, + BlockDriverState *driver_ptr); int repaget_start_protect(RepCmdStartProtect *pcmd, RepCmdDataStartProtect *pcmd_data); int repaget_read_vol(struct RepCmdReadVolReq *pcmd, uint8_t *pdata); diff --git a/block/repagent/repagent_drv.c b/block/repagent/repagent_drv.c index 49e110d..8c9f2b6 100644 --- a/block/repagent/repagent_drv.c +++ b/block/repagent/repagent_drv.c @@ -1,7 +1,6 @@ #include #include #include -#include #include #include "block.h" @@ -10,183 +9,164 @@ #include "repagent_client.h" #include "repagent.h" #include "rephub_cmds.h" +#include "module.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); + repagent_register_drive(bs->filename, bs); + printf("%s\n", __func__); + bs->sg = bs->file->sg; + return 0; } -static coroutine_fn int repagent_co_readv(BlockDriverState *bs, - int64_t sector_num, int remaining_sectors, QEMUIOVector *qiov) +static int coroutine_fn repagent_co_readv(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) { - return bs->file->drv->bdrv_co_readv(bs->file, sector_num, - remaining_sectors, qiov); + printf("%s\n", __func__); + return bdrv_co_readv(bs->file, sector_num, nb_sectors, qiov); } -static coroutine_fn int repagent_co_writev(BlockDriverState *bs, - int64_t sector_num, - int remaining_sectors, - QEMUIOVector *qiov) +static int coroutine_fn repagent_co_writev(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) { - return bs->file->drv->bdrv_co_writev(bs->file, sector_num, - remaining_sectors, qiov); + printf("%s\n", __func__); + int ret = 0; + repagent_handle_protected_write(bs, sector_num, + nb_sectors, qiov, ret); + printf("Before write off %lld, size %d\n", (long long int) sector_num, + nb_sectors); + ret = bdrv_co_writev(bs->file, sector_num, nb_sectors, qiov); + printf("After write ret %d\n", ret); + return ret; } static void repagent_close(BlockDriverState *bs) { - return bs->file->drv->bdrv_close(bs->file); + printf("%s\n", __func__); } -static void repagent_invalidate_cache(BlockDriverState *bs) +static int coroutine_fn repagent_co_flush(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); + printf("%s\n", __func__); + return bdrv_co_flush(bs->file); } -static int repagent_create(const char *filename, QEMUOptionParameter *options) +static int64_t repagent_getlength(BlockDriverState *bs) { - /* return bs->file->drv->bdrv_create(const char *filename, - * QEMUOptionParameter *options); - orim - create? - */ - return 0; + printf("%s\n", __func__); + return bdrv_getlength(bs->file); } -static int repagent_make_empty(BlockDriverState *bs) +static int repagent_truncate(BlockDriverState *bs, int64_t offset) { - return bs->file->drv->bdrv_make_empty(bs->file); + printf("%s\n", __func__); + return bdrv_truncate(bs->file, offset); } -static coroutine_fn int repagent_co_discard(BlockDriverState *bs, - int64_t sector_num, int nb_sectors) +static int repagent_probe(const uint8_t *buf, int buf_size, + const char *filename) { - return bs->file->drv->bdrv_make_empty(bs->file); + printf("%s\n", __func__); + return 1; /* everything can be opened as raw image */ } -static int repagent_truncate(BlockDriverState *bs, int64_t offset) +static int coroutine_fn repagent_co_discard(BlockDriverState *bs, + int64_t sector_num, int nb_sectors) { - return bs->file->drv->bdrv_truncate(bs->file, offset); + return bdrv_co_discard(bs->file, sector_num, nb_sectors); } -static int repagent_write_compressed(BlockDriverState *bs, int64_t sector_num, - const uint8_t *buf, int nb_sectors) +static int repagent_is_inserted(BlockDriverState *bs) { - return bs->file->drv->bdrv_write_compressed(bs->file, sector_num, - buf, nb_sectors); + printf("%s\n", __func__); + return bdrv_is_inserted(bs->file); } -static coroutine_fn int repagent_co_flush_to_os(BlockDriverState *bs) +static int repagent_media_changed(BlockDriverState *bs) { - return bs->file->drv->bdrv_co_flush_to_os(bs->file); + printf("%s\n", __func__); + return bdrv_media_changed(bs->file); } -static coroutine_fn int repagent_co_flush_to_disk(BlockDriverState *bs) +static void repagent_eject(BlockDriverState *bs, bool eject_flag) { - return bs->file->drv->bdrv_co_flush_to_disk(bs->file); + printf("%s\n", __func__); + bdrv_eject(bs->file, eject_flag); } -static int repagent_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) +static void repagent_lock_medium(BlockDriverState *bs, bool locked) { - return bs->file->drv->bdrv_get_info(bs->file, bdi); + printf("%s\n", __func__); + bdrv_lock_medium(bs->file, locked); } - -static int repagent_check(BlockDriverState *bs, BdrvCheckResult *result) +static int repagent_ioctl(BlockDriverState *bs, unsigned long int req, + void *buf) { - return bs->file->drv->bdrv_check(bs->file, result); + printf("%s\n", __func__); + return bdrv_ioctl(bs->file, req, buf); } -static int repagent_save_vmstate(BlockDriverState *bs, const uint8_t *buf, - int64_t pos, int size) +static BlockDriverAIOCB *repagent_aio_ioctl(BlockDriverState *bs, + unsigned long int req, void *buf, + BlockDriverCompletionFunc *cb, void *opaque) { - return bs->file->drv->bdrv_save_vmstate(bs->file, buf, pos, size); + printf("%s\n", __func__); + return bdrv_aio_ioctl(bs->file, req, buf, cb, opaque); } -static int repagent_load_vmstate(BlockDriverState *bs, uint8_t *buf, - int64_t pos, int size) +static int repagent_create(const char *filename, QEMUOptionParameter *options) { - return bs->file->drv->bdrv_load_vmstate(bs->file, buf, pos, size); + printf("%s\n", __func__); + return bdrv_create_file(filename, options); } - static QEMUOptionParameter repagent_create_options[] = { + { + .name = BLOCK_OPT_SIZE, + .type = OPT_SIZE, + .help = "Virtual disk size" + }, { NULL } }; +static int repagent_has_zero_init(BlockDriverState *bs) +{ + printf("%s\n", __func__); + return bdrv_has_zero_init(bs->file); +} + static BlockDriver bdrv_repagent = { .format_name = "repagent", - .instance_size = sizeof(BDRVRepagentState), - .bdrv_probe = repagent_probe, + + /* It's really 0, but we need to make g_malloc() happy */ + .instance_size = 1, + .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_flush_to_disk = repagent_co_flush, .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_probe = repagent_probe, + .bdrv_getlength = repagent_getlength, + .bdrv_truncate = repagent_truncate, - .bdrv_change_backing_file = repagent_change_backing_file, + .bdrv_is_inserted = repagent_is_inserted, + .bdrv_media_changed = repagent_media_changed, + .bdrv_eject = repagent_eject, + .bdrv_lock_medium = repagent_lock_medium, - .bdrv_invalidate_cache = repagent_invalidate_cache, + .bdrv_ioctl = repagent_ioctl, + .bdrv_aio_ioctl = repagent_aio_ioctl, - .create_options = repagent_create_options, - .bdrv_check = repagent_check, + .bdrv_create = repagent_create, + .create_options = repagent_create_options, + .bdrv_has_zero_init = repagent_has_zero_init, }; static void bdrv_repagent_init(void) diff --git a/block/repagent/rephub_cmds.h b/block/repagent/rephub_cmds.h index 3bd4eb4..d1bad06 100644 --- a/block/repagent/rephub_cmds.h +++ b/block/repagent/rephub_cmds.h @@ -128,7 +128,7 @@ typedef struct RepCmdReadVolReq { typedef struct RepCmdReadVolRes { RepCmdHdr hdr; int req_id; - int is_status_success; + int io_status; uint64_t volume_id; } RepCmdReadVolRes; diff --git a/blockdev.c b/blockdev.c index a75cee3..3c3afbc 100644 --- a/blockdev.c +++ b/blockdev.c @@ -20,6 +20,7 @@ #include "trace.h" #include "arch_init.h" + static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives); static const char *const if_name[IF_COUNT] = { @@ -292,7 +293,6 @@ 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; @@ -309,7 +309,6 @@ 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); @@ -589,10 +588,6 @@ 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 7d381ea..0fe2cff 100644 --- a/vl.c +++ b/vl.c @@ -775,14 +775,6 @@ 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) @@ -2295,7 +2287,6 @@ 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]); @@ -2423,9 +2414,9 @@ int main(int argc, char **argv, char **envp) break; case QEMU_OPTION_repagent: #ifdef CONFIG_REPAGENT + use_repagent = 1; repagent_init(optarg, 0); - enable_repagent = 1; - + printf("Repagent enabled\n"); #else fprintf(stderr, "Repagent support is disabled. " "Don't use -repagent option.\n"); @@ -3411,10 +3402,6 @@ 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 --20cf306f779e4a32c004bced8851 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable

Driver functions are in repag= ent_drv.c, it is basd on raw.c

Qemu runs and is a= ble to boot

---

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

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/re= pagent/repagent.c=A0=A0=A0=A0 |=A0=A0 53 ++++++++----

block/repagent/repagent.h=A0=A0=A0=A0 |=A0=A0=A0 6 = ++

block/repagent/repagent_drv.c |=A0 198 ++++++= ++++++++++++----------------------

block/repagen= t/rephub_cmds.h=A0 |=A0=A0=A0 2 +-

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

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

8 files changed, 160 insertions(+), = 157 deletions(-)

=A0

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

index 6612af1..8e11c03 100644

--- a/b= lock.c

+++ b/block.c

@@= -57,6 +57,7 @@ typedef enum {

=A0=A0=A0=A0 BDRV_REQ_ZERO_WRITE=A0=A0 =3D 0x2,

<= p class=3D"MsoNormal"> } BdrvRequestFlags;

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

static void bdrv_dev_cha= nge_media_cb(BlockDriverState *bs, bool load);

static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDri= verState *bs,

=A0=A0=A0=A0=A0=A0=A0=A0 int64_t se= ctor_num, QEMUIOVector *qiov, int nb_sectors,

@@ = -104,6 +105,9 @@ static BlockDriverState *bs_snapshots;

/* If non-zero, use only whitelisted block drivers = */

static int use_bdrv_whitelist;

+/* orim temporary */

+int use_repagent;

+

#= ifdef _WIN32

static int is_windows_drive_prefix(= const char *filename)

{

@@ -607,8 +611,7 @@ static int bdrv_open_common(BlockDriverState *bs, con= st char *filename,

=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

-=A0=A0=A0=A0=A0=A0=A0=A0 & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING | BDR= V_O_REPAGENT);

+=A0=A0=A0 open_flags =3D flags &a= mp; ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);

=

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

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

<= p class=3D"MsoNormal">@@ -690,8 +693,10 @@ int bdrv_open(BlockDriverState *= bs, const char *filename, int flags,

=A0=A0=A0=A0= int ret;

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

-=A0=A0=A0 if (flags & BDRV_O_REPAGENT) {

-=A0=A0=A0=A0=A0=A0=A0 drv =3D bdrv_find_format("rep= agent");

+=A0=A0=A0 if (use_repagent && bs->device_name[0] !=3D '\0&#= 39; && strcmp(

+=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0 bs->device_name, "pflash0") !=3D 0) {

+=A0=A0=A0=A0=A0=A0=A0 BlockDriver *bdrv_repagent =3D bdrv_find= _format("repagent");

+=A0=A0=A0=A0=A0=A0=A0 drv =3D bdrv_repagent;

=A0=A0=A0=A0 }

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

@@ -759,7 +764,7 @@ int bdrv_open(BlockDriverState *bs, con= st char *filename, int flags,

=A0=A0=A0=A0 }

=A0#ifdef CONFIG_REPAGENT

-=A0= =A0=A0 repagent_register_drive(filename,=A0 bs);

= +/*=A0=A0=A0 repagent_register_drive(filename,=A0 bs); */

#endif

=A0=A0=A0=A0 /* Op= en the image */

=A0=A0=A0=A0 ret =3D bdrv_open_co= mmon(bs, filename, flags, drv);

@@ -1481,6 +1486,= 13 @@ static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8= _t *buf,

=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 qemu_aio_wait()= ;

=A0=A0=A0=A0=A0=A0=A0=A0 }

=A0=A0=A0=A0 }

+=A0=A0=A0 /* orim todo remo= ve */

+=A0=A0=A0 printf("IO done. is_write %= d sec %lld size %d ", is_write,

+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 (long long int) s= ector_num, nb_sectors);

+=A0=A0=A0 if (bs->drv= !=3D NULL) {

+=A0=A0=A0=A0=A0=A0=A0 printf("= ;Drv %s, ", bs->drv->format_name);

+=A0=A0=A0 }

+=A0=A0=A0 pr= intf("file %s, ret %d\n", bs->filename, rwco.ret);

=A0=A0=A0=A0 return rwco.ret;

}

@@ -1861,8 +1873,9 @@ static int coroutine_fn bdrv_c= o_do_writev(BlockDriverState *bs,

=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0 Currently we know that by checking device_name - only

=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 highest level (closest to the guest) has = that name.

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

-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 repagent_handle_pr= otected_write(bs, sector_num,

+/*=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0 repagent_handle_protected_write(bs, sector_num,

=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 nb_= sectors, qiov, ret);

+*/

=A0=A0=A0=A0 }

#endif

=A0=A0=A0=A0 if (bs->dirty_bitmap) {

@@ -1942,16 +1955,20 @@ int64_t bdrv_get_allocated_file_size(BlockDriverSta= te *bs)

=A0 */

int64_t= bdrv_getlength(BlockDriverState *bs)

{

+=A0=A0=A0 int64_t ret =3D 0;

=A0=A0=A0=A0 BlockD= river *drv =3D bs->drv;

=A0=A0=A0=A0 if (!drv)=

=A0=A0=A0=A0=A0=A0=A0=A0 return -ENOMEDIUM;

<= p class=3D"MsoNormal">

+=A0=A0=A0 ret =3D bs->total_sectors * BDRV_SECTOR_SIZE;

=A0=A0=A0=A0 if (bs->growable || bdrv_dev_has_removable_media= (bs)) {

=A0=A0=A0=A0=A0=A0=A0=A0 if (drv->bdrv= _getlength) {

-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 return drv->bdrv_getlength(bs);

+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ret =3D drv->bdr= v_getlength(bs);

=A0=A0=A0=A0=A0 =A0=A0=A0}

=A0=A0=A0=A0 }

-=A0=A0=A0 re= turn bs->total_sectors * BDRV_SECTOR_SIZE;

+=A0=A0=A0 /* orim todo remove */

+=A0=A0=A0 printf("bdrv_getlength returned %d", (int)ret)= ;

+=A0=A0=A0 return ret;

}

=A0/* return 0 as number of sectors if no devic= e present or error */

diff --git a/block.h b/bloc= k.h

index d4a8257..48d0bf3 100644

--- a/block.h

+++ b/block.h

@@ -71,7 +71,6 @@ typedef struct BlockDevOps {

#define BDRV_O_NO_BACKING=A0 0x0100 /* don't open the backing file = */

#define BDRV_O_NO_FLUSH=A0=A0=A0 0x0200 /* disable = 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 replication - tempora= ry flag */

=A0#define BDRV_O_CACHE_= MASK=A0 (BDRV_O_NOCACHE | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH)

diff --git a/block/repagent/repagen= t.c b/block/repagent/repagent.c

index c291915..c3dd593 100644

--- a/block/repagent/repagent.c

+++ b/block/r= epagent/repagent.c

@@ -34,6 +34,8 @@ typedef stru= ct RepagentReadVolIo {

=A0=A0=A0=A0 struct timeval start_time;

} RepagentReadVolIo;

+static int repagent_get_volume_by_driver(

+=A0=A0=A0=A0=A0=A0=A0 BlockDriverState *bs);

static int repagent_get_volume_by_name(const char *= name);

static void repagent_report_volumes_to_hu= b(void);

static void repagent_vol_read_done(void= *opaque, int ret);

@@ -67,18 +69,16 @@ void repagent_init(const char *h= ubname, int port)

void repagent_register_drive(c= onst char *drive_path,

=A0=A0=A0=A0=A0=A0=A0=A0 B= lockDriverState *driver_ptr)

{

-=A0=A0=A0 int i;

-=A0=A0=A0 for (i =3D 0; i < g_rep_agent.num_volume= s ; i++) {

-=A0=A0=A0=A0=A0=A0=A0 RepagentVolume = *vol =3D g_rep_agent.volumes[i];

-=A0=A0=A0=A0=A0=A0=A0 if (vol !=3D NULL) {

-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 assert(

-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 strc= mp(drive_path, vol->vol_path) !=3D 0

-=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 && driver_ptr != =3D vol->driver_ptr);

-=A0=A0=A0=A0=A0=A0=A0 }

-= =A0=A0=A0 }

+=A0=A0=A0 /* Assert that the volume = is not registered yet */

+=A0=A0=A0 int i =3D rep= agent_get_volume_by_name(drive_path);

+=A0=A0=A0 assert(i =3D=3D -1);

+=A0=A0=A0 /*Add the volume at the last p= lace*/

=A0=A0=A0=A0 assert(g_rep_agent.num_volume= s < REPAGENT_MAX_NUM_VOLUMES);

+=A0=A0=A0 i =3D g_rep_a= gent.num_volumes;

+=A0=A0=A0 g_rep_agent.num_volu= mes++;

+

=A0=A0=A0=A0 p= rintf("zerto repagent: Registering drive. Num drives %d, path %s\n&quo= t;,

=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 g_rep_agent.num= _volumes, drive_path);

=A0=A0=A0=A0 g_rep_agent.v= olumes[i] =3D

@@ -93,9 +93,25 @@ void repagent_re= gister_drive(const char *drive_path,

=A0=A0=A0=A0 repagent_report_volumes_to_hub();

}

+void repagent_deregister_drive(const char *drive_path,

+=A0=A0=A0=A0=A0=A0=A0 BlockDriverState *driver_ptr)

+{

+=A0=A0=A0 /* Orim todo= thread-safety? */

+=A0=A0=A0 int i =3D repagent_= get_volume_by_driver(driver_ptr);

+=A0=A0=A0 asse= rt(i !=3D -1);

+

+=A0=A0=A0 RepagentVolume *vol =3D g_rep_agent.= volumes[i];

+=A0=A0=A0 /* Put the last volume in = the cell of the removed volume to maintain a

+=A0= =A0=A0=A0 * contiguous array */

+=A0=A0=A0 g_rep_agent.volumes[i] =3D g_rep_agent.vo= lumes[g_rep_agent.num_volumes - 1];

+=A0=A0=A0 g_= rep_agent.volumes[g_rep_agent.num_volumes - 1] =3D NULL;

+=A0=A0=A0 g_rep_agent.num_volumes--;

+=A0=A0=A0 g_free(vol);

+<= /p>

+}

/* orim todo destru= ction? */

-static Rep= agentVolume *repagent_get_protected_volume_by_driver(

+static int repagent_get_volume_by_driver(

=A0=A0=A0=A0=A0=A0=A0=A0 BlockDriverState *bs)

{

=A0=A0=A0=A0 /* orim todo optim= ize search */

@@ -103,10 +119,10 @@ static RepagentVolume *repagent_get_protected_volume_= by_driver(

=A0=A0=A0=A0 for (i =3D 0; i < g_re= p_agent.num_volumes ; i++) {

=A0=A0=A0=A0=A0=A0= =A0=A0 RepagentVolume *p_vol =3D g_rep_agent.volumes[i];

=A0=A0=A0=A0=A0=A0=A0=A0 if (p_vol !=3D NULL &&a= mp; p_vol->driver_ptr =3D=3D (void *) bs) {

-= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 return p_vol;

+= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 return i;

=A0= =A0=A0=A0=A0=A0=A0=A0 }

=A0=A0=A0=A0 }

-=A0=A0=A0 = return NULL;

+=A0=A0=A0 return -1;

}

=A0voi= d repagent_handle_protected_write(BlockDriverState *bs, int64_t sector_num,=

@@ -120,13 +136,16 @@ void repagent_handle_protected= _write(BlockDriverState *bs, int64_t sector_num,

=

=A0=A0=A0=A0=A0printf("\n");

-=A0=A0=A0 RepagentVolume *p_vol =3D repagent_g= et_protected_volume_by_driver(bs);

-=A0=A0=A0 if = (p_vol =3D=3D NULL || p_vol->vol_id =3D=3D REPAGENT_VOLUME_ID_NONE) {

+=A0=A0=A0 /* orim todo thread safety? */

+=A0=A0= =A0 int i =3D repagent_get_volume_by_driver(bs);

= +=A0=A0=A0 if (i =3D=3D -1 || g_rep_agent.volumes[i]->vol_id =3D=3D REPA= GENT_VOLUME_ID_NONE) {

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

=A0=A0= =A0=A0=A0=A0=A0=A0 printf("Got a write to an unprotected volume.\n&quo= t;);

=A0=A0=A0=A0=A0=A0=A0=A0 return;

=A0=A0=A0=A0 }

+=A0=A0=A0 RepagentVolume *p_vol =3D g_rep_agent.vol= umes[i];

+

=A0=A0=A0=A0= /* Report IO to rephub */

=A0=A0=A0=A0=A0int data_size =3D qiov->size;

@@ -234,7 +253,7 @@ int repaget_read_vol(RepCmdReadV= olReq *pcmd, uint8_t *pdata)

=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 REPHUB_CMD_READ_VOL_RES, 0, NULL);

=A0=A0=A0=A0=A0=A0=A0=A0 p_res_cmd->req_id =3D pcmd->= ;req_id;

=A0=A0=A0=A0=A0=A0=A0=A0 p_res_cmd->volume_id =3D= pcmd->volume_id;

-=A0=A0=A0=A0=A0=A0=A0 p_res= _cmd->is_status_success =3D FALSE;

+=A0=A0=A0= =A0=A0=A0=A0 p_res_cmd->io_status =3D -1;

=A0=A0=A0=A0=A0=A0=A0=A0 repagent_client_send((RepCmd *) p_res_cmd);

=A0=A0=A0=A0=A0=A0=A0=A0 return TRUE;

=A0=A0=A0=A0 }

@@ -280,7 +299,7 @@ stati= c void repagent_vol_read_done(void *opaque, int ret)

=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 &pdata);

=A0=A0=A0=A0 pcmd->req_id =3D read_xact->rep_= cmd.req_id;

=A0=A0=A0=A0 pcmd->volume_id =3D r= ead_xact->rep_cmd.volume_id;

-=A0=A0=A0 pcmd->is_status_success =3D FALSE;

= +=A0=A0=A0 pcmd->io_status =3D -1;

=A0=A0=A0=A0=A0printf("Protected vol read - volId %ll= u, offset %llu, size %u\n",

=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 (unsigned long = long int) read_xact->rep_cmd.volume_id,

@@ -29= 4,7 +313,7 @@ static void repagent_vol_read_done(void *opaque, int ret)

=

=A0=A0=A0=A0=A0=A0=A0=A0 printf("Read prot vol = done. Took %u seconds, %u us.",

=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 (ui= nt32_t) t2.tv_sec, (uint32_t) t2.tv_usec);

<= p class=3D"MsoNormal">-=A0=A0=A0=A0=A0=A0=A0 pcmd->is_status_success =3D= TRUE;

+=A0=A0=A0=A0=A0=A0=A0 pcmd->io_status = =3D 0;=A0=A0=A0 /* Success */

=A0=A0=A0=A0=A0=A0=A0=A0 /* orim todo optimize - don= 't copy, use the qiov buffer */

=A0=A0=A0=A0= =A0=A0=A0=A0 qemu_iovec_to_buffer(&read_xact->qiov, pdata);

=A0=A0=A0=A0 } else {

diff --git a/block/repagent/repagent.h b/block/repag= ent/repagent.h

index 98ccbf2..310db0f 100644

<= p class=3D"MsoNormal">--- a/block/repagent/repagent.h

+++ b/block/repagent/repagent.h

@@ -32,11 +32,17 = @@ typedef struct RepCmdStartProtect RepCmdStartProtect;

typedef struct RepCmdDataStartProtect RepCmdDataStartProtect;

<= p class=3D"MsoNormal"> struct RepCmdReadVolReq;

+/* orim temporary */

+extern int use_repage= nt;

+

+

void repagent_init(const char *hubname, int port);

void repagent_handle_protected_write(BlockDriverState *bs,

=A0=A0=A0=A0=A0=A0=A0=A0 int64_t sector_num, int nb_sectors,= QEMUIOVector *qiov, int ret_status);

void repagent_register_drive(const char *drive_path= ,

=A0=A0=A0=A0=A0=A0=A0=A0 BlockDriverState *driv= er_ptr);

+void repagent_deregister_drive(const ch= ar *drive_path,

+=A0=A0=A0=A0=A0=A0=A0 BlockDriverState *driver_ptr)= ;

int repaget_start_protect(RepCmdStartProtect *= pcmd,

=A0=A0=A0=A0=A0=A0=A0=A0 RepCmdDataStartPro= tect *pcmd_data);

int repaget_read_vol(struct RepCmdReadVolReq *pcmd, uint8_t *pdata);

diff --git a/block/repagent/repagent_drv.c b/block/rep= agent/repagent_drv.c

index 49e110d..8c9f2b6 10064= 4

--- a/block/repagent/repagent_drv.c

+++ b/block/repagent/repagent_drv.c

@@ = -1,7 +1,6 @@

#include <string.h>

#include <stdlib.h>

#include <stdio.h&= gt;

-#include <pthread.h>

#include <stdint.h>

=A0#include "block.h"

@@ -10,183 +9,164= @@

#include "repagent_client.h"

#include "repagent.h"

#include "rephub_cmds.h"

+#include "module.h"

=A0#define ZERO_MEM_OBJ(pObj) memset(pObj,= 0, sizeof(*pObj))

-t= ypedef 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);

+=A0=A0=A0 repagent_register_drive(bs->filename,=A0 bs)= ;

+=A0=A0=A0 printf("%s\n", __func__);<= /p>

+=A0=A0=A0 bs->sg =3D bs->file->sg;

+=A0=A0=A0 return 0;

}

-static coroutine_fn in= t repagent_co_readv(BlockDriverState *bs,

-=A0=A0= =A0=A0=A0=A0=A0=A0=A0 int64_t sector_num, int remaining_sectors, QEMUIOVect= or *qiov)

+static int coroutine_fn repagent_co_readv(BlockDriv= erState *bs,

+=A0=A0=A0=A0=A0=A0=A0 int64_t secto= r_num, int nb_sectors, QEMUIOVector *qiov)

{

=

-=A0=A0=A0 return bs->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=A0remaining_sectors, qiov);

+=A0= =A0=A0 printf("%s\n", __func__);

+=A0=A0=A0 return bdrv_co_readv(bs->file, sector_num, nb_sectors, qiov);=

}

-static coroutine_fn int repagent_co_writev(BlockDriverState *bs,<= /p>

-=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 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_sec= tors,

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

+static int coroutine_fn repagent_co_writev(BlockDriverState *bs,

+=A0=A0=A0=A0=A0=A0=A0 int64_t sector_num, int nb_se= ctors, 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);

+=A0=A0=A0 printf("%s\n", __func__);

+=A0=A0=A0 int ret =3D 0;

+=A0=A0=A0 re= pagent_handle_protected_write(bs, sector_num,

+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 nb_sectors, qiov,= ret);

+=A0=A0=A0 printf("Before write off %= lld, size %d\n", (long long int) sector_num,

+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 nb_sectors);

+=A0=A0=A0 ret =3D bdrv_co_writev(bs->file, secto= r_num, nb_sectors, qiov);

+=A0=A0=A0 printf("= ;After write ret %d\n", ret);

+=A0=A0=A0 ret= urn ret;

}

=A0static void rep= agent_close(BlockDriverState *bs)

{

-=A0=A0=A0 return bs->file->drv->bdrv_close(bs->= file);

+=A0=A0=A0 printf("%s\n", __func__);

}=

-static void repagen= t_invalidate_cache(BlockDriverState *bs)

+static = int coroutine_fn repagent_co_flush(BlockDriverState *bs)

{

-=A0=A0=A0 bs->file-= >drv->bdrv_invalidate_cache(bs->file);

-= }

-

-static int repagen= t_change_backing_file(BlockDriverState *bs,

-=A0=A0=A0=A0=A0=A0=A0 const char *backing_file, con= st char *backing_fmt) {

-=A0=A0=A0 return bs->= file->drv->bdrv_change_backing_file(bs->file, backing_file,

-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 backing_fmt);

+=A0=A0=A0 printf("%s\n", __func__);

+=A0=A0=A0 return bdrv_co_flush(bs->file);

}

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

+static int64_t repagent_getlength(BlockDriverState = *bs)

{

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

+=A0= =A0=A0 printf("%s\n", __func__);

+=A0=A0=A0 return bdrv_getlength(bs->file);

}

-static int repagent_make_empty(BlockDriverState *bs)

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

{

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

= +=A0=A0=A0 printf("%s\n", __func__);

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

}

-static coroutine_fn int repagent_co_discard(BlockDriverState *bs,

=

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

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

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

{

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

+=A0=A0=A0 printf("%s\n", __func__);

+=A0=A0=A0 return 1; /* everything can be opened as ra= w image */

}

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

+static int coroutine_fn repagent_co_discard(BlockDriver= State *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=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0int64_t sector_num, int nb_sectors)

{

-=A0=A0=A0 return bs-&g= t;file->drv->bdrv_truncate(bs->file, offset);

+=A0=A0=A0 return bdrv_co_discard(bs->file, sector_num, nb_sectors= );

}

-static int repage= nt_write_compressed(BlockDriverState *bs, int64_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=A0=A0=A0=A0=A0=A0=A0 const uint8_t *buf, int nb_secto= rs)

+static int repagent_is_inserted(BlockDriverState *b= s)

{

-=A0=A0=A0 return= bs->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)= ;

+=A0=A0=A0 printf("%s\n", __func__);<= /p>

+=A0=A0=A0 return bdrv_is_inserted(bs->file);<= /p>

}

-static coroutine_fn int repagent_co_flush_to_o= s(BlockDriverState *bs)

+static int repagent_medi= a_changed(BlockDriverState *bs)

{

-=A0=A0=A0 return bs->file->drv->bdrv_co_flush_to_os(bs->file);=

+=A0=A0=A0 printf("%s\n", __func__);

+=A0=A0=A0 return bdrv_media_changed(bs->file);=

}

-static coroutine_= fn int repagent_co_flush_to_disk(BlockDriverState *bs)

+static void repagent_eject(BlockDriverState *bs, bool eject_flag)

{

-=A0=A0=A0 return bs->file->drv->bdrv= _co_flush_to_disk(bs->file);

+=A0=A0=A0 printf= ("%s\n", __func__);

+=A0=A0=A0 bdrv_eje= ct(bs->file, eject_flag);

}

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

+static void repagent_lock_medium(BlockDriver= State *bs, bool locked)

{

-=A0=A0=A0 return bs-&g= t;file->drv->bdrv_get_info(bs->file, bdi);

+=A0=A0=A0 printf("%s\n", __func__);

+=A0=A0=A0 bdrv_lock_medium(bs->file, locked);

}

-

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

+static int repag= ent_ioctl(BlockDriverState *bs, unsigned long int req,

+=A0=A0=A0=A0=A0=A0=A0 void *buf)

{

-=A0=A0=A0 return bs->file->drv-= >bdrv_check(bs->file, result);

+=A0=A0=A0 p= rintf("%s\n", __func__);

+=A0=A0 return bdrv_ioctl(bs->file, req, buf);

}

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

+static BlockDriverAIOCB *repagent_aio_ioctl(BlockDriverState *b= s,

+=A0=A0=A0=A0=A0=A0=A0 unsigned long int req, = void *buf,

+=A0=A0=A0=A0=A0=A0=A0 BlockDriverCompletionFunc *cb= , void *opaque)

{

-=A0= =A0=A0 return bs->file->drv->bdrv_save_vmstate(bs->file, buf, p= os, size);

+=A0=A0=A0 printf("%s\n", __func__);

+= =A0=A0 return bdrv_aio_ioctl(bs->file, req, buf, cb, opaque);

}

-s= tatic int repagent_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)

+static int repagent_create(const char *filename, QEMUOption= Parameter *options)

{

-=A0=A0=A0 return bs->file->drv->bdrv_load_vmstate(bs->file, bu= f, pos, size);

+=A0=A0=A0 printf("%s\n"= , __func__);

+=A0=A0=A0 return bdrv_create_file(f= ilename, options);

}

-

static QEMUOptionParameter repagent_creat= e_options[] =3D {

+=A0=A0=A0 {

+=A0=A0=A0=A0=A0=A0=A0 .name =3D BLOCK_OPT_SIZE,

+=A0=A0=A0=A0=A0=A0=A0 .type =3D OPT_SIZE,

+=A0=A0=A0=A0=A0=A0=A0 .help =3D "Virtual disk size&q= uot;

+=A0=A0=A0 },

=A0= =A0=A0=A0 { NULL }

};

+static int repagent_has_zero_init(BlockDriverS= tate *bs)

+{

+=A0=A0=A0= printf("%s\n", __func__);

+=A0=A0=A0 r= eturn bdrv_has_zero_init(bs->file);

+}

+

static BlockDriver bdrv_repagent =3D {

=A0= =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(BD= RVRepagentState),

-=A0=A0=A0 .bdrv_probe=A0=A0=A0=A0=A0=A0=A0=A0 =3D r= epagent_probe,

+

+=A0= =A0=A0 /* It's really 0, but we need to make g_malloc() happy */

+=A0=A0=A0 .instance_size=A0=A0=A0=A0=A0 =3D 1,

+

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

= =A0=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 repage= nt_create,

-=A0=A0=A0 .bdrv_co_is_allocated =3D repagent_co_is_= allocated,

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

-=A0=A0=A0 .bdrv_mak= e_empty=A0=A0=A0 =3D repagent_make_empty,

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

=A0=A0=A0=A0 .bd= rv_co_writev=A0=A0=A0=A0=A0=A0=A0=A0 =3D repagent_co_writev,

-=A0=A0=A0 .bdrv_co_flush_to_os=A0=A0=A0 =3D repagent_co_flush_= to_os,

-=A0=A0=A0 .bdrv_co_flush_to_disk=A0 =3D repagent_co= _flush_to_disk,

-

+=A0= =A0=A0 .bdrv_co_flush_to_disk=A0 =3D repagent_co_flush,

=A0=A0=A0=A0 .bdrv_co_discard=A0=A0=A0=A0=A0=A0=A0 =3D repagent_co_d= iscard,

-=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_probe=A0=A0=A0=A0=A0=A0=A0=A0 =3D r= epagent_probe,

+=A0=A0=A0 .bdrv_getlength=A0=A0= =A0=A0 =3D repagent_getlength,

+=A0=A0=A0 .bdrv_t= runcate=A0=A0=A0=A0=A0 =3D repagent_truncate,

-=A0=A0=A0 .bdrv_change_backing_file=A0=A0 =3D = repagent_change_backing_file,

+=A0=A0=A0 .bdrv_is= _inserted=A0=A0 =3D repagent_is_inserted,

+=A0=A0= =A0 .bdrv_media_changed =3D repagent_media_changed,

+=A0=A0=A0 .bdrv_eject=A0=A0=A0=A0=A0=A0=A0=A0 =3D r= epagent_eject,

+=A0=A0=A0 .bdrv_lock_medium=A0=A0= =3D repagent_lock_medium,

-=A0=A0=A0 .bdrv_invalidate_cache=A0=A0=A0=A0=A0 =3D repagent_invalid= ate_cache,

+=A0=A0=A0 .bdrv_ioctl=A0=A0=A0=A0=A0=A0=A0=A0 =3D r= epagent_ioctl,

+=A0=A0=A0 .bdrv_aio_ioctl=A0=A0= =A0=A0 =3D repagent_aio_ioctl,

-=A0=A0=A0 .create_options =3D repagent_create_options,

-=A0=A0=A0 .bdrv_check =3D repagent_check,

+=A0=A0=A0 .bdrv_create=A0=A0=A0=A0=A0=A0=A0 =3D repagent_= create,

+=A0=A0=A0 .create_options=A0=A0=A0=A0 = =3D repagent_create_options,

+=A0=A0=A0 .bdrv_has_zero_init =3D repagent_has_zero_init,

};

=A0stat= ic void bdrv_repagent_init(void)

diff --git a/blo= ck/repagent/rephub_cmds.h b/block/repagent/rephub_cmds.h

index 3bd4eb4..d1bad06 100644

--- a/block/repagent/rephub_cmds.h

+++ b/bloc= k/repagent/rephub_cmds.h

@@ -128,7 +128,7 @@ type= def struct RepCmdReadVolReq {

typedef struct RepCmdReadVolRes {

=A0=A0=A0=A0 RepCmdHdr hdr;

=A0=A0=A0=A0= int req_id;

-=A0=A0=A0 int is_status_success;

+=A0=A0=A0 int io_status;

=A0=A0=A0=A0 uint64_t volume_id;

} RepCmdReadVolRes;

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

index= a75cee3..3c3afbc 100644

--- a/blockdev.c

+++ b/blo= ckdev.c

@@ -20,6 +20,7 @@

#include "trace.h"

#include "= arch_init.h"

+

static QTAILQ_HEAD(drivelist, DriveInfo) drives =3D QTAILQ_HEAD_INITIA= LIZER(drives);

=A0sta= tic const char *const if_name[IF_COUNT] =3D {

@@ -292,7 +293,6 @@ 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 r= epagent =3D 0;

=A0=A0=A0=A0 bool copy_on_read;

=A0=A0=A0=A0 int ret;

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

=A0=A0=A0=A0 secs=A0 =3D qemu_opt_get_number(opts, &= quot;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);

@@ -589,10 +588,6 @@ Dri= veInfo *drive_init(QemuOpts *opts, int default_to_scsi)

=A0=A0=A0=A0=A0=A0=A0=A0 bdrv_flags |=3D (BDRV_O_SNAPSHOT|BDRV_O_CAC= HE_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/v= l.c b/vl.c

index 7d381ea..0fe2cff 100644

--- a/vl.c

+++ b/vl.c

<= p class=3D"MsoNormal">@@ -775,14 +775,6 @@ static int drive_enable_snapshot= (QemuOpts *opts, void *opaque)

=A0=A0=A0=A0 retur= n 0;

}

-static int drive_= enable_repagent(QemuOpts *opts, void *opaque)

-{<= /p>

-=A0=A0=A0 if (NULL =3D=3D qemu_opt_get(opts, &qu= ot;repagent")) {

-=A0=A0=A0=A0=A0=A0=A0 qemu_opt_set(opts, "repa= gent", "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)

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

=A0=A0=A0=A0 const char *trace_eve= nts =3D NULL;

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

-=A0=A0=A0 int enable_repagent =3D 0;

=A0=A0=A0=A0 atexit(qemu_run_exit_notifiers);

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

@@ -2423,9 +2414,9 @@ int main(int argc, char **argv, char **envp)

=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 break;

=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case QEMU_OPT= ION_repagent:

#ifdef CONFIG_REPAGENT

+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 use_r= epagent =3D 1;

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

-

+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 printf("Repagent enable= d\n");

#else

=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 fprintf(stderr, "Repagen= t 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 op= tion.\n");

@@ -3411,10 +3402,6 @@ int main(int argc, char **arg= v, char **envp)

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

<= p class=3D"MsoNormal">

=A0=A0=A0=A0=A0/* open th= e virtual block devices */

-=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_foreach(qemu_find_opts(= "drive"), drive_enable_snapshot, NULL, 0);

=A0=A0=A0=A0 if (qemu_opts_foreach(qemu_find_opts("drive"), d= rive_init_func, &machine->use_scsi, 1) !=3D 0)

--

1.7.6.5

--20cf306f779e4a32c004bced8851--