Commit ce20db59 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/ericb/tags/pull-bitmaps-2020-05-26-v3' into staging



bitmaps patches for 2020-05-26

- fix non-blockdev migration of bitmaps when mirror job is in use
- add bitmap sizing to 'qemu-img measure'
- add 'qemu-img convert --bitmaps'

# gpg: Signature made Thu 28 May 2020 19:16:47 BST
# gpg:                using RSA key 71C2CC22B1C4602927D2F3AAA7A16B4A2527436A
# gpg: Good signature from "Eric Blake <eblake@redhat.com>" [full]
# gpg:                 aka "Eric Blake (Free Software Programmer) <ebb9@byu.net>" [full]
# gpg:                 aka "[jpeg image of size 6874]" [full]
# Primary key fingerprint: 71C2 CC22 B1C4 6029 27D2  F3AA A7A1 6B4A 2527 436A

* remotes/ericb/tags/pull-bitmaps-2020-05-26-v3:
  iotests: Add test 291 to for qemu-img bitmap coverage
  qemu-img: Add convert --bitmaps option
  qemu-img: Factor out code for merging bitmaps
  qcow2: Expose bitmaps' size during measure
  iotests: Fix test 178
  migration: forbid bitmap migration by generated node-name
  migration: add_bitmaps_to_list: check disk name once
  iotests: 194: test also migration of dirty bitmap
  migration: fix bitmaps pre-blockdev migration with mirror job
  block/dirty-bitmap: add bdrv_has_named_bitmaps helper
  migration: refactor init_dirty_bitmap_migration

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents c86274bc cf2d1203
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -552,7 +552,7 @@ static BlockMeasureInfo *block_crypto_measure(QemuOpts *opts,
     * Unallocated blocks are still encrypted so allocation status makes no
     * difference to the file size.
     */
    info = g_new(BlockMeasureInfo, 1);
    info = g_new0(BlockMeasureInfo, 1);
    info->fully_allocated = luks_payload_size + size;
    info->required = luks_payload_size + size;
    return info;
+13 −0
Original line number Diff line number Diff line
@@ -818,6 +818,19 @@ bool bdrv_has_readonly_bitmaps(BlockDriverState *bs)
    return false;
}

bool bdrv_has_named_bitmaps(BlockDriverState *bs)
{
    BdrvDirtyBitmap *bm;

    QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
        if (bdrv_dirty_bitmap_name(bm)) {
            return true;
        }
    }

    return false;
}

/* Called with BQL taken. */
void bdrv_dirty_bitmap_set_persistence(BdrvDirtyBitmap *bitmap, bool persistent)
{
+36 −0
Original line number Diff line number Diff line
@@ -1755,3 +1755,39 @@ bool qcow2_supports_persistent_dirty_bitmap(BlockDriverState *bs)

    return s->qcow_version >= 3;
}

/*
 * Compute the space required for bitmaps in @bs.
 *
 * The computation is based as if copying to a new image with the
 * given @cluster_size, which may differ from the cluster size in @bs.
 */
uint64_t qcow2_get_persistent_dirty_bitmap_size(BlockDriverState *bs,
                                                uint32_t cluster_size)
{
    uint64_t bitmaps_size = 0;
    BdrvDirtyBitmap *bm;
    size_t bitmap_dir_size = 0;

    FOR_EACH_DIRTY_BITMAP(bs, bm) {
        if (bdrv_dirty_bitmap_get_persistence(bm)) {
            const char *name = bdrv_dirty_bitmap_name(bm);
            uint32_t granularity = bdrv_dirty_bitmap_granularity(bm);
            uint64_t bmbytes =
                get_bitmap_bytes_needed(bdrv_dirty_bitmap_size(bm),
                                        granularity);
            uint64_t bmclusters = DIV_ROUND_UP(bmbytes, cluster_size);

            /* Assume the entire bitmap is allocated */
            bitmaps_size += bmclusters * cluster_size;
            /* Also reserve space for the bitmap table entries */
            bitmaps_size += ROUND_UP(bmclusters * sizeof(uint64_t),
                                     cluster_size);
            /* And space for contribution to bitmap directory size */
            bitmap_dir_size += calc_dir_entry_size(strlen(name), 0);
        }
    }
    bitmaps_size += ROUND_UP(bitmap_dir_size, cluster_size);

    return bitmaps_size;
}
+11 −3
Original line number Diff line number Diff line
@@ -4953,16 +4953,24 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
        required = virtual_size;
    }

    info = g_new(BlockMeasureInfo, 1);
    info = g_new0(BlockMeasureInfo, 1);
    info->fully_allocated =
        qcow2_calc_prealloc_size(virtual_size, cluster_size,
                                 ctz32(refcount_bits)) + luks_payload_size;

    /* Remove data clusters that are not required.  This overestimates the
    /*
     * Remove data clusters that are not required.  This overestimates the
     * required size because metadata needed for the fully allocated file is
     * still counted.
     * still counted.  Show bitmaps only if both source and destination
     * would support them.
     */
    info->required = info->fully_allocated - virtual_size + required;
    info->has_bitmaps = version >= 3 && in_bs &&
        bdrv_supports_persistent_dirty_bitmap(in_bs);
    if (info->has_bitmaps) {
        info->bitmaps = qcow2_get_persistent_dirty_bitmap_size(in_bs,
                                                               cluster_size);
    }
    return info;

err:
+2 −0
Original line number Diff line number Diff line
@@ -783,6 +783,8 @@ int qcow2_co_remove_persistent_dirty_bitmap(BlockDriverState *bs,
                                            const char *name,
                                            Error **errp);
bool qcow2_supports_persistent_dirty_bitmap(BlockDriverState *bs);
uint64_t qcow2_get_persistent_dirty_bitmap_size(BlockDriverState *bs,
                                                uint32_t cluster_size);

ssize_t coroutine_fn
qcow2_co_compress(BlockDriverState *bs, void *dest, size_t dest_size,
Loading