Commit 0fc9f8ea authored by Fam Zheng's avatar Fam Zheng Committed by Stefan Hajnoczi
Browse files

qmp: Add optional bool "unmap" to drive-mirror



If specified as "true", it allows discarding on target sectors where source is
not allocated.

Signed-off-by: default avatarFam Zheng <famz@redhat.com>
Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
parent ba3f0e25
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ typedef struct MirrorBlockJob {
    int in_flight;
    int sectors_in_flight;
    int ret;
    bool unmap;
} MirrorBlockJob;

typedef struct MirrorOp {
@@ -652,6 +653,7 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
                             int64_t buf_size,
                             BlockdevOnError on_source_error,
                             BlockdevOnError on_target_error,
                             bool unmap,
                             BlockCompletionFunc *cb,
                             void *opaque, Error **errp,
                             const BlockJobDriver *driver,
@@ -686,6 +688,7 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
    s->base = base;
    s->granularity = granularity;
    s->buf_size = MAX(buf_size, granularity);
    s->unmap = unmap;

    s->dirty_bitmap = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
    if (!s->dirty_bitmap) {
@@ -704,6 +707,7 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target,
                  int64_t speed, uint32_t granularity, int64_t buf_size,
                  MirrorSyncMode mode, BlockdevOnError on_source_error,
                  BlockdevOnError on_target_error,
                  bool unmap,
                  BlockCompletionFunc *cb,
                  void *opaque, Error **errp)
{
@@ -718,7 +722,7 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target,
    base = mode == MIRROR_SYNC_MODE_TOP ? bs->backing_hd : NULL;
    mirror_start_job(bs, target, replaces,
                     speed, granularity, buf_size,
                     on_source_error, on_target_error, cb, opaque, errp,
                     on_source_error, on_target_error, unmap, cb, opaque, errp,
                     &mirror_job_driver, is_none_mode, base);
}

@@ -766,7 +770,7 @@ void commit_active_start(BlockDriverState *bs, BlockDriverState *base,

    bdrv_ref(base);
    mirror_start_job(bs, base, NULL, speed, 0, 0,
                     on_error, on_error, cb, opaque, &local_err,
                     on_error, on_error, false, cb, opaque, &local_err,
                     &commit_active_job_driver, false, base);
    if (local_err) {
        error_propagate(errp, local_err);
+5 −0
Original line number Diff line number Diff line
@@ -2655,6 +2655,7 @@ void qmp_drive_mirror(const char *device, const char *target,
                      bool has_buf_size, int64_t buf_size,
                      bool has_on_source_error, BlockdevOnError on_source_error,
                      bool has_on_target_error, BlockdevOnError on_target_error,
                      bool has_unmap, bool unmap,
                      Error **errp)
{
    BlockBackend *blk;
@@ -2686,6 +2687,9 @@ void qmp_drive_mirror(const char *device, const char *target,
    if (!has_buf_size) {
        buf_size = DEFAULT_MIRROR_BUF_SIZE;
    }
    if (!has_unmap) {
        unmap = true;
    }

    if (granularity != 0 && (granularity < 512 || granularity > 1048576 * 64)) {
        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "granularity",
@@ -2827,6 +2831,7 @@ void qmp_drive_mirror(const char *device, const char *target,
                 has_replaces ? replaces : NULL,
                 speed, granularity, buf_size, sync,
                 on_source_error, on_target_error,
                 unmap,
                 block_job_cb, bs, &local_err);
    if (local_err != NULL) {
        bdrv_unref(target_bs);
+1 −1
Original line number Diff line number Diff line
@@ -1061,7 +1061,7 @@ void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
                     false, NULL, false, NULL,
                     full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
                     true, mode, false, 0, false, 0, false, 0,
                     false, 0, false, 0, &err);
                     false, 0, false, 0, false, true, &err);
    hmp_handle_error(mon, &err);
}

+2 −0
Original line number Diff line number Diff line
@@ -612,6 +612,7 @@ void commit_active_start(BlockDriverState *bs, BlockDriverState *base,
 * @mode: Whether to collapse all images in the chain to the target.
 * @on_source_error: The action to take upon error reading from the source.
 * @on_target_error: The action to take upon error writing to the target.
 * @unmap: Whether to unmap target where source sectors only contain zeroes.
 * @cb: Completion function for the job.
 * @opaque: Opaque pointer value passed to @cb.
 * @errp: Error object.
@@ -626,6 +627,7 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target,
                  int64_t speed, uint32_t granularity, int64_t buf_size,
                  MirrorSyncMode mode, BlockdevOnError on_source_error,
                  BlockdevOnError on_target_error,
                  bool unmap,
                  BlockCompletionFunc *cb,
                  void *opaque, Error **errp);

+7 −1
Original line number Diff line number Diff line
@@ -975,6 +975,11 @@
# @on-target-error: #optional the action to take on an error on the target,
#                   default 'report' (no limitations, since this applies to
#                   a different block device than @device).
# @unmap: #optional Whether to try to unmap target sectors where source has
#         only zero. If true, and target unallocated sectors will read as zero,
#         target image sectors will be unmapped; otherwise, zeroes will be
#         written. Both will result in identical contents.
#         Default is true. (Since 2.4)
#
# Returns: nothing on success
#          If @device is not a valid block device, DeviceNotFound
@@ -987,7 +992,8 @@
            'sync': 'MirrorSyncMode', '*mode': 'NewImageMode',
            '*speed': 'int', '*granularity': 'uint32',
            '*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
            '*on-target-error': 'BlockdevOnError' } }
            '*on-target-error': 'BlockdevOnError',
            '*unmap': 'bool' } }

##
# @BlockDirtyBitmap
Loading