Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
---
block/dirty-bitmap.c | 5 +++++
blockdev.c | 29 +++++++++++++++++++++++++++++
include/block/dirty-bitmap.h | 2 ++
include/qemu/hbitmap.h | 8 ++++++++
qapi/block-core.json | 27 +++++++++++++++++++++++++++
tests/Makefile.include | 2 +-
util/hbitmap.c | 11 +++++++++++
7 files changed, 83 insertions(+), 1 deletion(-)
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index 32aa6eb..5bec99b 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -558,3 +558,8 @@ BdrvDirtyBitmap *bdrv_next_dirty_bitmap(BlockDriverState *bs,
return QLIST_NEXT(bitmap, list);
}
+
+char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp)
+{
+ return hbitmap_sha256(bitmap->bitmap, errp);
+}
diff --git a/blockdev.c b/blockdev.c
index db82ac9..4d06885 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2790,6 +2790,35 @@ void qmp_block_dirty_bitmap_clear(const char *node, const char *name,
aio_context_release(aio_context);
}
+BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node,
+ const char *name,
+ Error **errp)
+{
+ AioContext *aio_context;
+ BdrvDirtyBitmap *bitmap;
+ BlockDriverState *bs;
+ BlockDirtyBitmapSha256 *ret = NULL;
+ char *sha256;
+
+ bitmap = block_dirty_bitmap_lookup(node, name, &bs, &aio_context, errp);
+ if (!bitmap || !bs) {
+ return NULL;
+ }
+
+ sha256 = bdrv_dirty_bitmap_sha256(bitmap, errp);
+ if (sha256 == NULL) {
+ goto out;
+ }
+
+ ret = g_new(BlockDirtyBitmapSha256, 1);
+ ret->sha256 = sha256;
+
+out:
+ aio_context_release(aio_context);
+
+ return ret;
+}
+
void hmp_drive_del(Monitor *mon, const QDict *qdict)
{
const char *id = qdict_get_str(qdict, "id");
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
index 20b3ec7..ded872a 100644
--- a/include/block/dirty-bitmap.h
+++ b/include/block/dirty-bitmap.h
@@ -78,4 +78,6 @@ void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap);
BdrvDirtyBitmap *bdrv_next_dirty_bitmap(BlockDriverState *bs,
BdrvDirtyBitmap *bitmap);
+char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp);
+
#endif
diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h
index 9239fe5..f353e56 100644
--- a/include/qemu/hbitmap.h
+++ b/include/qemu/hbitmap.h
@@ -238,6 +238,14 @@ void hbitmap_deserialize_zeroes(HBitmap *hb, uint64_t start, uint64_t count,
void hbitmap_deserialize_finish(HBitmap *hb);
/**
+ * hbitmap_sha256:
+ * @bitmap: HBitmap to operate on.
+ *
+ * Returns SHA256 hash of the last level.
+ */
+char *hbitmap_sha256(const HBitmap *bitmap, Error **errp);
+
+/**
* hbitmap_free:
* @hb: HBitmap to operate on.
*
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 932f5bb..8646054 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1632,6 +1632,33 @@
'data': 'BlockDirtyBitmap' }
##
+# @BlockDirtyBitmapSha256:
+#
+# SHA256 hash of dirty bitmap data
+#
+# @sha256: ASCII representation of SHA256 bitmap hash
+#
+# Since: 2.9
+##
+ { 'struct': 'BlockDirtyBitmapSha256',
+ 'data': {'sha256': 'str'} }
+
+##
+# @x-debug-block-dirty-bitmap-sha256:
+#
+# Get bitmap SHA256
+#
+# Returns: BlockDirtyBitmapSha256 on success
+# If @node is not a valid block device, DeviceNotFound
+# If @name is not found or if hashing has failed, GenericError with an
+# explanation
+#
+# Since: 2.9
+##
+ { 'command': 'x-debug-block-dirty-bitmap-sha256',
+ 'data': 'BlockDirtyBitmap', 'returns': 'BlockDirtyBitmapSha256' }
+
+##
# @blockdev-mirror:
#
# Start mirroring a block device's writes to a new destination.
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 634394a..7a71b4d 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -526,7 +526,7 @@ tests/test-blockjob$(EXESUF): tests/test-blockjob.o $(test-block-obj-y) $(test-u
tests/test-blockjob-txn$(EXESUF): tests/test-blockjob-txn.o $(test-block-obj-y) $(test-util-obj-y)
tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(test-block-obj-y)
tests/test-iov$(EXESUF): tests/test-iov.o $(test-util-obj-y)
-tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o $(test-util-obj-y)
+tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o $(test-util-obj-y) $(test-crypto-obj-y)
tests/test-x86-cpuid$(EXESUF): tests/test-x86-cpuid.o
tests/test-xbzrle$(EXESUF): tests/test-xbzrle.o migration/xbzrle.o page_cache.o $(test-util-obj-y)
tests/test-cutils$(EXESUF): tests/test-cutils.o util/cutils.o
diff --git a/util/hbitmap.c b/util/hbitmap.c
index 35088e1..412b0fa 100644
--- a/util/hbitmap.c
+++ b/util/hbitmap.c
@@ -13,6 +13,7 @@
#include "qemu/hbitmap.h"
#include "qemu/host-utils.h"
#include "trace.h"
+#include "crypto/hash.h"
/* HBitmaps provides an array of bits. The bits are stored as usual in an
* array of unsigned longs, but HBitmap is also optimized to provide fast
@@ -689,3 +690,13 @@ void hbitmap_free_meta(HBitmap *hb)
hbitmap_free(hb->meta);
hb->meta = NULL;
}
+
+char *hbitmap_sha256(const HBitmap *bitmap, Error **errp)
+{
+ size_t size = bitmap->sizes[HBITMAP_LEVELS - 1] * sizeof(unsigned long);
+ char *data = (char *)bitmap->levels[HBITMAP_LEVELS - 1];
+ char *hash = NULL;
+ qcrypto_hash_digest(QCRYPTO_HASH_ALG_SHA256, data, size, &hash, errp);
+
+ return hash;
+}
--
1.8.3.1
On 02/13/2017 04:54 AM, Vladimir Sementsov-Ogievskiy wrote:
> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
> Reviewed-by: Max Reitz <mreitz@redhat.com>
This is simply the same as the version in the other two series, right?
Reviewed-by: John Snow <jsnow@redhat.com>
> ---
> block/dirty-bitmap.c | 5 +++++
> blockdev.c | 29 +++++++++++++++++++++++++++++
> include/block/dirty-bitmap.h | 2 ++
> include/qemu/hbitmap.h | 8 ++++++++
> qapi/block-core.json | 27 +++++++++++++++++++++++++++
> tests/Makefile.include | 2 +-
> util/hbitmap.c | 11 +++++++++++
> 7 files changed, 83 insertions(+), 1 deletion(-)
>
> diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
> index 32aa6eb..5bec99b 100644
> --- a/block/dirty-bitmap.c
> +++ b/block/dirty-bitmap.c
> @@ -558,3 +558,8 @@ BdrvDirtyBitmap *bdrv_next_dirty_bitmap(BlockDriverState *bs,
>
> return QLIST_NEXT(bitmap, list);
> }
> +
> +char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp)
> +{
> + return hbitmap_sha256(bitmap->bitmap, errp);
> +}
> diff --git a/blockdev.c b/blockdev.c
> index db82ac9..4d06885 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -2790,6 +2790,35 @@ void qmp_block_dirty_bitmap_clear(const char *node, const char *name,
> aio_context_release(aio_context);
> }
>
> +BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node,
> + const char *name,
> + Error **errp)
> +{
> + AioContext *aio_context;
> + BdrvDirtyBitmap *bitmap;
> + BlockDriverState *bs;
> + BlockDirtyBitmapSha256 *ret = NULL;
> + char *sha256;
> +
> + bitmap = block_dirty_bitmap_lookup(node, name, &bs, &aio_context, errp);
> + if (!bitmap || !bs) {
> + return NULL;
> + }
> +
> + sha256 = bdrv_dirty_bitmap_sha256(bitmap, errp);
> + if (sha256 == NULL) {
> + goto out;
> + }
> +
> + ret = g_new(BlockDirtyBitmapSha256, 1);
> + ret->sha256 = sha256;
> +
> +out:
> + aio_context_release(aio_context);
> +
> + return ret;
> +}
> +
> void hmp_drive_del(Monitor *mon, const QDict *qdict)
> {
> const char *id = qdict_get_str(qdict, "id");
> diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
> index 20b3ec7..ded872a 100644
> --- a/include/block/dirty-bitmap.h
> +++ b/include/block/dirty-bitmap.h
> @@ -78,4 +78,6 @@ void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap);
> BdrvDirtyBitmap *bdrv_next_dirty_bitmap(BlockDriverState *bs,
> BdrvDirtyBitmap *bitmap);
>
> +char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp);
> +
> #endif
> diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h
> index 9239fe5..f353e56 100644
> --- a/include/qemu/hbitmap.h
> +++ b/include/qemu/hbitmap.h
> @@ -238,6 +238,14 @@ void hbitmap_deserialize_zeroes(HBitmap *hb, uint64_t start, uint64_t count,
> void hbitmap_deserialize_finish(HBitmap *hb);
>
> /**
> + * hbitmap_sha256:
> + * @bitmap: HBitmap to operate on.
> + *
> + * Returns SHA256 hash of the last level.
> + */
> +char *hbitmap_sha256(const HBitmap *bitmap, Error **errp);
> +
> +/**
> * hbitmap_free:
> * @hb: HBitmap to operate on.
> *
> diff --git a/qapi/block-core.json b/qapi/block-core.json
> index 932f5bb..8646054 100644
> --- a/qapi/block-core.json
> +++ b/qapi/block-core.json
> @@ -1632,6 +1632,33 @@
> 'data': 'BlockDirtyBitmap' }
>
> ##
> +# @BlockDirtyBitmapSha256:
> +#
> +# SHA256 hash of dirty bitmap data
> +#
> +# @sha256: ASCII representation of SHA256 bitmap hash
> +#
> +# Since: 2.9
> +##
> + { 'struct': 'BlockDirtyBitmapSha256',
> + 'data': {'sha256': 'str'} }
> +
> +##
> +# @x-debug-block-dirty-bitmap-sha256:
> +#
> +# Get bitmap SHA256
> +#
> +# Returns: BlockDirtyBitmapSha256 on success
> +# If @node is not a valid block device, DeviceNotFound
> +# If @name is not found or if hashing has failed, GenericError with an
> +# explanation
> +#
> +# Since: 2.9
> +##
> + { 'command': 'x-debug-block-dirty-bitmap-sha256',
> + 'data': 'BlockDirtyBitmap', 'returns': 'BlockDirtyBitmapSha256' }
> +
> +##
> # @blockdev-mirror:
> #
> # Start mirroring a block device's writes to a new destination.
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index 634394a..7a71b4d 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -526,7 +526,7 @@ tests/test-blockjob$(EXESUF): tests/test-blockjob.o $(test-block-obj-y) $(test-u
> tests/test-blockjob-txn$(EXESUF): tests/test-blockjob-txn.o $(test-block-obj-y) $(test-util-obj-y)
> tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(test-block-obj-y)
> tests/test-iov$(EXESUF): tests/test-iov.o $(test-util-obj-y)
> -tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o $(test-util-obj-y)
> +tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o $(test-util-obj-y) $(test-crypto-obj-y)
> tests/test-x86-cpuid$(EXESUF): tests/test-x86-cpuid.o
> tests/test-xbzrle$(EXESUF): tests/test-xbzrle.o migration/xbzrle.o page_cache.o $(test-util-obj-y)
> tests/test-cutils$(EXESUF): tests/test-cutils.o util/cutils.o
> diff --git a/util/hbitmap.c b/util/hbitmap.c
> index 35088e1..412b0fa 100644
> --- a/util/hbitmap.c
> +++ b/util/hbitmap.c
> @@ -13,6 +13,7 @@
> #include "qemu/hbitmap.h"
> #include "qemu/host-utils.h"
> #include "trace.h"
> +#include "crypto/hash.h"
>
> /* HBitmaps provides an array of bits. The bits are stored as usual in an
> * array of unsigned longs, but HBitmap is also optimized to provide fast
> @@ -689,3 +690,13 @@ void hbitmap_free_meta(HBitmap *hb)
> hbitmap_free(hb->meta);
> hb->meta = NULL;
> }
> +
> +char *hbitmap_sha256(const HBitmap *bitmap, Error **errp)
> +{
> + size_t size = bitmap->sizes[HBITMAP_LEVELS - 1] * sizeof(unsigned long);
> + char *data = (char *)bitmap->levels[HBITMAP_LEVELS - 1];
> + char *hash = NULL;
> + qcrypto_hash_digest(QCRYPTO_HASH_ALG_SHA256, data, size, &hash, errp);
> +
> + return hash;
> +}
>
16.02.2017 03:35, John Snow wrote:
>
> On 02/13/2017 04:54 AM, Vladimir Sementsov-Ogievskiy wrote:
>> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
>> Reviewed-by: Max Reitz <mreitz@redhat.com>
> This is simply the same as the version in the other two series, right?
Yes. Context a bit differs... Aha, I've discovered that in migration I'm
adding bdrv_next_dirty_bitmap and in persistent -
bdrv_dirty_bitmap_next. Anyway, one series should be rebased after
applying the second..
>
> Reviewed-by: John Snow <jsnow@redhat.com>
>
>> ---
>> block/dirty-bitmap.c | 5 +++++
>> blockdev.c | 29 +++++++++++++++++++++++++++++
>> include/block/dirty-bitmap.h | 2 ++
>> include/qemu/hbitmap.h | 8 ++++++++
>> qapi/block-core.json | 27 +++++++++++++++++++++++++++
>> tests/Makefile.include | 2 +-
>> util/hbitmap.c | 11 +++++++++++
>> 7 files changed, 83 insertions(+), 1 deletion(-)
>>
>> diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
>> index 32aa6eb..5bec99b 100644
>> --- a/block/dirty-bitmap.c
>> +++ b/block/dirty-bitmap.c
>> @@ -558,3 +558,8 @@ BdrvDirtyBitmap *bdrv_next_dirty_bitmap(BlockDriverState *bs,
>>
>> return QLIST_NEXT(bitmap, list);
>> }
>> +
>> +char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp)
>> +{
>> + return hbitmap_sha256(bitmap->bitmap, errp);
>> +}
>> diff --git a/blockdev.c b/blockdev.c
>> index db82ac9..4d06885 100644
>> --- a/blockdev.c
>> +++ b/blockdev.c
>> @@ -2790,6 +2790,35 @@ void qmp_block_dirty_bitmap_clear(const char *node, const char *name,
>> aio_context_release(aio_context);
>> }
>>
>> +BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node,
>> + const char *name,
>> + Error **errp)
>> +{
>> + AioContext *aio_context;
>> + BdrvDirtyBitmap *bitmap;
>> + BlockDriverState *bs;
>> + BlockDirtyBitmapSha256 *ret = NULL;
>> + char *sha256;
>> +
>> + bitmap = block_dirty_bitmap_lookup(node, name, &bs, &aio_context, errp);
>> + if (!bitmap || !bs) {
>> + return NULL;
>> + }
>> +
>> + sha256 = bdrv_dirty_bitmap_sha256(bitmap, errp);
>> + if (sha256 == NULL) {
>> + goto out;
>> + }
>> +
>> + ret = g_new(BlockDirtyBitmapSha256, 1);
>> + ret->sha256 = sha256;
>> +
>> +out:
>> + aio_context_release(aio_context);
>> +
>> + return ret;
>> +}
>> +
>> void hmp_drive_del(Monitor *mon, const QDict *qdict)
>> {
>> const char *id = qdict_get_str(qdict, "id");
>> diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
>> index 20b3ec7..ded872a 100644
>> --- a/include/block/dirty-bitmap.h
>> +++ b/include/block/dirty-bitmap.h
>> @@ -78,4 +78,6 @@ void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap);
>> BdrvDirtyBitmap *bdrv_next_dirty_bitmap(BlockDriverState *bs,
>> BdrvDirtyBitmap *bitmap);
>>
>> +char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp);
>> +
>> #endif
>> diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h
>> index 9239fe5..f353e56 100644
>> --- a/include/qemu/hbitmap.h
>> +++ b/include/qemu/hbitmap.h
>> @@ -238,6 +238,14 @@ void hbitmap_deserialize_zeroes(HBitmap *hb, uint64_t start, uint64_t count,
>> void hbitmap_deserialize_finish(HBitmap *hb);
>>
>> /**
>> + * hbitmap_sha256:
>> + * @bitmap: HBitmap to operate on.
>> + *
>> + * Returns SHA256 hash of the last level.
>> + */
>> +char *hbitmap_sha256(const HBitmap *bitmap, Error **errp);
>> +
>> +/**
>> * hbitmap_free:
>> * @hb: HBitmap to operate on.
>> *
>> diff --git a/qapi/block-core.json b/qapi/block-core.json
>> index 932f5bb..8646054 100644
>> --- a/qapi/block-core.json
>> +++ b/qapi/block-core.json
>> @@ -1632,6 +1632,33 @@
>> 'data': 'BlockDirtyBitmap' }
>>
>> ##
>> +# @BlockDirtyBitmapSha256:
>> +#
>> +# SHA256 hash of dirty bitmap data
>> +#
>> +# @sha256: ASCII representation of SHA256 bitmap hash
>> +#
>> +# Since: 2.9
>> +##
>> + { 'struct': 'BlockDirtyBitmapSha256',
>> + 'data': {'sha256': 'str'} }
>> +
>> +##
>> +# @x-debug-block-dirty-bitmap-sha256:
>> +#
>> +# Get bitmap SHA256
>> +#
>> +# Returns: BlockDirtyBitmapSha256 on success
>> +# If @node is not a valid block device, DeviceNotFound
>> +# If @name is not found or if hashing has failed, GenericError with an
>> +# explanation
>> +#
>> +# Since: 2.9
>> +##
>> + { 'command': 'x-debug-block-dirty-bitmap-sha256',
>> + 'data': 'BlockDirtyBitmap', 'returns': 'BlockDirtyBitmapSha256' }
>> +
>> +##
>> # @blockdev-mirror:
>> #
>> # Start mirroring a block device's writes to a new destination.
>> diff --git a/tests/Makefile.include b/tests/Makefile.include
>> index 634394a..7a71b4d 100644
>> --- a/tests/Makefile.include
>> +++ b/tests/Makefile.include
>> @@ -526,7 +526,7 @@ tests/test-blockjob$(EXESUF): tests/test-blockjob.o $(test-block-obj-y) $(test-u
>> tests/test-blockjob-txn$(EXESUF): tests/test-blockjob-txn.o $(test-block-obj-y) $(test-util-obj-y)
>> tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(test-block-obj-y)
>> tests/test-iov$(EXESUF): tests/test-iov.o $(test-util-obj-y)
>> -tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o $(test-util-obj-y)
>> +tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o $(test-util-obj-y) $(test-crypto-obj-y)
>> tests/test-x86-cpuid$(EXESUF): tests/test-x86-cpuid.o
>> tests/test-xbzrle$(EXESUF): tests/test-xbzrle.o migration/xbzrle.o page_cache.o $(test-util-obj-y)
>> tests/test-cutils$(EXESUF): tests/test-cutils.o util/cutils.o
>> diff --git a/util/hbitmap.c b/util/hbitmap.c
>> index 35088e1..412b0fa 100644
>> --- a/util/hbitmap.c
>> +++ b/util/hbitmap.c
>> @@ -13,6 +13,7 @@
>> #include "qemu/hbitmap.h"
>> #include "qemu/host-utils.h"
>> #include "trace.h"
>> +#include "crypto/hash.h"
>>
>> /* HBitmaps provides an array of bits. The bits are stored as usual in an
>> * array of unsigned longs, but HBitmap is also optimized to provide fast
>> @@ -689,3 +690,13 @@ void hbitmap_free_meta(HBitmap *hb)
>> hbitmap_free(hb->meta);
>> hb->meta = NULL;
>> }
>> +
>> +char *hbitmap_sha256(const HBitmap *bitmap, Error **errp)
>> +{
>> + size_t size = bitmap->sizes[HBITMAP_LEVELS - 1] * sizeof(unsigned long);
>> + char *data = (char *)bitmap->levels[HBITMAP_LEVELS - 1];
>> + char *hash = NULL;
>> + qcrypto_hash_digest(QCRYPTO_HASH_ALG_SHA256, data, size, &hash, errp);
>> +
>> + return hash;
>> +}
>>
--
Best regards,
Vladimir
© 2016 - 2026 Red Hat, Inc.