mirror of https://github.com/xemu-project/xemu.git
Block patches:
- qcow2 subclusters (extended L2 entries) -----BEGIN PGP SIGNATURE----- iQFGBAABCAAwFiEEkb62CjDbPohX0Rgp9AfbAGHVz0AFAl9GESASHG1yZWl0ekBy ZWRoYXQuY29tAAoJEPQH2wBh1c9AKNsH/1iG6YVi9c25BoE/3nnu1yJSQiVqpjzt hRsV0LzqqaUd3r/yLx5wyFpmcOC+iqJsNrrJCMR9GqMCXyOiH2S9xZs9rVnL44dr gt8bhbAfLTQr6ix9rzJUekRHWa0oeoECS6FLdkAnc6xB5Tf5YwOXdX8FYGiR6M9Q mibqBIRbQX10ptdZjRpQaDNiTAGMoXfXa1YxTfeFuvW/vwnP34mT+K1B6o1CxDdL G9mG9atF0Zu5qjovapw0a/lnEppyxIJXSpU0s6s7dGbuAzw8IRM5utJLSNu4hL/c fTxmAnhcB6bFPaMHHMP4izQFds1M1NBZFX/4ji+u0cE8CgTGSqmupRA= =j4jq -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/maxreitz/tags/pull-block-2020-08-26' into staging Block patches: - qcow2 subclusters (extended L2 entries) # gpg: Signature made Wed 26 Aug 2020 08:37:04 BST # gpg: using RSA key 91BEB60A30DB3E8857D11829F407DB0061D5CF40 # gpg: issuer "mreitz@redhat.com" # gpg: Good signature from "Max Reitz <mreitz@redhat.com>" [full] # Primary key fingerprint: 91BE B60A 30DB 3E88 57D1 1829 F407 DB00 61D5 CF40 * remotes/maxreitz/tags/pull-block-2020-08-26: (34 commits) iotests: Add tests for qcow2 images with extended L2 entries qcow2: Assert that expand_zero_clusters_in_l1() does not support subclusters qcow2: Allow preallocation and backing files if extended_l2 is set qcow2: Add the 'extended_l2' option and the QCOW2_INCOMPAT_EXTL2 bit qcow2: Add prealloc field to QCowL2Meta qcow2: Add subcluster support to qcow2_measure() qcow2: Add subcluster support to qcow2_co_pwrite_zeroes() qcow2: Add subcluster support to handle_alloc_space() qcow2: Clear the L2 bitmap when allocating a compressed cluster qcow2: Update L2 bitmap in qcow2_alloc_cluster_link_l2() qcow2: Add subcluster support to check_refcounts_l2() qcow2: Add subcluster support to discard_in_l2_slice() qcow2: Add subcluster support to zero_in_l2_slice() qcow2: Add subcluster support to qcow2_get_host_offset() qcow2: Add subcluster support to calculate_l2_meta() qcow2: Handle QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC qcow2: Replace QCOW2_CLUSTER_* with QCOW2_SUBCLUSTER_* qcow2: Add cluster type parameter to qcow2_get_host_offset() qcow2: Add qcow2_cluster_is_allocated() qcow2: Add qcow2_get_subcluster_range_type() ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
25f6dc28a3
File diff suppressed because it is too large
Load Diff
|
@ -1254,7 +1254,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
|
|||
l2_slice = NULL;
|
||||
l1_table = NULL;
|
||||
l1_size2 = l1_size * sizeof(uint64_t);
|
||||
slice_size2 = s->l2_slice_size * sizeof(uint64_t);
|
||||
slice_size2 = s->l2_slice_size * l2_entry_size(s);
|
||||
n_slices = s->cluster_size / slice_size2;
|
||||
|
||||
s->cache_discards = true;
|
||||
|
@ -1310,7 +1310,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
|
|||
uint64_t cluster_index;
|
||||
uint64_t offset;
|
||||
|
||||
entry = be64_to_cpu(l2_slice[j]);
|
||||
entry = get_l2_entry(s, l2_slice, j);
|
||||
old_entry = entry;
|
||||
entry &= ~QCOW_OFLAG_COPIED;
|
||||
offset = entry & L2E_OFFSET_MASK;
|
||||
|
@ -1384,7 +1384,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
|
|||
qcow2_cache_set_dependency(bs, s->l2_table_cache,
|
||||
s->refcount_block_cache);
|
||||
}
|
||||
l2_slice[j] = cpu_to_be64(entry);
|
||||
set_l2_entry(s, l2_slice, j, entry);
|
||||
qcow2_cache_entry_mark_dirty(s->l2_table_cache,
|
||||
l2_slice);
|
||||
}
|
||||
|
@ -1605,7 +1605,7 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
|
|||
int i, l2_size, nb_csectors, ret;
|
||||
|
||||
/* Read L2 table from disk */
|
||||
l2_size = s->l2_size * sizeof(uint64_t);
|
||||
l2_size = s->l2_size * l2_entry_size(s);
|
||||
l2_table = g_malloc(l2_size);
|
||||
|
||||
ret = bdrv_pread(bs->file, l2_offset, l2_table, l2_size);
|
||||
|
@ -1617,7 +1617,7 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
|
|||
|
||||
/* Do the actual checks */
|
||||
for(i = 0; i < s->l2_size; i++) {
|
||||
l2_entry = be64_to_cpu(l2_table[i]);
|
||||
l2_entry = get_l2_entry(s, l2_table, i);
|
||||
|
||||
switch (qcow2_get_cluster_type(bs, l2_entry)) {
|
||||
case QCOW2_CLUSTER_COMPRESSED:
|
||||
|
@ -1669,26 +1669,33 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
|
|||
|
||||
/* Correct offsets are cluster aligned */
|
||||
if (offset_into_cluster(s, offset)) {
|
||||
bool contains_data;
|
||||
res->corruptions++;
|
||||
|
||||
if (qcow2_get_cluster_type(bs, l2_entry) ==
|
||||
QCOW2_CLUSTER_ZERO_ALLOC)
|
||||
{
|
||||
fprintf(stderr, "%s offset=%" PRIx64 ": Preallocated zero "
|
||||
if (has_subclusters(s)) {
|
||||
uint64_t l2_bitmap = get_l2_bitmap(s, l2_table, i);
|
||||
contains_data = (l2_bitmap & QCOW_L2_BITMAP_ALL_ALLOC);
|
||||
} else {
|
||||
contains_data = !(l2_entry & QCOW_OFLAG_ZERO);
|
||||
}
|
||||
|
||||
if (!contains_data) {
|
||||
fprintf(stderr, "%s offset=%" PRIx64 ": Preallocated "
|
||||
"cluster is not properly aligned; L2 entry "
|
||||
"corrupted.\n",
|
||||
fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR",
|
||||
offset);
|
||||
if (fix & BDRV_FIX_ERRORS) {
|
||||
int idx = i * (l2_entry_size(s) / sizeof(uint64_t));
|
||||
uint64_t l2e_offset =
|
||||
l2_offset + (uint64_t)i * sizeof(uint64_t);
|
||||
l2_offset + (uint64_t)i * l2_entry_size(s);
|
||||
int ign = active ? QCOW2_OL_ACTIVE_L2 :
|
||||
QCOW2_OL_INACTIVE_L2;
|
||||
|
||||
l2_entry = QCOW_OFLAG_ZERO;
|
||||
l2_table[i] = cpu_to_be64(l2_entry);
|
||||
l2_entry = has_subclusters(s) ? 0 : QCOW_OFLAG_ZERO;
|
||||
set_l2_entry(s, l2_table, i, l2_entry);
|
||||
ret = qcow2_pre_write_overlap_check(bs, ign,
|
||||
l2e_offset, sizeof(uint64_t), false);
|
||||
l2e_offset, l2_entry_size(s), false);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "ERROR: Overlap check failed\n");
|
||||
res->check_errors++;
|
||||
|
@ -1698,7 +1705,8 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
|
|||
}
|
||||
|
||||
ret = bdrv_pwrite_sync(bs->file, l2e_offset,
|
||||
&l2_table[i], sizeof(uint64_t));
|
||||
&l2_table[idx],
|
||||
l2_entry_size(s));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "ERROR: Failed to overwrite L2 "
|
||||
"table entry: %s\n", strerror(-ret));
|
||||
|
@ -1905,7 +1913,7 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
|
|||
}
|
||||
|
||||
ret = bdrv_pread(bs->file, l2_offset, l2_table,
|
||||
s->l2_size * sizeof(uint64_t));
|
||||
s->l2_size * l2_entry_size(s));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "ERROR: Could not read L2 table: %s\n",
|
||||
strerror(-ret));
|
||||
|
@ -1914,7 +1922,7 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
|
|||
}
|
||||
|
||||
for (j = 0; j < s->l2_size; j++) {
|
||||
uint64_t l2_entry = be64_to_cpu(l2_table[j]);
|
||||
uint64_t l2_entry = get_l2_entry(s, l2_table, j);
|
||||
uint64_t data_offset = l2_entry & L2E_OFFSET_MASK;
|
||||
QCow2ClusterType cluster_type = qcow2_get_cluster_type(bs, l2_entry);
|
||||
|
||||
|
@ -1937,9 +1945,10 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
|
|||
"l2_entry=%" PRIx64 " refcount=%" PRIu64 "\n",
|
||||
repair ? "Repairing" : "ERROR", l2_entry, refcount);
|
||||
if (repair) {
|
||||
l2_table[j] = cpu_to_be64(refcount == 1
|
||||
? l2_entry | QCOW_OFLAG_COPIED
|
||||
: l2_entry & ~QCOW_OFLAG_COPIED);
|
||||
set_l2_entry(s, l2_table, j,
|
||||
refcount == 1 ?
|
||||
l2_entry | QCOW_OFLAG_COPIED :
|
||||
l2_entry & ~QCOW_OFLAG_COPIED);
|
||||
l2_dirty++;
|
||||
}
|
||||
}
|
||||
|
|
302
block/qcow2.c
302
block/qcow2.c
|
@ -74,7 +74,7 @@ typedef struct {
|
|||
|
||||
static int coroutine_fn
|
||||
qcow2_co_preadv_compressed(BlockDriverState *bs,
|
||||
uint64_t file_cluster_offset,
|
||||
uint64_t cluster_descriptor,
|
||||
uint64_t offset,
|
||||
uint64_t bytes,
|
||||
QEMUIOVector *qiov,
|
||||
|
@ -883,7 +883,7 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
|
|||
uint64_t max_l2_entries = DIV_ROUND_UP(virtual_disk_size, s->cluster_size);
|
||||
/* An L2 table is always one cluster in size so the max cache size
|
||||
* should be a multiple of the cluster size. */
|
||||
uint64_t max_l2_cache = ROUND_UP(max_l2_entries * sizeof(uint64_t),
|
||||
uint64_t max_l2_cache = ROUND_UP(max_l2_entries * l2_entry_size(s),
|
||||
s->cluster_size);
|
||||
|
||||
combined_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_CACHE_SIZE);
|
||||
|
@ -1042,7 +1042,7 @@ static int qcow2_update_options_prepare(BlockDriverState *bs,
|
|||
}
|
||||
}
|
||||
|
||||
r->l2_slice_size = l2_cache_entry_size / sizeof(uint64_t);
|
||||
r->l2_slice_size = l2_cache_entry_size / l2_entry_size(s);
|
||||
r->l2_table_cache = qcow2_cache_create(bs, l2_cache_size,
|
||||
l2_cache_entry_size);
|
||||
r->refcount_block_cache = qcow2_cache_create(bs, refcount_cache_size,
|
||||
|
@ -1444,6 +1444,17 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
|
|||
}
|
||||
}
|
||||
|
||||
s->subclusters_per_cluster =
|
||||
has_subclusters(s) ? QCOW_EXTL2_SUBCLUSTERS_PER_CLUSTER : 1;
|
||||
s->subcluster_size = s->cluster_size / s->subclusters_per_cluster;
|
||||
s->subcluster_bits = ctz32(s->subcluster_size);
|
||||
|
||||
if (s->subcluster_size < (1 << MIN_CLUSTER_BITS)) {
|
||||
error_setg(errp, "Unsupported subcluster size: %d", s->subcluster_size);
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Check support for various header values */
|
||||
if (header.refcount_order > 6) {
|
||||
error_setg(errp, "Reference count entry width too large; may not "
|
||||
|
@ -1484,7 +1495,7 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
|
|||
bs->encrypted = true;
|
||||
}
|
||||
|
||||
s->l2_bits = s->cluster_bits - 3; /* L2 is always one cluster */
|
||||
s->l2_bits = s->cluster_bits - ctz32(l2_entry_size(s));
|
||||
s->l2_size = 1 << s->l2_bits;
|
||||
/* 2^(s->refcount_order - 3) is the refcount width in bytes */
|
||||
s->refcount_block_bits = s->cluster_bits - (s->refcount_order - 3);
|
||||
|
@ -1908,7 +1919,7 @@ static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp)
|
|||
/* Encryption works on a sector granularity */
|
||||
bs->bl.request_alignment = qcrypto_block_get_sector_size(s->crypto);
|
||||
}
|
||||
bs->bl.pwrite_zeroes_alignment = s->cluster_size;
|
||||
bs->bl.pwrite_zeroes_alignment = s->subcluster_size;
|
||||
bs->bl.pdiscard_alignment = s->cluster_size;
|
||||
}
|
||||
|
||||
|
@ -2036,8 +2047,9 @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
|
|||
BlockDriverState **file)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
uint64_t cluster_offset;
|
||||
uint64_t host_offset;
|
||||
unsigned int bytes;
|
||||
QCow2SubclusterType type;
|
||||
int ret, status = 0;
|
||||
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
|
@ -2049,7 +2061,7 @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
|
|||
}
|
||||
|
||||
bytes = MIN(INT_MAX, count);
|
||||
ret = qcow2_get_cluster_offset(bs, offset, &bytes, &cluster_offset);
|
||||
ret = qcow2_get_host_offset(bs, offset, &bytes, &host_offset, &type);
|
||||
qemu_co_mutex_unlock(&s->lock);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
|
@ -2057,15 +2069,18 @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
|
|||
|
||||
*pnum = bytes;
|
||||
|
||||
if ((ret == QCOW2_CLUSTER_NORMAL || ret == QCOW2_CLUSTER_ZERO_ALLOC) &&
|
||||
!s->crypto) {
|
||||
*map = cluster_offset | offset_into_cluster(s, offset);
|
||||
if ((type == QCOW2_SUBCLUSTER_NORMAL ||
|
||||
type == QCOW2_SUBCLUSTER_ZERO_ALLOC ||
|
||||
type == QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC) && !s->crypto) {
|
||||
*map = host_offset;
|
||||
*file = s->data_file->bs;
|
||||
status |= BDRV_BLOCK_OFFSET_VALID;
|
||||
}
|
||||
if (ret == QCOW2_CLUSTER_ZERO_PLAIN || ret == QCOW2_CLUSTER_ZERO_ALLOC) {
|
||||
if (type == QCOW2_SUBCLUSTER_ZERO_PLAIN ||
|
||||
type == QCOW2_SUBCLUSTER_ZERO_ALLOC) {
|
||||
status |= BDRV_BLOCK_ZERO;
|
||||
} else if (ret != QCOW2_CLUSTER_UNALLOCATED) {
|
||||
} else if (type != QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN &&
|
||||
type != QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC) {
|
||||
status |= BDRV_BLOCK_DATA;
|
||||
}
|
||||
if (s->metadata_preallocation && (status & BDRV_BLOCK_DATA) &&
|
||||
|
@ -2087,6 +2102,7 @@ static coroutine_fn int qcow2_handle_l2meta(BlockDriverState *bs,
|
|||
QCowL2Meta *next;
|
||||
|
||||
if (link_l2) {
|
||||
assert(!l2meta->prealloc);
|
||||
ret = qcow2_alloc_cluster_link_l2(bs, l2meta);
|
||||
if (ret) {
|
||||
goto out;
|
||||
|
@ -2113,7 +2129,7 @@ out:
|
|||
|
||||
static coroutine_fn int
|
||||
qcow2_co_preadv_encrypted(BlockDriverState *bs,
|
||||
uint64_t file_cluster_offset,
|
||||
uint64_t host_offset,
|
||||
uint64_t offset,
|
||||
uint64_t bytes,
|
||||
QEMUIOVector *qiov,
|
||||
|
@ -2140,16 +2156,12 @@ qcow2_co_preadv_encrypted(BlockDriverState *bs,
|
|||
}
|
||||
|
||||
BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
|
||||
ret = bdrv_co_pread(s->data_file,
|
||||
file_cluster_offset + offset_into_cluster(s, offset),
|
||||
bytes, buf, 0);
|
||||
ret = bdrv_co_pread(s->data_file, host_offset, bytes, buf, 0);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (qcow2_co_decrypt(bs,
|
||||
file_cluster_offset + offset_into_cluster(s, offset),
|
||||
offset, buf, bytes) < 0)
|
||||
if (qcow2_co_decrypt(bs, host_offset, offset, buf, bytes) < 0)
|
||||
{
|
||||
ret = -EIO;
|
||||
goto fail;
|
||||
|
@ -2166,8 +2178,8 @@ typedef struct Qcow2AioTask {
|
|||
AioTask task;
|
||||
|
||||
BlockDriverState *bs;
|
||||
QCow2ClusterType cluster_type; /* only for read */
|
||||
uint64_t file_cluster_offset;
|
||||
QCow2SubclusterType subcluster_type; /* only for read */
|
||||
uint64_t host_offset; /* or full descriptor in compressed clusters */
|
||||
uint64_t offset;
|
||||
uint64_t bytes;
|
||||
QEMUIOVector *qiov;
|
||||
|
@ -2179,8 +2191,8 @@ static coroutine_fn int qcow2_co_preadv_task_entry(AioTask *task);
|
|||
static coroutine_fn int qcow2_add_task(BlockDriverState *bs,
|
||||
AioTaskPool *pool,
|
||||
AioTaskFunc func,
|
||||
QCow2ClusterType cluster_type,
|
||||
uint64_t file_cluster_offset,
|
||||
QCow2SubclusterType subcluster_type,
|
||||
uint64_t host_offset,
|
||||
uint64_t offset,
|
||||
uint64_t bytes,
|
||||
QEMUIOVector *qiov,
|
||||
|
@ -2193,9 +2205,9 @@ static coroutine_fn int qcow2_add_task(BlockDriverState *bs,
|
|||
*task = (Qcow2AioTask) {
|
||||
.task.func = func,
|
||||
.bs = bs,
|
||||
.cluster_type = cluster_type,
|
||||
.subcluster_type = subcluster_type,
|
||||
.qiov = qiov,
|
||||
.file_cluster_offset = file_cluster_offset,
|
||||
.host_offset = host_offset,
|
||||
.offset = offset,
|
||||
.bytes = bytes,
|
||||
.qiov_offset = qiov_offset,
|
||||
|
@ -2204,7 +2216,7 @@ static coroutine_fn int qcow2_add_task(BlockDriverState *bs,
|
|||
|
||||
trace_qcow2_add_task(qemu_coroutine_self(), bs, pool,
|
||||
func == qcow2_co_preadv_task_entry ? "read" : "write",
|
||||
cluster_type, file_cluster_offset, offset, bytes,
|
||||
subcluster_type, host_offset, offset, bytes,
|
||||
qiov, qiov_offset);
|
||||
|
||||
if (!pool) {
|
||||
|
@ -2217,42 +2229,40 @@ static coroutine_fn int qcow2_add_task(BlockDriverState *bs,
|
|||
}
|
||||
|
||||
static coroutine_fn int qcow2_co_preadv_task(BlockDriverState *bs,
|
||||
QCow2ClusterType cluster_type,
|
||||
uint64_t file_cluster_offset,
|
||||
QCow2SubclusterType subc_type,
|
||||
uint64_t host_offset,
|
||||
uint64_t offset, uint64_t bytes,
|
||||
QEMUIOVector *qiov,
|
||||
size_t qiov_offset)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
int offset_in_cluster = offset_into_cluster(s, offset);
|
||||
|
||||
switch (cluster_type) {
|
||||
case QCOW2_CLUSTER_ZERO_PLAIN:
|
||||
case QCOW2_CLUSTER_ZERO_ALLOC:
|
||||
switch (subc_type) {
|
||||
case QCOW2_SUBCLUSTER_ZERO_PLAIN:
|
||||
case QCOW2_SUBCLUSTER_ZERO_ALLOC:
|
||||
/* Both zero types are handled in qcow2_co_preadv_part */
|
||||
g_assert_not_reached();
|
||||
|
||||
case QCOW2_CLUSTER_UNALLOCATED:
|
||||
case QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN:
|
||||
case QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC:
|
||||
assert(bs->backing); /* otherwise handled in qcow2_co_preadv_part */
|
||||
|
||||
BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
|
||||
return bdrv_co_preadv_part(bs->backing, offset, bytes,
|
||||
qiov, qiov_offset, 0);
|
||||
|
||||
case QCOW2_CLUSTER_COMPRESSED:
|
||||
return qcow2_co_preadv_compressed(bs, file_cluster_offset,
|
||||
case QCOW2_SUBCLUSTER_COMPRESSED:
|
||||
return qcow2_co_preadv_compressed(bs, host_offset,
|
||||
offset, bytes, qiov, qiov_offset);
|
||||
|
||||
case QCOW2_CLUSTER_NORMAL:
|
||||
assert(offset_into_cluster(s, file_cluster_offset) == 0);
|
||||
case QCOW2_SUBCLUSTER_NORMAL:
|
||||
if (bs->encrypted) {
|
||||
return qcow2_co_preadv_encrypted(bs, file_cluster_offset,
|
||||
return qcow2_co_preadv_encrypted(bs, host_offset,
|
||||
offset, bytes, qiov, qiov_offset);
|
||||
}
|
||||
|
||||
BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
|
||||
return bdrv_co_preadv_part(s->data_file,
|
||||
file_cluster_offset + offset_in_cluster,
|
||||
return bdrv_co_preadv_part(s->data_file, host_offset,
|
||||
bytes, qiov, qiov_offset, 0);
|
||||
|
||||
default:
|
||||
|
@ -2268,8 +2278,9 @@ static coroutine_fn int qcow2_co_preadv_task_entry(AioTask *task)
|
|||
|
||||
assert(!t->l2meta);
|
||||
|
||||
return qcow2_co_preadv_task(t->bs, t->cluster_type, t->file_cluster_offset,
|
||||
t->offset, t->bytes, t->qiov, t->qiov_offset);
|
||||
return qcow2_co_preadv_task(t->bs, t->subcluster_type,
|
||||
t->host_offset, t->offset, t->bytes,
|
||||
t->qiov, t->qiov_offset);
|
||||
}
|
||||
|
||||
static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs,
|
||||
|
@ -2280,7 +2291,8 @@ static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs,
|
|||
BDRVQcow2State *s = bs->opaque;
|
||||
int ret = 0;
|
||||
unsigned int cur_bytes; /* number of bytes in current iteration */
|
||||
uint64_t cluster_offset = 0;
|
||||
uint64_t host_offset = 0;
|
||||
QCow2SubclusterType type;
|
||||
AioTaskPool *aio = NULL;
|
||||
|
||||
while (bytes != 0 && aio_task_pool_status(aio) == 0) {
|
||||
|
@ -2292,23 +2304,25 @@ static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs,
|
|||
}
|
||||
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
ret = qcow2_get_cluster_offset(bs, offset, &cur_bytes, &cluster_offset);
|
||||
ret = qcow2_get_host_offset(bs, offset, &cur_bytes,
|
||||
&host_offset, &type);
|
||||
qemu_co_mutex_unlock(&s->lock);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ret == QCOW2_CLUSTER_ZERO_PLAIN ||
|
||||
ret == QCOW2_CLUSTER_ZERO_ALLOC ||
|
||||
(ret == QCOW2_CLUSTER_UNALLOCATED && !bs->backing))
|
||||
if (type == QCOW2_SUBCLUSTER_ZERO_PLAIN ||
|
||||
type == QCOW2_SUBCLUSTER_ZERO_ALLOC ||
|
||||
(type == QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN && !bs->backing) ||
|
||||
(type == QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC && !bs->backing))
|
||||
{
|
||||
qemu_iovec_memset(qiov, qiov_offset, 0, cur_bytes);
|
||||
} else {
|
||||
if (!aio && cur_bytes != bytes) {
|
||||
aio = aio_task_pool_new(QCOW2_MAX_WORKERS);
|
||||
}
|
||||
ret = qcow2_add_task(bs, aio, qcow2_co_preadv_task_entry, ret,
|
||||
cluster_offset, offset, cur_bytes,
|
||||
ret = qcow2_add_task(bs, aio, qcow2_co_preadv_task_entry, type,
|
||||
host_offset, offset, cur_bytes,
|
||||
qiov, qiov_offset, NULL);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
|
@ -2414,6 +2428,9 @@ static int handle_alloc_space(BlockDriverState *bs, QCowL2Meta *l2meta)
|
|||
|
||||
for (m = l2meta; m != NULL; m = m->next) {
|
||||
int ret;
|
||||
uint64_t start_offset = m->alloc_offset + m->cow_start.offset;
|
||||
unsigned nb_bytes = m->cow_end.offset + m->cow_end.nb_bytes -
|
||||
m->cow_start.offset;
|
||||
|
||||
if (!m->cow_start.nb_bytes && !m->cow_end.nb_bytes) {
|
||||
continue;
|
||||
|
@ -2428,16 +2445,14 @@ static int handle_alloc_space(BlockDriverState *bs, QCowL2Meta *l2meta)
|
|||
* efficiently zero out the whole clusters
|
||||
*/
|
||||
|
||||
ret = qcow2_pre_write_overlap_check(bs, 0, m->alloc_offset,
|
||||
m->nb_clusters * s->cluster_size,
|
||||
ret = qcow2_pre_write_overlap_check(bs, 0, start_offset, nb_bytes,
|
||||
true);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC_SPACE);
|
||||
ret = bdrv_co_pwrite_zeroes(s->data_file, m->alloc_offset,
|
||||
m->nb_clusters * s->cluster_size,
|
||||
ret = bdrv_co_pwrite_zeroes(s->data_file, start_offset, nb_bytes,
|
||||
BDRV_REQ_NO_FALLBACK);
|
||||
if (ret < 0) {
|
||||
if (ret != -ENOTSUP && ret != -EAGAIN) {
|
||||
|
@ -2459,7 +2474,7 @@ static int handle_alloc_space(BlockDriverState *bs, QCowL2Meta *l2meta)
|
|||
* not use it somehow after qcow2_co_pwritev_task() call
|
||||
*/
|
||||
static coroutine_fn int qcow2_co_pwritev_task(BlockDriverState *bs,
|
||||
uint64_t file_cluster_offset,
|
||||
uint64_t host_offset,
|
||||
uint64_t offset, uint64_t bytes,
|
||||
QEMUIOVector *qiov,
|
||||
uint64_t qiov_offset,
|
||||
|
@ -2468,7 +2483,6 @@ static coroutine_fn int qcow2_co_pwritev_task(BlockDriverState *bs,
|
|||
int ret;
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
void *crypt_buf = NULL;
|
||||
int offset_in_cluster = offset_into_cluster(s, offset);
|
||||
QEMUIOVector encrypted_qiov;
|
||||
|
||||
if (bs->encrypted) {
|
||||
|
@ -2481,9 +2495,7 @@ static coroutine_fn int qcow2_co_pwritev_task(BlockDriverState *bs,
|
|||
}
|
||||
qemu_iovec_to_buf(qiov, qiov_offset, crypt_buf, bytes);
|
||||
|
||||
if (qcow2_co_encrypt(bs, file_cluster_offset + offset_in_cluster,
|
||||
offset, crypt_buf, bytes) < 0)
|
||||
{
|
||||
if (qcow2_co_encrypt(bs, host_offset, offset, crypt_buf, bytes) < 0) {
|
||||
ret = -EIO;
|
||||
goto out_unlocked;
|
||||
}
|
||||
|
@ -2507,10 +2519,8 @@ static coroutine_fn int qcow2_co_pwritev_task(BlockDriverState *bs,
|
|||
*/
|
||||
if (!merge_cow(offset, bytes, qiov, qiov_offset, l2meta)) {
|
||||
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
|
||||
trace_qcow2_writev_data(qemu_coroutine_self(),
|
||||
file_cluster_offset + offset_in_cluster);
|
||||
ret = bdrv_co_pwritev_part(s->data_file,
|
||||
file_cluster_offset + offset_in_cluster,
|
||||
trace_qcow2_writev_data(qemu_coroutine_self(), host_offset);
|
||||
ret = bdrv_co_pwritev_part(s->data_file, host_offset,
|
||||
bytes, qiov, qiov_offset, 0);
|
||||
if (ret < 0) {
|
||||
goto out_unlocked;
|
||||
|
@ -2538,9 +2548,9 @@ static coroutine_fn int qcow2_co_pwritev_task_entry(AioTask *task)
|
|||
{
|
||||
Qcow2AioTask *t = container_of(task, Qcow2AioTask, task);
|
||||
|
||||
assert(!t->cluster_type);
|
||||
assert(!t->subcluster_type);
|
||||
|
||||
return qcow2_co_pwritev_task(t->bs, t->file_cluster_offset,
|
||||
return qcow2_co_pwritev_task(t->bs, t->host_offset,
|
||||
t->offset, t->bytes, t->qiov, t->qiov_offset,
|
||||
t->l2meta);
|
||||
}
|
||||
|
@ -2595,8 +2605,8 @@ static coroutine_fn int qcow2_co_pwritev_part(
|
|||
aio = aio_task_pool_new(QCOW2_MAX_WORKERS);
|
||||
}
|
||||
ret = qcow2_add_task(bs, aio, qcow2_co_pwritev_task_entry, 0,
|
||||
cluster_offset, offset, cur_bytes,
|
||||
qiov, qiov_offset, l2meta);
|
||||
cluster_offset + offset_in_cluster, offset,
|
||||
cur_bytes, qiov, qiov_offset, l2meta);
|
||||
l2meta = NULL; /* l2meta is consumed by qcow2_co_pwritev_task() */
|
||||
if (ret < 0) {
|
||||
goto fail_nometa;
|
||||
|
@ -2930,6 +2940,11 @@ int qcow2_update_header(BlockDriverState *bs)
|
|||
.bit = QCOW2_INCOMPAT_COMPRESSION_BITNR,
|
||||
.name = "compression type",
|
||||
},
|
||||
{
|
||||
.type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
|
||||
.bit = QCOW2_INCOMPAT_EXTL2_BITNR,
|
||||
.name = "extended L2 entries",
|
||||
},
|
||||
{
|
||||
.type = QCOW2_FEAT_TYPE_COMPATIBLE,
|
||||
.bit = QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR,
|
||||
|
@ -3127,6 +3142,7 @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
|
|||
|
||||
while (meta) {
|
||||
QCowL2Meta *next = meta->next;
|
||||
meta->prealloc = true;
|
||||
|
||||
ret = qcow2_alloc_cluster_link_l2(bs, meta);
|
||||
if (ret < 0) {
|
||||
|
@ -3229,28 +3245,31 @@ int64_t qcow2_refcount_metadata_size(int64_t clusters, size_t cluster_size,
|
|||
* @total_size: virtual disk size in bytes
|
||||
* @cluster_size: cluster size in bytes
|
||||
* @refcount_order: refcount bits power-of-2 exponent
|
||||
* @extended_l2: true if the image has extended L2 entries
|
||||
*
|
||||
* Returns: Total number of bytes required for the fully allocated image
|
||||
* (including metadata).
|
||||
*/
|
||||
static int64_t qcow2_calc_prealloc_size(int64_t total_size,
|
||||
size_t cluster_size,
|
||||
int refcount_order)
|
||||
int refcount_order,
|
||||
bool extended_l2)
|
||||
{
|
||||
int64_t meta_size = 0;
|
||||
uint64_t nl1e, nl2e;
|
||||
int64_t aligned_total_size = ROUND_UP(total_size, cluster_size);
|
||||
size_t l2e_size = extended_l2 ? L2E_SIZE_EXTENDED : L2E_SIZE_NORMAL;
|
||||
|
||||
/* header: 1 cluster */
|
||||
meta_size += cluster_size;
|
||||
|
||||
/* total size of L2 tables */
|
||||
nl2e = aligned_total_size / cluster_size;
|
||||
nl2e = ROUND_UP(nl2e, cluster_size / sizeof(uint64_t));
|
||||
meta_size += nl2e * sizeof(uint64_t);
|
||||
nl2e = ROUND_UP(nl2e, cluster_size / l2e_size);
|
||||
meta_size += nl2e * l2e_size;
|
||||
|
||||
/* total size of L1 tables */
|
||||
nl1e = nl2e * sizeof(uint64_t) / cluster_size;
|
||||
nl1e = nl2e * l2e_size / cluster_size;
|
||||
nl1e = ROUND_UP(nl1e, cluster_size / sizeof(uint64_t));
|
||||
meta_size += nl1e * sizeof(uint64_t);
|
||||
|
||||
|
@ -3262,7 +3281,8 @@ static int64_t qcow2_calc_prealloc_size(int64_t total_size,
|
|||
return meta_size + aligned_total_size;
|
||||
}
|
||||
|
||||
static bool validate_cluster_size(size_t cluster_size, Error **errp)
|
||||
static bool validate_cluster_size(size_t cluster_size, bool extended_l2,
|
||||
Error **errp)
|
||||
{
|
||||
int cluster_bits = ctz32(cluster_size);
|
||||
if (cluster_bits < MIN_CLUSTER_BITS || cluster_bits > MAX_CLUSTER_BITS ||
|
||||
|
@ -3272,16 +3292,28 @@ static bool validate_cluster_size(size_t cluster_size, Error **errp)
|
|||
"%dk", 1 << MIN_CLUSTER_BITS, 1 << (MAX_CLUSTER_BITS - 10));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (extended_l2) {
|
||||
unsigned min_cluster_size =
|
||||
(1 << MIN_CLUSTER_BITS) * QCOW_EXTL2_SUBCLUSTERS_PER_CLUSTER;
|
||||
if (cluster_size < min_cluster_size) {
|
||||
error_setg(errp, "Extended L2 entries are only supported with "
|
||||
"cluster sizes of at least %u bytes", min_cluster_size);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static size_t qcow2_opt_get_cluster_size_del(QemuOpts *opts, Error **errp)
|
||||
static size_t qcow2_opt_get_cluster_size_del(QemuOpts *opts, bool extended_l2,
|
||||
Error **errp)
|
||||
{
|
||||
size_t cluster_size;
|
||||
|
||||
cluster_size = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE,
|
||||
DEFAULT_CLUSTER_SIZE);
|
||||
if (!validate_cluster_size(cluster_size, errp)) {
|
||||
if (!validate_cluster_size(cluster_size, extended_l2, errp)) {
|
||||
return 0;
|
||||
}
|
||||
return cluster_size;
|
||||
|
@ -3395,7 +3427,20 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
|
|||
cluster_size = DEFAULT_CLUSTER_SIZE;
|
||||
}
|
||||
|
||||
if (!validate_cluster_size(cluster_size, errp)) {
|
||||
if (!qcow2_opts->has_extended_l2) {
|
||||
qcow2_opts->extended_l2 = false;
|
||||
}
|
||||
if (qcow2_opts->extended_l2) {
|
||||
if (version < 3) {
|
||||
error_setg(errp, "Extended L2 entries are only supported with "
|
||||
"compatibility level 1.1 and above (use version=v3 or "
|
||||
"greater)");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!validate_cluster_size(cluster_size, qcow2_opts->extended_l2, errp)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
@ -3404,10 +3449,11 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
|
|||
qcow2_opts->preallocation = PREALLOC_MODE_OFF;
|
||||
}
|
||||
if (qcow2_opts->has_backing_file &&
|
||||
qcow2_opts->preallocation != PREALLOC_MODE_OFF)
|
||||
qcow2_opts->preallocation != PREALLOC_MODE_OFF &&
|
||||
!qcow2_opts->extended_l2)
|
||||
{
|
||||
error_setg(errp, "Backing file and preallocation cannot be used at "
|
||||
"the same time");
|
||||
error_setg(errp, "Backing file and preallocation can only be used at "
|
||||
"the same time if extended_l2 is on");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
@ -3546,6 +3592,11 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
|
|||
cpu_to_be64(QCOW2_INCOMPAT_COMPRESSION);
|
||||
}
|
||||
|
||||
if (qcow2_opts->extended_l2) {
|
||||
header->incompatible_features |=
|
||||
cpu_to_be64(QCOW2_INCOMPAT_EXTL2);
|
||||
}
|
||||
|
||||
ret = blk_pwrite(blk, 0, header, cluster_size, 0);
|
||||
g_free(header);
|
||||
if (ret < 0) {
|
||||
|
@ -3723,6 +3774,7 @@ static int coroutine_fn qcow2_co_create_opts(BlockDriver *drv,
|
|||
{ BLOCK_OPT_BACKING_FMT, "backing-fmt" },
|
||||
{ BLOCK_OPT_CLUSTER_SIZE, "cluster-size" },
|
||||
{ BLOCK_OPT_LAZY_REFCOUNTS, "lazy-refcounts" },
|
||||
{ BLOCK_OPT_EXTL2, "extended-l2" },
|
||||
{ BLOCK_OPT_REFCOUNT_BITS, "refcount-bits" },
|
||||
{ BLOCK_OPT_ENCRYPT, BLOCK_OPT_ENCRYPT_FORMAT },
|
||||
{ BLOCK_OPT_COMPAT_LEVEL, "version" },
|
||||
|
@ -3830,8 +3882,9 @@ static coroutine_fn int qcow2_co_pwrite_zeroes(BlockDriverState *bs,
|
|||
int ret;
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
|
||||
uint32_t head = offset % s->cluster_size;
|
||||
uint32_t tail = (offset + bytes) % s->cluster_size;
|
||||
uint32_t head = offset_into_subcluster(s, offset);
|
||||
uint32_t tail = ROUND_UP(offset + bytes, s->subcluster_size) -
|
||||
(offset + bytes);
|
||||
|
||||
trace_qcow2_pwrite_zeroes_start_req(qemu_coroutine_self(), offset, bytes);
|
||||
if (offset + bytes == bs->total_sectors * BDRV_SECTOR_SIZE) {
|
||||
|
@ -3841,25 +3894,27 @@ static coroutine_fn int qcow2_co_pwrite_zeroes(BlockDriverState *bs,
|
|||
if (head || tail) {
|
||||
uint64_t off;
|
||||
unsigned int nr;
|
||||
QCow2SubclusterType type;
|
||||
|
||||
assert(head + bytes <= s->cluster_size);
|
||||
assert(head + bytes + tail <= s->subcluster_size);
|
||||
|
||||
/* check whether remainder of cluster already reads as zero */
|
||||
if (!(is_zero(bs, offset - head, head) &&
|
||||
is_zero(bs, offset + bytes,
|
||||
tail ? s->cluster_size - tail : 0))) {
|
||||
is_zero(bs, offset + bytes, tail))) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
/* We can have new write after previous check */
|
||||
offset = QEMU_ALIGN_DOWN(offset, s->cluster_size);
|
||||
bytes = s->cluster_size;
|
||||
nr = s->cluster_size;
|
||||
ret = qcow2_get_cluster_offset(bs, offset, &nr, &off);
|
||||
if (ret != QCOW2_CLUSTER_UNALLOCATED &&
|
||||
ret != QCOW2_CLUSTER_ZERO_PLAIN &&
|
||||
ret != QCOW2_CLUSTER_ZERO_ALLOC) {
|
||||
offset -= head;
|
||||
bytes = s->subcluster_size;
|
||||
nr = s->subcluster_size;
|
||||
ret = qcow2_get_host_offset(bs, offset, &nr, &off, &type);
|
||||
if (ret < 0 ||
|
||||
(type != QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN &&
|
||||
type != QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC &&
|
||||
type != QCOW2_SUBCLUSTER_ZERO_PLAIN &&
|
||||
type != QCOW2_SUBCLUSTER_ZERO_ALLOC)) {
|
||||
qemu_co_mutex_unlock(&s->lock);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
@ -3869,8 +3924,8 @@ static coroutine_fn int qcow2_co_pwrite_zeroes(BlockDriverState *bs,
|
|||
|
||||
trace_qcow2_pwrite_zeroes(qemu_coroutine_self(), offset, bytes);
|
||||
|
||||
/* Whatever is left can use real zero clusters */
|
||||
ret = qcow2_cluster_zeroize(bs, offset, bytes, flags);
|
||||
/* Whatever is left can use real zero subclusters */
|
||||
ret = qcow2_subcluster_zeroize(bs, offset, bytes, flags);
|
||||
qemu_co_mutex_unlock(&s->lock);
|
||||
|
||||
return ret;
|
||||
|
@ -3923,17 +3978,20 @@ qcow2_co_copy_range_from(BlockDriverState *bs,
|
|||
|
||||
while (bytes != 0) {
|
||||
uint64_t copy_offset = 0;
|
||||
QCow2SubclusterType type;
|
||||
/* prepare next request */
|
||||
cur_bytes = MIN(bytes, INT_MAX);
|
||||
cur_write_flags = write_flags;
|
||||
|
||||
ret = qcow2_get_cluster_offset(bs, src_offset, &cur_bytes, ©_offset);
|
||||
ret = qcow2_get_host_offset(bs, src_offset, &cur_bytes,
|
||||
©_offset, &type);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (ret) {
|
||||
case QCOW2_CLUSTER_UNALLOCATED:
|
||||
switch (type) {
|
||||
case QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN:
|
||||
case QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC:
|
||||
if (bs->backing && bs->backing->bs) {
|
||||
int64_t backing_length = bdrv_getlength(bs->backing->bs);
|
||||
if (src_offset >= backing_length) {
|
||||
|
@ -3948,18 +4006,17 @@ qcow2_co_copy_range_from(BlockDriverState *bs,
|
|||
}
|
||||
break;
|
||||
|
||||
case QCOW2_CLUSTER_ZERO_PLAIN:
|
||||
case QCOW2_CLUSTER_ZERO_ALLOC:
|
||||
case QCOW2_SUBCLUSTER_ZERO_PLAIN:
|
||||
case QCOW2_SUBCLUSTER_ZERO_ALLOC:
|
||||
cur_write_flags |= BDRV_REQ_ZERO_WRITE;
|
||||
break;
|
||||
|
||||
case QCOW2_CLUSTER_COMPRESSED:
|
||||
case QCOW2_SUBCLUSTER_COMPRESSED:
|
||||
ret = -ENOTSUP;
|
||||
goto out;
|
||||
|
||||
case QCOW2_CLUSTER_NORMAL:
|
||||
case QCOW2_SUBCLUSTER_NORMAL:
|
||||
child = s->data_file;
|
||||
copy_offset += offset_into_cluster(s, src_offset);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -4206,6 +4263,7 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
|
|||
int64_t clusters_allocated;
|
||||
int64_t old_file_size, last_cluster, new_file_size;
|
||||
uint64_t nb_new_data_clusters, nb_new_l2_tables;
|
||||
bool subclusters_need_allocation = false;
|
||||
|
||||
/* With a data file, preallocation means just allocating the metadata
|
||||
* and forwarding the truncate request to the data file */
|
||||
|
@ -4246,7 +4304,7 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
|
|||
* preallocation. All that matters is that we will not have to allocate
|
||||
* new refcount structures for them.) */
|
||||
nb_new_l2_tables = DIV_ROUND_UP(nb_new_data_clusters,
|
||||
s->cluster_size / sizeof(uint64_t));
|
||||
s->cluster_size / l2_entry_size(s));
|
||||
/* The cluster range may not be aligned to L2 boundaries, so add one L2
|
||||
* table for a potential head/tail */
|
||||
nb_new_l2_tables++;
|
||||
|
@ -4287,6 +4345,8 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
|
|||
BDRV_REQ_ZERO_WRITE, NULL);
|
||||
if (ret >= 0) {
|
||||
flags &= ~BDRV_REQ_ZERO_WRITE;
|
||||
/* Ensure that we read zeroes and not backing file data */
|
||||
subclusters_need_allocation = true;
|
||||
}
|
||||
} else {
|
||||
ret = -1;
|
||||
|
@ -4325,6 +4385,7 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
|
|||
.offset = nb_clusters << s->cluster_bits,
|
||||
.nb_bytes = 0,
|
||||
},
|
||||
.prealloc = !subclusters_need_allocation,
|
||||
};
|
||||
qemu_co_queue_init(&allocation.dependent_requests);
|
||||
|
||||
|
@ -4349,15 +4410,16 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
|
|||
}
|
||||
|
||||
if ((flags & BDRV_REQ_ZERO_WRITE) && offset > old_length) {
|
||||
uint64_t zero_start = QEMU_ALIGN_UP(old_length, s->cluster_size);
|
||||
uint64_t zero_start = QEMU_ALIGN_UP(old_length, s->subcluster_size);
|
||||
|
||||
/*
|
||||
* Use zero clusters as much as we can. qcow2_cluster_zeroize()
|
||||
* requires a cluster-aligned start. The end may be unaligned if it is
|
||||
* at the end of the image (which it is here).
|
||||
* Use zero clusters as much as we can. qcow2_subcluster_zeroize()
|
||||
* requires a subcluster-aligned start. The end may be unaligned if
|
||||
* it is at the end of the image (which it is here).
|
||||
*/
|
||||
if (offset > zero_start) {
|
||||
ret = qcow2_cluster_zeroize(bs, zero_start, offset - zero_start, 0);
|
||||
ret = qcow2_subcluster_zeroize(bs, zero_start, offset - zero_start,
|
||||
0);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "Failed to zero out new clusters");
|
||||
goto fail;
|
||||
|
@ -4487,7 +4549,7 @@ static coroutine_fn int qcow2_co_pwritev_compressed_task_entry(AioTask *task)
|
|||
{
|
||||
Qcow2AioTask *t = container_of(task, Qcow2AioTask, task);
|
||||
|
||||
assert(!t->cluster_type && !t->l2meta);
|
||||
assert(!t->subcluster_type && !t->l2meta);
|
||||
|
||||
return qcow2_co_pwritev_compressed_task(t->bs, t->offset, t->bytes, t->qiov,
|
||||
t->qiov_offset);
|
||||
|
@ -4562,7 +4624,7 @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
|
|||
|
||||
static int coroutine_fn
|
||||
qcow2_co_preadv_compressed(BlockDriverState *bs,
|
||||
uint64_t file_cluster_offset,
|
||||
uint64_t cluster_descriptor,
|
||||
uint64_t offset,
|
||||
uint64_t bytes,
|
||||
QEMUIOVector *qiov,
|
||||
|
@ -4574,8 +4636,8 @@ qcow2_co_preadv_compressed(BlockDriverState *bs,
|
|||
uint8_t *buf, *out_buf;
|
||||
int offset_in_cluster = offset_into_cluster(s, offset);
|
||||
|
||||
coffset = file_cluster_offset & s->cluster_offset_mask;
|
||||
nb_csectors = ((file_cluster_offset >> s->csize_shift) & s->csize_mask) + 1;
|
||||
coffset = cluster_descriptor & s->cluster_offset_mask;
|
||||
nb_csectors = ((cluster_descriptor >> s->csize_shift) & s->csize_mask) + 1;
|
||||
csize = nb_csectors * QCOW2_COMPRESSED_SECTOR_SIZE -
|
||||
(coffset & ~QCOW2_COMPRESSED_SECTOR_MASK);
|
||||
|
||||
|
@ -4829,9 +4891,14 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
|
|||
PreallocMode prealloc;
|
||||
bool has_backing_file;
|
||||
bool has_luks;
|
||||
bool extended_l2;
|
||||
size_t l2e_size;
|
||||
|
||||
/* Parse image creation options */
|
||||
cluster_size = qcow2_opt_get_cluster_size_del(opts, &local_err);
|
||||
extended_l2 = qemu_opt_get_bool_del(opts, BLOCK_OPT_EXTL2, false);
|
||||
|
||||
cluster_size = qcow2_opt_get_cluster_size_del(opts, extended_l2,
|
||||
&local_err);
|
||||
if (local_err) {
|
||||
goto err;
|
||||
}
|
||||
|
@ -4887,8 +4954,9 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
|
|||
virtual_size = ROUND_UP(virtual_size, cluster_size);
|
||||
|
||||
/* Check that virtual disk size is valid */
|
||||
l2e_size = extended_l2 ? L2E_SIZE_EXTENDED : L2E_SIZE_NORMAL;
|
||||
l2_tables = DIV_ROUND_UP(virtual_size / cluster_size,
|
||||
cluster_size / sizeof(uint64_t));
|
||||
cluster_size / l2e_size);
|
||||
if (l2_tables * sizeof(uint64_t) > QCOW_MAX_L1_SIZE) {
|
||||
error_setg(&local_err, "The image size is too large "
|
||||
"(try using a larger cluster size)");
|
||||
|
@ -4951,9 +5019,9 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
|
|||
}
|
||||
|
||||
info = g_new0(BlockMeasureInfo, 1);
|
||||
info->fully_allocated =
|
||||
info->fully_allocated = luks_payload_size +
|
||||
qcow2_calc_prealloc_size(virtual_size, cluster_size,
|
||||
ctz32(refcount_bits)) + luks_payload_size;
|
||||
ctz32(refcount_bits), extended_l2);
|
||||
|
||||
/*
|
||||
* Remove data clusters that are not required. This overestimates the
|
||||
|
@ -5026,6 +5094,8 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs,
|
|||
.corrupt = s->incompatible_features &
|
||||
QCOW2_INCOMPAT_CORRUPT,
|
||||
.has_corrupt = true,
|
||||
.has_extended_l2 = true,
|
||||
.extended_l2 = has_subclusters(s),
|
||||
.refcount_bits = s->refcount_bits,
|
||||
.has_bitmaps = !!bitmaps,
|
||||
.bitmaps = bitmaps,
|
||||
|
@ -5753,6 +5823,12 @@ static QemuOptsList qcow2_create_opts = {
|
|||
.help = "qcow2 cluster size", \
|
||||
.def_value_str = stringify(DEFAULT_CLUSTER_SIZE) \
|
||||
}, \
|
||||
{ \
|
||||
.name = BLOCK_OPT_EXTL2, \
|
||||
.type = QEMU_OPT_BOOL, \
|
||||
.help = "Extended L2 tables", \
|
||||
.def_value_str = "off" \
|
||||
}, \
|
||||
{ \
|
||||
.name = BLOCK_OPT_PREALLOC, \
|
||||
.type = QEMU_OPT_STRING, \
|
||||
|
|
211
block/qcow2.h
211
block/qcow2.h
|
@ -78,6 +78,27 @@
|
|||
/* The cluster reads as all zeros */
|
||||
#define QCOW_OFLAG_ZERO (1ULL << 0)
|
||||
|
||||
#define QCOW_EXTL2_SUBCLUSTERS_PER_CLUSTER 32
|
||||
|
||||
/* The subcluster X [0..31] is allocated */
|
||||
#define QCOW_OFLAG_SUB_ALLOC(X) (1ULL << (X))
|
||||
/* The subcluster X [0..31] reads as zeroes */
|
||||
#define QCOW_OFLAG_SUB_ZERO(X) (QCOW_OFLAG_SUB_ALLOC(X) << 32)
|
||||
/* Subclusters [X, Y) (0 <= X <= Y <= 32) are allocated */
|
||||
#define QCOW_OFLAG_SUB_ALLOC_RANGE(X, Y) \
|
||||
(QCOW_OFLAG_SUB_ALLOC(Y) - QCOW_OFLAG_SUB_ALLOC(X))
|
||||
/* Subclusters [X, Y) (0 <= X <= Y <= 32) read as zeroes */
|
||||
#define QCOW_OFLAG_SUB_ZERO_RANGE(X, Y) \
|
||||
(QCOW_OFLAG_SUB_ALLOC_RANGE(X, Y) << 32)
|
||||
/* L2 entry bitmap with all allocation bits set */
|
||||
#define QCOW_L2_BITMAP_ALL_ALLOC (QCOW_OFLAG_SUB_ALLOC_RANGE(0, 32))
|
||||
/* L2 entry bitmap with all "read as zeroes" bits set */
|
||||
#define QCOW_L2_BITMAP_ALL_ZEROES (QCOW_OFLAG_SUB_ZERO_RANGE(0, 32))
|
||||
|
||||
/* Size of normal and extended L2 entries */
|
||||
#define L2E_SIZE_NORMAL (sizeof(uint64_t))
|
||||
#define L2E_SIZE_EXTENDED (sizeof(uint64_t) * 2)
|
||||
|
||||
#define MIN_CLUSTER_BITS 9
|
||||
#define MAX_CLUSTER_BITS 21
|
||||
|
||||
|
@ -225,15 +246,18 @@ enum {
|
|||
QCOW2_INCOMPAT_CORRUPT_BITNR = 1,
|
||||
QCOW2_INCOMPAT_DATA_FILE_BITNR = 2,
|
||||
QCOW2_INCOMPAT_COMPRESSION_BITNR = 3,
|
||||
QCOW2_INCOMPAT_EXTL2_BITNR = 4,
|
||||
QCOW2_INCOMPAT_DIRTY = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
|
||||
QCOW2_INCOMPAT_CORRUPT = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
|
||||
QCOW2_INCOMPAT_DATA_FILE = 1 << QCOW2_INCOMPAT_DATA_FILE_BITNR,
|
||||
QCOW2_INCOMPAT_COMPRESSION = 1 << QCOW2_INCOMPAT_COMPRESSION_BITNR,
|
||||
QCOW2_INCOMPAT_EXTL2 = 1 << QCOW2_INCOMPAT_EXTL2_BITNR,
|
||||
|
||||
QCOW2_INCOMPAT_MASK = QCOW2_INCOMPAT_DIRTY
|
||||
| QCOW2_INCOMPAT_CORRUPT
|
||||
| QCOW2_INCOMPAT_DATA_FILE
|
||||
| QCOW2_INCOMPAT_COMPRESSION,
|
||||
| QCOW2_INCOMPAT_COMPRESSION
|
||||
| QCOW2_INCOMPAT_EXTL2,
|
||||
};
|
||||
|
||||
/* Compatible feature bits */
|
||||
|
@ -295,6 +319,9 @@ typedef struct BDRVQcow2State {
|
|||
int cluster_bits;
|
||||
int cluster_size;
|
||||
int l2_slice_size;
|
||||
int subcluster_bits;
|
||||
int subcluster_size;
|
||||
int subclusters_per_cluster;
|
||||
int l2_bits;
|
||||
int l2_size;
|
||||
int l1_size;
|
||||
|
@ -439,6 +466,14 @@ typedef struct QCowL2Meta
|
|||
*/
|
||||
bool skip_cow;
|
||||
|
||||
/**
|
||||
* Indicates that this is not a normal write request but a preallocation.
|
||||
* If the image has extended L2 entries this means that no new individual
|
||||
* subclusters will be marked as allocated in the L2 bitmap (but any
|
||||
* existing contents of that bitmap will be kept).
|
||||
*/
|
||||
bool prealloc;
|
||||
|
||||
/**
|
||||
* The I/O vector with the data from the actual guest write request.
|
||||
* If non-NULL, this is meant to be merged together with the data
|
||||
|
@ -453,6 +488,33 @@ typedef struct QCowL2Meta
|
|||
QLIST_ENTRY(QCowL2Meta) next_in_flight;
|
||||
} QCowL2Meta;
|
||||
|
||||
/*
|
||||
* In images with standard L2 entries all clusters are treated as if
|
||||
* they had one subcluster so QCow2ClusterType and QCow2SubclusterType
|
||||
* can be mapped to each other and have the exact same meaning
|
||||
* (QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC cannot happen in these images).
|
||||
*
|
||||
* In images with extended L2 entries QCow2ClusterType refers to the
|
||||
* complete cluster and QCow2SubclusterType to each of the individual
|
||||
* subclusters, so there are several possible combinations:
|
||||
*
|
||||
* |--------------+---------------------------|
|
||||
* | Cluster type | Possible subcluster types |
|
||||
* |--------------+---------------------------|
|
||||
* | UNALLOCATED | UNALLOCATED_PLAIN |
|
||||
* | | ZERO_PLAIN |
|
||||
* |--------------+---------------------------|
|
||||
* | NORMAL | UNALLOCATED_ALLOC |
|
||||
* | | ZERO_ALLOC |
|
||||
* | | NORMAL |
|
||||
* |--------------+---------------------------|
|
||||
* | COMPRESSED | COMPRESSED |
|
||||
* |--------------+---------------------------|
|
||||
*
|
||||
* QCOW2_SUBCLUSTER_INVALID means that the L2 entry is incorrect and
|
||||
* the image should be marked corrupt.
|
||||
*/
|
||||
|
||||
typedef enum QCow2ClusterType {
|
||||
QCOW2_CLUSTER_UNALLOCATED,
|
||||
QCOW2_CLUSTER_ZERO_PLAIN,
|
||||
|
@ -461,6 +523,16 @@ typedef enum QCow2ClusterType {
|
|||
QCOW2_CLUSTER_COMPRESSED,
|
||||
} QCow2ClusterType;
|
||||
|
||||
typedef enum QCow2SubclusterType {
|
||||
QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN,
|
||||
QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC,
|
||||
QCOW2_SUBCLUSTER_ZERO_PLAIN,
|
||||
QCOW2_SUBCLUSTER_ZERO_ALLOC,
|
||||
QCOW2_SUBCLUSTER_NORMAL,
|
||||
QCOW2_SUBCLUSTER_COMPRESSED,
|
||||
QCOW2_SUBCLUSTER_INVALID,
|
||||
} QCow2SubclusterType;
|
||||
|
||||
typedef enum QCow2MetadataOverlap {
|
||||
QCOW2_OL_MAIN_HEADER_BITNR = 0,
|
||||
QCOW2_OL_ACTIVE_L1_BITNR = 1,
|
||||
|
@ -510,6 +582,49 @@ typedef enum QCow2MetadataOverlap {
|
|||
|
||||
#define INV_OFFSET (-1ULL)
|
||||
|
||||
static inline bool has_subclusters(BDRVQcow2State *s)
|
||||
{
|
||||
return s->incompatible_features & QCOW2_INCOMPAT_EXTL2;
|
||||
}
|
||||
|
||||
static inline size_t l2_entry_size(BDRVQcow2State *s)
|
||||
{
|
||||
return has_subclusters(s) ? L2E_SIZE_EXTENDED : L2E_SIZE_NORMAL;
|
||||
}
|
||||
|
||||
static inline uint64_t get_l2_entry(BDRVQcow2State *s, uint64_t *l2_slice,
|
||||
int idx)
|
||||
{
|
||||
idx *= l2_entry_size(s) / sizeof(uint64_t);
|
||||
return be64_to_cpu(l2_slice[idx]);
|
||||
}
|
||||
|
||||
static inline uint64_t get_l2_bitmap(BDRVQcow2State *s, uint64_t *l2_slice,
|
||||
int idx)
|
||||
{
|
||||
if (has_subclusters(s)) {
|
||||
idx *= l2_entry_size(s) / sizeof(uint64_t);
|
||||
return be64_to_cpu(l2_slice[idx + 1]);
|
||||
} else {
|
||||
return 0; /* For convenience only; this value has no meaning. */
|
||||
}
|
||||
}
|
||||
|
||||
static inline void set_l2_entry(BDRVQcow2State *s, uint64_t *l2_slice,
|
||||
int idx, uint64_t entry)
|
||||
{
|
||||
idx *= l2_entry_size(s) / sizeof(uint64_t);
|
||||
l2_slice[idx] = cpu_to_be64(entry);
|
||||
}
|
||||
|
||||
static inline void set_l2_bitmap(BDRVQcow2State *s, uint64_t *l2_slice,
|
||||
int idx, uint64_t bitmap)
|
||||
{
|
||||
assert(has_subclusters(s));
|
||||
idx *= l2_entry_size(s) / sizeof(uint64_t);
|
||||
l2_slice[idx + 1] = cpu_to_be64(bitmap);
|
||||
}
|
||||
|
||||
static inline bool has_data_file(BlockDriverState *bs)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
|
@ -532,11 +647,21 @@ static inline int64_t offset_into_cluster(BDRVQcow2State *s, int64_t offset)
|
|||
return offset & (s->cluster_size - 1);
|
||||
}
|
||||
|
||||
static inline int64_t offset_into_subcluster(BDRVQcow2State *s, int64_t offset)
|
||||
{
|
||||
return offset & (s->subcluster_size - 1);
|
||||
}
|
||||
|
||||
static inline uint64_t size_to_clusters(BDRVQcow2State *s, uint64_t size)
|
||||
{
|
||||
return (size + (s->cluster_size - 1)) >> s->cluster_bits;
|
||||
}
|
||||
|
||||
static inline uint64_t size_to_subclusters(BDRVQcow2State *s, uint64_t size)
|
||||
{
|
||||
return (size + (s->subcluster_size - 1)) >> s->subcluster_bits;
|
||||
}
|
||||
|
||||
static inline int64_t size_to_l1(BDRVQcow2State *s, int64_t size)
|
||||
{
|
||||
int shift = s->cluster_bits + s->l2_bits;
|
||||
|
@ -558,6 +683,11 @@ static inline int offset_to_l2_slice_index(BDRVQcow2State *s, int64_t offset)
|
|||
return (offset >> s->cluster_bits) & (s->l2_slice_size - 1);
|
||||
}
|
||||
|
||||
static inline int offset_to_sc_index(BDRVQcow2State *s, int64_t offset)
|
||||
{
|
||||
return (offset >> s->subcluster_bits) & (s->subclusters_per_cluster - 1);
|
||||
}
|
||||
|
||||
static inline int64_t qcow2_vm_state_offset(BDRVQcow2State *s)
|
||||
{
|
||||
return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits);
|
||||
|
@ -566,9 +696,11 @@ static inline int64_t qcow2_vm_state_offset(BDRVQcow2State *s)
|
|||
static inline QCow2ClusterType qcow2_get_cluster_type(BlockDriverState *bs,
|
||||
uint64_t l2_entry)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
|
||||
if (l2_entry & QCOW_OFLAG_COMPRESSED) {
|
||||
return QCOW2_CLUSTER_COMPRESSED;
|
||||
} else if (l2_entry & QCOW_OFLAG_ZERO) {
|
||||
} else if ((l2_entry & QCOW_OFLAG_ZERO) && !has_subclusters(s)) {
|
||||
if (l2_entry & L2E_OFFSET_MASK) {
|
||||
return QCOW2_CLUSTER_ZERO_ALLOC;
|
||||
}
|
||||
|
@ -588,6 +720,72 @@ static inline QCow2ClusterType qcow2_get_cluster_type(BlockDriverState *bs,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* In an image without subsclusters @l2_bitmap is ignored and
|
||||
* @sc_index must be 0.
|
||||
* Return QCOW2_SUBCLUSTER_INVALID if an invalid l2 entry is detected
|
||||
* (this checks the whole entry and bitmap, not only the bits related
|
||||
* to subcluster @sc_index).
|
||||
*/
|
||||
static inline
|
||||
QCow2SubclusterType qcow2_get_subcluster_type(BlockDriverState *bs,
|
||||
uint64_t l2_entry,
|
||||
uint64_t l2_bitmap,
|
||||
unsigned sc_index)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
QCow2ClusterType type = qcow2_get_cluster_type(bs, l2_entry);
|
||||
assert(sc_index < s->subclusters_per_cluster);
|
||||
|
||||
if (has_subclusters(s)) {
|
||||
switch (type) {
|
||||
case QCOW2_CLUSTER_COMPRESSED:
|
||||
return QCOW2_SUBCLUSTER_COMPRESSED;
|
||||
case QCOW2_CLUSTER_NORMAL:
|
||||
if ((l2_bitmap >> 32) & l2_bitmap) {
|
||||
return QCOW2_SUBCLUSTER_INVALID;
|
||||
} else if (l2_bitmap & QCOW_OFLAG_SUB_ZERO(sc_index)) {
|
||||
return QCOW2_SUBCLUSTER_ZERO_ALLOC;
|
||||
} else if (l2_bitmap & QCOW_OFLAG_SUB_ALLOC(sc_index)) {
|
||||
return QCOW2_SUBCLUSTER_NORMAL;
|
||||
} else {
|
||||
return QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC;
|
||||
}
|
||||
case QCOW2_CLUSTER_UNALLOCATED:
|
||||
if (l2_bitmap & QCOW_L2_BITMAP_ALL_ALLOC) {
|
||||
return QCOW2_SUBCLUSTER_INVALID;
|
||||
} else if (l2_bitmap & QCOW_OFLAG_SUB_ZERO(sc_index)) {
|
||||
return QCOW2_SUBCLUSTER_ZERO_PLAIN;
|
||||
} else {
|
||||
return QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN;
|
||||
}
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
} else {
|
||||
switch (type) {
|
||||
case QCOW2_CLUSTER_COMPRESSED:
|
||||
return QCOW2_SUBCLUSTER_COMPRESSED;
|
||||
case QCOW2_CLUSTER_ZERO_PLAIN:
|
||||
return QCOW2_SUBCLUSTER_ZERO_PLAIN;
|
||||
case QCOW2_CLUSTER_ZERO_ALLOC:
|
||||
return QCOW2_SUBCLUSTER_ZERO_ALLOC;
|
||||
case QCOW2_CLUSTER_NORMAL:
|
||||
return QCOW2_SUBCLUSTER_NORMAL;
|
||||
case QCOW2_CLUSTER_UNALLOCATED:
|
||||
return QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool qcow2_cluster_is_allocated(QCow2ClusterType type)
|
||||
{
|
||||
return (type == QCOW2_CLUSTER_COMPRESSED || type == QCOW2_CLUSTER_NORMAL ||
|
||||
type == QCOW2_CLUSTER_ZERO_ALLOC);
|
||||
}
|
||||
|
||||
/* Check whether refcounts are eager or lazy */
|
||||
static inline bool qcow2_need_accurate_refcounts(BDRVQcow2State *s)
|
||||
{
|
||||
|
@ -694,8 +892,9 @@ int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index);
|
|||
int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
|
||||
uint8_t *buf, int nb_sectors, bool enc, Error **errp);
|
||||
|
||||
int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
|
||||
unsigned int *bytes, uint64_t *cluster_offset);
|
||||
int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset,
|
||||
unsigned int *bytes, uint64_t *host_offset,
|
||||
QCow2SubclusterType *subcluster_type);
|
||||
int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
|
||||
unsigned int *bytes, uint64_t *host_offset,
|
||||
QCowL2Meta **m);
|
||||
|
@ -709,8 +908,8 @@ void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m);
|
|||
int qcow2_cluster_discard(BlockDriverState *bs, uint64_t offset,
|
||||
uint64_t bytes, enum qcow2_discard_type type,
|
||||
bool full_discard);
|
||||
int qcow2_cluster_zeroize(BlockDriverState *bs, uint64_t offset,
|
||||
uint64_t bytes, int flags);
|
||||
int qcow2_subcluster_zeroize(BlockDriverState *bs, uint64_t offset,
|
||||
uint64_t bytes, int flags);
|
||||
|
||||
int qcow2_expand_zero_clusters(BlockDriverState *bs,
|
||||
BlockDriverAmendStatusCB *status_cb,
|
||||
|
|
|
@ -77,7 +77,7 @@ luring_io_uring_submit(void *s, int ret) "LuringState %p ret %d"
|
|||
luring_resubmit_short_read(void *s, void *luringcb, int nread) "LuringState %p luringcb %p nread %d"
|
||||
|
||||
# qcow2.c
|
||||
qcow2_add_task(void *co, void *bs, void *pool, const char *action, int cluster_type, uint64_t file_cluster_offset, uint64_t offset, uint64_t bytes, void *qiov, size_t qiov_offset) "co %p bs %p pool %p: %s: cluster_type %d file_cluster_offset %" PRIu64 " offset %" PRIu64 " bytes %" PRIu64 " qiov %p qiov_offset %zu"
|
||||
qcow2_add_task(void *co, void *bs, void *pool, const char *action, int cluster_type, uint64_t host_offset, uint64_t offset, uint64_t bytes, void *qiov, size_t qiov_offset) "co %p bs %p pool %p: %s: cluster_type %d file_cluster_offset %" PRIu64 " offset %" PRIu64 " bytes %" PRIu64 " qiov %p qiov_offset %zu"
|
||||
qcow2_writev_start_req(void *co, int64_t offset, int bytes) "co %p offset 0x%" PRIx64 " bytes %d"
|
||||
qcow2_writev_done_req(void *co, int ret) "co %p ret %d"
|
||||
qcow2_writev_start_part(void *co) "co %p"
|
||||
|
|
|
@ -42,6 +42,9 @@ The first cluster of a qcow2 image contains the file header:
|
|||
as the maximum cluster size and won't be able to open images
|
||||
with larger cluster sizes.
|
||||
|
||||
Note: if the image has Extended L2 Entries then cluster_bits
|
||||
must be at least 14 (i.e. 16384 byte clusters).
|
||||
|
||||
24 - 31: size
|
||||
Virtual disk size in bytes.
|
||||
|
||||
|
@ -117,7 +120,12 @@ the next fields through header_length.
|
|||
clusters. The compression_type field must be
|
||||
present and not zero.
|
||||
|
||||
Bits 4-63: Reserved (set to 0)
|
||||
Bit 4: Extended L2 Entries. If this bit is set then
|
||||
L2 table entries use an extended format that
|
||||
allows subcluster-based allocation. See the
|
||||
Extended L2 Entries section for more details.
|
||||
|
||||
Bits 5-63: Reserved (set to 0)
|
||||
|
||||
80 - 87: compatible_features
|
||||
Bitmask of compatible features. An implementation can
|
||||
|
@ -498,7 +506,7 @@ cannot be relaxed without an incompatible layout change).
|
|||
Given an offset into the virtual disk, the offset into the image file can be
|
||||
obtained as follows:
|
||||
|
||||
l2_entries = (cluster_size / sizeof(uint64_t))
|
||||
l2_entries = (cluster_size / sizeof(uint64_t)) [*]
|
||||
|
||||
l2_index = (offset / cluster_size) % l2_entries
|
||||
l1_index = (offset / cluster_size) / l2_entries
|
||||
|
@ -508,6 +516,8 @@ obtained as follows:
|
|||
|
||||
return cluster_offset + (offset % cluster_size)
|
||||
|
||||
[*] this changes if Extended L2 Entries are enabled, see next section
|
||||
|
||||
L1 table entry:
|
||||
|
||||
Bit 0 - 8: Reserved (set to 0)
|
||||
|
@ -548,7 +558,8 @@ Standard Cluster Descriptor:
|
|||
nor is data read from the backing file if the cluster is
|
||||
unallocated.
|
||||
|
||||
With version 2, this is always 0.
|
||||
With version 2 or with extended L2 entries (see the next
|
||||
section), this is always 0.
|
||||
|
||||
1 - 8: Reserved (set to 0)
|
||||
|
||||
|
@ -585,6 +596,57 @@ file (except if bit 0 in the Standard Cluster Descriptor is set). If there is
|
|||
no backing file or the backing file is smaller than the image, they shall read
|
||||
zeros for all parts that are not covered by the backing file.
|
||||
|
||||
== Extended L2 Entries ==
|
||||
|
||||
An image uses Extended L2 Entries if bit 4 is set on the incompatible_features
|
||||
field of the header.
|
||||
|
||||
In these images standard data clusters are divided into 32 subclusters of the
|
||||
same size. They are contiguous and start from the beginning of the cluster.
|
||||
Subclusters can be allocated independently and the L2 entry contains information
|
||||
indicating the status of each one of them. Compressed data clusters don't have
|
||||
subclusters so they are treated the same as in images without this feature.
|
||||
|
||||
The size of an extended L2 entry is 128 bits so the number of entries per table
|
||||
is calculated using this formula:
|
||||
|
||||
l2_entries = (cluster_size / (2 * sizeof(uint64_t)))
|
||||
|
||||
The first 64 bits have the same format as the standard L2 table entry described
|
||||
in the previous section, with the exception of bit 0 of the standard cluster
|
||||
descriptor.
|
||||
|
||||
The last 64 bits contain a subcluster allocation bitmap with this format:
|
||||
|
||||
Subcluster Allocation Bitmap (for standard clusters):
|
||||
|
||||
Bit 0 - 31: Allocation status (one bit per subcluster)
|
||||
|
||||
1: the subcluster is allocated. In this case the
|
||||
host cluster offset field must contain a valid
|
||||
offset.
|
||||
0: the subcluster is not allocated. In this case
|
||||
read requests shall go to the backing file or
|
||||
return zeros if there is no backing file data.
|
||||
|
||||
Bits are assigned starting from the least significant
|
||||
one (i.e. bit x is used for subcluster x).
|
||||
|
||||
32 - 63 Subcluster reads as zeros (one bit per subcluster)
|
||||
|
||||
1: the subcluster reads as zeros. In this case the
|
||||
allocation status bit must be unset. The host
|
||||
cluster offset field may or may not be set.
|
||||
0: no effect.
|
||||
|
||||
Bits are assigned starting from the least significant
|
||||
one (i.e. bit x is used for subcluster x - 32).
|
||||
|
||||
Subcluster Allocation Bitmap (for compressed clusters):
|
||||
|
||||
Bit 0 - 63: Reserved (set to 0)
|
||||
Compressed clusters don't have subclusters,
|
||||
so this field is not used.
|
||||
|
||||
== Snapshots ==
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
qcow2 L2/refcount cache configuration
|
||||
=====================================
|
||||
Copyright (C) 2015, 2018 Igalia, S.L.
|
||||
Copyright (C) 2015, 2018-2020 Igalia, S.L.
|
||||
Author: Alberto Garcia <berto@igalia.com>
|
||||
|
||||
This work is licensed under the terms of the GNU GPL, version 2 or
|
||||
|
@ -222,3 +222,20 @@ support this functionality, and is 0 (disabled) on other platforms.
|
|||
This functionality currently relies on the MADV_DONTNEED argument for
|
||||
madvise() to actually free the memory. This is a Linux-specific feature,
|
||||
so cache-clean-interval is not supported on other systems.
|
||||
|
||||
|
||||
Extended L2 Entries
|
||||
-------------------
|
||||
All numbers shown in this document are valid for qcow2 images with normal
|
||||
64-bit L2 entries.
|
||||
|
||||
Images with extended L2 entries need twice as much L2 metadata, so the L2
|
||||
cache size must be twice as large for the same disk space.
|
||||
|
||||
disk_size = l2_cache_size * cluster_size / 16
|
||||
|
||||
i.e.
|
||||
|
||||
l2_cache_size = disk_size * 16 / cluster_size
|
||||
|
||||
Refcount blocks are not affected by this.
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
#define BLOCK_OPT_DATA_FILE "data_file"
|
||||
#define BLOCK_OPT_DATA_FILE_RAW "data_file_raw"
|
||||
#define BLOCK_OPT_COMPRESSION_TYPE "compression_type"
|
||||
#define BLOCK_OPT_EXTL2 "extended_l2"
|
||||
|
||||
#define BLOCK_PROBE_BUF_SIZE 512
|
||||
|
||||
|
|
|
@ -67,6 +67,9 @@
|
|||
# standalone (read-only) raw image without looking at qcow2
|
||||
# metadata (since: 4.0)
|
||||
#
|
||||
# @extended-l2: true if the image has extended L2 entries; only valid for
|
||||
# compat >= 1.1 (since 5.2)
|
||||
#
|
||||
# @lazy-refcounts: on or off; only valid for compat >= 1.1
|
||||
#
|
||||
# @corrupt: true if the image has been marked corrupt; only valid for
|
||||
|
@ -88,6 +91,7 @@
|
|||
'compat': 'str',
|
||||
'*data-file': 'str',
|
||||
'*data-file-raw': 'bool',
|
||||
'*extended-l2': 'bool',
|
||||
'*lazy-refcounts': 'bool',
|
||||
'*corrupt': 'bool',
|
||||
'refcount-bits': 'int',
|
||||
|
@ -4304,6 +4308,8 @@
|
|||
# @data-file-raw: True if the external data file must stay valid as a
|
||||
# standalone (read-only) raw image without looking at qcow2
|
||||
# metadata (default: false; since: 4.0)
|
||||
# @extended-l2 True to make the image have extended L2 entries
|
||||
# (default: false; since 5.2)
|
||||
# @size: Size of the virtual disk in bytes
|
||||
# @version: Compatibility level (default: v3)
|
||||
# @backing-file: File name of the backing file if a backing file
|
||||
|
@ -4324,6 +4330,7 @@
|
|||
'data': { 'file': 'BlockdevRef',
|
||||
'*data-file': 'BlockdevRef',
|
||||
'*data-file-raw': 'bool',
|
||||
'*extended-l2': 'bool',
|
||||
'size': 'size',
|
||||
'*version': 'BlockdevQcow2Version',
|
||||
'*backing-file': 'str',
|
||||
|
|
|
@ -117,7 +117,7 @@ header_length 112
|
|||
|
||||
Header extension:
|
||||
magic 0x6803f857 (Feature table)
|
||||
length 336
|
||||
length 384
|
||||
data <binary>
|
||||
|
||||
Header extension:
|
||||
|
@ -150,7 +150,7 @@ header_length 112
|
|||
|
||||
Header extension:
|
||||
magic 0x6803f857 (Feature table)
|
||||
length 336
|
||||
length 384
|
||||
data <binary>
|
||||
|
||||
Header extension:
|
||||
|
@ -164,7 +164,7 @@ No errors were found on the image.
|
|||
|
||||
magic 0x514649fb
|
||||
version 3
|
||||
backing_file_offset 0x210
|
||||
backing_file_offset 0x240
|
||||
backing_file_size 0x17
|
||||
cluster_bits 16
|
||||
size 67108864
|
||||
|
@ -188,7 +188,7 @@ data 'host_device'
|
|||
|
||||
Header extension:
|
||||
magic 0x6803f857 (Feature table)
|
||||
length 336
|
||||
length 384
|
||||
data <binary>
|
||||
|
||||
Header extension:
|
||||
|
|
|
@ -26,7 +26,7 @@ compatible_features []
|
|||
autoclear_features [63]
|
||||
Header extension:
|
||||
magic 0x6803f857 (Feature table)
|
||||
length 336
|
||||
length 384
|
||||
data <binary>
|
||||
|
||||
|
||||
|
@ -38,7 +38,7 @@ compatible_features []
|
|||
autoclear_features []
|
||||
Header extension:
|
||||
magic 0x6803f857 (Feature table)
|
||||
length 336
|
||||
length 384
|
||||
data <binary>
|
||||
|
||||
*** done
|
||||
|
|
|
@ -4,90 +4,90 @@ QA output created by 049
|
|||
== 1. Traditional size parameter ==
|
||||
|
||||
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024b
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1k
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1K
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1048576 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1048576 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1G
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1073741824 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1073741824 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1T
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1099511627776 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1099511627776 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024.0
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024.0b
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5k
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5K
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1572864 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1572864 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5G
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1610612736 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1610612736 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5T
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1649267441664 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1649267441664 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
== 2. Specifying size via -o ==
|
||||
|
||||
qemu-img create -f qcow2 -o size=1024 TEST_DIR/t.qcow2
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o size=1024b TEST_DIR/t.qcow2
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o size=1k TEST_DIR/t.qcow2
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o size=1K TEST_DIR/t.qcow2
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o size=1M TEST_DIR/t.qcow2
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1048576 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1048576 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o size=1G TEST_DIR/t.qcow2
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1073741824 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1073741824 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o size=1T TEST_DIR/t.qcow2
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1099511627776 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1099511627776 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o size=1024.0 TEST_DIR/t.qcow2
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o size=1024.0b TEST_DIR/t.qcow2
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o size=1.5k TEST_DIR/t.qcow2
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o size=1.5K TEST_DIR/t.qcow2
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o size=1.5M TEST_DIR/t.qcow2
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1572864 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1572864 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o size=1.5G TEST_DIR/t.qcow2
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1610612736 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1610612736 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o size=1.5T TEST_DIR/t.qcow2
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1649267441664 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1649267441664 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
== 3. Invalid sizes ==
|
||||
|
||||
|
@ -129,84 +129,84 @@ qemu-img: TEST_DIR/t.qcow2: The image size must be specified only once
|
|||
== Check correct interpretation of suffixes for cluster size ==
|
||||
|
||||
qemu-img create -f qcow2 -o cluster_size=1024 TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o cluster_size=1024b TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o cluster_size=1k TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o cluster_size=1K TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o cluster_size=1M TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1048576 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1048576 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o cluster_size=1024.0 TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o cluster_size=1024.0b TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o cluster_size=0.5k TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=512 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=512 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o cluster_size=0.5K TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=512 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=512 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o cluster_size=0.5M TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=524288 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=524288 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
== Check compat level option ==
|
||||
|
||||
qemu-img create -f qcow2 -o compat=0.10 TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o compat=1.1 TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o compat=0.42 TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=0.42 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.42 lazy_refcounts=off refcount_bits=16
|
||||
qemu-img: TEST_DIR/t.qcow2: Invalid parameter '0.42'
|
||||
|
||||
qemu-img create -f qcow2 -o compat=foobar TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=foobar lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=foobar lazy_refcounts=off refcount_bits=16
|
||||
qemu-img: TEST_DIR/t.qcow2: Invalid parameter 'foobar'
|
||||
|
||||
== Check preallocation option ==
|
||||
|
||||
qemu-img create -f qcow2 -o preallocation=off TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 preallocation=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off preallocation=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o preallocation=metadata TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 preallocation=metadata compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off preallocation=metadata compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o preallocation=1234 TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 preallocation=1234 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off preallocation=1234 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
qemu-img: TEST_DIR/t.qcow2: Invalid parameter '1234'
|
||||
|
||||
== Check encryption option ==
|
||||
|
||||
qemu-img create -f qcow2 -o encryption=off TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 encryption=off cluster_size=65536 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 encryption=off cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 --object secret,id=sec0,data=123456 -o encryption=on,encrypt.key-secret=sec0 TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 encryption=on encrypt.key-secret=sec0 cluster_size=65536 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 encryption=on encrypt.key-secret=sec0 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
== Check lazy_refcounts option (only with v3) ==
|
||||
|
||||
qemu-img create -f qcow2 -o compat=1.1,lazy_refcounts=off TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o compat=1.1,lazy_refcounts=on TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=on refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=on refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=off TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=on TEST_DIR/t.qcow2 64M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=on refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=on refcount_bits=16
|
||||
qemu-img: TEST_DIR/t.qcow2: Lazy refcounts only supported with compatibility level 1.1 and above (use version=v3 or greater)
|
||||
|
||||
*** done
|
||||
|
|
|
@ -21,6 +21,7 @@ Format specific information:
|
|||
lazy refcounts: false
|
||||
refcount bits: 16
|
||||
corrupt: true
|
||||
extended l2: false
|
||||
qemu-io: can't open device TEST_DIR/t.IMGFMT: IMGFMT: Image is corrupt; cannot be opened read/write
|
||||
no file open, try 'help open'
|
||||
read 512/512 bytes at offset 0
|
||||
|
@ -320,7 +321,7 @@ discard 65536/65536 bytes at offset 0
|
|||
qcow2: Marking image as corrupt: Preallocated zero cluster offset 0x2a00 unaligned (guest offset: 0); further corruption events will be suppressed
|
||||
write failed: Input/output error
|
||||
--- Repairing ---
|
||||
Repairing offset=2a00: Preallocated zero cluster is not properly aligned; L2 entry corrupted.
|
||||
Repairing offset=2a00: Preallocated cluster is not properly aligned; L2 entry corrupted.
|
||||
The following inconsistencies were found and repaired:
|
||||
|
||||
0 leaked clusters
|
||||
|
|
|
@ -303,6 +303,12 @@ $QEMU_IMG amend -o "compat=0.10" "$TEST_IMG"
|
|||
_img_info --format-specific
|
||||
_check_test_img
|
||||
|
||||
echo
|
||||
echo "=== Testing version downgrade with extended L2 entries ==="
|
||||
echo
|
||||
_make_test_img -o "compat=1.1,extended_l2=on" 64M
|
||||
$QEMU_IMG amend -o "compat=0.10" "$TEST_IMG"
|
||||
|
||||
echo
|
||||
echo "=== Try changing the external data file ==="
|
||||
echo
|
||||
|
|
|
@ -26,7 +26,7 @@ header_length 112
|
|||
|
||||
Header extension:
|
||||
magic 0x6803f857 (Feature table)
|
||||
length 336
|
||||
length 384
|
||||
data <binary>
|
||||
|
||||
magic 0x514649fb
|
||||
|
@ -84,7 +84,7 @@ header_length 112
|
|||
|
||||
Header extension:
|
||||
magic 0x6803f857 (Feature table)
|
||||
length 336
|
||||
length 384
|
||||
data <binary>
|
||||
|
||||
magic 0x514649fb
|
||||
|
@ -140,7 +140,7 @@ header_length 112
|
|||
|
||||
Header extension:
|
||||
magic 0x6803f857 (Feature table)
|
||||
length 336
|
||||
length 384
|
||||
data <binary>
|
||||
|
||||
ERROR cluster 5 refcount=0 reference=1
|
||||
|
@ -195,7 +195,7 @@ header_length 112
|
|||
|
||||
Header extension:
|
||||
magic 0x6803f857 (Feature table)
|
||||
length 336
|
||||
length 384
|
||||
data <binary>
|
||||
|
||||
magic 0x514649fb
|
||||
|
@ -264,7 +264,7 @@ header_length 112
|
|||
|
||||
Header extension:
|
||||
magic 0x6803f857 (Feature table)
|
||||
length 336
|
||||
length 384
|
||||
data <binary>
|
||||
|
||||
read 65536/65536 bytes at offset 44040192
|
||||
|
@ -326,7 +326,7 @@ header_length 112
|
|||
|
||||
Header extension:
|
||||
magic 0x6803f857 (Feature table)
|
||||
length 336
|
||||
length 384
|
||||
data <binary>
|
||||
|
||||
ERROR cluster 5 refcount=0 reference=1
|
||||
|
@ -355,7 +355,7 @@ header_length 112
|
|||
|
||||
Header extension:
|
||||
magic 0x6803f857 (Feature table)
|
||||
length 336
|
||||
length 384
|
||||
data <binary>
|
||||
|
||||
read 131072/131072 bytes at offset 0
|
||||
|
@ -530,8 +530,14 @@ Format specific information:
|
|||
data file: TEST_DIR/t.IMGFMT.data
|
||||
data file raw: false
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
No errors were found on the image.
|
||||
|
||||
=== Testing version downgrade with extended L2 entries ===
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
||||
qemu-img: Cannot downgrade an image with incompatible features 0x10 set
|
||||
|
||||
=== Try changing the external data file ===
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
||||
|
@ -551,6 +557,7 @@ Format specific information:
|
|||
data file: foo
|
||||
data file raw: false
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'data-file' is required for this image
|
||||
image: TEST_DIR/t.IMGFMT
|
||||
|
@ -564,6 +571,7 @@ Format specific information:
|
|||
refcount bits: 16
|
||||
data file raw: false
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
=== Clearing and setting data-file-raw ===
|
||||
|
||||
|
@ -580,6 +588,7 @@ Format specific information:
|
|||
data file: TEST_DIR/t.IMGFMT.data
|
||||
data file raw: true
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
No errors were found on the image.
|
||||
image: TEST_DIR/t.IMGFMT
|
||||
file format: IMGFMT
|
||||
|
@ -593,6 +602,7 @@ Format specific information:
|
|||
data file: TEST_DIR/t.IMGFMT.data
|
||||
data file raw: false
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
No errors were found on the image.
|
||||
qemu-img: data-file-raw cannot be set on existing images
|
||||
image: TEST_DIR/t.IMGFMT
|
||||
|
@ -607,5 +617,6 @@ Format specific information:
|
|||
data file: TEST_DIR/t.IMGFMT.data
|
||||
data file raw: false
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
No errors were found on the image.
|
||||
*** done
|
||||
|
|
|
@ -98,20 +98,20 @@ class TestQCow3NotLazy(TestQemuImgInfo):
|
|||
img_options = 'compat=1.1,lazy_refcounts=off'
|
||||
json_compare = { 'compat': '1.1', 'lazy-refcounts': False,
|
||||
'refcount-bits': 16, 'corrupt': False,
|
||||
'compression-type': 'zlib' }
|
||||
'compression-type': 'zlib', 'extended-l2': False }
|
||||
human_compare = [ 'compat: 1.1', 'compression type: zlib',
|
||||
'lazy refcounts: false', 'refcount bits: 16',
|
||||
'corrupt: false' ]
|
||||
'corrupt: false', 'extended l2: false' ]
|
||||
|
||||
class TestQCow3Lazy(TestQemuImgInfo):
|
||||
'''Testing a qcow2 version 3 image with lazy refcounts enabled'''
|
||||
img_options = 'compat=1.1,lazy_refcounts=on'
|
||||
json_compare = { 'compat': '1.1', 'lazy-refcounts': True,
|
||||
'refcount-bits': 16, 'corrupt': False,
|
||||
'compression-type': 'zlib' }
|
||||
'compression-type': 'zlib', 'extended-l2': False }
|
||||
human_compare = [ 'compat: 1.1', 'compression type: zlib',
|
||||
'lazy refcounts: true', 'refcount bits: 16',
|
||||
'corrupt: false' ]
|
||||
'corrupt: false', 'extended l2: false' ]
|
||||
|
||||
class TestQCow3NotLazyQMP(TestQMP):
|
||||
'''Testing a qcow2 version 3 image with lazy refcounts disabled, opening
|
||||
|
@ -120,7 +120,7 @@ class TestQCow3NotLazyQMP(TestQMP):
|
|||
qemu_options = 'lazy-refcounts=on'
|
||||
compare = { 'compat': '1.1', 'lazy-refcounts': False,
|
||||
'refcount-bits': 16, 'corrupt': False,
|
||||
'compression-type': 'zlib' }
|
||||
'compression-type': 'zlib', 'extended-l2': False }
|
||||
|
||||
|
||||
class TestQCow3LazyQMP(TestQMP):
|
||||
|
@ -130,7 +130,7 @@ class TestQCow3LazyQMP(TestQMP):
|
|||
qemu_options = 'lazy-refcounts=off'
|
||||
compare = { 'compat': '1.1', 'lazy-refcounts': True,
|
||||
'refcount-bits': 16, 'corrupt': False,
|
||||
'compression-type': 'zlib' }
|
||||
'compression-type': 'zlib', 'extended-l2': False }
|
||||
|
||||
TestImageInfoSpecific = None
|
||||
TestQemuImgInfo = None
|
||||
|
|
|
@ -3,14 +3,14 @@ QA output created by 082
|
|||
=== create: Options specified more than once ===
|
||||
|
||||
Testing: create -f foo -f qcow2 TEST_DIR/t.qcow2 128M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
|
||||
image: TEST_DIR/t.IMGFMT
|
||||
file format: IMGFMT
|
||||
virtual size: 128 MiB (134217728 bytes)
|
||||
cluster_size: 65536
|
||||
|
||||
Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on TEST_DIR/t.qcow2 128M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=4096 compression_type=zlib size=134217728 lazy_refcounts=on refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=4096 extended_l2=off compression_type=zlib size=134217728 lazy_refcounts=on refcount_bits=16
|
||||
image: TEST_DIR/t.IMGFMT
|
||||
file format: IMGFMT
|
||||
virtual size: 128 MiB (134217728 bytes)
|
||||
|
@ -21,9 +21,10 @@ Format specific information:
|
|||
lazy refcounts: true
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k TEST_DIR/t.qcow2 128M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=8192 compression_type=zlib size=134217728 lazy_refcounts=on refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=8192 extended_l2=off compression_type=zlib size=134217728 lazy_refcounts=on refcount_bits=16
|
||||
image: TEST_DIR/t.IMGFMT
|
||||
file format: IMGFMT
|
||||
virtual size: 128 MiB (134217728 bytes)
|
||||
|
@ -34,9 +35,10 @@ Format specific information:
|
|||
lazy refcounts: true
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
Testing: create -f qcow2 -o cluster_size=4k,cluster_size=8k TEST_DIR/t.qcow2 128M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=8192 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=8192 extended_l2=off compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
|
||||
image: TEST_DIR/t.IMGFMT
|
||||
file format: IMGFMT
|
||||
virtual size: 128 MiB (134217728 bytes)
|
||||
|
@ -62,6 +64,7 @@ Supported options:
|
|||
encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
|
||||
encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
|
@ -87,6 +90,7 @@ Supported options:
|
|||
encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
|
||||
encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
|
@ -112,6 +116,7 @@ Supported options:
|
|||
encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
|
||||
encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
|
@ -137,6 +142,7 @@ Supported options:
|
|||
encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
|
||||
encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
|
@ -162,6 +168,7 @@ Supported options:
|
|||
encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
|
||||
encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
|
@ -187,6 +194,7 @@ Supported options:
|
|||
encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
|
||||
encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
|
@ -212,6 +220,7 @@ Supported options:
|
|||
encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
|
||||
encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
|
@ -237,6 +246,7 @@ Supported options:
|
|||
encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
|
||||
encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
|
@ -245,10 +255,10 @@ Supported options:
|
|||
size=<size> - Virtual disk size
|
||||
|
||||
Testing: create -f qcow2 -u -o backing_file=TEST_DIR/t.qcow2,,help -F qcow2 TEST_DIR/t.qcow2 128M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/t.qcow2,,help backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/t.qcow2,,help backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
Testing: create -f qcow2 -u -o backing_file=TEST_DIR/t.qcow2,,? -F qcow2 TEST_DIR/t.qcow2 128M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/t.qcow2,,? backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/t.qcow2,,? backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2, -o help TEST_DIR/t.qcow2 128M
|
||||
qemu-img: Invalid option list: backing_file=TEST_DIR/t.qcow2,
|
||||
|
@ -277,6 +287,7 @@ Supported qcow2 options:
|
|||
encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
|
||||
encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
|
||||
refcount_bits=<num> - Width of a reference count entry in bits
|
||||
|
@ -298,7 +309,7 @@ qemu-img: Format driver 'bochs' does not support image creation
|
|||
=== convert: Options specified more than once ===
|
||||
|
||||
Testing: create -f qcow2 TEST_DIR/t.qcow2 128M
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
Testing: convert -f foo -f qcow2 TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
|
||||
image: TEST_DIR/t.IMGFMT.base
|
||||
|
@ -322,6 +333,7 @@ Format specific information:
|
|||
lazy refcounts: true
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
Testing: convert -O qcow2 -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
|
||||
image: TEST_DIR/t.IMGFMT.base
|
||||
|
@ -334,6 +346,7 @@ Format specific information:
|
|||
lazy refcounts: true
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
Testing: convert -O qcow2 -o cluster_size=4k,cluster_size=8k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
|
||||
image: TEST_DIR/t.IMGFMT.base
|
||||
|
@ -361,6 +374,7 @@ Supported options:
|
|||
encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
|
||||
encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
|
@ -386,6 +400,7 @@ Supported options:
|
|||
encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
|
||||
encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
|
@ -411,6 +426,7 @@ Supported options:
|
|||
encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
|
||||
encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
|
@ -436,6 +452,7 @@ Supported options:
|
|||
encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
|
||||
encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
|
@ -461,6 +478,7 @@ Supported options:
|
|||
encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
|
||||
encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
|
@ -486,6 +504,7 @@ Supported options:
|
|||
encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
|
||||
encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
|
@ -511,6 +530,7 @@ Supported options:
|
|||
encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
|
||||
encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
|
@ -536,6 +556,7 @@ Supported options:
|
|||
encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
|
||||
encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
|
||||
|
@ -576,6 +597,7 @@ Supported qcow2 options:
|
|||
encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
|
||||
encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
|
||||
encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
|
||||
extended_l2=<bool (on/off)> - Extended L2 tables
|
||||
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
|
||||
preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
|
||||
refcount_bits=<num> - Width of a reference count entry in bits
|
||||
|
@ -621,6 +643,7 @@ Format specific information:
|
|||
lazy refcounts: true
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
Testing: amend -f qcow2 -o size=130M -o lazy_refcounts=off TEST_DIR/t.qcow2
|
||||
image: TEST_DIR/t.IMGFMT
|
||||
|
@ -633,6 +656,7 @@ Format specific information:
|
|||
lazy refcounts: false
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
Testing: amend -f qcow2 -o size=8M -o lazy_refcounts=on -o size=132M TEST_DIR/t.qcow2
|
||||
image: TEST_DIR/t.IMGFMT
|
||||
|
@ -645,6 +669,7 @@ Format specific information:
|
|||
lazy refcounts: true
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
Testing: amend -f qcow2 -o size=4M,size=148M TEST_DIR/t.qcow2
|
||||
image: TEST_DIR/t.IMGFMT
|
||||
|
|
|
@ -13,7 +13,7 @@ Formatting 'TEST_DIR/t.IMGFMT.2', fmt=IMGFMT size=134217728
|
|||
=== Create a single snapshot on virtio0 ===
|
||||
|
||||
{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/1-snapshot-v0.IMGFMT', 'format': 'IMGFMT' } }
|
||||
Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/t.qcow2.1 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/t.qcow2.1 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
{"return": {}}
|
||||
|
||||
=== Invalid command - missing device and nodename ===
|
||||
|
@ -30,40 +30,40 @@ Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compress
|
|||
=== Create several transactional group snapshots ===
|
||||
|
||||
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/2-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/2-snapshot-v1.IMGFMT' } } ] } }
|
||||
Formatting 'TEST_DIR/2-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/1-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/2-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/t.qcow2.2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/2-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/1-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/2-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/t.qcow2.2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
{"return": {}}
|
||||
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/3-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/3-snapshot-v1.IMGFMT' } } ] } }
|
||||
Formatting 'TEST_DIR/3-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/2-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/3-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/2-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/3-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/2-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/3-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/2-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
{"return": {}}
|
||||
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/4-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/4-snapshot-v1.IMGFMT' } } ] } }
|
||||
Formatting 'TEST_DIR/4-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/3-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/4-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/3-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/4-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/3-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/4-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/3-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
{"return": {}}
|
||||
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/5-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/5-snapshot-v1.IMGFMT' } } ] } }
|
||||
Formatting 'TEST_DIR/5-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/4-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/5-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/4-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/5-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/4-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/5-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/4-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
{"return": {}}
|
||||
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/6-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/6-snapshot-v1.IMGFMT' } } ] } }
|
||||
Formatting 'TEST_DIR/6-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/5-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/6-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/5-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/6-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/5-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/6-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/5-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
{"return": {}}
|
||||
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/7-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/7-snapshot-v1.IMGFMT' } } ] } }
|
||||
Formatting 'TEST_DIR/7-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/6-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/7-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/6-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/7-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/6-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/7-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/6-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
{"return": {}}
|
||||
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/8-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/8-snapshot-v1.IMGFMT' } } ] } }
|
||||
Formatting 'TEST_DIR/8-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/7-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/8-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/7-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/8-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/7-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/8-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/7-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
{"return": {}}
|
||||
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/9-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/9-snapshot-v1.IMGFMT' } } ] } }
|
||||
Formatting 'TEST_DIR/9-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/8-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/9-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/8-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/9-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/8-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/9-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/8-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
{"return": {}}
|
||||
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/10-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/10-snapshot-v1.IMGFMT' } } ] } }
|
||||
Formatting 'TEST_DIR/10-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/9-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/10-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/9-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/10-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/9-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/10-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 backing_file=TEST_DIR/9-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
{"return": {}}
|
||||
|
||||
=== Create a couple of snapshots using blockdev-snapshot ===
|
||||
|
|
|
@ -9,7 +9,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=536870912
|
|||
{ 'execute': 'qmp_capabilities' }
|
||||
{"return": {}}
|
||||
{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/tmp.IMGFMT', 'format': 'IMGFMT' } }
|
||||
Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
{"return": {}}
|
||||
|
||||
=== Performing block-commit on active layer ===
|
||||
|
@ -31,6 +31,6 @@ Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 cluster_size=65536 compression_type=z
|
|||
=== Performing Live Snapshot 2 ===
|
||||
|
||||
{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/tmp2.IMGFMT', 'format': 'IMGFMT' } }
|
||||
Formatting 'TEST_DIR/tmp2.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/tmp2.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
{"return": {}}
|
||||
*** done
|
||||
|
|
|
@ -13,7 +13,7 @@ Is another process using the image [TEST_DIR/t.qcow2]?
|
|||
{'execute': 'blockdev-add', 'arguments': { 'node-name': 'node0', 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT', 'locking': 'on' } }
|
||||
{"return": {}}
|
||||
{'execute': 'blockdev-snapshot-sync', 'arguments': { 'node-name': 'node0', 'snapshot-file': 'TEST_DIR/t.IMGFMT.overlay', 'snapshot-node-name': 'node1' } }
|
||||
Formatting 'TEST_DIR/t.qcow2.overlay', fmt=qcow2 cluster_size=65536 compression_type=zlib size=197120 backing_file=TEST_DIR/t.qcow2 backing_fmt=file lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2.overlay', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=197120 backing_file=TEST_DIR/t.qcow2 backing_fmt=file lazy_refcounts=off refcount_bits=16
|
||||
{"return": {}}
|
||||
{'execute': 'blockdev-add', 'arguments': { 'node-name': 'node1', 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT', 'locking': 'on' } }
|
||||
{"return": {}}
|
||||
|
|
|
@ -9,14 +9,14 @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
|
|||
=== Creating backing chain ===
|
||||
|
||||
{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'disk', 'snapshot-file': 'TEST_DIR/t.IMGFMT.mid', 'format': 'IMGFMT', 'mode': 'absolute-paths' } }
|
||||
Formatting 'TEST_DIR/t.qcow2.mid', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 backing_file=TEST_DIR/t.qcow2.base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2.mid', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 backing_file=TEST_DIR/t.qcow2.base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
{"return": {}}
|
||||
{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io disk "write 0 4M"' } }
|
||||
wrote 4194304/4194304 bytes at offset 0
|
||||
4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
{"return": ""}
|
||||
{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'disk', 'snapshot-file': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'absolute-paths' } }
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 backing_file=TEST_DIR/t.qcow2.mid backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 backing_file=TEST_DIR/t.qcow2.mid backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
{"return": {}}
|
||||
|
||||
=== Start commit job and exit qemu ===
|
||||
|
@ -48,7 +48,7 @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zli
|
|||
{ 'execute': 'qmp_capabilities' }
|
||||
{"return": {}}
|
||||
{ 'execute': 'drive-mirror', 'arguments': { 'device': 'disk', 'target': 'TEST_DIR/t.IMGFMT.copy', 'format': 'IMGFMT', 'sync': 'full', 'speed': 65536 } }
|
||||
Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk"}}
|
||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}}
|
||||
{"return": {}}
|
||||
|
@ -62,7 +62,7 @@ Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 cluster_size=65536 compression_typ
|
|||
{ 'execute': 'qmp_capabilities' }
|
||||
{"return": {}}
|
||||
{ 'execute': 'drive-backup', 'arguments': { 'device': 'disk', 'target': 'TEST_DIR/t.IMGFMT.copy', 'format': 'IMGFMT', 'sync': 'full', 'speed': 65536 } }
|
||||
Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk"}}
|
||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}}
|
||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "disk"}}
|
||||
|
|
|
@ -94,6 +94,7 @@ echo "== checking image base =="
|
|||
$QEMU_IMG info --image-opts $IMGSPECBASE | _filter_img_info --format-specific \
|
||||
| sed -e "/^disk size:/ D" -e '/refcount bits:/ D' -e '/compat:/ D' \
|
||||
-e '/lazy refcounts:/ D' -e '/corrupt:/ D' -e '/^\s*data file/ D' \
|
||||
-e '/extended l2:/ D' \
|
||||
| _filter_json_filename
|
||||
|
||||
echo
|
||||
|
@ -101,6 +102,7 @@ echo "== checking image layer =="
|
|||
$QEMU_IMG info --image-opts $IMGSPECLAYER | _filter_img_info --format-specific \
|
||||
| sed -e "/^disk size:/ D" -e '/refcount bits:/ D' -e '/compat:/ D' \
|
||||
-e '/lazy refcounts:/ D' -e '/corrupt:/ D' -e '/^\s*data file/ D' \
|
||||
-e '/extended l2:/ D' \
|
||||
| _filter_json_filename
|
||||
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ Format specific information:
|
|||
lazy refcounts: false
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
=== Successful image creation (inline blockdev-add, explicit defaults) ===
|
||||
|
||||
|
@ -45,6 +46,7 @@ Format specific information:
|
|||
lazy refcounts: false
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
=== Successful image creation (v3 non-default options) ===
|
||||
|
||||
|
@ -68,6 +70,7 @@ Format specific information:
|
|||
lazy refcounts: true
|
||||
refcount bits: 1
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
=== Successful image creation (v2 non-default options) ===
|
||||
|
||||
|
@ -146,6 +149,7 @@ Format specific information:
|
|||
payload offset: 528384
|
||||
master key iters: XXX
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
=== Invalid BlockdevRef ===
|
||||
|
||||
|
@ -199,7 +203,7 @@ Job failed: Different refcount widths than 16 bits require compatibility level 1
|
|||
=== Invalid backing file options ===
|
||||
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"backing-file": "/dev/null", "driver": "qcow2", "file": "node0", "preallocation": "full", "size": 67108864}}}
|
||||
{"return": {}}
|
||||
Job failed: Backing file and preallocation cannot be used at the same time
|
||||
Job failed: Backing file and preallocation can only be used at the same time if extended_l2 is on
|
||||
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
|
||||
{"return": {}}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ Format specific information:
|
|||
lazy refcounts: false
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
No bitmap in JSON format output
|
||||
|
||||
|
@ -42,6 +43,7 @@ Format specific information:
|
|||
granularity: 32768
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
The same bitmaps in JSON format:
|
||||
[
|
||||
|
@ -80,6 +82,7 @@ Format specific information:
|
|||
granularity: 65536
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
The same bitmaps in JSON format:
|
||||
[
|
||||
|
@ -123,6 +126,7 @@ Format specific information:
|
|||
granularity: 65536
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
The same bitmaps in JSON format:
|
||||
[
|
||||
|
@ -167,5 +171,6 @@ Format specific information:
|
|||
granularity: 16384
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
Test complete
|
||||
|
|
|
@ -3,9 +3,9 @@ Finishing a commit job with background reads
|
|||
|
||||
=== Create backing chain and start VM ===
|
||||
|
||||
Formatting 'TEST_DIR/PID-t.qcow2.mid', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-t.qcow2.mid', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
Formatting 'TEST_DIR/PID-t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
=== Start background read requests ===
|
||||
|
||||
|
@ -23,9 +23,9 @@ Closing the VM while a job is being cancelled
|
|||
|
||||
=== Create images and start VM ===
|
||||
|
||||
Formatting 'TEST_DIR/PID-src.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-src.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
Formatting 'TEST_DIR/PID-dst.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-dst.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
wrote 1048576/1048576 bytes at offset 0
|
||||
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
|
|
@ -0,0 +1,901 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Test qcow2 images with extended L2 entries
|
||||
#
|
||||
# Copyright (C) 2019-2020 Igalia, S.L.
|
||||
# Author: Alberto Garcia <berto@igalia.com>
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
|
||||
# creator
|
||||
owner=berto@igalia.com
|
||||
|
||||
seq="$(basename $0)"
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here="$PWD"
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
{
|
||||
_cleanup_test_img
|
||||
rm -f "$TEST_IMG.raw"
|
||||
}
|
||||
trap "_cleanup; exit \$status" 0 1 2 3 15
|
||||
|
||||
# get standard environment, filters and checks
|
||||
. ./common.rc
|
||||
. ./common.filter
|
||||
|
||||
_supported_fmt qcow2
|
||||
_supported_proto file nfs
|
||||
_supported_os Linux
|
||||
_unsupported_imgopts extended_l2 compat=0.10 cluster_size data_file refcount_bits=1[^0-9]
|
||||
|
||||
l2_offset=$((0x40000))
|
||||
|
||||
_verify_img()
|
||||
{
|
||||
$QEMU_IMG compare "$TEST_IMG" "$TEST_IMG.raw" | grep -v 'Images are identical'
|
||||
$QEMU_IMG check "$TEST_IMG" | _filter_qemu_img_check | \
|
||||
grep -v 'No errors were found on the image'
|
||||
}
|
||||
|
||||
# Compare the bitmap of an extended L2 entry against an expected value
|
||||
_verify_l2_bitmap()
|
||||
{
|
||||
entry_no="$1" # L2 entry number, starting from 0
|
||||
expected_alloc="$alloc" # Space-separated list of allocated subcluster indexes
|
||||
expected_zero="$zero" # Space-separated list of zero subcluster indexes
|
||||
|
||||
offset=$(($l2_offset + $entry_no * 16))
|
||||
entry=$(peek_file_be "$TEST_IMG" $offset 8)
|
||||
offset=$(($offset + 8))
|
||||
bitmap=$(peek_file_be "$TEST_IMG" $offset 8)
|
||||
|
||||
expected_bitmap=0
|
||||
for bit in $expected_alloc; do
|
||||
expected_bitmap=$(($expected_bitmap | (1 << $bit)))
|
||||
done
|
||||
for bit in $expected_zero; do
|
||||
expected_bitmap=$(($expected_bitmap | (1 << (32 + $bit))))
|
||||
done
|
||||
printf -v expected_bitmap "%u" $expected_bitmap # Convert to unsigned
|
||||
|
||||
printf "L2 entry #%d: 0x%016x %016x\n" "$entry_no" "$entry" "$bitmap"
|
||||
if [ "$bitmap" != "$expected_bitmap" ]; then
|
||||
printf "ERROR: expecting bitmap 0x%016x\n" "$expected_bitmap"
|
||||
fi
|
||||
}
|
||||
|
||||
# This should be called as _run_test c=XXX sc=XXX off=XXX len=XXX cmd=XXX
|
||||
# c: cluster number (0 if unset)
|
||||
# sc: subcluster number inside cluster @c (0 if unset)
|
||||
# off: offset inside subcluster @sc, in kilobytes (0 if unset)
|
||||
# len: request length, passed directly to qemu-io (e.g: 256, 4k, 1M, ...)
|
||||
# cmd: the command to pass to qemu-io, must be one of
|
||||
# write -> write
|
||||
# zero -> write -z
|
||||
# unmap -> write -z -u
|
||||
# compress -> write -c
|
||||
# discard -> discard
|
||||
_run_test()
|
||||
{
|
||||
unset c sc off len cmd
|
||||
for var in "$@"; do eval "$var"; done
|
||||
case "${cmd:-write}" in
|
||||
zero)
|
||||
cmd="write -q -z";;
|
||||
unmap)
|
||||
cmd="write -q -z -u";;
|
||||
compress)
|
||||
pat=$((${pat:-0} + 1))
|
||||
cmd="write -q -c -P ${pat}";;
|
||||
write)
|
||||
pat=$((${pat:-0} + 1))
|
||||
cmd="write -q -P ${pat}";;
|
||||
discard)
|
||||
cmd="discard -q";;
|
||||
*)
|
||||
echo "Unknown option $cmd"
|
||||
exit 1;;
|
||||
esac
|
||||
c="${c:-0}"
|
||||
sc="${sc:-0}"
|
||||
off="${off:-0}"
|
||||
offset="$(($c * 64 + $sc * 2 + $off))"
|
||||
[ "$offset" != 0 ] && offset="${offset}k"
|
||||
cmd="$cmd ${offset} ${len}"
|
||||
raw_cmd=$(echo $cmd | sed s/-c//) # Raw images don't support -c
|
||||
echo $cmd | sed 's/-P [0-9][0-9]\?/-P PATTERN/'
|
||||
$QEMU_IO -c "$cmd" "$TEST_IMG" | _filter_qemu_io
|
||||
$QEMU_IO -c "$raw_cmd" -f raw "$TEST_IMG.raw" | _filter_qemu_io
|
||||
_verify_img
|
||||
_verify_l2_bitmap "$c"
|
||||
}
|
||||
|
||||
_reset_img()
|
||||
{
|
||||
size="$1"
|
||||
$QEMU_IMG create -f raw "$TEST_IMG.raw" "$size" | _filter_img_create
|
||||
if [ "$use_backing_file" = "yes" ]; then
|
||||
$QEMU_IMG create -f raw "$TEST_IMG.base" "$size" | _filter_img_create
|
||||
$QEMU_IO -c "write -q -P 0xFF 0 $size" -f raw "$TEST_IMG.base" | _filter_qemu_io
|
||||
$QEMU_IO -c "write -q -P 0xFF 0 $size" -f raw "$TEST_IMG.raw" | _filter_qemu_io
|
||||
_make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base" "$size"
|
||||
else
|
||||
_make_test_img -o extended_l2=on "$size"
|
||||
fi
|
||||
}
|
||||
|
||||
############################################################
|
||||
############################################################
|
||||
############################################################
|
||||
|
||||
# Test that writing to an image with subclusters produces the expected
|
||||
# results, in images with and without backing files
|
||||
for use_backing_file in yes no; do
|
||||
echo
|
||||
echo "### Standard write tests (backing file: $use_backing_file) ###"
|
||||
echo
|
||||
_reset_img 1M
|
||||
### Write subcluster #0 (beginning of subcluster) ###
|
||||
alloc="0"; zero=""
|
||||
_run_test sc=0 len=1k
|
||||
|
||||
### Write subcluster #1 (middle of subcluster) ###
|
||||
alloc="0 1"; zero=""
|
||||
_run_test sc=1 off=1 len=512
|
||||
|
||||
### Write subcluster #2 (end of subcluster) ###
|
||||
alloc="0 1 2"; zero=""
|
||||
_run_test sc=2 off=1 len=1k
|
||||
|
||||
### Write subcluster #3 (full subcluster) ###
|
||||
alloc="0 1 2 3"; zero=""
|
||||
_run_test sc=3 len=2k
|
||||
|
||||
### Write subclusters #4-6 (full subclusters) ###
|
||||
alloc="$(seq 0 6)"; zero=""
|
||||
_run_test sc=4 len=6k
|
||||
|
||||
### Write subclusters #7-9 (partial subclusters) ###
|
||||
alloc="$(seq 0 9)"; zero=""
|
||||
_run_test sc=7 off=1 len=4k
|
||||
|
||||
### Write subcluster #16 (partial subcluster) ###
|
||||
alloc="$(seq 0 9) 16"; zero=""
|
||||
_run_test sc=16 len=1k
|
||||
|
||||
### Write subcluster #31-#33 (cluster overlap) ###
|
||||
alloc="$(seq 0 9) 16 31"; zero=""
|
||||
_run_test sc=31 off=1 len=4k
|
||||
alloc="0 1" ; zero=""
|
||||
_verify_l2_bitmap 1
|
||||
|
||||
### Zero subcluster #1
|
||||
alloc="0 $(seq 2 9) 16 31"; zero="1"
|
||||
_run_test sc=1 len=2k cmd=zero
|
||||
|
||||
### Zero cluster #0
|
||||
alloc=""; zero="$(seq 0 31)"
|
||||
_run_test sc=0 len=64k cmd=zero
|
||||
|
||||
### Fill cluster #0 with data
|
||||
alloc="$(seq 0 31)"; zero=""
|
||||
_run_test sc=0 len=64k
|
||||
|
||||
### Zero and unmap half of cluster #0 (this won't unmap it)
|
||||
alloc="$(seq 16 31)"; zero="$(seq 0 15)"
|
||||
_run_test sc=0 len=32k cmd=unmap
|
||||
|
||||
### Zero and unmap cluster #0
|
||||
alloc=""; zero="$(seq 0 31)"
|
||||
_run_test sc=0 len=64k cmd=unmap
|
||||
|
||||
### Write subcluster #1 (middle of subcluster)
|
||||
alloc="1"; zero="0 $(seq 2 31)"
|
||||
_run_test sc=1 off=1 len=512
|
||||
|
||||
### Fill cluster #0 with data
|
||||
alloc="$(seq 0 31)"; zero=""
|
||||
_run_test sc=0 len=64k
|
||||
|
||||
### Discard cluster #0
|
||||
alloc=""; zero="$(seq 0 31)"
|
||||
_run_test sc=0 len=64k cmd=discard
|
||||
|
||||
### Write compressed data to cluster #0
|
||||
alloc=""; zero=""
|
||||
_run_test sc=0 len=64k cmd=compress
|
||||
|
||||
### Write subcluster #1 (middle of subcluster)
|
||||
alloc="$(seq 0 31)"; zero=""
|
||||
_run_test sc=1 off=1 len=512
|
||||
done
|
||||
|
||||
############################################################
|
||||
############################################################
|
||||
############################################################
|
||||
|
||||
# calculate_l2_meta() checks if none of the clusters affected by a
|
||||
# write operation need COW or changes to their L2 metadata and simply
|
||||
# returns when they don't. This is a test for that optimization.
|
||||
# Here clusters #0-#3 are overwritten but only #1 and #2 need changes.
|
||||
echo
|
||||
echo '### Overwriting several clusters without COW ###'
|
||||
echo
|
||||
use_backing_file="no" _reset_img 1M
|
||||
# Write cluster #0, subclusters #12-#31
|
||||
alloc="$(seq 12 31)"; zero=""
|
||||
_run_test sc=12 len=40k
|
||||
|
||||
# Write cluster #1, subcluster #13
|
||||
alloc="13"; zero=""
|
||||
_run_test c=1 sc=13 len=2k
|
||||
|
||||
# Zeroize cluster #2, subcluster #14
|
||||
alloc="14"; zero=""
|
||||
_run_test c=2 sc=14 len=2k
|
||||
alloc=""; zero="14"
|
||||
_run_test c=2 sc=14 len=2k cmd=zero
|
||||
|
||||
# Write cluster #3, subclusters #0-#16
|
||||
alloc="$(seq 0 16)"; zero=""
|
||||
_run_test c=3 sc=0 len=34k
|
||||
|
||||
# Write from cluster #0, subcluster #12 to cluster #3, subcluster #11
|
||||
alloc="$(seq 12 31)"; zero=""
|
||||
_run_test sc=12 len=192k
|
||||
alloc="$(seq 0 31)"; zero=""
|
||||
_verify_l2_bitmap 1
|
||||
_verify_l2_bitmap 2
|
||||
|
||||
alloc="$(seq 0 16)"; zero=""
|
||||
_verify_l2_bitmap 3
|
||||
|
||||
############################################################
|
||||
############################################################
|
||||
############################################################
|
||||
|
||||
# Test different patterns of writing zeroes
|
||||
for use_backing_file in yes no; do
|
||||
echo
|
||||
echo "### Writing zeroes 1: unallocated clusters (backing file: $use_backing_file) ###"
|
||||
echo
|
||||
# Note that the image size is not a multiple of the cluster size
|
||||
_reset_img 2083k
|
||||
|
||||
# Cluster-aligned request from clusters #0 to #2
|
||||
alloc=""; zero="$(seq 0 31)"
|
||||
_run_test c=0 sc=0 len=192k cmd=zero
|
||||
_verify_l2_bitmap 1
|
||||
_verify_l2_bitmap 2
|
||||
|
||||
# Subcluster-aligned request from clusters #3 to #5
|
||||
alloc=""; zero="$(seq 16 31)"
|
||||
_run_test c=3 sc=16 len=128k cmd=zero
|
||||
alloc=""; zero="$(seq 0 31)"
|
||||
_verify_l2_bitmap 4
|
||||
alloc=""; zero="$(seq 0 15)"
|
||||
_verify_l2_bitmap 5
|
||||
|
||||
# Unaligned request from clusters #6 to #8
|
||||
if [ "$use_backing_file" = "yes" ]; then
|
||||
alloc="15"; zero="$(seq 16 31)" # copy-on-write happening here
|
||||
else
|
||||
alloc=""; zero="$(seq 15 31)"
|
||||
fi
|
||||
_run_test c=6 sc=15 off=1 len=128k cmd=zero
|
||||
alloc=""; zero="$(seq 0 31)"
|
||||
_verify_l2_bitmap 7
|
||||
if [ "$use_backing_file" = "yes" ]; then
|
||||
alloc="15"; zero="$(seq 0 14)" # copy-on-write happening here
|
||||
else
|
||||
alloc=""; zero="$(seq 0 15)"
|
||||
fi
|
||||
_verify_l2_bitmap 8
|
||||
|
||||
echo
|
||||
echo "### Writing zeroes 2: allocated clusters (backing file: $use_backing_file) ###"
|
||||
echo
|
||||
alloc="$(seq 0 31)"; zero=""
|
||||
_run_test c=9 sc=0 len=576k
|
||||
_verify_l2_bitmap 10
|
||||
_verify_l2_bitmap 11
|
||||
_verify_l2_bitmap 12
|
||||
_verify_l2_bitmap 13
|
||||
_verify_l2_bitmap 14
|
||||
_verify_l2_bitmap 15
|
||||
_verify_l2_bitmap 16
|
||||
_verify_l2_bitmap 17
|
||||
|
||||
# Cluster-aligned request from clusters #9 to #11
|
||||
alloc=""; zero="$(seq 0 31)"
|
||||
_run_test c=9 sc=0 len=192k cmd=zero
|
||||
_verify_l2_bitmap 10
|
||||
_verify_l2_bitmap 11
|
||||
|
||||
# Subcluster-aligned request from clusters #12 to #14
|
||||
alloc="$(seq 0 15)"; zero="$(seq 16 31)"
|
||||
_run_test c=12 sc=16 len=128k cmd=zero
|
||||
alloc=""; zero="$(seq 0 31)"
|
||||
_verify_l2_bitmap 13
|
||||
alloc="$(seq 16 31)"; zero="$(seq 0 15)"
|
||||
_verify_l2_bitmap 14
|
||||
|
||||
# Unaligned request from clusters #15 to #17
|
||||
alloc="$(seq 0 15)"; zero="$(seq 16 31)"
|
||||
_run_test c=15 sc=15 off=1 len=128k cmd=zero
|
||||
alloc=""; zero="$(seq 0 31)"
|
||||
_verify_l2_bitmap 16
|
||||
alloc="$(seq 15 31)"; zero="$(seq 0 14)"
|
||||
_verify_l2_bitmap 17
|
||||
|
||||
echo
|
||||
echo "### Writing zeroes 3: compressed clusters (backing file: $use_backing_file) ###"
|
||||
echo
|
||||
alloc=""; zero=""
|
||||
for c in $(seq 18 28); do
|
||||
_run_test c=$c sc=0 len=64k cmd=compress
|
||||
done
|
||||
|
||||
# Cluster-aligned request from clusters #18 to #20
|
||||
alloc=""; zero="$(seq 0 31)"
|
||||
_run_test c=18 sc=0 len=192k cmd=zero
|
||||
_verify_l2_bitmap 19
|
||||
_verify_l2_bitmap 20
|
||||
|
||||
# Subcluster-aligned request from clusters #21 to #23.
|
||||
# We cannot partially zero a compressed cluster so the code
|
||||
# returns -ENOTSUP, which means copy-on-write of the compressed
|
||||
# data and fill the rest with actual zeroes on disk.
|
||||
# TODO: cluster #22 should use the 'all zeroes' bits.
|
||||
alloc="$(seq 0 31)"; zero=""
|
||||
_run_test c=21 sc=16 len=128k cmd=zero
|
||||
_verify_l2_bitmap 22
|
||||
_verify_l2_bitmap 23
|
||||
|
||||
# Unaligned request from clusters #24 to #26
|
||||
# In this case QEMU internally sends a 1k request followed by a
|
||||
# subcluster-aligned 128k request. The first request decompresses
|
||||
# cluster #24, but that's not enough to perform the second request
|
||||
# efficiently because it partially writes to cluster #26 (which is
|
||||
# compressed) so we hit the same problem as before.
|
||||
alloc="$(seq 0 31)"; zero=""
|
||||
_run_test c=24 sc=15 off=1 len=129k cmd=zero
|
||||
_verify_l2_bitmap 25
|
||||
_verify_l2_bitmap 26
|
||||
|
||||
# Unaligned request from clusters #27 to #29
|
||||
# Similar to the previous case, but this time the tail of the
|
||||
# request does not correspond to a compressed cluster, so it can
|
||||
# be zeroed efficiently.
|
||||
# Note that the very last subcluster is partially written, so if
|
||||
# there's a backing file we need to perform cow.
|
||||
alloc="$(seq 0 15)"; zero="$(seq 16 31)"
|
||||
_run_test c=27 sc=15 off=1 len=128k cmd=zero
|
||||
alloc=""; zero="$(seq 0 31)"
|
||||
_verify_l2_bitmap 28
|
||||
if [ "$use_backing_file" = "yes" ]; then
|
||||
alloc="15"; zero="$(seq 0 14)" # copy-on-write happening here
|
||||
else
|
||||
alloc=""; zero="$(seq 0 15)"
|
||||
fi
|
||||
_verify_l2_bitmap 29
|
||||
|
||||
echo
|
||||
echo "### Writing zeroes 4: other tests (backing file: $use_backing_file) ###"
|
||||
echo
|
||||
# Unaligned request in the middle of cluster #30.
|
||||
# If there's a backing file we need to allocate and do
|
||||
# copy-on-write on the partially zeroed subclusters.
|
||||
# If not we can set the 'all zeroes' bit on them.
|
||||
if [ "$use_backing_file" = "yes" ]; then
|
||||
alloc="15 19"; zero="$(seq 16 18)" # copy-on-write happening here
|
||||
else
|
||||
alloc=""; zero="$(seq 15 19)"
|
||||
fi
|
||||
_run_test c=30 sc=15 off=1 len=8k cmd=zero
|
||||
|
||||
# Fill the last cluster with zeroes, up to the end of the image
|
||||
# (the image size is not a multiple of the cluster or subcluster size).
|
||||
alloc=""; zero="$(seq 0 17)"
|
||||
_run_test c=32 sc=0 len=35k cmd=zero
|
||||
done
|
||||
|
||||
############################################################
|
||||
############################################################
|
||||
############################################################
|
||||
|
||||
# Zero + unmap
|
||||
for use_backing_file in yes no; do
|
||||
echo
|
||||
echo "### Zero + unmap 1: allocated clusters (backing file: $use_backing_file) ###"
|
||||
echo
|
||||
# Note that the image size is not a multiple of the cluster size
|
||||
_reset_img 2083k
|
||||
alloc="$(seq 0 31)"; zero=""
|
||||
_run_test c=9 sc=0 len=576k
|
||||
_verify_l2_bitmap 10
|
||||
_verify_l2_bitmap 11
|
||||
_verify_l2_bitmap 12
|
||||
_verify_l2_bitmap 13
|
||||
_verify_l2_bitmap 14
|
||||
_verify_l2_bitmap 15
|
||||
_verify_l2_bitmap 16
|
||||
_verify_l2_bitmap 17
|
||||
|
||||
# Cluster-aligned request from clusters #9 to #11
|
||||
alloc=""; zero="$(seq 0 31)"
|
||||
_run_test c=9 sc=0 len=192k cmd=unmap
|
||||
_verify_l2_bitmap 10
|
||||
_verify_l2_bitmap 11
|
||||
|
||||
# Subcluster-aligned request from clusters #12 to #14
|
||||
alloc="$(seq 0 15)"; zero="$(seq 16 31)"
|
||||
_run_test c=12 sc=16 len=128k cmd=unmap
|
||||
alloc=""; zero="$(seq 0 31)"
|
||||
_verify_l2_bitmap 13
|
||||
alloc="$(seq 16 31)"; zero="$(seq 0 15)"
|
||||
_verify_l2_bitmap 14
|
||||
|
||||
# Unaligned request from clusters #15 to #17
|
||||
alloc="$(seq 0 15)"; zero="$(seq 16 31)"
|
||||
_run_test c=15 sc=15 off=1 len=128k cmd=unmap
|
||||
alloc=""; zero="$(seq 0 31)"
|
||||
_verify_l2_bitmap 16
|
||||
alloc="$(seq 15 31)"; zero="$(seq 0 14)"
|
||||
_verify_l2_bitmap 17
|
||||
|
||||
echo
|
||||
echo "### Zero + unmap 2: compressed clusters (backing file: $use_backing_file) ###"
|
||||
echo
|
||||
alloc=""; zero=""
|
||||
for c in $(seq 18 28); do
|
||||
_run_test c=$c sc=0 len=64k cmd=compress
|
||||
done
|
||||
|
||||
# Cluster-aligned request from clusters #18 to #20
|
||||
alloc=""; zero="$(seq 0 31)"
|
||||
_run_test c=18 sc=0 len=192k cmd=unmap
|
||||
_verify_l2_bitmap 19
|
||||
_verify_l2_bitmap 20
|
||||
|
||||
# Subcluster-aligned request from clusters #21 to #23.
|
||||
# We cannot partially zero a compressed cluster so the code
|
||||
# returns -ENOTSUP, which means copy-on-write of the compressed
|
||||
# data and fill the rest with actual zeroes on disk.
|
||||
# TODO: cluster #22 should use the 'all zeroes' bits.
|
||||
alloc="$(seq 0 31)"; zero=""
|
||||
_run_test c=21 sc=16 len=128k cmd=unmap
|
||||
_verify_l2_bitmap 22
|
||||
_verify_l2_bitmap 23
|
||||
|
||||
# Unaligned request from clusters #24 to #26
|
||||
# In this case QEMU internally sends a 1k request followed by a
|
||||
# subcluster-aligned 128k request. The first request decompresses
|
||||
# cluster #24, but that's not enough to perform the second request
|
||||
# efficiently because it partially writes to cluster #26 (which is
|
||||
# compressed) so we hit the same problem as before.
|
||||
alloc="$(seq 0 31)"; zero=""
|
||||
_run_test c=24 sc=15 off=1 len=129k cmd=unmap
|
||||
_verify_l2_bitmap 25
|
||||
_verify_l2_bitmap 26
|
||||
|
||||
# Unaligned request from clusters #27 to #29
|
||||
# Similar to the previous case, but this time the tail of the
|
||||
# request does not correspond to a compressed cluster, so it can
|
||||
# be zeroed efficiently.
|
||||
# Note that the very last subcluster is partially written, so if
|
||||
# there's a backing file we need to perform cow.
|
||||
alloc="$(seq 0 15)"; zero="$(seq 16 31)"
|
||||
_run_test c=27 sc=15 off=1 len=128k cmd=unmap
|
||||
alloc=""; zero="$(seq 0 31)"
|
||||
_verify_l2_bitmap 28
|
||||
if [ "$use_backing_file" = "yes" ]; then
|
||||
alloc="15"; zero="$(seq 0 14)" # copy-on-write happening here
|
||||
else
|
||||
alloc=""; zero="$(seq 0 15)"
|
||||
fi
|
||||
_verify_l2_bitmap 29
|
||||
done
|
||||
|
||||
############################################################
|
||||
############################################################
|
||||
############################################################
|
||||
|
||||
# Test qcow2_cluster_discard() with full and normal discards
|
||||
for use_backing_file in yes no; do
|
||||
echo
|
||||
echo "### Discarding clusters with non-zero bitmaps (backing file: $use_backing_file) ###"
|
||||
echo
|
||||
if [ "$use_backing_file" = "yes" ]; then
|
||||
_make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base" 1M
|
||||
else
|
||||
_make_test_img -o extended_l2=on 1M
|
||||
fi
|
||||
# Write clusters #0-#2 and then discard them
|
||||
$QEMU_IO -c 'write -q 0 128k' "$TEST_IMG"
|
||||
$QEMU_IO -c 'discard -q 0 128k' "$TEST_IMG"
|
||||
# 'qemu-io discard' doesn't do a full discard, it zeroizes the
|
||||
# cluster, so both clusters have all zero bits set now
|
||||
alloc=""; zero="$(seq 0 31)"
|
||||
_verify_l2_bitmap 0
|
||||
_verify_l2_bitmap 1
|
||||
# Now mark the 2nd half of the subclusters from cluster #0 as unallocated
|
||||
poke_file "$TEST_IMG" $(($l2_offset+8)) "\x00\x00"
|
||||
# Discard cluster #0 again to see how the zero bits have changed
|
||||
$QEMU_IO -c 'discard -q 0 64k' "$TEST_IMG"
|
||||
# And do a full discard of cluster #1 by shrinking and growing the image
|
||||
$QEMU_IMG resize --shrink "$TEST_IMG" 64k
|
||||
$QEMU_IMG resize "$TEST_IMG" 1M
|
||||
# A normal discard sets all 'zero' bits only if the image has a
|
||||
# backing file, otherwise it won't touch them.
|
||||
if [ "$use_backing_file" = "yes" ]; then
|
||||
alloc=""; zero="$(seq 0 31)"
|
||||
else
|
||||
alloc=""; zero="$(seq 0 15)"
|
||||
fi
|
||||
_verify_l2_bitmap 0
|
||||
# A full discard should clear the L2 entry completely. However
|
||||
# when growing an image with a backing file the new clusters are
|
||||
# zeroized to hide the stale data from the backing file
|
||||
if [ "$use_backing_file" = "yes" ]; then
|
||||
alloc=""; zero="$(seq 0 31)"
|
||||
else
|
||||
alloc=""; zero=""
|
||||
fi
|
||||
_verify_l2_bitmap 1
|
||||
done
|
||||
|
||||
############################################################
|
||||
############################################################
|
||||
############################################################
|
||||
|
||||
# Test that corrupted L2 entries are detected in both read and write
|
||||
# operations
|
||||
for corruption_test_cmd in read write; do
|
||||
echo
|
||||
echo "### Corrupted L2 entries - $corruption_test_cmd test (allocated) ###"
|
||||
echo
|
||||
echo "# 'cluster is zero' bit set on the standard cluster descriptor"
|
||||
echo
|
||||
# We actually don't consider this a corrupted image.
|
||||
# The 'cluster is zero' bit is unused in extended L2 entries so
|
||||
# QEMU ignores it.
|
||||
# TODO: maybe treat the image as corrupted and make qemu-img check fix it?
|
||||
_make_test_img -o extended_l2=on 1M
|
||||
$QEMU_IO -c 'write -q -P 0x11 0 2k' "$TEST_IMG"
|
||||
poke_file "$TEST_IMG" $(($l2_offset+7)) "\x01"
|
||||
alloc="0"; zero=""
|
||||
_verify_l2_bitmap 0
|
||||
$QEMU_IO -c "$corruption_test_cmd -q -P 0x11 0 1k" "$TEST_IMG"
|
||||
if [ "$corruption_test_cmd" = "write" ]; then
|
||||
alloc="0"; zero=""
|
||||
fi
|
||||
_verify_l2_bitmap 0
|
||||
|
||||
echo
|
||||
echo "# Both 'subcluster is zero' and 'subcluster is allocated' bits set"
|
||||
echo
|
||||
_make_test_img -o extended_l2=on 1M
|
||||
# Write from the middle of cluster #0 to the middle of cluster #2
|
||||
$QEMU_IO -c 'write -q 32k 128k' "$TEST_IMG"
|
||||
# Corrupt the L2 entry from cluster #1
|
||||
poke_file_be "$TEST_IMG" $(($l2_offset+24)) 4 1
|
||||
alloc="$(seq 0 31)"; zero="0"
|
||||
_verify_l2_bitmap 1
|
||||
$QEMU_IO -c "$corruption_test_cmd 0 192k" "$TEST_IMG"
|
||||
|
||||
echo
|
||||
echo "### Corrupted L2 entries - $corruption_test_cmd test (unallocated) ###"
|
||||
echo
|
||||
echo "# 'cluster is zero' bit set on the standard cluster descriptor"
|
||||
echo
|
||||
# We actually don't consider this a corrupted image.
|
||||
# The 'cluster is zero' bit is unused in extended L2 entries so
|
||||
# QEMU ignores it.
|
||||
# TODO: maybe treat the image as corrupted and make qemu-img check fix it?
|
||||
_make_test_img -o extended_l2=on 1M
|
||||
# We want to modify the (empty) L2 entry from cluster #0,
|
||||
# but we write to #4 in order to initialize the L2 table first
|
||||
$QEMU_IO -c 'write -q 256k 1k' "$TEST_IMG"
|
||||
poke_file "$TEST_IMG" $(($l2_offset+7)) "\x01"
|
||||
alloc=""; zero=""
|
||||
_verify_l2_bitmap 0
|
||||
$QEMU_IO -c "$corruption_test_cmd -q 0 1k" "$TEST_IMG"
|
||||
if [ "$corruption_test_cmd" = "write" ]; then
|
||||
alloc="0"; zero=""
|
||||
fi
|
||||
_verify_l2_bitmap 0
|
||||
|
||||
echo
|
||||
echo "# 'subcluster is allocated' bit set"
|
||||
echo
|
||||
_make_test_img -o extended_l2=on 1M
|
||||
# We want to corrupt the (empty) L2 entry from cluster #0,
|
||||
# but we write to #4 in order to initialize the L2 table first
|
||||
$QEMU_IO -c 'write -q 256k 1k' "$TEST_IMG"
|
||||
poke_file "$TEST_IMG" $(($l2_offset+15)) "\x01"
|
||||
alloc="0"; zero=""
|
||||
_verify_l2_bitmap 0
|
||||
$QEMU_IO -c "$corruption_test_cmd 0 1k" "$TEST_IMG"
|
||||
|
||||
echo
|
||||
echo "# Both 'subcluster is zero' and 'subcluster is allocated' bits set"
|
||||
echo
|
||||
_make_test_img -o extended_l2=on 1M
|
||||
# We want to corrupt the (empty) L2 entry from cluster #1,
|
||||
# but we write to #4 in order to initialize the L2 table first
|
||||
$QEMU_IO -c 'write -q 256k 1k' "$TEST_IMG"
|
||||
# Corrupt the L2 entry from cluster #1
|
||||
poke_file_be "$TEST_IMG" $(($l2_offset+24)) 8 $(((1 << 32) | 1))
|
||||
alloc="0"; zero="0"
|
||||
_verify_l2_bitmap 1
|
||||
$QEMU_IO -c "$corruption_test_cmd 0 192k" "$TEST_IMG"
|
||||
|
||||
echo
|
||||
echo "### Compressed cluster with subcluster bitmap != 0 - $corruption_test_cmd test ###"
|
||||
echo
|
||||
# We actually don't consider this a corrupted image.
|
||||
# The bitmap in compressed clusters is unused so QEMU should just ignore it.
|
||||
_make_test_img -o extended_l2=on 1M
|
||||
$QEMU_IO -c 'write -q -P 11 -c 0 64k' "$TEST_IMG"
|
||||
# Change the L2 bitmap to allocate subcluster #31 and zeroize subcluster #0
|
||||
poke_file "$TEST_IMG" $(($l2_offset+11)) "\x01\x80"
|
||||
alloc="31"; zero="0"
|
||||
_verify_l2_bitmap 0
|
||||
$QEMU_IO -c "$corruption_test_cmd -P 11 0 64k" "$TEST_IMG" | _filter_qemu_io
|
||||
# Writing allocates a new uncompressed cluster so we get a new bitmap
|
||||
if [ "$corruption_test_cmd" = "write" ]; then
|
||||
alloc="$(seq 0 31)"; zero=""
|
||||
fi
|
||||
_verify_l2_bitmap 0
|
||||
done
|
||||
|
||||
############################################################
|
||||
############################################################
|
||||
############################################################
|
||||
|
||||
echo
|
||||
echo "### Detect and repair unaligned clusters ###"
|
||||
echo
|
||||
# Create a backing file and fill it with data
|
||||
$QEMU_IMG create -f raw "$TEST_IMG.base" 128k | _filter_img_create
|
||||
$QEMU_IO -c "write -q -P 0xff 0 128k" -f raw "$TEST_IMG.base" | _filter_qemu_io
|
||||
|
||||
echo "# Corrupted L2 entry, allocated subcluster #"
|
||||
# Create a new image, allocate a cluster and write some data to it
|
||||
_make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base"
|
||||
$QEMU_IO -c 'write -q -P 1 4k 2k' "$TEST_IMG"
|
||||
# Corrupt the L2 entry by making the offset unaligned
|
||||
poke_file "$TEST_IMG" "$(($l2_offset+6))" "\x02"
|
||||
# This cannot be repaired, qemu-img check will fail to fix it
|
||||
_check_test_img -r all
|
||||
# Attempting to read the image will still show that it's corrupted
|
||||
$QEMU_IO -c 'read -q 0 2k' "$TEST_IMG"
|
||||
|
||||
echo "# Corrupted L2 entry, no allocated subclusters #"
|
||||
# Create a new image, allocate a cluster and zeroize subcluster #2
|
||||
_make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base"
|
||||
$QEMU_IO -c 'write -q -P 1 4k 2k' "$TEST_IMG"
|
||||
$QEMU_IO -c 'write -q -z 4k 2k' "$TEST_IMG"
|
||||
# Corrupt the L2 entry by making the offset unaligned
|
||||
poke_file "$TEST_IMG" "$(($l2_offset+6))" "\x02"
|
||||
# This time none of the subclusters are allocated so we can repair the image
|
||||
_check_test_img -r all
|
||||
# And the data can be read normally
|
||||
$QEMU_IO -c 'read -q -P 0xff 0 4k' "$TEST_IMG"
|
||||
$QEMU_IO -c 'read -q -P 0x00 4k 2k' "$TEST_IMG"
|
||||
$QEMU_IO -c 'read -q -P 0xff 6k 122k' "$TEST_IMG"
|
||||
|
||||
############################################################
|
||||
############################################################
|
||||
############################################################
|
||||
|
||||
echo
|
||||
echo "### Image creation options ###"
|
||||
echo
|
||||
echo "# cluster_size < 16k"
|
||||
_make_test_img -o extended_l2=on,cluster_size=8k 1M
|
||||
|
||||
echo "# backing file and preallocation=metadata"
|
||||
# For preallocation with backing files, create a backing file first
|
||||
$QEMU_IMG create -f raw "$TEST_IMG.base" 1M | _filter_img_create
|
||||
$QEMU_IO -c "write -q -P 0xff 0 1M" -f raw "$TEST_IMG.base" | _filter_qemu_io
|
||||
|
||||
_make_test_img -o extended_l2=on,preallocation=metadata -F raw -b "$TEST_IMG.base" 512k
|
||||
$QEMU_IMG resize "$TEST_IMG" 1M
|
||||
$QEMU_IO -c 'read -P 0xff 0 512k' "$TEST_IMG" | _filter_qemu_io
|
||||
$QEMU_IO -c 'read -P 0x00 512k 512k' "$TEST_IMG" | _filter_qemu_io
|
||||
$QEMU_IMG map "$TEST_IMG" | _filter_testdir
|
||||
|
||||
echo "# backing file and preallocation=falloc"
|
||||
_make_test_img -o extended_l2=on,preallocation=falloc -F raw -b "$TEST_IMG.base" 512k
|
||||
$QEMU_IMG resize "$TEST_IMG" 1M
|
||||
$QEMU_IO -c 'read -P 0xff 0 512k' "$TEST_IMG" | _filter_qemu_io
|
||||
$QEMU_IO -c 'read -P 0x00 512k 512k' "$TEST_IMG" | _filter_qemu_io
|
||||
$QEMU_IMG map "$TEST_IMG" | _filter_testdir
|
||||
|
||||
echo "# backing file and preallocation=full"
|
||||
_make_test_img -o extended_l2=on,preallocation=full -F raw -b "$TEST_IMG.base" 512k
|
||||
$QEMU_IMG resize "$TEST_IMG" 1M
|
||||
$QEMU_IO -c 'read -P 0xff 0 512k' "$TEST_IMG" | _filter_qemu_io
|
||||
$QEMU_IO -c 'read -P 0x00 512k 512k' "$TEST_IMG" | _filter_qemu_io
|
||||
$QEMU_IMG map "$TEST_IMG" | _filter_testdir
|
||||
|
||||
echo
|
||||
echo "### Image resizing with preallocation and backing files ###"
|
||||
echo
|
||||
# In this case the new subclusters must have the 'all zeroes' bit set
|
||||
echo "# resize --preallocation=metadata"
|
||||
_make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base" 503k
|
||||
$QEMU_IMG resize --preallocation=metadata "$TEST_IMG" 1013k
|
||||
$QEMU_IO -c 'read -P 0xff 0 503k' "$TEST_IMG" | _filter_qemu_io
|
||||
$QEMU_IO -c 'read -P 0x00 503k 510k' "$TEST_IMG" | _filter_qemu_io
|
||||
|
||||
# In this case and the next one the new subclusters must be allocated
|
||||
echo "# resize --preallocation=falloc"
|
||||
_make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base" 503k
|
||||
$QEMU_IMG resize --preallocation=falloc "$TEST_IMG" 1013k
|
||||
$QEMU_IO -c 'read -P 0xff 0 503k' "$TEST_IMG" | _filter_qemu_io
|
||||
$QEMU_IO -c 'read -P 0x00 503k 510k' "$TEST_IMG" | _filter_qemu_io
|
||||
|
||||
echo "# resize --preallocation=full"
|
||||
_make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base" 503k
|
||||
$QEMU_IMG resize --preallocation=full "$TEST_IMG" 1013k
|
||||
$QEMU_IO -c 'read -P 0xff 0 503k' "$TEST_IMG" | _filter_qemu_io
|
||||
$QEMU_IO -c 'read -P 0x00 503k 510k' "$TEST_IMG" | _filter_qemu_io
|
||||
|
||||
echo
|
||||
echo "### Image resizing with preallocation without backing files ###"
|
||||
echo
|
||||
# In this case the new subclusters must have the 'all zeroes' bit set
|
||||
echo "# resize --preallocation=metadata"
|
||||
_make_test_img -o extended_l2=on 503k
|
||||
$QEMU_IO -c 'write -P 0xff 0 503k' "$TEST_IMG" | _filter_qemu_io
|
||||
$QEMU_IMG resize --preallocation=metadata "$TEST_IMG" 1013k
|
||||
$QEMU_IO -c 'read -P 0xff 0 503k' "$TEST_IMG" | _filter_qemu_io
|
||||
$QEMU_IO -c 'read -P 0x00 503k 510k' "$TEST_IMG" | _filter_qemu_io
|
||||
|
||||
# In this case and the next one the new subclusters must be allocated
|
||||
echo "# resize --preallocation=falloc"
|
||||
_make_test_img -o extended_l2=on 503k
|
||||
$QEMU_IO -c 'write -P 0xff 0 503k' "$TEST_IMG" | _filter_qemu_io
|
||||
$QEMU_IMG resize --preallocation=falloc "$TEST_IMG" 1013k
|
||||
$QEMU_IO -c 'read -P 0xff 0 503k' "$TEST_IMG" | _filter_qemu_io
|
||||
$QEMU_IO -c 'read -P 0x00 503k 510k' "$TEST_IMG" | _filter_qemu_io
|
||||
|
||||
echo "# resize --preallocation=full"
|
||||
_make_test_img -o extended_l2=on 503k
|
||||
$QEMU_IO -c 'write -P 0xff 0 503k' "$TEST_IMG" | _filter_qemu_io
|
||||
$QEMU_IMG resize --preallocation=full "$TEST_IMG" 1013k
|
||||
$QEMU_IO -c 'read -P 0xff 0 503k' "$TEST_IMG" | _filter_qemu_io
|
||||
$QEMU_IO -c 'read -P 0x00 503k 510k' "$TEST_IMG" | _filter_qemu_io
|
||||
|
||||
echo
|
||||
echo "### qemu-img measure ###"
|
||||
echo
|
||||
echo "# 512MB, extended_l2=off" # This needs one L2 table
|
||||
$QEMU_IMG measure --size 512M -O qcow2 -o extended_l2=off
|
||||
echo "# 512MB, extended_l2=on" # This needs two L2 tables
|
||||
$QEMU_IMG measure --size 512M -O qcow2 -o extended_l2=on
|
||||
|
||||
echo "# 16K clusters, 64GB, extended_l2=off" # This needs one full L1 table cluster
|
||||
$QEMU_IMG measure --size 64G -O qcow2 -o cluster_size=16k,extended_l2=off
|
||||
echo "# 16K clusters, 64GB, extended_l2=on" # This needs two full L2 table clusters
|
||||
$QEMU_IMG measure --size 64G -O qcow2 -o cluster_size=16k,extended_l2=on
|
||||
|
||||
echo "# 8k clusters" # This should fail
|
||||
$QEMU_IMG measure --size 1M -O qcow2 -o cluster_size=8k,extended_l2=on
|
||||
|
||||
echo "# 1024 TB" # Maximum allowed size with extended_l2=on and 64K clusters
|
||||
$QEMU_IMG measure --size 1024T -O qcow2 -o extended_l2=on
|
||||
echo "# 1025 TB" # This should fail
|
||||
$QEMU_IMG measure --size 1025T -O qcow2 -o extended_l2=on
|
||||
|
||||
echo
|
||||
echo "### qemu-img amend ###"
|
||||
echo
|
||||
_make_test_img -o extended_l2=on 1M
|
||||
$QEMU_IMG amend -o extended_l2=off "$TEST_IMG" && echo "Unexpected pass"
|
||||
|
||||
_make_test_img -o extended_l2=off 1M
|
||||
$QEMU_IMG amend -o extended_l2=on "$TEST_IMG" && echo "Unexpected pass"
|
||||
|
||||
echo
|
||||
echo "### Test copy-on-write on an image with snapshots ###"
|
||||
echo
|
||||
_make_test_img -o extended_l2=on 1M
|
||||
|
||||
# For each cluster from #0 to #9 this loop zeroes subcluster #7
|
||||
# and allocates subclusters #13 and #18.
|
||||
alloc="13 18"; zero="7"
|
||||
for c in $(seq 0 9); do
|
||||
$QEMU_IO -c "write -q -z $((64*$c+14))k 2k" \
|
||||
-c "write -q -P $((0xd0+$c)) $((64*$c+26))k 2k" \
|
||||
-c "write -q -P $((0xe0+$c)) $((64*$c+36))k 2k" "$TEST_IMG"
|
||||
_verify_l2_bitmap "$c"
|
||||
done
|
||||
|
||||
# Create a snapshot and set l2_offset to the new L2 table
|
||||
$QEMU_IMG snapshot -c snap1 "$TEST_IMG"
|
||||
l2_offset=$((0x110000))
|
||||
|
||||
# Write different patterns to each one of the clusters
|
||||
# in order to see how copy-on-write behaves in each case.
|
||||
$QEMU_IO -c "write -q -P 0xf0 $((64*0+30))k 1k" \
|
||||
-c "write -q -P 0xf1 $((64*1+20))k 1k" \
|
||||
-c "write -q -P 0xf2 $((64*2+40))k 1k" \
|
||||
-c "write -q -P 0xf3 $((64*3+26))k 1k" \
|
||||
-c "write -q -P 0xf4 $((64*4+14))k 1k" \
|
||||
-c "write -q -P 0xf5 $((64*5+1))k 1k" \
|
||||
-c "write -q -z $((64*6+30))k 3k" \
|
||||
-c "write -q -z $((64*7+26))k 2k" \
|
||||
-c "write -q -z $((64*8+26))k 1k" \
|
||||
-c "write -q -z $((64*9+12))k 1k" \
|
||||
"$TEST_IMG"
|
||||
alloc="$(seq 13 18)"; zero="7" _verify_l2_bitmap 0
|
||||
alloc="$(seq 10 18)"; zero="7" _verify_l2_bitmap 1
|
||||
alloc="$(seq 13 20)"; zero="7" _verify_l2_bitmap 2
|
||||
alloc="$(seq 13 18)"; zero="7" _verify_l2_bitmap 3
|
||||
alloc="$(seq 7 18)"; zero="" _verify_l2_bitmap 4
|
||||
alloc="$(seq 0 18)"; zero="" _verify_l2_bitmap 5
|
||||
alloc="13 18"; zero="7 15 16" _verify_l2_bitmap 6
|
||||
alloc="18"; zero="7 13" _verify_l2_bitmap 7
|
||||
alloc="$(seq 13 18)"; zero="7" _verify_l2_bitmap 8
|
||||
alloc="13 18"; zero="6 7" _verify_l2_bitmap 9
|
||||
|
||||
echo
|
||||
echo "### Test concurrent requests ###"
|
||||
echo
|
||||
|
||||
_concurrent_io()
|
||||
{
|
||||
# Allocate three subclusters in the same cluster.
|
||||
# This works because handle_dependencies() checks whether the requests
|
||||
# allocate the same cluster, even if the COW regions don't overlap (in
|
||||
# this case they don't).
|
||||
cat <<EOF
|
||||
open -o driver=$IMGFMT blkdebug::$TEST_IMG
|
||||
break write_aio A
|
||||
aio_write -P 10 30k 2k
|
||||
wait_break A
|
||||
aio_write -P 11 20k 2k
|
||||
aio_write -P 12 40k 2k
|
||||
resume A
|
||||
aio_flush
|
||||
EOF
|
||||
}
|
||||
|
||||
_concurrent_verify()
|
||||
{
|
||||
cat <<EOF
|
||||
open -o driver=$IMGFMT $TEST_IMG
|
||||
read -q -P 10 30k 2k
|
||||
read -q -P 11 20k 2k
|
||||
read -q -P 12 40k 2k
|
||||
EOF
|
||||
}
|
||||
|
||||
_make_test_img -o extended_l2=on 1M
|
||||
_concurrent_io | $QEMU_IO | _filter_qemu_io
|
||||
_concurrent_verify | $QEMU_IO | _filter_qemu_io
|
||||
|
||||
# success, all done
|
||||
echo "*** done"
|
||||
rm -f $seq.full
|
||||
status=0
|
|
@ -0,0 +1,726 @@
|
|||
QA output created by 271
|
||||
|
||||
### Standard write tests (backing file: yes) ###
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT.raw', fmt=raw size=1048576
|
||||
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=raw size=1048576
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=raw
|
||||
write -q -P PATTERN 0 1k
|
||||
L2 entry #0: 0x8000000000050000 0000000000000001
|
||||
write -q -P PATTERN 3k 512
|
||||
L2 entry #0: 0x8000000000050000 0000000000000003
|
||||
write -q -P PATTERN 5k 1k
|
||||
L2 entry #0: 0x8000000000050000 0000000000000007
|
||||
write -q -P PATTERN 6k 2k
|
||||
L2 entry #0: 0x8000000000050000 000000000000000f
|
||||
write -q -P PATTERN 8k 6k
|
||||
L2 entry #0: 0x8000000000050000 000000000000007f
|
||||
write -q -P PATTERN 15k 4k
|
||||
L2 entry #0: 0x8000000000050000 00000000000003ff
|
||||
write -q -P PATTERN 32k 1k
|
||||
L2 entry #0: 0x8000000000050000 00000000000103ff
|
||||
write -q -P PATTERN 63k 4k
|
||||
L2 entry #0: 0x8000000000050000 00000000800103ff
|
||||
L2 entry #1: 0x8000000000060000 0000000000000003
|
||||
write -q -z 2k 2k
|
||||
L2 entry #0: 0x8000000000050000 00000002800103fd
|
||||
write -q -z 0 64k
|
||||
L2 entry #0: 0x8000000000050000 ffffffff00000000
|
||||
write -q -P PATTERN 0 64k
|
||||
L2 entry #0: 0x8000000000050000 00000000ffffffff
|
||||
write -q -z -u 0 32k
|
||||
L2 entry #0: 0x8000000000050000 0000ffffffff0000
|
||||
write -q -z -u 0 64k
|
||||
L2 entry #0: 0x0000000000000000 ffffffff00000000
|
||||
write -q -P PATTERN 3k 512
|
||||
L2 entry #0: 0x8000000000050000 fffffffd00000002
|
||||
write -q -P PATTERN 0 64k
|
||||
L2 entry #0: 0x8000000000050000 00000000ffffffff
|
||||
discard -q 0 64k
|
||||
L2 entry #0: 0x0000000000000000 ffffffff00000000
|
||||
write -q -c -P PATTERN 0 64k
|
||||
L2 entry #0: 0x4000000000050000 0000000000000000
|
||||
write -q -P PATTERN 3k 512
|
||||
L2 entry #0: 0x8000000000070000 00000000ffffffff
|
||||
|
||||
### Standard write tests (backing file: no) ###
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT.raw', fmt=raw size=1048576
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
write -q -P PATTERN 0 1k
|
||||
L2 entry #0: 0x8000000000050000 0000000000000001
|
||||
write -q -P PATTERN 3k 512
|
||||
L2 entry #0: 0x8000000000050000 0000000000000003
|
||||
write -q -P PATTERN 5k 1k
|
||||
L2 entry #0: 0x8000000000050000 0000000000000007
|
||||
write -q -P PATTERN 6k 2k
|
||||
L2 entry #0: 0x8000000000050000 000000000000000f
|
||||
write -q -P PATTERN 8k 6k
|
||||
L2 entry #0: 0x8000000000050000 000000000000007f
|
||||
write -q -P PATTERN 15k 4k
|
||||
L2 entry #0: 0x8000000000050000 00000000000003ff
|
||||
write -q -P PATTERN 32k 1k
|
||||
L2 entry #0: 0x8000000000050000 00000000000103ff
|
||||
write -q -P PATTERN 63k 4k
|
||||
L2 entry #0: 0x8000000000050000 00000000800103ff
|
||||
L2 entry #1: 0x8000000000060000 0000000000000003
|
||||
write -q -z 2k 2k
|
||||
L2 entry #0: 0x8000000000050000 00000002800103fd
|
||||
write -q -z 0 64k
|
||||
L2 entry #0: 0x8000000000050000 ffffffff00000000
|
||||
write -q -P PATTERN 0 64k
|
||||
L2 entry #0: 0x8000000000050000 00000000ffffffff
|
||||
write -q -z -u 0 32k
|
||||
L2 entry #0: 0x8000000000050000 0000ffffffff0000
|
||||
write -q -z -u 0 64k
|
||||
L2 entry #0: 0x0000000000000000 ffffffff00000000
|
||||
write -q -P PATTERN 3k 512
|
||||
L2 entry #0: 0x8000000000050000 fffffffd00000002
|
||||
write -q -P PATTERN 0 64k
|
||||
L2 entry #0: 0x8000000000050000 00000000ffffffff
|
||||
discard -q 0 64k
|
||||
L2 entry #0: 0x0000000000000000 ffffffff00000000
|
||||
write -q -c -P PATTERN 0 64k
|
||||
L2 entry #0: 0x4000000000050000 0000000000000000
|
||||
write -q -P PATTERN 3k 512
|
||||
L2 entry #0: 0x8000000000070000 00000000ffffffff
|
||||
|
||||
### Overwriting several clusters without COW ###
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT.raw', fmt=raw size=1048576
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
write -q -P PATTERN 24k 40k
|
||||
L2 entry #0: 0x8000000000050000 00000000fffff000
|
||||
write -q -P PATTERN 90k 2k
|
||||
L2 entry #1: 0x8000000000060000 0000000000002000
|
||||
write -q -P PATTERN 156k 2k
|
||||
L2 entry #2: 0x8000000000070000 0000000000004000
|
||||
write -q -z 156k 2k
|
||||
L2 entry #2: 0x8000000000070000 0000400000000000
|
||||
write -q -P PATTERN 192k 34k
|
||||
L2 entry #3: 0x8000000000080000 000000000001ffff
|
||||
write -q -P PATTERN 24k 192k
|
||||
L2 entry #0: 0x8000000000050000 00000000fffff000
|
||||
L2 entry #1: 0x8000000000060000 00000000ffffffff
|
||||
L2 entry #2: 0x8000000000070000 00000000ffffffff
|
||||
L2 entry #3: 0x8000000000080000 000000000001ffff
|
||||
|
||||
### Writing zeroes 1: unallocated clusters (backing file: yes) ###
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT.raw', fmt=raw size=2132992
|
||||
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=raw size=2132992
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2132992 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=raw
|
||||
write -q -z 0 192k
|
||||
L2 entry #0: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #1: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #2: 0x0000000000000000 ffffffff00000000
|
||||
write -q -z 224k 128k
|
||||
L2 entry #3: 0x0000000000000000 ffff000000000000
|
||||
L2 entry #4: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #5: 0x0000000000000000 0000ffff00000000
|
||||
write -q -z 415k 128k
|
||||
L2 entry #6: 0x8000000000050000 ffff000000008000
|
||||
L2 entry #7: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #8: 0x8000000000060000 00007fff00008000
|
||||
|
||||
### Writing zeroes 2: allocated clusters (backing file: yes) ###
|
||||
|
||||
write -q -P PATTERN 576k 576k
|
||||
L2 entry #9: 0x8000000000070000 00000000ffffffff
|
||||
L2 entry #10: 0x8000000000080000 00000000ffffffff
|
||||
L2 entry #11: 0x8000000000090000 00000000ffffffff
|
||||
L2 entry #12: 0x80000000000a0000 00000000ffffffff
|
||||
L2 entry #13: 0x80000000000b0000 00000000ffffffff
|
||||
L2 entry #14: 0x80000000000c0000 00000000ffffffff
|
||||
L2 entry #15: 0x80000000000d0000 00000000ffffffff
|
||||
L2 entry #16: 0x80000000000e0000 00000000ffffffff
|
||||
L2 entry #17: 0x80000000000f0000 00000000ffffffff
|
||||
write -q -z 576k 192k
|
||||
L2 entry #9: 0x8000000000070000 ffffffff00000000
|
||||
L2 entry #10: 0x8000000000080000 ffffffff00000000
|
||||
L2 entry #11: 0x8000000000090000 ffffffff00000000
|
||||
write -q -z 800k 128k
|
||||
L2 entry #12: 0x80000000000a0000 ffff00000000ffff
|
||||
L2 entry #13: 0x80000000000b0000 ffffffff00000000
|
||||
L2 entry #14: 0x80000000000c0000 0000ffffffff0000
|
||||
write -q -z 991k 128k
|
||||
L2 entry #15: 0x80000000000d0000 ffff00000000ffff
|
||||
L2 entry #16: 0x80000000000e0000 ffffffff00000000
|
||||
L2 entry #17: 0x80000000000f0000 00007fffffff8000
|
||||
|
||||
### Writing zeroes 3: compressed clusters (backing file: yes) ###
|
||||
|
||||
write -q -c -P PATTERN 1152k 64k
|
||||
L2 entry #18: 0x4000000000100000 0000000000000000
|
||||
write -q -c -P PATTERN 1216k 64k
|
||||
L2 entry #19: 0x4000000000110000 0000000000000000
|
||||
write -q -c -P PATTERN 1280k 64k
|
||||
L2 entry #20: 0x4000000000120000 0000000000000000
|
||||
write -q -c -P PATTERN 1344k 64k
|
||||
L2 entry #21: 0x4000000000130000 0000000000000000
|
||||
write -q -c -P PATTERN 1408k 64k
|
||||
L2 entry #22: 0x4000000000140000 0000000000000000
|
||||
write -q -c -P PATTERN 1472k 64k
|
||||
L2 entry #23: 0x4000000000150000 0000000000000000
|
||||
write -q -c -P PATTERN 1536k 64k
|
||||
L2 entry #24: 0x4000000000160000 0000000000000000
|
||||
write -q -c -P PATTERN 1600k 64k
|
||||
L2 entry #25: 0x4000000000170000 0000000000000000
|
||||
write -q -c -P PATTERN 1664k 64k
|
||||
L2 entry #26: 0x4000000000180000 0000000000000000
|
||||
write -q -c -P PATTERN 1728k 64k
|
||||
L2 entry #27: 0x4000000000190000 0000000000000000
|
||||
write -q -c -P PATTERN 1792k 64k
|
||||
L2 entry #28: 0x40000000001a0000 0000000000000000
|
||||
write -q -z 1152k 192k
|
||||
L2 entry #18: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #19: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #20: 0x0000000000000000 ffffffff00000000
|
||||
write -q -z 1376k 128k
|
||||
L2 entry #21: 0x8000000000100000 00000000ffffffff
|
||||
L2 entry #22: 0x8000000000110000 00000000ffffffff
|
||||
L2 entry #23: 0x8000000000120000 00000000ffffffff
|
||||
write -q -z 1567k 129k
|
||||
L2 entry #24: 0x8000000000130000 00000000ffffffff
|
||||
L2 entry #25: 0x8000000000140000 00000000ffffffff
|
||||
L2 entry #26: 0x8000000000150000 00000000ffffffff
|
||||
write -q -z 1759k 128k
|
||||
L2 entry #27: 0x8000000000160000 ffff00000000ffff
|
||||
L2 entry #28: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #29: 0x8000000000170000 00007fff00008000
|
||||
|
||||
### Writing zeroes 4: other tests (backing file: yes) ###
|
||||
|
||||
write -q -z 1951k 8k
|
||||
L2 entry #30: 0x8000000000180000 0007000000088000
|
||||
write -q -z 2048k 35k
|
||||
L2 entry #32: 0x0000000000000000 0003ffff00000000
|
||||
|
||||
### Writing zeroes 1: unallocated clusters (backing file: no) ###
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT.raw', fmt=raw size=2132992
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2132992
|
||||
write -q -z 0 192k
|
||||
L2 entry #0: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #1: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #2: 0x0000000000000000 ffffffff00000000
|
||||
write -q -z 224k 128k
|
||||
L2 entry #3: 0x0000000000000000 ffff000000000000
|
||||
L2 entry #4: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #5: 0x0000000000000000 0000ffff00000000
|
||||
write -q -z 415k 128k
|
||||
L2 entry #6: 0x0000000000000000 ffff800000000000
|
||||
L2 entry #7: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #8: 0x0000000000000000 0000ffff00000000
|
||||
|
||||
### Writing zeroes 2: allocated clusters (backing file: no) ###
|
||||
|
||||
write -q -P PATTERN 576k 576k
|
||||
L2 entry #9: 0x8000000000050000 00000000ffffffff
|
||||
L2 entry #10: 0x8000000000060000 00000000ffffffff
|
||||
L2 entry #11: 0x8000000000070000 00000000ffffffff
|
||||
L2 entry #12: 0x8000000000080000 00000000ffffffff
|
||||
L2 entry #13: 0x8000000000090000 00000000ffffffff
|
||||
L2 entry #14: 0x80000000000a0000 00000000ffffffff
|
||||
L2 entry #15: 0x80000000000b0000 00000000ffffffff
|
||||
L2 entry #16: 0x80000000000c0000 00000000ffffffff
|
||||
L2 entry #17: 0x80000000000d0000 00000000ffffffff
|
||||
write -q -z 576k 192k
|
||||
L2 entry #9: 0x8000000000050000 ffffffff00000000
|
||||
L2 entry #10: 0x8000000000060000 ffffffff00000000
|
||||
L2 entry #11: 0x8000000000070000 ffffffff00000000
|
||||
write -q -z 800k 128k
|
||||
L2 entry #12: 0x8000000000080000 ffff00000000ffff
|
||||
L2 entry #13: 0x8000000000090000 ffffffff00000000
|
||||
L2 entry #14: 0x80000000000a0000 0000ffffffff0000
|
||||
write -q -z 991k 128k
|
||||
L2 entry #15: 0x80000000000b0000 ffff00000000ffff
|
||||
L2 entry #16: 0x80000000000c0000 ffffffff00000000
|
||||
L2 entry #17: 0x80000000000d0000 00007fffffff8000
|
||||
|
||||
### Writing zeroes 3: compressed clusters (backing file: no) ###
|
||||
|
||||
write -q -c -P PATTERN 1152k 64k
|
||||
L2 entry #18: 0x40000000000e0000 0000000000000000
|
||||
write -q -c -P PATTERN 1216k 64k
|
||||
L2 entry #19: 0x40000000000f0000 0000000000000000
|
||||
write -q -c -P PATTERN 1280k 64k
|
||||
L2 entry #20: 0x4000000000100000 0000000000000000
|
||||
write -q -c -P PATTERN 1344k 64k
|
||||
L2 entry #21: 0x4000000000110000 0000000000000000
|
||||
write -q -c -P PATTERN 1408k 64k
|
||||
L2 entry #22: 0x4000000000120000 0000000000000000
|
||||
write -q -c -P PATTERN 1472k 64k
|
||||
L2 entry #23: 0x4000000000130000 0000000000000000
|
||||
write -q -c -P PATTERN 1536k 64k
|
||||
L2 entry #24: 0x4000000000140000 0000000000000000
|
||||
write -q -c -P PATTERN 1600k 64k
|
||||
L2 entry #25: 0x4000000000150000 0000000000000000
|
||||
write -q -c -P PATTERN 1664k 64k
|
||||
L2 entry #26: 0x4000000000160000 0000000000000000
|
||||
write -q -c -P PATTERN 1728k 64k
|
||||
L2 entry #27: 0x4000000000170000 0000000000000000
|
||||
write -q -c -P PATTERN 1792k 64k
|
||||
L2 entry #28: 0x4000000000180000 0000000000000000
|
||||
write -q -z 1152k 192k
|
||||
L2 entry #18: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #19: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #20: 0x0000000000000000 ffffffff00000000
|
||||
write -q -z 1376k 128k
|
||||
L2 entry #21: 0x80000000000e0000 00000000ffffffff
|
||||
L2 entry #22: 0x80000000000f0000 00000000ffffffff
|
||||
L2 entry #23: 0x8000000000100000 00000000ffffffff
|
||||
write -q -z 1567k 129k
|
||||
L2 entry #24: 0x8000000000110000 00000000ffffffff
|
||||
L2 entry #25: 0x8000000000120000 00000000ffffffff
|
||||
L2 entry #26: 0x8000000000130000 00000000ffffffff
|
||||
write -q -z 1759k 128k
|
||||
L2 entry #27: 0x8000000000140000 ffff00000000ffff
|
||||
L2 entry #28: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #29: 0x0000000000000000 0000ffff00000000
|
||||
|
||||
### Writing zeroes 4: other tests (backing file: no) ###
|
||||
|
||||
write -q -z 1951k 8k
|
||||
L2 entry #30: 0x0000000000000000 000f800000000000
|
||||
write -q -z 2048k 35k
|
||||
L2 entry #32: 0x0000000000000000 0003ffff00000000
|
||||
|
||||
### Zero + unmap 1: allocated clusters (backing file: yes) ###
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT.raw', fmt=raw size=2132992
|
||||
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=raw size=2132992
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2132992 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=raw
|
||||
write -q -P PATTERN 576k 576k
|
||||
L2 entry #9: 0x8000000000050000 00000000ffffffff
|
||||
L2 entry #10: 0x8000000000060000 00000000ffffffff
|
||||
L2 entry #11: 0x8000000000070000 00000000ffffffff
|
||||
L2 entry #12: 0x8000000000080000 00000000ffffffff
|
||||
L2 entry #13: 0x8000000000090000 00000000ffffffff
|
||||
L2 entry #14: 0x80000000000a0000 00000000ffffffff
|
||||
L2 entry #15: 0x80000000000b0000 00000000ffffffff
|
||||
L2 entry #16: 0x80000000000c0000 00000000ffffffff
|
||||
L2 entry #17: 0x80000000000d0000 00000000ffffffff
|
||||
write -q -z -u 576k 192k
|
||||
L2 entry #9: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #10: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #11: 0x0000000000000000 ffffffff00000000
|
||||
write -q -z -u 800k 128k
|
||||
L2 entry #12: 0x8000000000080000 ffff00000000ffff
|
||||
L2 entry #13: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #14: 0x80000000000a0000 0000ffffffff0000
|
||||
write -q -z -u 991k 128k
|
||||
L2 entry #15: 0x80000000000b0000 ffff00000000ffff
|
||||
L2 entry #16: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #17: 0x80000000000d0000 00007fffffff8000
|
||||
|
||||
### Zero + unmap 2: compressed clusters (backing file: yes) ###
|
||||
|
||||
write -q -c -P PATTERN 1152k 64k
|
||||
L2 entry #18: 0x4000000000050000 0000000000000000
|
||||
write -q -c -P PATTERN 1216k 64k
|
||||
L2 entry #19: 0x4000000000060000 0000000000000000
|
||||
write -q -c -P PATTERN 1280k 64k
|
||||
L2 entry #20: 0x4000000000070000 0000000000000000
|
||||
write -q -c -P PATTERN 1344k 64k
|
||||
L2 entry #21: 0x4000000000090000 0000000000000000
|
||||
write -q -c -P PATTERN 1408k 64k
|
||||
L2 entry #22: 0x40000000000c0000 0000000000000000
|
||||
write -q -c -P PATTERN 1472k 64k
|
||||
L2 entry #23: 0x40000000000e0000 0000000000000000
|
||||
write -q -c -P PATTERN 1536k 64k
|
||||
L2 entry #24: 0x40000000000f0000 0000000000000000
|
||||
write -q -c -P PATTERN 1600k 64k
|
||||
L2 entry #25: 0x4000000000100000 0000000000000000
|
||||
write -q -c -P PATTERN 1664k 64k
|
||||
L2 entry #26: 0x4000000000110000 0000000000000000
|
||||
write -q -c -P PATTERN 1728k 64k
|
||||
L2 entry #27: 0x4000000000120000 0000000000000000
|
||||
write -q -c -P PATTERN 1792k 64k
|
||||
L2 entry #28: 0x4000000000130000 0000000000000000
|
||||
write -q -z -u 1152k 192k
|
||||
L2 entry #18: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #19: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #20: 0x0000000000000000 ffffffff00000000
|
||||
write -q -z -u 1376k 128k
|
||||
L2 entry #21: 0x8000000000050000 00000000ffffffff
|
||||
L2 entry #22: 0x8000000000060000 00000000ffffffff
|
||||
L2 entry #23: 0x8000000000070000 00000000ffffffff
|
||||
write -q -z -u 1567k 129k
|
||||
L2 entry #24: 0x8000000000090000 00000000ffffffff
|
||||
L2 entry #25: 0x80000000000e0000 00000000ffffffff
|
||||
L2 entry #26: 0x80000000000f0000 00000000ffffffff
|
||||
write -q -z -u 1759k 128k
|
||||
L2 entry #27: 0x80000000000c0000 ffff00000000ffff
|
||||
L2 entry #28: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #29: 0x8000000000100000 00007fff00008000
|
||||
|
||||
### Zero + unmap 1: allocated clusters (backing file: no) ###
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT.raw', fmt=raw size=2132992
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2132992
|
||||
write -q -P PATTERN 576k 576k
|
||||
L2 entry #9: 0x8000000000050000 00000000ffffffff
|
||||
L2 entry #10: 0x8000000000060000 00000000ffffffff
|
||||
L2 entry #11: 0x8000000000070000 00000000ffffffff
|
||||
L2 entry #12: 0x8000000000080000 00000000ffffffff
|
||||
L2 entry #13: 0x8000000000090000 00000000ffffffff
|
||||
L2 entry #14: 0x80000000000a0000 00000000ffffffff
|
||||
L2 entry #15: 0x80000000000b0000 00000000ffffffff
|
||||
L2 entry #16: 0x80000000000c0000 00000000ffffffff
|
||||
L2 entry #17: 0x80000000000d0000 00000000ffffffff
|
||||
write -q -z -u 576k 192k
|
||||
L2 entry #9: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #10: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #11: 0x0000000000000000 ffffffff00000000
|
||||
write -q -z -u 800k 128k
|
||||
L2 entry #12: 0x8000000000080000 ffff00000000ffff
|
||||
L2 entry #13: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #14: 0x80000000000a0000 0000ffffffff0000
|
||||
write -q -z -u 991k 128k
|
||||
L2 entry #15: 0x80000000000b0000 ffff00000000ffff
|
||||
L2 entry #16: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #17: 0x80000000000d0000 00007fffffff8000
|
||||
|
||||
### Zero + unmap 2: compressed clusters (backing file: no) ###
|
||||
|
||||
write -q -c -P PATTERN 1152k 64k
|
||||
L2 entry #18: 0x4000000000050000 0000000000000000
|
||||
write -q -c -P PATTERN 1216k 64k
|
||||
L2 entry #19: 0x4000000000060000 0000000000000000
|
||||
write -q -c -P PATTERN 1280k 64k
|
||||
L2 entry #20: 0x4000000000070000 0000000000000000
|
||||
write -q -c -P PATTERN 1344k 64k
|
||||
L2 entry #21: 0x4000000000090000 0000000000000000
|
||||
write -q -c -P PATTERN 1408k 64k
|
||||
L2 entry #22: 0x40000000000c0000 0000000000000000
|
||||
write -q -c -P PATTERN 1472k 64k
|
||||
L2 entry #23: 0x40000000000e0000 0000000000000000
|
||||
write -q -c -P PATTERN 1536k 64k
|
||||
L2 entry #24: 0x40000000000f0000 0000000000000000
|
||||
write -q -c -P PATTERN 1600k 64k
|
||||
L2 entry #25: 0x4000000000100000 0000000000000000
|
||||
write -q -c -P PATTERN 1664k 64k
|
||||
L2 entry #26: 0x4000000000110000 0000000000000000
|
||||
write -q -c -P PATTERN 1728k 64k
|
||||
L2 entry #27: 0x4000000000120000 0000000000000000
|
||||
write -q -c -P PATTERN 1792k 64k
|
||||
L2 entry #28: 0x4000000000130000 0000000000000000
|
||||
write -q -z -u 1152k 192k
|
||||
L2 entry #18: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #19: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #20: 0x0000000000000000 ffffffff00000000
|
||||
write -q -z -u 1376k 128k
|
||||
L2 entry #21: 0x8000000000050000 00000000ffffffff
|
||||
L2 entry #22: 0x8000000000060000 00000000ffffffff
|
||||
L2 entry #23: 0x8000000000070000 00000000ffffffff
|
||||
write -q -z -u 1567k 129k
|
||||
L2 entry #24: 0x8000000000090000 00000000ffffffff
|
||||
L2 entry #25: 0x80000000000e0000 00000000ffffffff
|
||||
L2 entry #26: 0x80000000000f0000 00000000ffffffff
|
||||
write -q -z -u 1759k 128k
|
||||
L2 entry #27: 0x80000000000c0000 ffff00000000ffff
|
||||
L2 entry #28: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #29: 0x0000000000000000 0000ffff00000000
|
||||
|
||||
### Discarding clusters with non-zero bitmaps (backing file: yes) ###
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=raw
|
||||
L2 entry #0: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #1: 0x0000000000000000 ffffffff00000000
|
||||
Image resized.
|
||||
Image resized.
|
||||
L2 entry #0: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #1: 0x0000000000000000 ffffffff00000000
|
||||
|
||||
### Discarding clusters with non-zero bitmaps (backing file: no) ###
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
L2 entry #0: 0x0000000000000000 ffffffff00000000
|
||||
L2 entry #1: 0x0000000000000000 ffffffff00000000
|
||||
Image resized.
|
||||
Image resized.
|
||||
L2 entry #0: 0x0000000000000000 0000ffff00000000
|
||||
L2 entry #1: 0x0000000000000000 0000000000000000
|
||||
|
||||
### Corrupted L2 entries - read test (allocated) ###
|
||||
|
||||
# 'cluster is zero' bit set on the standard cluster descriptor
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
L2 entry #0: 0x8000000000050001 0000000000000001
|
||||
L2 entry #0: 0x8000000000050001 0000000000000001
|
||||
|
||||
# Both 'subcluster is zero' and 'subcluster is allocated' bits set
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
L2 entry #1: 0x8000000000060000 00000001ffffffff
|
||||
qcow2: Marking image as corrupt: Invalid cluster entry found (L2 offset: 0x40000, L2 index: 0x1); further corruption events will be suppressed
|
||||
read failed: Input/output error
|
||||
|
||||
### Corrupted L2 entries - read test (unallocated) ###
|
||||
|
||||
# 'cluster is zero' bit set on the standard cluster descriptor
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
L2 entry #0: 0x0000000000000001 0000000000000000
|
||||
L2 entry #0: 0x0000000000000001 0000000000000000
|
||||
|
||||
# 'subcluster is allocated' bit set
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
L2 entry #0: 0x0000000000000000 0000000000000001
|
||||
qcow2: Marking image as corrupt: Invalid cluster entry found (L2 offset: 0x40000, L2 index: 0); further corruption events will be suppressed
|
||||
read failed: Input/output error
|
||||
|
||||
# Both 'subcluster is zero' and 'subcluster is allocated' bits set
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
L2 entry #1: 0x0000000000000000 0000000100000001
|
||||
qcow2: Marking image as corrupt: Invalid cluster entry found (L2 offset: 0x40000, L2 index: 0x1); further corruption events will be suppressed
|
||||
read failed: Input/output error
|
||||
|
||||
### Compressed cluster with subcluster bitmap != 0 - read test ###
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
L2 entry #0: 0x4000000000050000 0000000180000000
|
||||
read 65536/65536 bytes at offset 0
|
||||
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
L2 entry #0: 0x4000000000050000 0000000180000000
|
||||
|
||||
### Corrupted L2 entries - write test (allocated) ###
|
||||
|
||||
# 'cluster is zero' bit set on the standard cluster descriptor
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
L2 entry #0: 0x8000000000050001 0000000000000001
|
||||
L2 entry #0: 0x8000000000050001 0000000000000001
|
||||
|
||||
# Both 'subcluster is zero' and 'subcluster is allocated' bits set
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
L2 entry #1: 0x8000000000060000 00000001ffffffff
|
||||
qcow2: Marking image as corrupt: Invalid cluster entry found (L2 offset: 0x40000, L2 index: 0x1); further corruption events will be suppressed
|
||||
write failed: Input/output error
|
||||
|
||||
### Corrupted L2 entries - write test (unallocated) ###
|
||||
|
||||
# 'cluster is zero' bit set on the standard cluster descriptor
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
L2 entry #0: 0x0000000000000001 0000000000000000
|
||||
L2 entry #0: 0x8000000000060000 0000000000000001
|
||||
|
||||
# 'subcluster is allocated' bit set
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
L2 entry #0: 0x0000000000000000 0000000000000001
|
||||
qcow2: Marking image as corrupt: Invalid cluster entry found (L2 offset: 0x40000, L2 index: 0); further corruption events will be suppressed
|
||||
write failed: Input/output error
|
||||
|
||||
# Both 'subcluster is zero' and 'subcluster is allocated' bits set
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
L2 entry #1: 0x0000000000000000 0000000100000001
|
||||
qcow2: Marking image as corrupt: Invalid cluster entry found (L2 offset: 0x40000, L2 index: 0x1); further corruption events will be suppressed
|
||||
write failed: Input/output error
|
||||
|
||||
### Compressed cluster with subcluster bitmap != 0 - write test ###
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
L2 entry #0: 0x4000000000050000 0000000180000000
|
||||
wrote 65536/65536 bytes at offset 0
|
||||
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
L2 entry #0: 0x8000000000060000 00000000ffffffff
|
||||
|
||||
### Detect and repair unaligned clusters ###
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=raw size=131072
|
||||
# Corrupted L2 entry, allocated subcluster #
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=raw
|
||||
ERROR offset=50200: Data cluster is not properly aligned; L2 entry corrupted.
|
||||
ERROR cluster 6 refcount=0 reference=1
|
||||
Rebuilding refcount structure
|
||||
ERROR offset=50200: Data cluster is not properly aligned; L2 entry corrupted.
|
||||
Repairing cluster 1 refcount=1 reference=0
|
||||
Repairing cluster 2 refcount=1 reference=0
|
||||
ERROR offset=50200: Data cluster is not properly aligned; L2 entry corrupted.
|
||||
The following inconsistencies were found and repaired:
|
||||
|
||||
0 leaked clusters
|
||||
1 corruptions
|
||||
|
||||
Double checking the fixed image now...
|
||||
|
||||
1 errors were found on the image.
|
||||
Data may be corrupted, or further writes to the image may corrupt it.
|
||||
qcow2: Marking image as corrupt: Cluster allocation offset 0x50200 unaligned (L2 offset: 0x40000, L2 index: 0); further corruption events will be suppressed
|
||||
read failed: Input/output error
|
||||
# Corrupted L2 entry, no allocated subclusters #
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=raw
|
||||
Repairing offset=50200: Preallocated cluster is not properly aligned; L2 entry corrupted.
|
||||
Leaked cluster 5 refcount=1 reference=0
|
||||
Repairing cluster 5 refcount=1 reference=0
|
||||
The following inconsistencies were found and repaired:
|
||||
|
||||
1 leaked clusters
|
||||
1 corruptions
|
||||
|
||||
Double checking the fixed image now...
|
||||
No errors were found on the image.
|
||||
|
||||
### Image creation options ###
|
||||
|
||||
# cluster_size < 16k
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
qemu-img: TEST_DIR/t.IMGFMT: Extended L2 entries are only supported with cluster sizes of at least 16384 bytes
|
||||
# backing file and preallocation=metadata
|
||||
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=raw size=1048576
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=524288 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=raw preallocation=metadata
|
||||
Image resized.
|
||||
read 524288/524288 bytes at offset 0
|
||||
512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 524288/524288 bytes at offset 524288
|
||||
512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
Offset Length Mapped to File
|
||||
0 0x80000 0 TEST_DIR/t.qcow2.base
|
||||
# backing file and preallocation=falloc
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=524288 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=raw preallocation=falloc
|
||||
Image resized.
|
||||
read 524288/524288 bytes at offset 0
|
||||
512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 524288/524288 bytes at offset 524288
|
||||
512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
Offset Length Mapped to File
|
||||
0 0x80000 0 TEST_DIR/t.qcow2.base
|
||||
# backing file and preallocation=full
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=524288 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=raw preallocation=full
|
||||
Image resized.
|
||||
read 524288/524288 bytes at offset 0
|
||||
512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 524288/524288 bytes at offset 524288
|
||||
512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
Offset Length Mapped to File
|
||||
0 0x80000 0 TEST_DIR/t.qcow2.base
|
||||
|
||||
### Image resizing with preallocation and backing files ###
|
||||
|
||||
# resize --preallocation=metadata
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=515072 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=raw
|
||||
Image resized.
|
||||
read 515072/515072 bytes at offset 0
|
||||
503 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 522240/522240 bytes at offset 515072
|
||||
510 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
# resize --preallocation=falloc
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=515072 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=raw
|
||||
Image resized.
|
||||
read 515072/515072 bytes at offset 0
|
||||
503 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 522240/522240 bytes at offset 515072
|
||||
510 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
# resize --preallocation=full
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=515072 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=raw
|
||||
Image resized.
|
||||
read 515072/515072 bytes at offset 0
|
||||
503 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 522240/522240 bytes at offset 515072
|
||||
510 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
### Image resizing with preallocation without backing files ###
|
||||
|
||||
# resize --preallocation=metadata
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=515072
|
||||
wrote 515072/515072 bytes at offset 0
|
||||
503 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
Image resized.
|
||||
read 515072/515072 bytes at offset 0
|
||||
503 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 522240/522240 bytes at offset 515072
|
||||
510 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
# resize --preallocation=falloc
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=515072
|
||||
wrote 515072/515072 bytes at offset 0
|
||||
503 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
Image resized.
|
||||
read 515072/515072 bytes at offset 0
|
||||
503 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 522240/522240 bytes at offset 515072
|
||||
510 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
# resize --preallocation=full
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=515072
|
||||
wrote 515072/515072 bytes at offset 0
|
||||
503 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
Image resized.
|
||||
read 515072/515072 bytes at offset 0
|
||||
503 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 522240/522240 bytes at offset 515072
|
||||
510 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
### qemu-img measure ###
|
||||
|
||||
# 512MB, extended_l2=off
|
||||
required size: 327680
|
||||
fully allocated size: 537198592
|
||||
# 512MB, extended_l2=on
|
||||
required size: 393216
|
||||
fully allocated size: 537264128
|
||||
# 16K clusters, 64GB, extended_l2=off
|
||||
required size: 42008576
|
||||
fully allocated size: 68761485312
|
||||
# 16K clusters, 64GB, extended_l2=on
|
||||
required size: 75579392
|
||||
fully allocated size: 68795056128
|
||||
# 8k clusters
|
||||
qemu-img: Extended L2 entries are only supported with cluster sizes of at least 16384 bytes
|
||||
# 1024 TB
|
||||
required size: 309285027840
|
||||
fully allocated size: 1126209191870464
|
||||
# 1025 TB
|
||||
qemu-img: The image size is too large (try using a larger cluster size)
|
||||
|
||||
### qemu-img amend ###
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
qemu-img: Invalid parameter 'extended_l2'
|
||||
This option is only supported for image creation
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
qemu-img: Invalid parameter 'extended_l2'
|
||||
This option is only supported for image creation
|
||||
|
||||
### Test copy-on-write on an image with snapshots ###
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
L2 entry #0: 0x8000000000050000 0000008000042000
|
||||
L2 entry #1: 0x8000000000060000 0000008000042000
|
||||
L2 entry #2: 0x8000000000070000 0000008000042000
|
||||
L2 entry #3: 0x8000000000080000 0000008000042000
|
||||
L2 entry #4: 0x8000000000090000 0000008000042000
|
||||
L2 entry #5: 0x80000000000a0000 0000008000042000
|
||||
L2 entry #6: 0x80000000000b0000 0000008000042000
|
||||
L2 entry #7: 0x80000000000c0000 0000008000042000
|
||||
L2 entry #8: 0x80000000000d0000 0000008000042000
|
||||
L2 entry #9: 0x80000000000e0000 0000008000042000
|
||||
L2 entry #0: 0x8000000000120000 000000800007e000
|
||||
L2 entry #1: 0x8000000000130000 000000800007fc00
|
||||
L2 entry #2: 0x8000000000140000 00000080001fe000
|
||||
L2 entry #3: 0x8000000000150000 000000800007e000
|
||||
L2 entry #4: 0x8000000000160000 000000000007ff80
|
||||
L2 entry #5: 0x8000000000170000 000000000007ffff
|
||||
L2 entry #6: 0x00000000000b0000 0001808000042000
|
||||
L2 entry #7: 0x00000000000c0000 0000208000040000
|
||||
L2 entry #8: 0x8000000000180000 000000800007e000
|
||||
L2 entry #9: 0x00000000000e0000 000000c000042000
|
||||
|
||||
### Test concurrent requests ###
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
|
||||
blkdebug: Suspended request 'A'
|
||||
blkdebug: Resuming request 'A'
|
||||
wrote 2048/2048 bytes at offset 30720
|
||||
2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 2048/2048 bytes at offset 20480
|
||||
2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 2048/2048 bytes at offset 40960
|
||||
2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
*** done
|
|
@ -1,9 +1,9 @@
|
|||
== Commit tests ==
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=2097152 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=2097152 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
Formatting 'TEST_DIR/PID-mid', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1048576 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-mid', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1048576 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=2097152 backing_file=TEST_DIR/PID-mid backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=2097152 backing_file=TEST_DIR/PID-mid backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
wrote 2097152/2097152 bytes at offset 0
|
||||
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
@ -57,6 +57,7 @@ Format specific information:
|
|||
lazy refcounts: false
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
read 1048576/1048576 bytes at offset 0
|
||||
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
@ -65,11 +66,11 @@ read 1048576/1048576 bytes at offset 1048576
|
|||
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
=== Testing HMP commit (top -> mid) ===
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=2097152 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=2097152 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
Formatting 'TEST_DIR/PID-mid', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1048576 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-mid', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1048576 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=2097152 backing_file=TEST_DIR/PID-mid backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=2097152 backing_file=TEST_DIR/PID-mid backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
wrote 2097152/2097152 bytes at offset 0
|
||||
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
@ -88,6 +89,7 @@ Format specific information:
|
|||
lazy refcounts: false
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
read 1048576/1048576 bytes at offset 0
|
||||
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
@ -96,11 +98,11 @@ read 1048576/1048576 bytes at offset 1048576
|
|||
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
=== Testing QMP active commit (top -> mid) ===
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=2097152 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=2097152 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
Formatting 'TEST_DIR/PID-mid', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1048576 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-mid', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1048576 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=2097152 backing_file=TEST_DIR/PID-mid backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=2097152 backing_file=TEST_DIR/PID-mid backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
wrote 2097152/2097152 bytes at offset 0
|
||||
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
@ -125,6 +127,7 @@ Format specific information:
|
|||
lazy refcounts: false
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
read 1048576/1048576 bytes at offset 0
|
||||
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
@ -134,9 +137,9 @@ read 1048576/1048576 bytes at offset 1048576
|
|||
|
||||
== Resize tests ==
|
||||
=== preallocation=off ===
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=6442450944 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=6442450944 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1073741824 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1073741824 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
wrote 65536/65536 bytes at offset 5368709120
|
||||
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
@ -153,9 +156,9 @@ read 65536/65536 bytes at offset 5368709120
|
|||
{ "start": 1073741824, "length": 7516192768, "depth": 0, "zero": true, "data": false}]
|
||||
|
||||
=== preallocation=metadata ===
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=34359738368 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=34359738368 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=32212254720 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=32212254720 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
wrote 65536/65536 bytes at offset 33285996544
|
||||
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
@ -177,9 +180,9 @@ read 65536/65536 bytes at offset 33285996544
|
|||
{ "start": 34896609280, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2685075456}]
|
||||
|
||||
=== preallocation=falloc ===
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=10485760 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=10485760 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=5242880 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=5242880 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
wrote 65536/65536 bytes at offset 9437184
|
||||
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
@ -196,9 +199,9 @@ read 65536/65536 bytes at offset 9437184
|
|||
{ "start": 5242880, "length": 10485760, "depth": 0, "zero": false, "data": true, "offset": 327680}]
|
||||
|
||||
=== preallocation=full ===
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=16777216 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=16777216 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=8388608 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=8388608 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
wrote 65536/65536 bytes at offset 11534336
|
||||
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
@ -215,9 +218,9 @@ read 65536/65536 bytes at offset 11534336
|
|||
{ "start": 8388608, "length": 4194304, "depth": 0, "zero": false, "data": true, "offset": 327680}]
|
||||
|
||||
=== preallocation=off ===
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=393216 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=393216 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=259072 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=259072 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
wrote 65536/65536 bytes at offset 259072
|
||||
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
@ -235,9 +238,9 @@ read 65536/65536 bytes at offset 259072
|
|||
{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
|
||||
|
||||
=== preallocation=off ===
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=409600 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=409600 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=262144 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=262144 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
wrote 65536/65536 bytes at offset 344064
|
||||
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
@ -254,9 +257,9 @@ read 65536/65536 bytes at offset 344064
|
|||
{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
|
||||
|
||||
=== preallocation=off ===
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=524288 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=524288 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=262144 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=262144 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
wrote 65536/65536 bytes at offset 446464
|
||||
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
|
||||
|
||||
=== Launch VM ===
|
||||
Enabling migration QMP events on VM...
|
||||
|
|
|
@ -41,6 +41,7 @@ Format specific information:
|
|||
granularity: 65536
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
image: TEST_DIR/t.IMGFMT
|
||||
file format: IMGFMT
|
||||
virtual size: 10 MiB (10485760 bytes)
|
||||
|
@ -65,6 +66,7 @@ Format specific information:
|
|||
granularity: 65536
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
=== Check bitmap contents ===
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ Format specific information:
|
|||
lazy refcounts: false
|
||||
refcount bits: 16
|
||||
corrupt: false
|
||||
extended l2: false
|
||||
|
||||
=== Converted image check ===
|
||||
No errors were found on the image.
|
||||
|
|
|
@ -47,7 +47,7 @@ header_length 112
|
|||
|
||||
Header extension:
|
||||
magic 0x6803f857 (Feature table)
|
||||
length 336
|
||||
length 384
|
||||
data <binary>
|
||||
|
||||
Header extension:
|
||||
|
@ -105,7 +105,7 @@ Bitmap table type size offset
|
|||
{
|
||||
"name": "Feature table",
|
||||
"magic": 1745090647,
|
||||
"length": 336,
|
||||
"length": 384,
|
||||
"data_str": "<binary>"
|
||||
},
|
||||
{
|
||||
|
|
|
@ -239,6 +239,7 @@ _filter_img_info()
|
|||
-e "/adapter_type: '[^']*'/d" \
|
||||
-e "/hwversion: '[^']*'/d" \
|
||||
-e "/lazy_refcounts: \\(on\\|off\\)/d" \
|
||||
-e "/extended_l2=\\(on\\|off\\)/d" \
|
||||
-e "/block_size: [0-9]\\+/d" \
|
||||
-e "/block_state_zero: \\(on\\|off\\)/d" \
|
||||
-e "/log_size: [0-9]\\+/d" \
|
||||
|
|
|
@ -284,6 +284,7 @@
|
|||
267 rw auto quick snapshot
|
||||
268 rw auto quick
|
||||
270 rw backing quick
|
||||
271 rw auto
|
||||
272 rw
|
||||
273 backing quick
|
||||
274 rw backing
|
||||
|
|
Loading…
Reference in New Issue