nbd patches for 2019-02-11
- Add qcow2 bitmap details to 'qemu-img info' -----BEGIN PGP SIGNATURE----- iQEcBAABCAAGBQJcYd1IAAoJEKeha0olJ0Nq6WMH/1gUi2tc6719yz+pvEwBv7VI D720qBoSwEFyrRn1Nk1S3KjKHZ/jemE9bWKsGaIjOf8bIDqlgbElVh/Fc7aBAE6G eNGy5zadzhSXDmoNFpqSKjA91OEGPlNm4zMZpqtVQeaGyGzh9PkkPdOkkQZj3M9J wf4gmgcFjHbsLgItEx7umn0j0SlDeEyl6WUAKsObEl0Crd+TFoORAimIU6+eoX97 YZ4+h4s7G+A7cXEPJyfy9c7Et5w9WGRqI0ITBWo7Z9rNLrQt0iT0sgSiZVGgtNbf eac9KJiUAkomucC2wUtASJeEKserRdzVpF4FwzA0f4xeDwPZFxtq/+9ncZbWcbs= =os/6 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2019-02-11' into staging nbd patches for 2019-02-11 - Add qcow2 bitmap details to 'qemu-img info' # gpg: Signature made Mon 11 Feb 2019 20:38:32 GMT # gpg: using RSA key A7A16B4A2527436A # 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-nbd-2019-02-11: qcow2: list of bitmaps new test 242 qcow2: Add list of bitmaps to ImageInfoSpecificQCow2 bdrv_query_image_info Error parameter added nbd/server: Kill pointless shadowed variable Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
d85e60e993
5
block.c
5
block.c
|
@ -4462,11 +4462,12 @@ int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
|||
return drv->bdrv_get_info(bs, bdi);
|
||||
}
|
||||
|
||||
ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs)
|
||||
ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs,
|
||||
Error **errp)
|
||||
{
|
||||
BlockDriver *drv = bs->drv;
|
||||
if (drv && drv->bdrv_get_specific_info) {
|
||||
return drv->bdrv_get_specific_info(bs);
|
||||
return drv->bdrv_get_specific_info(bs, errp);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -594,20 +594,17 @@ static int block_crypto_get_info_luks(BlockDriverState *bs,
|
|||
}
|
||||
|
||||
static ImageInfoSpecific *
|
||||
block_crypto_get_specific_info_luks(BlockDriverState *bs)
|
||||
block_crypto_get_specific_info_luks(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
BlockCrypto *crypto = bs->opaque;
|
||||
ImageInfoSpecific *spec_info;
|
||||
QCryptoBlockInfo *info;
|
||||
|
||||
info = qcrypto_block_get_info(crypto->block, NULL);
|
||||
info = qcrypto_block_get_info(crypto->block, errp);
|
||||
if (!info) {
|
||||
return NULL;
|
||||
}
|
||||
if (info->format != Q_CRYPTO_BLOCK_FORMAT_LUKS) {
|
||||
qapi_free_QCryptoBlockInfo(info);
|
||||
return NULL;
|
||||
}
|
||||
assert(info->format == Q_CRYPTO_BLOCK_FORMAT_LUKS);
|
||||
|
||||
spec_info = g_new(ImageInfoSpecific, 1);
|
||||
spec_info->type = IMAGE_INFO_SPECIFIC_KIND_LUKS;
|
||||
|
|
|
@ -282,7 +282,12 @@ void bdrv_query_image_info(BlockDriverState *bs,
|
|||
info->dirty_flag = bdi.is_dirty;
|
||||
info->has_dirty_flag = true;
|
||||
}
|
||||
info->format_specific = bdrv_get_specific_info(bs);
|
||||
info->format_specific = bdrv_get_specific_info(bs, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
qapi_free_ImageInfo(info);
|
||||
goto out;
|
||||
}
|
||||
info->has_format_specific = info->format_specific != NULL;
|
||||
|
||||
backing_filename = bs->backing_file;
|
||||
|
|
|
@ -1006,6 +1006,82 @@ fail:
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
static Qcow2BitmapInfoFlagsList *get_bitmap_info_flags(uint32_t flags)
|
||||
{
|
||||
Qcow2BitmapInfoFlagsList *list = NULL;
|
||||
Qcow2BitmapInfoFlagsList **plist = &list;
|
||||
int i;
|
||||
|
||||
static const struct {
|
||||
int bme; /* Bitmap directory entry flags */
|
||||
int info; /* The flags to report to the user */
|
||||
} map[] = {
|
||||
{ BME_FLAG_IN_USE, QCOW2_BITMAP_INFO_FLAGS_IN_USE },
|
||||
{ BME_FLAG_AUTO, QCOW2_BITMAP_INFO_FLAGS_AUTO },
|
||||
};
|
||||
|
||||
int map_size = ARRAY_SIZE(map);
|
||||
|
||||
for (i = 0; i < map_size; ++i) {
|
||||
if (flags & map[i].bme) {
|
||||
Qcow2BitmapInfoFlagsList *entry =
|
||||
g_new0(Qcow2BitmapInfoFlagsList, 1);
|
||||
entry->value = map[i].info;
|
||||
*plist = entry;
|
||||
plist = &entry->next;
|
||||
flags &= ~map[i].bme;
|
||||
}
|
||||
}
|
||||
/* Check if the BME_* mapping above is complete */
|
||||
assert(!flags);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/*
|
||||
* qcow2_get_bitmap_info_list()
|
||||
* Returns a list of QCOW2 bitmap details.
|
||||
* In case of no bitmaps, the function returns NULL and
|
||||
* the @errp parameter is not set.
|
||||
* When bitmap information can not be obtained, the function returns
|
||||
* NULL and the @errp parameter is set.
|
||||
*/
|
||||
Qcow2BitmapInfoList *qcow2_get_bitmap_info_list(BlockDriverState *bs,
|
||||
Error **errp)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
Qcow2BitmapList *bm_list;
|
||||
Qcow2Bitmap *bm;
|
||||
Qcow2BitmapInfoList *list = NULL;
|
||||
Qcow2BitmapInfoList **plist = &list;
|
||||
|
||||
if (s->nb_bitmaps == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
|
||||
s->bitmap_directory_size, errp);
|
||||
if (bm_list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QSIMPLEQ_FOREACH(bm, bm_list, entry) {
|
||||
Qcow2BitmapInfo *info = g_new0(Qcow2BitmapInfo, 1);
|
||||
Qcow2BitmapInfoList *obj = g_new0(Qcow2BitmapInfoList, 1);
|
||||
info->granularity = 1U << bm->granularity_bits;
|
||||
info->name = g_strdup(bm->name);
|
||||
info->flags = get_bitmap_info_flags(bm->flags & ~BME_RESERVED_FLAGS);
|
||||
obj->value = info;
|
||||
*plist = obj;
|
||||
plist = &obj->next;
|
||||
}
|
||||
|
||||
bitmap_list_free(bm_list);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs, bool *header_updated,
|
||||
Error **errp)
|
||||
{
|
||||
|
|
|
@ -4368,20 +4368,26 @@ static int qcow2_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs)
|
||||
static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs,
|
||||
Error **errp)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
ImageInfoSpecific *spec_info;
|
||||
QCryptoBlockInfo *encrypt_info = NULL;
|
||||
Error *local_err = NULL;
|
||||
|
||||
if (s->crypto != NULL) {
|
||||
encrypt_info = qcrypto_block_get_info(s->crypto, &error_abort);
|
||||
encrypt_info = qcrypto_block_get_info(s->crypto, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
spec_info = g_new(ImageInfoSpecific, 1);
|
||||
*spec_info = (ImageInfoSpecific){
|
||||
.type = IMAGE_INFO_SPECIFIC_KIND_QCOW2,
|
||||
.u.qcow2.data = g_new(ImageInfoSpecificQCow2, 1),
|
||||
.u.qcow2.data = g_new0(ImageInfoSpecificQCow2, 1),
|
||||
};
|
||||
if (s->qcow_version == 2) {
|
||||
*spec_info->u.qcow2.data = (ImageInfoSpecificQCow2){
|
||||
|
@ -4389,6 +4395,13 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs)
|
|||
.refcount_bits = s->refcount_bits,
|
||||
};
|
||||
} else if (s->qcow_version == 3) {
|
||||
Qcow2BitmapInfoList *bitmaps;
|
||||
bitmaps = qcow2_get_bitmap_info_list(bs, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
qapi_free_ImageInfoSpecific(spec_info);
|
||||
return NULL;
|
||||
}
|
||||
*spec_info->u.qcow2.data = (ImageInfoSpecificQCow2){
|
||||
.compat = g_strdup("1.1"),
|
||||
.lazy_refcounts = s->compatible_features &
|
||||
|
@ -4398,6 +4411,8 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs)
|
|||
QCOW2_INCOMPAT_CORRUPT,
|
||||
.has_corrupt = true,
|
||||
.refcount_bits = s->refcount_bits,
|
||||
.has_bitmaps = !!bitmaps,
|
||||
.bitmaps = bitmaps,
|
||||
};
|
||||
} else {
|
||||
/* if this assertion fails, this probably means a new version was
|
||||
|
|
|
@ -684,6 +684,8 @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
|
|||
void **refcount_table,
|
||||
int64_t *refcount_table_size);
|
||||
bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, Error **errp);
|
||||
Qcow2BitmapInfoList *qcow2_get_bitmap_info_list(BlockDriverState *bs,
|
||||
Error **errp);
|
||||
int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs, bool *header_updated,
|
||||
Error **errp);
|
||||
int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp);
|
||||
|
|
|
@ -2543,7 +2543,8 @@ static int coroutine_fn vmdk_co_check(BlockDriverState *bs,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs)
|
||||
static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs,
|
||||
Error **errp)
|
||||
{
|
||||
int i;
|
||||
BDRVVmdkState *s = bs->opaque;
|
||||
|
|
|
@ -478,7 +478,8 @@ const char *bdrv_get_device_name(const BlockDriverState *bs);
|
|||
const char *bdrv_get_device_or_node_name(const BlockDriverState *bs);
|
||||
int bdrv_get_flags(BlockDriverState *bs);
|
||||
int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
|
||||
ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs);
|
||||
ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs,
|
||||
Error **errp);
|
||||
void bdrv_round_to_clusters(BlockDriverState *bs,
|
||||
int64_t offset, int64_t bytes,
|
||||
int64_t *cluster_offset,
|
||||
|
|
|
@ -319,7 +319,8 @@ struct BlockDriver {
|
|||
const char *name,
|
||||
Error **errp);
|
||||
int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
|
||||
ImageInfoSpecific *(*bdrv_get_specific_info)(BlockDriverState *bs);
|
||||
ImageInfoSpecific *(*bdrv_get_specific_info)(BlockDriverState *bs,
|
||||
Error **errp);
|
||||
|
||||
int coroutine_fn (*bdrv_save_vmstate)(BlockDriverState *bs,
|
||||
QEMUIOVector *qiov,
|
||||
|
|
|
@ -1495,7 +1495,6 @@ NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset,
|
|||
|
||||
if (bitmap) {
|
||||
BdrvDirtyBitmap *bm = NULL;
|
||||
BlockDriverState *bs = blk_bs(blk);
|
||||
|
||||
while (true) {
|
||||
bm = bdrv_find_dirty_bitmap(bs, bitmap);
|
||||
|
|
|
@ -69,6 +69,8 @@
|
|||
# @encrypt: details about encryption parameters; only set if image
|
||||
# is encrypted (since 2.10)
|
||||
#
|
||||
# @bitmaps: A list of qcow2 bitmap details (since 4.0)
|
||||
#
|
||||
# Since: 1.7
|
||||
##
|
||||
{ 'struct': 'ImageInfoSpecificQCow2',
|
||||
|
@ -77,7 +79,8 @@
|
|||
'*lazy-refcounts': 'bool',
|
||||
'*corrupt': 'bool',
|
||||
'refcount-bits': 'int',
|
||||
'*encrypt': 'ImageInfoSpecificQCow2Encryption'
|
||||
'*encrypt': 'ImageInfoSpecificQCow2Encryption',
|
||||
'*bitmaps': ['Qcow2BitmapInfo']
|
||||
} }
|
||||
|
||||
##
|
||||
|
@ -453,6 +456,42 @@
|
|||
'data': {'*name': 'str', 'count': 'int', 'granularity': 'uint32',
|
||||
'status': 'DirtyBitmapStatus'} }
|
||||
|
||||
##
|
||||
# @Qcow2BitmapInfoFlags:
|
||||
#
|
||||
# An enumeration of flags that a bitmap can report to the user.
|
||||
#
|
||||
# @in-use: This flag is set by any process actively modifying the qcow2 file,
|
||||
# and cleared when the updated bitmap is flushed to the qcow2 image.
|
||||
# The presence of this flag in an offline image means that the bitmap
|
||||
# was not saved correctly after its last usage, and may contain
|
||||
# inconsistent data.
|
||||
#
|
||||
# @auto: The bitmap must reflect all changes of the virtual disk by any
|
||||
# application that would write to this qcow2 file.
|
||||
#
|
||||
# Since: 4.0
|
||||
##
|
||||
{ 'enum': 'Qcow2BitmapInfoFlags',
|
||||
'data': ['in-use', 'auto'] }
|
||||
|
||||
##
|
||||
# @Qcow2BitmapInfo:
|
||||
#
|
||||
# Qcow2 bitmap information.
|
||||
#
|
||||
# @name: the name of the bitmap
|
||||
#
|
||||
# @granularity: granularity of the bitmap in bytes
|
||||
#
|
||||
# @flags: flags of the bitmap
|
||||
#
|
||||
# Since: 4.0
|
||||
##
|
||||
{ 'struct': 'Qcow2BitmapInfo',
|
||||
'data': {'name': 'str', 'granularity': 'uint32',
|
||||
'flags': ['Qcow2BitmapInfoFlags'] } }
|
||||
|
||||
##
|
||||
# @BlockLatencyHistogramInfo:
|
||||
#
|
||||
|
|
|
@ -1661,6 +1661,7 @@ static int info_f(BlockBackend *blk, int argc, char **argv)
|
|||
BlockDriverState *bs = blk_bs(blk);
|
||||
BlockDriverInfo bdi;
|
||||
ImageInfoSpecific *spec_info;
|
||||
Error *local_err = NULL;
|
||||
char s1[64], s2[64];
|
||||
int ret;
|
||||
|
||||
|
@ -1682,7 +1683,11 @@ static int info_f(BlockBackend *blk, int argc, char **argv)
|
|||
printf("cluster size: %s\n", s1);
|
||||
printf("vm state offset: %s\n", s2);
|
||||
|
||||
spec_info = bdrv_get_specific_info(bs);
|
||||
spec_info = bdrv_get_specific_info(bs, &local_err);
|
||||
if (local_err) {
|
||||
error_report_err(local_err);
|
||||
return -EIO;
|
||||
}
|
||||
if (spec_info) {
|
||||
printf("Format specific information:\n");
|
||||
bdrv_image_info_specific_dump(fprintf, stdout, spec_info);
|
||||
|
|
104
tests/qemu-iotests/242
Executable file
104
tests/qemu-iotests/242
Executable file
|
@ -0,0 +1,104 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Test for qcow2 bitmap printed information
|
||||
#
|
||||
# Copyright (c) 2019 Virtuozzo International GmbH
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import iotests
|
||||
import json
|
||||
from iotests import qemu_img_create, qemu_io, qemu_img_pipe, \
|
||||
file_path, img_info_log, log, filter_qemu_io
|
||||
|
||||
iotests.verify_image_format(supported_fmts=['qcow2'])
|
||||
|
||||
disk = file_path('disk')
|
||||
chunk = 256 * 1024
|
||||
bitmap_flag_unknown = 1 << 2
|
||||
# flag_offset = 5*cluster_size + flag_offset_in_bitmap_directory_entry
|
||||
flag_offset = 0x5000f
|
||||
|
||||
|
||||
def print_bitmap(extra_args):
|
||||
log('qemu-img info dump:\n')
|
||||
img_info_log(disk, extra_args=extra_args)
|
||||
result = json.loads(qemu_img_pipe('info', '--force-share',
|
||||
'--output=json', disk))
|
||||
if 'bitmaps' in result['format-specific']['data']:
|
||||
bitmaps = result['format-specific']['data']['bitmaps']
|
||||
log('The same bitmaps in JSON format:')
|
||||
log(bitmaps, indent=2)
|
||||
else:
|
||||
log('No bitmap in JSON format output')
|
||||
|
||||
|
||||
def add_bitmap(bitmap_number, persistent, disabled):
|
||||
granularity = 1 << (13 + bitmap_number)
|
||||
bitmap_name = 'bitmap-' + str(bitmap_number-1)
|
||||
vm = iotests.VM().add_drive(disk)
|
||||
vm.launch()
|
||||
vm.qmp_log('block-dirty-bitmap-add', node='drive0', name=bitmap_name,
|
||||
granularity=granularity, persistent=persistent,
|
||||
disabled=disabled)
|
||||
vm.shutdown()
|
||||
|
||||
|
||||
def write_to_disk(offset, size):
|
||||
write = 'write {} {}'.format(offset, size)
|
||||
log(qemu_io('-c', write, disk), filters=[filter_qemu_io])
|
||||
|
||||
|
||||
def toggle_flag(offset):
|
||||
with open(disk, "r+b") as f:
|
||||
f.seek(offset, 0)
|
||||
c = f.read(1)
|
||||
toggled = chr(ord(c) ^ bitmap_flag_unknown)
|
||||
f.seek(-1, 1)
|
||||
f.write(toggled)
|
||||
|
||||
|
||||
qemu_img_create('-f', iotests.imgfmt, disk, '1M')
|
||||
|
||||
for num in range(1, 4):
|
||||
disabled = False
|
||||
if num == 2:
|
||||
disabled = True
|
||||
log('Test {}'.format(num))
|
||||
add_bitmap(num, num > 1, disabled)
|
||||
write_to_disk((num-1) * chunk, chunk)
|
||||
print_bitmap([])
|
||||
log('')
|
||||
|
||||
vm = iotests.VM().add_drive(disk)
|
||||
vm.launch()
|
||||
num += 1
|
||||
log('Test {}\nChecking "in-use" flag...'.format(num))
|
||||
print_bitmap(['--force-share'])
|
||||
vm.shutdown()
|
||||
|
||||
num += 1
|
||||
log('\nTest {}'.format(num))
|
||||
qemu_img_create('-f', iotests.imgfmt, disk, '1M')
|
||||
add_bitmap(1, True, False)
|
||||
log('Write an unknown bitmap flag \'{}\' into a new QCOW2 image at offset {}'
|
||||
.format(hex(bitmap_flag_unknown), flag_offset))
|
||||
toggle_flag(flag_offset)
|
||||
img_info_log(disk)
|
||||
toggle_flag(flag_offset)
|
||||
log('Unset the unknown bitmap flag \'{}\' in the bitmap directory entry:\n'
|
||||
.format(hex(bitmap_flag_unknown)))
|
||||
img_info_log(disk)
|
||||
log('Test complete')
|
166
tests/qemu-iotests/242.out
Normal file
166
tests/qemu-iotests/242.out
Normal file
|
@ -0,0 +1,166 @@
|
|||
Test 1
|
||||
{"execute": "block-dirty-bitmap-add", "arguments": {"disabled": false, "granularity": 16384, "name": "bitmap-0", "node": "drive0", "persistent": false}}
|
||||
{"return": {}}
|
||||
wrote 262144/262144 bytes at offset 0
|
||||
256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
qemu-img info dump:
|
||||
|
||||
image: TEST_IMG
|
||||
file format: IMGFMT
|
||||
virtual size: 1.0M (1048576 bytes)
|
||||
cluster_size: 65536
|
||||
Format specific information:
|
||||
compat: 1.1
|
||||
lazy refcounts: false
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
|
||||
No bitmap in JSON format output
|
||||
|
||||
Test 2
|
||||
{"execute": "block-dirty-bitmap-add", "arguments": {"disabled": true, "granularity": 32768, "name": "bitmap-1", "node": "drive0", "persistent": true}}
|
||||
{"return": {}}
|
||||
wrote 262144/262144 bytes at offset 262144
|
||||
256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
qemu-img info dump:
|
||||
|
||||
image: TEST_IMG
|
||||
file format: IMGFMT
|
||||
virtual size: 1.0M (1048576 bytes)
|
||||
cluster_size: 65536
|
||||
Format specific information:
|
||||
compat: 1.1
|
||||
lazy refcounts: false
|
||||
bitmaps:
|
||||
[0]:
|
||||
flags:
|
||||
name: bitmap-1
|
||||
granularity: 32768
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
|
||||
The same bitmaps in JSON format:
|
||||
[
|
||||
{
|
||||
"flags": [],
|
||||
"granularity": 32768,
|
||||
"name": "bitmap-1"
|
||||
}
|
||||
]
|
||||
|
||||
Test 3
|
||||
{"execute": "block-dirty-bitmap-add", "arguments": {"disabled": false, "granularity": 65536, "name": "bitmap-2", "node": "drive0", "persistent": true}}
|
||||
{"return": {}}
|
||||
wrote 262144/262144 bytes at offset 524288
|
||||
256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
qemu-img info dump:
|
||||
|
||||
image: TEST_IMG
|
||||
file format: IMGFMT
|
||||
virtual size: 1.0M (1048576 bytes)
|
||||
cluster_size: 65536
|
||||
Format specific information:
|
||||
compat: 1.1
|
||||
lazy refcounts: false
|
||||
bitmaps:
|
||||
[0]:
|
||||
flags:
|
||||
name: bitmap-1
|
||||
granularity: 32768
|
||||
[1]:
|
||||
flags:
|
||||
[0]: auto
|
||||
name: bitmap-2
|
||||
granularity: 65536
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
|
||||
The same bitmaps in JSON format:
|
||||
[
|
||||
{
|
||||
"flags": [],
|
||||
"granularity": 32768,
|
||||
"name": "bitmap-1"
|
||||
},
|
||||
{
|
||||
"flags": [
|
||||
"auto"
|
||||
],
|
||||
"granularity": 65536,
|
||||
"name": "bitmap-2"
|
||||
}
|
||||
]
|
||||
|
||||
Test 4
|
||||
Checking "in-use" flag...
|
||||
qemu-img info dump:
|
||||
|
||||
image: TEST_IMG
|
||||
file format: IMGFMT
|
||||
virtual size: 1.0M (1048576 bytes)
|
||||
cluster_size: 65536
|
||||
Format specific information:
|
||||
compat: 1.1
|
||||
lazy refcounts: false
|
||||
bitmaps:
|
||||
[0]:
|
||||
flags:
|
||||
[0]: in-use
|
||||
name: bitmap-1
|
||||
granularity: 32768
|
||||
[1]:
|
||||
flags:
|
||||
[0]: in-use
|
||||
[1]: auto
|
||||
name: bitmap-2
|
||||
granularity: 65536
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
|
||||
The same bitmaps in JSON format:
|
||||
[
|
||||
{
|
||||
"flags": [
|
||||
"in-use"
|
||||
],
|
||||
"granularity": 32768,
|
||||
"name": "bitmap-1"
|
||||
},
|
||||
{
|
||||
"flags": [
|
||||
"in-use",
|
||||
"auto"
|
||||
],
|
||||
"granularity": 65536,
|
||||
"name": "bitmap-2"
|
||||
}
|
||||
]
|
||||
|
||||
Test 5
|
||||
{"execute": "block-dirty-bitmap-add", "arguments": {"disabled": false, "granularity": 16384, "name": "bitmap-0", "node": "drive0", "persistent": true}}
|
||||
{"return": {}}
|
||||
Write an unknown bitmap flag '0x4' into a new QCOW2 image at offset 327695
|
||||
qemu-img: Could not open 'TEST_IMG': Bitmap 'bitmap-0' doesn't satisfy the constraints
|
||||
|
||||
Unset the unknown bitmap flag '0x4' in the bitmap directory entry:
|
||||
|
||||
image: TEST_IMG
|
||||
file format: IMGFMT
|
||||
virtual size: 1.0M (1048576 bytes)
|
||||
cluster_size: 65536
|
||||
Format specific information:
|
||||
compat: 1.1
|
||||
lazy refcounts: false
|
||||
bitmaps:
|
||||
[0]:
|
||||
flags:
|
||||
[0]: auto
|
||||
name: bitmap-0
|
||||
granularity: 16384
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
|
||||
Test complete
|
|
@ -238,3 +238,4 @@
|
|||
238 auto quick
|
||||
239 rw auto quick
|
||||
240 auto quick
|
||||
242 rw auto quick
|
||||
|
|
Loading…
Reference in a new issue