summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--aio-posix.c5
-rw-r--r--aio-win32.c5
-rw-r--r--block.c160
-rw-r--r--block/iscsi.c37
-rw-r--r--block/qcow2-cluster.c2
-rw-r--r--block/qcow2-refcount.c22
-rw-r--r--block/qcow2-snapshot.c10
-rw-r--r--block/qcow2.c39
-rw-r--r--block/qcow2.h5
-rw-r--r--block/qed.c3
-rw-r--r--block/raw-aio.h3
-rw-r--r--block/raw-posix.c175
-rw-r--r--block/snapshot.c77
-rw-r--r--block/vdi.c1
-rw-r--r--block/vhdx.c13
-rw-r--r--block/vmdk.c66
-rw-r--r--block/vpc.c15
-rw-r--r--hw/scsi/scsi-disk.c154
-rw-r--r--include/block/block.h4
-rw-r--r--include/block/block_int.h7
-rw-r--r--include/block/coroutine.h7
-rw-r--r--include/block/snapshot.h15
-rw-r--r--qemu-coroutine-lock.c8
-rw-r--r--qemu-img-cmds.hx4
-rw-r--r--qemu-img.c169
-rw-r--r--qemu-img.texi12
-rw-r--r--qemu-nbd.c47
-rw-r--r--qemu-nbd.texi10
-rwxr-xr-xtests/qemu-iotests/0263
-rwxr-xr-xtests/qemu-iotests/0393
-rwxr-xr-xtests/qemu-iotests/04827
-rw-r--r--tests/qemu-iotests/048.out16
-rw-r--r--tests/qemu-iotests/051.out112
-rwxr-xr-xtests/qemu-iotests/0524
-rwxr-xr-xtests/qemu-iotests/058138
-rw-r--r--tests/qemu-iotests/058.out44
-rwxr-xr-xtests/qemu-iotests/0595
-rw-r--r--tests/qemu-iotests/059.out2012
-rwxr-xr-xtests/qemu-iotests/07486
-rw-r--r--tests/qemu-iotests/074.out18
-rwxr-xr-xtests/qemu-iotests/check3
-rw-r--r--tests/qemu-iotests/common37
-rw-r--r--tests/qemu-iotests/common.filter3
-rw-r--r--tests/qemu-iotests/common.rc28
-rw-r--r--tests/qemu-iotests/group4
-rw-r--r--tests/qemu-iotests/iotests.py3
-rw-r--r--tests/test-aio.c1
-rw-r--r--trace-events4
48 files changed, 3238 insertions, 388 deletions
diff --git a/aio-posix.c b/aio-posix.c
index bd06f33c78..f921d4f538 100644
--- a/aio-posix.c
+++ b/aio-posix.c
@@ -217,11 +217,6 @@ bool aio_poll(AioContext *ctx, bool blocking)
ctx->walking_handlers--;
- /* early return if we only have the aio_notify() fd */
- if (ctx->pollfds->len == 1) {
- return progress;
- }
-
/* wait until next event */
ret = qemu_poll_ns((GPollFD *)ctx->pollfds->data,
ctx->pollfds->len,
diff --git a/aio-win32.c b/aio-win32.c
index f9cfbb75ac..23f4e5ba19 100644
--- a/aio-win32.c
+++ b/aio-win32.c
@@ -161,11 +161,6 @@ bool aio_poll(AioContext *ctx, bool blocking)
ctx->walking_handlers--;
- /* early return if we only have the aio_notify() fd */
- if (count == 1) {
- return progress;
- }
-
/* wait until next event */
while (count > 0) {
int ret;
diff --git a/block.c b/block.c
index 3d78581c63..13f001ad69 100644
--- a/block.c
+++ b/block.c
@@ -79,6 +79,7 @@ static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
int64_t sector_num,
QEMUIOVector *qiov,
int nb_sectors,
+ BdrvRequestFlags flags,
BlockDriverCompletionFunc *cb,
void *opaque,
bool is_write);
@@ -1556,13 +1557,8 @@ void bdrv_drain_all(void)
BlockDriverState *bs;
while (busy) {
- /* FIXME: We do not have timer support here, so this is effectively
- * a busy wait.
- */
QTAILQ_FOREACH(bs, &bdrv_states, list) {
- if (bdrv_start_throttled_reqs(bs)) {
- busy = true;
- }
+ bdrv_start_throttled_reqs(bs);
}
busy = bdrv_requests_pending_all();
@@ -2770,14 +2766,21 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs,
while (nb_sectors > 0 && !ret) {
int num = nb_sectors;
- /* align request */
- if (bs->bl.write_zeroes_alignment &&
- num >= bs->bl.write_zeroes_alignment &&
- sector_num % bs->bl.write_zeroes_alignment) {
- if (num > bs->bl.write_zeroes_alignment) {
+ /* Align request. Block drivers can expect the "bulk" of the request
+ * to be aligned.
+ */
+ if (bs->bl.write_zeroes_alignment
+ && num > bs->bl.write_zeroes_alignment) {
+ if (sector_num % bs->bl.write_zeroes_alignment != 0) {
+ /* Make a small request up to the first aligned sector. */
num = bs->bl.write_zeroes_alignment;
+ num -= sector_num % bs->bl.write_zeroes_alignment;
+ } else if ((sector_num + num) % bs->bl.write_zeroes_alignment != 0) {
+ /* Shorten the request to the last aligned sector. num cannot
+ * underflow because num > bs->bl.write_zeroes_alignment.
+ */
+ num -= (sector_num + num) % bs->bl.write_zeroes_alignment;
}
- num -= sector_num % bs->bl.write_zeroes_alignment;
}
/* limit request size */
@@ -2795,16 +2798,20 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs,
/* Fall back to bounce buffer if write zeroes is unsupported */
iov.iov_len = num * BDRV_SECTOR_SIZE;
if (iov.iov_base == NULL) {
- /* allocate bounce buffer only once and ensure that it
- * is big enough for this and all future requests.
- */
- size_t bufsize = num <= nb_sectors ? num : max_write_zeroes;
- iov.iov_base = qemu_blockalign(bs, bufsize * BDRV_SECTOR_SIZE);
- memset(iov.iov_base, 0, bufsize * BDRV_SECTOR_SIZE);
+ iov.iov_base = qemu_blockalign(bs, num * BDRV_SECTOR_SIZE);
+ memset(iov.iov_base, 0, num * BDRV_SECTOR_SIZE);
}
qemu_iovec_init_external(&qiov, &iov, 1);
ret = drv->bdrv_co_writev(bs, sector_num, num, &qiov);
+
+ /* Keep bounce buffer around if it is big enough for all
+ * all future requests.
+ */
+ if (num < max_write_zeroes) {
+ qemu_vfree(iov.iov_base);
+ iov.iov_base = NULL;
+ }
}
sector_num += num;
@@ -2887,7 +2894,7 @@ int coroutine_fn bdrv_co_write_zeroes(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
BdrvRequestFlags flags)
{
- trace_bdrv_co_write_zeroes(bs, sector_num, nb_sectors);
+ trace_bdrv_co_write_zeroes(bs, sector_num, nb_sectors, flags);
if (!(bs->open_flags & BDRV_O_UNMAP)) {
flags &= ~BDRV_REQ_MAY_UNMAP;
@@ -3669,7 +3676,7 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
{
trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque);
- return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
+ return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, 0,
cb, opaque, false);
}
@@ -3679,7 +3686,18 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
{
trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque);
- return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
+ return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, 0,
+ cb, opaque, true);
+}
+
+BlockDriverAIOCB *bdrv_aio_write_zeroes(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors, BdrvRequestFlags flags,
+ BlockDriverCompletionFunc *cb, void *opaque)
+{
+ trace_bdrv_aio_write_zeroes(bs, sector_num, nb_sectors, flags, opaque);
+
+ return bdrv_co_aio_rw_vector(bs, sector_num, NULL, nb_sectors,
+ BDRV_REQ_ZERO_WRITE | flags,
cb, opaque, true);
}
@@ -3851,8 +3869,10 @@ int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
/* Run the aio requests. */
mcb->num_requests = num_reqs;
for (i = 0; i < num_reqs; i++) {
- bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov,
- reqs[i].nb_sectors, multiwrite_cb, mcb);
+ bdrv_co_aio_rw_vector(bs, reqs[i].sector, reqs[i].qiov,
+ reqs[i].nb_sectors, reqs[i].flags,
+ multiwrite_cb, mcb,
+ true);
}
return 0;
@@ -3994,10 +4014,10 @@ static void coroutine_fn bdrv_co_do_rw(void *opaque)
if (!acb->is_write) {
acb->req.error = bdrv_co_do_readv(bs, acb->req.sector,
- acb->req.nb_sectors, acb->req.qiov, 0);
+ acb->req.nb_sectors, acb->req.qiov, acb->req.flags);
} else {
acb->req.error = bdrv_co_do_writev(bs, acb->req.sector,
- acb->req.nb_sectors, acb->req.qiov, 0);
+ acb->req.nb_sectors, acb->req.qiov, acb->req.flags);
}
acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
@@ -4008,6 +4028,7 @@ static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
int64_t sector_num,
QEMUIOVector *qiov,
int nb_sectors,
+ BdrvRequestFlags flags,
BlockDriverCompletionFunc *cb,
void *opaque,
bool is_write)
@@ -4019,6 +4040,7 @@ static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
acb->req.sector = sector_num;
acb->req.nb_sectors = nb_sectors;
acb->req.qiov = qiov;
+ acb->req.flags = flags;
acb->is_write = is_write;
acb->done = NULL;
@@ -4302,6 +4324,8 @@ static void coroutine_fn bdrv_discard_co_entry(void *opaque)
int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
int nb_sectors)
{
+ int max_discard;
+
if (!bs->drv) {
return -ENOMEDIUM;
} else if (bdrv_check_request(bs, sector_num, nb_sectors)) {
@@ -4317,55 +4341,55 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
return 0;
}
- if (bs->drv->bdrv_co_discard) {
- int max_discard = bs->bl.max_discard ?
- bs->bl.max_discard : MAX_DISCARD_DEFAULT;
+ if (!bs->drv->bdrv_co_discard && !bs->drv->bdrv_aio_discard) {
+ return 0;
+ }
- while (nb_sectors > 0) {
- int ret;
- int num = nb_sectors;
+ max_discard = bs->bl.max_discard ? bs->bl.max_discard : MAX_DISCARD_DEFAULT;
+ while (nb_sectors > 0) {
+ int ret;
+ int num = nb_sectors;
- /* align request */
- if (bs->bl.discard_alignment &&
- num >= bs->bl.discard_alignment &&
- sector_num % bs->bl.discard_alignment) {
- if (num > bs->bl.discard_alignment) {
- num = bs->bl.discard_alignment;
- }
- num -= sector_num % bs->bl.discard_alignment;
+ /* align request */
+ if (bs->bl.discard_alignment &&
+ num >= bs->bl.discard_alignment &&
+ sector_num % bs->bl.discard_alignment) {
+ if (num > bs->bl.discard_alignment) {
+ num = bs->bl.discard_alignment;
}
+ num -= sector_num % bs->bl.discard_alignment;
+ }
- /* limit request size */
- if (num > max_discard) {
- num = max_discard;
- }
+ /* limit request size */
+ if (num > max_discard) {
+ num = max_discard;
+ }
+ if (bs->drv->bdrv_co_discard) {
ret = bs->drv->bdrv_co_discard(bs, sector_num, num);
- if (ret) {
- return ret;
+ } else {
+ BlockDriverAIOCB *acb;
+ CoroutineIOCompletion co = {
+ .coroutine = qemu_coroutine_self(),
+ };
+
+ acb = bs->drv->bdrv_aio_discard(bs, sector_num, nb_sectors,
+ bdrv_co_io_em_complete, &co);
+ if (acb == NULL) {
+ return -EIO;
+ } else {
+ qemu_coroutine_yield();
+ ret = co.ret;
}
-
- sector_num += num;
- nb_sectors -= num;
}
- return 0;
- } else if (bs->drv->bdrv_aio_discard) {
- BlockDriverAIOCB *acb;
- CoroutineIOCompletion co = {
- .coroutine = qemu_coroutine_self(),
- };
-
- acb = bs->drv->bdrv_aio_discard(bs, sector_num, nb_sectors,
- bdrv_co_io_em_complete, &co);
- if (acb == NULL) {
- return -EIO;
- } else {
- qemu_coroutine_yield();
- return co.ret;
+ if (ret && ret != -ENOTSUP) {
+ return ret;
}
- } else {
- return 0;
+
+ sector_num += num;
+ nb_sectors -= num;
}
+ return 0;
}
int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
@@ -4684,7 +4708,6 @@ void bdrv_img_create(const char *filename, const char *fmt,
{
QEMUOptionParameter *param = NULL, *create_options = NULL;
QEMUOptionParameter *backing_fmt, *backing_file, *size;
- BlockDriverState *bs = NULL;
BlockDriver *drv, *proto_drv;
BlockDriver *backing_drv = NULL;
Error *local_err = NULL;
@@ -4763,6 +4786,7 @@ void bdrv_img_create(const char *filename, const char *fmt,
size = get_option_parameter(param, BLOCK_OPT_SIZE);
if (size && size->value.n == -1) {
if (backing_file && backing_file->value.s) {
+ BlockDriverState *bs;
uint64_t size;
char buf[32];
int back_flags;
@@ -4781,6 +4805,7 @@ void bdrv_img_create(const char *filename, const char *fmt,
error_get_pretty(local_err));
error_free(local_err);
local_err = NULL;
+ bdrv_unref(bs);
goto out;
}
bdrv_get_geometry(bs, &size);
@@ -4788,6 +4813,8 @@ void bdrv_img_create(const char *filename, const char *fmt,
snprintf(buf, sizeof(buf), "%" PRId64, size);
set_option_parameter(param, BLOCK_OPT_SIZE, buf);
+
+ bdrv_unref(bs);
} else {
error_setg(errp, "Image creation needs a size parameter");
goto out;
@@ -4818,9 +4845,6 @@ out:
free_option_parameters(create_options);
free_option_parameters(param);
- if (bs) {
- bdrv_unref(bs);
- }
if (error_is_set(&local_err)) {
error_propagate(errp, local_err);
}
diff --git a/block/iscsi.c b/block/iscsi.c
index b7b52381d6..829d444733 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -2,6 +2,7 @@
* QEMU Block driver for iSCSI images
*
* Copyright (c) 2010-2011 Ronnie Sahlberg <ronniesahlberg@gmail.com>
+ * Copyright (c) 2012-2013 Peter Lieven <pl@kamp.de>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -54,6 +55,7 @@ typedef struct IscsiLun {
QEMUTimer *nop_timer;
uint8_t lbpme;
uint8_t lbprz;
+ uint8_t has_write_same;
struct scsi_inquiry_logical_block_provisioning lbp;
struct scsi_inquiry_block_limits bl;
unsigned char *zeroblock;
@@ -975,8 +977,13 @@ coroutine_fn iscsi_co_write_zeroes(BlockDriverState *bs, int64_t sector_num,
return -EINVAL;
}
- if (!iscsilun->lbp.lbpws) {
- /* WRITE SAME is not supported by the target */
+ if (!(flags & BDRV_REQ_MAY_UNMAP) && !iscsilun->has_write_same) {
+ /* WRITE SAME without UNMAP is not supported by the target */
+ return -ENOTSUP;
+ }
+
+ if ((flags & BDRV_REQ_MAY_UNMAP) && !iscsilun->lbp.lbpws) {
+ /* WRITE SAME with UNMAP is not supported by the target */
return -ENOTSUP;
}
@@ -1011,6 +1018,14 @@ retry:
}
if (iTask.status != SCSI_STATUS_GOOD) {
+ if (iTask.status == SCSI_STATUS_CHECK_CONDITION &&
+ iTask.task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST &&
+ iTask.task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) {
+ /* WRITE SAME is not supported by the target */
+ iscsilun->has_write_same = false;
+ return -ENOTSUP;
+ }
+
return -EIO;
}
@@ -1374,6 +1389,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
}
iscsilun->type = inq->periperal_device_type;
+ iscsilun->has_write_same = true;
if ((ret = iscsi_readcapacity_sync(iscsilun)) != 0) {
goto out;
@@ -1441,6 +1457,9 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
}
bs->bl.write_zeroes_alignment = sector_lun2qemu(iscsilun->bl.opt_unmap_gran,
iscsilun);
+
+ bs->bl.opt_transfer_length = sector_lun2qemu(iscsilun->bl.opt_xfer_len,
+ iscsilun);
}
#if defined(LIBISCSI_FEATURE_NOP_COUNTER)
@@ -1505,11 +1524,6 @@ static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
return 0;
}
-static int iscsi_has_zero_init(BlockDriverState *bs)
-{
- return 0;
-}
-
static int iscsi_create(const char *filename, QEMUOptionParameter *options,
Error **errp)
{
@@ -1569,6 +1583,13 @@ static int iscsi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
IscsiLun *iscsilun = bs->opaque;
bdi->unallocated_blocks_are_zero = !!iscsilun->lbprz;
bdi->can_write_zeroes_with_unmap = iscsilun->lbprz && iscsilun->lbp.lbpws;
+ /* Guess the internal cluster (page) size of the iscsi target by the means
+ * of opt_unmap_gran. Transfer the unmap granularity only if it has a
+ * reasonable size for bdi->cluster_size */
+ if (iscsilun->bl.opt_unmap_gran * iscsilun->block_size >= 64 * 1024 &&
+ iscsilun->bl.opt_unmap_gran * iscsilun->block_size <= 16 * 1024 * 1024) {
+ bdi->cluster_size = iscsilun->bl.opt_unmap_gran * iscsilun->block_size;
+ }
return 0;
}
@@ -1608,8 +1629,6 @@ static BlockDriver bdrv_iscsi = {
.bdrv_aio_writev = iscsi_aio_writev,
.bdrv_aio_flush = iscsi_aio_flush,
- .bdrv_has_zero_init = iscsi_has_zero_init,
-
#ifdef __linux__
.bdrv_ioctl = iscsi_ioctl,
.bdrv_aio_ioctl = iscsi_aio_ioctl,
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 11f9c50aa7..853408438a 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -1401,7 +1401,7 @@ int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset,
/* Round start up and end down */
offset = align_offset(offset, s->cluster_size);
- end_offset &= ~(s->cluster_size - 1);
+ end_offset = start_of_cluster(s, end_offset);
if (offset > end_offset) {
return 0;
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 1ff43d0906..c974abe795 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -515,8 +515,8 @@ static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
s->l2_table_cache);
}
- start = offset & ~(s->cluster_size - 1);
- last = (offset + length - 1) & ~(s->cluster_size - 1);
+ start = start_of_cluster(s, offset);
+ last = start_of_cluster(s, offset + length - 1);
for(cluster_offset = start; cluster_offset <= last;
cluster_offset += s->cluster_size)
{
@@ -724,7 +724,7 @@ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)
}
redo:
free_in_cluster = s->cluster_size -
- (s->free_byte_offset & (s->cluster_size - 1));
+ offset_into_cluster(s, s->free_byte_offset);
if (size <= free_in_cluster) {
/* enough space in current cluster */
offset = s->free_byte_offset;
@@ -732,7 +732,7 @@ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)
free_in_cluster -= size;
if (free_in_cluster == 0)
s->free_byte_offset = 0;
- if ((offset & (s->cluster_size - 1)) != 0)
+ if (offset_into_cluster(s, offset) != 0)
qcow2_update_cluster_refcount(bs, offset >> s->cluster_bits, 1,
QCOW2_DISCARD_NEVER);
} else {
@@ -740,7 +740,7 @@ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)
if (offset < 0) {
return offset;
}
- cluster_offset = s->free_byte_offset & ~(s->cluster_size - 1);
+ cluster_offset = start_of_cluster(s, s->free_byte_offset);
if ((cluster_offset + s->cluster_size) == offset) {
/* we are lucky: contiguous data */
offset = s->free_byte_offset;
@@ -1010,8 +1010,8 @@ static void inc_refcounts(BlockDriverState *bs,
if (size <= 0)
return;
- start = offset & ~(s->cluster_size - 1);
- last = (offset + size - 1) & ~(s->cluster_size - 1);
+ start = start_of_cluster(s, offset);
+ last = start_of_cluster(s, offset + size - 1);
for(cluster_offset = start; cluster_offset <= last;
cluster_offset += s->cluster_size) {
k = cluster_offset >> s->cluster_bits;
@@ -1122,7 +1122,7 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
offset, s->cluster_size);
/* Correct offsets are cluster aligned */
- if (offset & (s->cluster_size - 1)) {
+ if (offset_into_cluster(s, offset)) {
fprintf(stderr, "ERROR offset=%" PRIx64 ": Cluster is not "
"properly aligned; L2 entry corrupted.\n", offset);
res->corruptions++;
@@ -1194,7 +1194,7 @@ static int check_refcounts_l1(BlockDriverState *bs,
l2_offset, s->cluster_size);
/* L2 tables are cluster aligned */
- if (l2_offset & (s->cluster_size - 1)) {
+ if (offset_into_cluster(s, l2_offset)) {
fprintf(stderr, "ERROR l2_offset=%" PRIx64 ": Table is not "
"cluster aligned; L1 entry corrupted\n", l2_offset);
res->corruptions++;
@@ -1423,7 +1423,7 @@ static int64_t realloc_refcount_block(BlockDriverState *bs, int reftable_index,
}
/* update refcount table */
- assert(!(new_offset & (s->cluster_size - 1)));
+ assert(!offset_into_cluster(s, new_offset));
s->refcount_table[reftable_index] = new_offset;
ret = write_reftable_entry(bs, reftable_index);
if (ret < 0) {
@@ -1507,7 +1507,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
cluster = offset >> s->cluster_bits;
/* Refcount blocks are cluster aligned */
- if (offset & (s->cluster_size - 1)) {
+ if (offset_into_cluster(s, offset)) {
fprintf(stderr, "ERROR refcount block %" PRId64 " is not "
"cluster aligned; refcount table entry corrupted\n", i);
res->corruptions++;
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index 3529c683c6..ad8bf3dcd9 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -675,7 +675,10 @@ int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
return s->nb_snapshots;
}
-int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name)
+int qcow2_snapshot_load_tmp(BlockDriverState *bs,
+ const char *snapshot_id,
+ const char *name,
+ Error **errp)
{
int i, snapshot_index;
BDRVQcowState *s = bs->opaque;
@@ -687,8 +690,10 @@ int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name)
assert(bs->read_only);
/* Search the snapshot */
- snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_name);
+ snapshot_index = find_snapshot_by_id_and_name(bs, snapshot_id, name);
if (snapshot_index < 0) {
+ error_setg(errp,
+ "Can't find snapshot");
return -ENOENT;
}
sn = &s->snapshots[snapshot_index];
@@ -699,6 +704,7 @@ int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name)
ret = bdrv_pread(bs->file, sn->l1_table_offset, new_l1_table, new_l1_bytes);
if (ret < 0) {
+ error_setg(errp, "Failed to read l1 table for snapshot");
g_free(new_l1_table);
return ret;
}
diff --git a/block/qcow2.c b/block/qcow2.c
index 8e2b6c7548..f29aa88671 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -718,6 +718,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
}
qemu_opts_del(opts);
+ bs->bl.write_zeroes_alignment = s->cluster_sectors;
if (s->use_lazy_refcounts && s->qcow_version < 3) {
error_setg(errp, "Lazy refcounts require a qcow2 image with at least "
@@ -1471,7 +1472,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
* size for any qcow2 image.
*/
BlockDriverState* bs;
- QCowHeader header;
+ QCowHeader *header;
uint8_t* refcount_table;
Error *local_err = NULL;
int ret;
@@ -1489,30 +1490,34 @@ static int qcow2_create2(const char *filename, int64_t total_size,
}
/* Write the header */
- memset(&header, 0, sizeof(header));
- header.magic = cpu_to_be32(QCOW_MAGIC);
- header.version = cpu_to_be32(version);
- header.cluster_bits = cpu_to_be32(cluster_bits);
- header.size = cpu_to_be64(0);
- header.l1_table_offset = cpu_to_be64(0);
- header.l1_size = cpu_to_be32(0);
- header.refcount_table_offset = cpu_to_be64(cluster_size);
- header.refcount_table_clusters = cpu_to_be32(1);
- header.refcount_order = cpu_to_be32(3 + REFCOUNT_SHIFT);
- header.header_length = cpu_to_be32(sizeof(header));
+ QEMU_BUILD_BUG_ON((1 << MIN_CLUSTER_BITS) < sizeof(*header));
+ header = g_malloc0(cluster_size);
+ *header = (QCowHeader) {
+ .magic = cpu_to_be32(QCOW_MAGIC),
+ .version = cpu_to_be32(version),
+ .cluster_bits = cpu_to_be32(cluster_bits),
+ .size = cpu_to_be64(0),
+ .l1_table_offset = cpu_to_be64(0),
+ .l1_size = cpu_to_be32(0),
+ .refcount_table_offset = cpu_to_be64(cluster_size),
+ .refcount_table_clusters = cpu_to_be32(1),
+ .refcount_order = cpu_to_be32(3 + REFCOUNT_SHIFT),
+ .header_length = cpu_to_be32(sizeof(*header)),
+ };
if (flags & BLOCK_FLAG_ENCRYPT) {
- header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
+ header->crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
} else {
- header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
+ header->crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
}
if (flags & BLOCK_FLAG_LAZY_REFCOUNTS) {
- header.compatible_features |=
+ header->compatible_features |=
cpu_to_be64(QCOW2_COMPAT_LAZY_REFCOUNTS);
}
- ret = bdrv_pwrite(bs, 0, &header, sizeof(header));
+ ret = bdrv_pwrite(bs, 0, header, cluster_size);
+ g_free(header);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not write qcow2 header");
goto out;
@@ -1893,6 +1898,8 @@ static coroutine_fn int qcow2_co_flush_to_os(BlockDriverState *bs)
static int qcow2_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
{
BDRVQcowState *s = bs->opaque;
+ bdi->unallocated_blocks_are_zero = true;
+ bdi->can_write_zeroes_with_unmap = (s->qcow_version >= 3);
bdi->cluster_size = s->cluster_size;
bdi->vm_state_offset = qcow2_vm_state_offset(s);
return 0;
diff --git a/block/qcow2.h b/block/qcow2.h
index 922e19062a..303eb26629 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -488,7 +488,10 @@ int qcow2_snapshot_delete(BlockDriverState *bs,
const char *name,
Error **errp);
int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab);
-int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name);
+int qcow2_snapshot_load_tmp(BlockDriverState *bs,
+ const char *snapshot_id,
+ const char *name,
+ Error **errp);
void qcow2_free_snapshots(BlockDriverState *bs);
int qcow2_read_snapshots(BlockDriverState *bs);
diff --git a/block/qed.c b/block/qed.c
index adc2736dd7..450a1fa2e9 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -495,6 +495,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
}
}
+ bs->bl.write_zeroes_alignment = s->header.cluster_size >> BDRV_SECTOR_BITS;
s->need_check_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
qed_need_check_timer_cb, s);
@@ -1475,6 +1476,8 @@ static int bdrv_qed_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
memset(bdi, 0, sizeof(*bdi));
bdi->cluster_size = s->header.cluster_size;
bdi->is_dirty = s->header.features & QED_F_NEED_CHECK;
+ bdi->unallocated_blocks_are_zero = true;
+ bdi->can_write_zeroes_with_unmap = true;
return 0;
}
diff --git a/block/raw-aio.h b/block/raw-aio.h
index c61f1595d9..7ad0a8a0a7 100644
--- a/block/raw-aio.h
+++ b/block/raw-aio.h
@@ -21,9 +21,10 @@
#define QEMU_AIO_IOCTL 0x0004
#define QEMU_AIO_FLUSH 0x0008
#define QEMU_AIO_DISCARD 0x0010
+#define QEMU_AIO_WRITE_ZEROES 0x0020
#define QEMU_AIO_TYPE_MASK \
(QEMU_AIO_READ|QEMU_AIO_WRITE|QEMU_AIO_IOCTL|QEMU_AIO_FLUSH| \
- QEMU_AIO_DISCARD)
+ QEMU_AIO_DISCARD|QEMU_AIO_WRITE_ZEROES)
/* AIO flags */
#define QEMU_AIO_MISALIGNED 0x1000
diff --git a/block/raw-posix.c b/block/raw-posix.c
index f836c8e745..10c6b34ba9 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -139,9 +139,11 @@ typedef struct BDRVRawState {
void *aio_ctx;
#endif
#ifdef CONFIG_XFS
- bool is_xfs : 1;
+ bool is_xfs:1;
#endif
- bool has_discard : 1;
+ bool has_discard:1;
+ bool has_write_zeroes:1;
+ bool discard_zeroes:1;
} BDRVRawState;
typedef struct BDRVRawReopenState {
@@ -283,6 +285,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
Error *local_err = NULL;
const char *filename;
int fd, ret;
+ struct stat st;
opts = qemu_opts_create_nofail(&raw_runtime_opts);
qemu_opts_absorb_qdict(opts, options, &local_err);
@@ -323,10 +326,38 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
}
#endif
- s->has_discard = 1;
+ s->has_discard = true;
+ s->has_write_zeroes = true;
+
+ if (fstat(s->fd, &st) < 0) {
+ error_setg_errno(errp, errno, "Could not stat file");
+ goto fail;
+ }
+ if (S_ISREG(st.st_mode)) {
+ s->discard_zeroes = true;
+ }
+ if (S_ISBLK(st.st_mode)) {
+#ifdef BLKDISCARDZEROES
+ unsigned int arg;
+ if (ioctl(s->fd, BLKDISCARDZEROES, &arg) == 0 && arg) {
+ s->discard_zeroes = true;
+ }
+#endif
+#ifdef __linux__
+ /* On Linux 3.10, BLKDISCARD leaves stale data in the page cache. Do
+ * not rely on the contents of discarded blocks unless using O_DIRECT.
+ * Same for BLKZEROOUT.
+ */
+ if (!(bs->open_flags & BDRV_O_NOCACHE)) {
+ s->discard_zeroes = false;
+ s->has_write_zeroes = false;
+ }
+#endif
+ }
+
#ifdef CONFIG_XFS
if (platform_test_xfs_fd(s->fd)) {
- s->is_xfs = 1;
+ s->is_xfs = true;
}
#endif
@@ -675,6 +706,23 @@ static ssize_t handle_aiocb_rw(RawPosixAIOData *aiocb)
}
#ifdef CONFIG_XFS
+static int xfs_write_zeroes(BDRVRawState *s, int64_t offset, uint64_t bytes)
+{
+ struct xfs_flock64 fl;
+
+ memset(&fl, 0, sizeof(fl));
+ fl.l_whence = SEEK_SET;
+ fl.l_start = offset;
+ fl.l_len = bytes;
+
+ if (xfsctl(NULL, s->fd, XFS_IOC_ZERO_RANGE, &fl) < 0) {
+ DEBUG_BLOCK_PRINT("cannot write zero range (%s)\n", strerror(errno));
+ return -errno;
+ }
+
+ return 0;
+}
+
static int xfs_discard(BDRVRawState *s, int64_t offset, uint64_t bytes)
{
struct xfs_flock64 fl;
@@ -693,13 +741,49 @@ static int xfs_discard(BDRVRawState *s, int64_t offset, uint64_t bytes)
}
#endif
+static ssize_t handle_aiocb_write_zeroes(RawPosixAIOData *aiocb)
+{
+ int ret = -EOPNOTSUPP;
+ BDRVRawState *s = aiocb->bs->opaque;
+
+ if (s->has_write_zeroes == 0) {
+ return -ENOTSUP;
+ }
+
+ if (aiocb->aio_type & QEMU_AIO_BLKDEV) {
+#ifdef BLKZEROOUT
+ do {
+ uint64_t range[2] = { aiocb->aio_offset, aiocb->aio_nbytes };
+ if (ioctl(aiocb->aio_fildes, BLKZEROOUT, range) == 0) {
+ return 0;
+ }
+ } while (errno == EINTR);
+
+ ret = -errno;
+#endif
+ } else {
+#ifdef CONFIG_XFS
+ if (s->is_xfs) {
+ return xfs_write_zeroes(s, aiocb->aio_offset, aiocb->aio_nbytes);
+ }
+#endif
+ }
+
+ if (ret == -ENODEV || ret == -ENOSYS || ret == -EOPNOTSUPP ||
+ ret == -ENOTTY) {
+ s->has_write_zeroes = false;
+ ret = -ENOTSUP;
+ }
+ return ret;
+}
+
static ssize_t handle_aiocb_discard(RawPosixAIOData *aiocb)
{
int ret = -EOPNOTSUPP;
BDRVRawState *s = aiocb->bs->opaque;
- if (s->has_discard == 0) {
- return 0;
+ if (!s->has_discard) {
+ return -ENOTSUP;
}
if (aiocb->aio_type & QEMU_AIO_BLKDEV) {
@@ -734,8 +818,8 @@ static ssize_t handle_aiocb_discard(RawPosixAIOData *aiocb)
if (ret == -ENODEV || ret == -ENOSYS || ret == -EOPNOTSUPP ||
ret == -ENOTTY) {
- s->has_discard = 0;
- ret = 0;
+ s->has_discard = false;
+ ret = -ENOTSUP;
}
return ret;
}
@@ -777,6 +861,9 @@ static int aio_worker(void *arg)
case QEMU_AIO_DISCARD:
ret = handle_aiocb_discard(aiocb);
break;
+ case QEMU_AIO_WRITE_ZEROES:
+ ret = handle_aiocb_write_zeroes(aiocb);
+ break;
default:
fprintf(stderr, "invalid aio request (0x%x)\n", aiocb->aio_type);
ret = -EINVAL;
@@ -787,6 +874,29 @@ static int aio_worker(void *arg)
return ret;
}
+static int paio_submit_co(BlockDriverState *bs, int fd,
+ int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+ int type)
+{
+ RawPosixAIOData *acb = g_slice_new(RawPosixAIOData);
+ ThreadPool *pool;
+
+ acb->bs = bs;
+ acb->aio_type = type;
+ acb->aio_fildes = fd;
+
+ if (qiov) {
+ acb->aio_iov = qiov->iov;
+ acb->aio_niov = qiov->niov;
+ }
+ acb->aio_nbytes = nb_sectors * 512;
+ acb->aio_offset = sector_num * 512;
+
+ trace_paio_submit_co(sector_num, nb_sectors, type);
+ pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
+ return thread_pool_submit_co(pool, aio_worker, acb);
+}
+
static BlockDriverAIOCB *paio_submit(BlockDriverState *bs, int fd,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque, int type)
@@ -1199,6 +1309,31 @@ static coroutine_fn BlockDriverAIOCB *raw_aio_discard(BlockDriverState *bs,
cb, opaque, QEMU_AIO_DISCARD);
}
+static int coroutine_fn raw_co_write_zeroes(
+ BlockDriverState *bs, int64_t sector_num,
+ int nb_sectors, BdrvRequestFlags flags)
+{
+ BDRVRawState *s = bs->opaque;
+
+ if (!(flags & BDRV_REQ_MAY_UNMAP)) {
+ return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors,
+ QEMU_AIO_WRITE_ZEROES);
+ } else if (s->discard_zeroes) {
+ return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors,
+ QEMU_AIO_DISCARD);
+ }
+ return -ENOTSUP;
+}
+
+static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
+{
+ BDRVRawState *s = bs->opaque;
+
+ bdi->unallocated_blocks_are_zero = s->discard_zeroes;
+ bdi->can_write_zeroes_with_unmap = s->discard_zeroes;
+ return 0;
+}
+
static QEMUOptionParameter raw_create_options[] = {
{
.name = BLOCK_OPT_SIZE,
@@ -1222,6 +1357,7 @@ static BlockDriver bdrv_file = {
.bdrv_create = raw_create,
.bdrv_has_zero_init = bdrv_has_zero_init_1,
.bdrv_co_get_block_status = raw_co_get_block_status,
+ .bdrv_co_write_zeroes = raw_co_write_zeroes,
.bdrv_aio_readv = raw_aio_readv,
.bdrv_aio_writev = raw_aio_writev,
@@ -1230,6 +1366,7 @@ static BlockDriver bdrv_file = {
.bdrv_truncate = raw_truncate,
.bdrv_getlength = raw_getlength,
+ .bdrv_get_info = raw_get_info,
.bdrv_get_allocated_file_size
= raw_get_allocated_file_size,
@@ -1525,6 +1662,26 @@ static coroutine_fn BlockDriverAIOCB *hdev_aio_discard(BlockDriverState *bs,
cb, opaque, QEMU_AIO_DISCARD|QEMU_AIO_BLKDEV);
}
+static coroutine_fn int hdev_co_write_zeroes(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors, BdrvRequestFlags flags)
+{
+ BDRVRawState *s = bs->opaque;
+ int rc;
+
+ rc = fd_open(bs);
+ if (rc < 0) {
+ return rc;
+ }
+ if (!(flags & BDRV_REQ_MAY_UNMAP)) {
+ return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors,
+ QEMU_AIO_WRITE_ZEROES|QEMU_AIO_BLKDEV);
+ } else if (s->discard_zeroes) {
+ return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors,
+ QEMU_AIO_DISCARD|QEMU_AIO_BLKDEV);
+ }
+ return -ENOTSUP;
+}
+
static int hdev_create(const char *filename, QEMUOptionParameter *options,
Error **errp)
{
@@ -1577,6 +1734,7 @@ static BlockDriver bdrv_host_device = {
.bdrv_reopen_abort = raw_reopen_abort,
.bdrv_create = hdev_create,
.create_options = raw_create_options,
+ .bdrv_co_write_zeroes = hdev_co_write_zeroes,
.bdrv_aio_readv = raw_aio_readv,
.bdrv_aio_writev = raw_aio_writev,
@@ -1585,6 +1743,7 @@ static BlockDriver bdrv_host_device = {
.bdrv_truncate = raw_truncate,
.bdrv_getlength = raw_getlength,
+ .bdrv_get_info = raw_get_info,
.bdrv_get_allocated_file_size
= raw_get_allocated_file_size,
diff --git a/block/snapshot.c b/block/snapshot.c
index a05c0c0be0..9047f8ddc9 100644
--- a/block/snapshot.c
+++ b/block/snapshot.c
@@ -25,6 +25,24 @@
#include "block/snapshot.h"
#include "block/block_int.h"
+QemuOptsList internal_snapshot_opts = {
+ .name = "snapshot",
+ .head = QTAILQ_HEAD_INITIALIZER(internal_snapshot_opts.head),
+ .desc = {
+ {
+ .name = SNAPSHOT_OPT_ID,
+ .type = QEMU_OPT_STRING,
+ .help = "snapshot id"
+ },{
+ .name = SNAPSHOT_OPT_NAME,
+ .type = QEMU_OPT_STRING,
+ .help = "snapshot name"
+ },{
+ /* end of list */
+ }
+ },
+};
+
int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
const char *name)
{
@@ -194,7 +212,7 @@ int bdrv_snapshot_goto(BlockDriverState *bs,
* If only @snapshot_id is specified, delete the first one with id
* @snapshot_id.
* If only @name is specified, delete the first one with name @name.
- * if none is specified, return -ENINVAL.
+ * if none is specified, return -EINVAL.
*
* Returns: 0 on success, -errno on failure. If @bs is not inserted, return
* -ENOMEDIUM. If @snapshot_id and @name are both NULL, return -EINVAL. If @bs
@@ -265,18 +283,71 @@ int bdrv_snapshot_list(BlockDriverState *bs,
return -ENOTSUP;
}
+/**
+ * Temporarily load an internal snapshot by @snapshot_id and @name.
+ * @bs: block device used in the operation
+ * @snapshot_id: unique snapshot ID, or NULL
+ * @name: snapshot name, or NULL
+ * @errp: location to store error
+ *
+ * If both @snapshot_id and @name are specified, load the first one with
+ * id @snapshot_id and name @name.
+ * If only @snapshot_id is specified, load the first one with id
+ * @snapshot_id.
+ * If only @name is specified, load the first one with name @name.
+ * if none is specified, return -EINVAL.
+ *
+ * Returns: 0 on success, -errno on fail. If @bs is not inserted, return
+ * -ENOMEDIUM. If @bs is not readonly, return -EINVAL. If @bs did not support
+ * internal snapshot, return -ENOTSUP. If qemu can't find a matching @id and
+ * @name, return -ENOENT. If @errp != NULL, it will always be filled on
+ * failure.
+ */
int bdrv_snapshot_load_tmp(BlockDriverState *bs,
- const char *snapshot_name)
+ const char *snapshot_id,
+ const char *name,
+ Error **errp)
{
BlockDriver *drv = bs->drv;
+
if (!drv) {
+ error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, bdrv_get_device_name(bs));
return -ENOMEDIUM;
}
+ if (!snapshot_id && !name) {
+ error_setg(errp, "snapshot_id and name are both NULL");
+ return -EINVAL;
+ }
if (!bs->read_only) {
+ error_setg(errp, "Device is not readonly");
return -EINVAL;
}
if (drv->bdrv_snapshot_load_tmp) {
- return drv->bdrv_snapshot_load_tmp(bs, snapshot_name);
+ return drv->bdrv_snapshot_load_tmp(bs, snapshot_id, name, errp);
}
+ error_set(errp, QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
+ drv->format_name, bdrv_get_device_name(bs),
+ "temporarily load internal snapshot");
return -ENOTSUP;
}
+
+int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs,
+ const char *id_or_name,
+ Error **errp)
+{
+ int ret;
+ Error *local_err = NULL;
+
+ ret = bdrv_snapshot_load_tmp(bs, id_or_name, NULL, &local_err);
+ if (ret == -ENOENT || ret == -EINVAL) {
+ error_free(local_err);
+ local_err = NULL;
+ ret = bdrv_snapshot_load_tmp(bs, NULL, id_or_name, &local_err);
+ }
+
+ if (error_is_set(&local_err)) {
+ error_propagate(errp, local_err);
+ }
+
+ return ret;
+}
diff --git a/block/vdi.c b/block/vdi.c
index b6ec0020dc..2d7490f173 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -331,6 +331,7 @@ static int vdi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
logout("\n");
bdi->cluster_size = s->block_size;
bdi->vm_state_offset = 0;
+ bdi->unallocated_blocks_are_zero = true;
return 0;
}
diff --git a/block/vhdx.c b/block/vhdx.c
index 7d1af9663b..67bbe103a1 100644
--- a/block/vhdx.c
+++ b/block/vhdx.c
@@ -1043,6 +1043,18 @@ static void vhdx_block_translate(BDRVVHDXState *s, int64_t sector_num,
}
+static int vhdx_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
+{
+ BDRVVHDXState *s = bs->opaque;
+
+ bdi->cluster_size = s->block_size;
+
+ bdi->unallocated_blocks_are_zero =
+ (s->params.data_bits & VHDX_PARAMS_HAS_PARENT) == 0;
+
+ return 0;
+}
+
static coroutine_fn int vhdx_co_readv(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, QEMUIOVector *qiov)
@@ -1885,6 +1897,7 @@ static BlockDriver bdrv_vhdx = {
.bdrv_co_readv = vhdx_co_readv,
.bdrv_co_writev = vhdx_co_writev,
.bdrv_create = vhdx_create,
+ .bdrv_get_info = vhdx_get_info,
.create_options = vhdx_create_options,
};
diff --git a/block/vmdk.c b/block/vmdk.c
index 88d09e3e16..0734bc200c 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -428,6 +428,10 @@ static int vmdk_add_extent(BlockDriverState *bs,
extent->l2_size = l2_size;
extent->cluster_sectors = flat ? sectors : cluster_sectors;
+ if (!flat) {
+ bs->bl.write_zeroes_alignment =
+ MAX(bs->bl.write_zeroes_alignment, cluster_sectors);
+ }
if (s->num_extents > 1) {
extent->end_sector = (*(extent - 1)).end_sector + extent->sectors;
} else {
@@ -1596,7 +1600,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
Error **errp)
{
int fd, idx = 0;
- char desc[BUF_SIZE];
+ char *desc = NULL;
int64_t total_size = 0, filesize;
const char *adapter_type = NULL;
const char *backing_file = NULL;
@@ -1604,7 +1608,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
int flags = 0;
int ret = 0;
bool flat, split, compress;
- char ext_desc_lines[BUF_SIZE] = "";
+ GString *ext_desc_lines;
char path[PATH_MAX], prefix[PATH_MAX], postfix[PATH_MAX];
const int64_t split_size = 0x80000000; /* VMDK has constant split size */
const char *desc_extent_line;
@@ -1632,8 +1636,11 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
"ddb.geometry.sectors = \"63\"\n"
"ddb.adapterType = \"%s\"\n";
+ ext_desc_lines = g_string_new(NULL);
+
if (filename_decompose(filename, path, prefix, postfix, PATH_MAX, errp)) {
- return -EINVAL;
+ ret = -EINVAL;
+ goto exit;
}
/* Read out options */
while (options && options->name) {
@@ -1659,7 +1666,8 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
strcmp(adapter_type, "lsilogic") &&
strcmp(adapter_type, "legacyESX")) {
error_setg(errp, "Unknown adapter type: '%s'", adapter_type);
- return -EINVAL;
+ ret = -EINVAL;
+ goto exit;
}
if (strcmp(adapter_type, "ide") != 0) {
/* that's the number of heads with which vmware operates when
@@ -1675,7 +1683,8 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
strcmp(fmt, "twoGbMaxExtentFlat") &&
strcmp(fmt, "streamOptimized")) {
error_setg(errp, "Unknown subformat: '%s'", fmt);
- return -EINVAL;
+ ret = -EINVAL;
+ goto exit;
}
split = !(strcmp(fmt, "twoGbMaxExtentFlat") &&
strcmp(fmt, "twoGbMaxExtentSparse"));
@@ -1689,22 +1698,25 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
}
if (flat && backing_file) {
error_setg(errp, "Flat image can't have backing file");
- return -ENOTSUP;
+ ret = -ENOTSUP;
+ goto exit;
}
if (flat && zeroed_grain) {
error_setg(errp, "Flat image can't enable zeroed grain");
- return -ENOTSUP;
+ ret = -ENOTSUP;
+ goto exit;
}
if (backing_file) {
BlockDriverState *bs = bdrv_new("");
ret = bdrv_open(bs, backing_file, NULL, BDRV_O_NO_BACKING, NULL, errp);
if (ret != 0) {
bdrv_unref(bs);
- return ret;
+ goto exit;
}
if (strcmp(bs->drv->format_name, "vmdk")) {
bdrv_unref(bs);
- return -EINVAL;
+ ret = -EINVAL;
+ goto exit;
}
parent_cid = vmdk_read_cid(bs, 0);
bdrv_unref(bs);
@@ -1738,25 +1750,27 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
if (vmdk_create_extent(ext_filename, size,
flat, compress, zeroed_grain)) {
- return -EINVAL;
+ ret = -EINVAL;
+ goto exit;
}
filesize -= size;
/* Format description line */
snprintf(desc_line, sizeof(desc_line),
desc_extent_line, size / 512, desc_filename);
- pstrcat(ext_desc_lines, sizeof(ext_desc_lines), desc_line);
+ g_string_append(ext_desc_lines, desc_line);
}
/* generate descriptor file */
- snprintf(desc, sizeof(desc), desc_template,
- (unsigned int)time(NULL),
- parent_cid,
- fmt,
- parent_desc_line,
- ext_desc_lines,
- (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4),
- total_size / (int64_t)(63 * number_heads * 512), number_heads,
- adapter_type);
+ desc = g_strdup_printf(desc_template,
+ (unsigned int)time(NULL),
+ parent_cid,
+ fmt,
+ parent_desc_line,
+ ext_desc_lines->str,
+ (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4),
+ total_size / (int64_t)(63 * number_heads * 512),
+ number_heads,
+ adapter_type);
if (split || flat) {
fd = qemu_open(filename,
O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
@@ -1767,21 +1781,25 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
0644);
}
if (fd < 0) {
- return -errno;
+ ret = -errno;
+ goto exit;
}
/* the descriptor offset = 0x200 */
if (!split && !flat && 0x200 != lseek(fd, 0x200, SEEK_SET)) {
ret = -errno;
- goto exit;
+ goto close_exit;
}
ret = qemu_write_full(fd, desc, strlen(desc));
if (ret != strlen(desc)) {
ret = -errno;
- goto exit;
+ goto close_exit;
}
ret = 0;
-exit:
+close_exit:
qemu_close(fd);
+exit:
+ g_free(desc);
+ g_string_free(ext_desc_lines, true);
return ret;
}
diff --git a/block/vpc.c b/block/vpc.c
index 577cc45992..1d326cbf44 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -455,6 +455,19 @@ fail:
return -1;
}
+static int vpc_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
+{
+ BDRVVPCState *s = (BDRVVPCState *)bs->opaque;
+ VHDFooter *footer = (VHDFooter *) s->footer_buf;
+
+ if (cpu_to_be32(footer->type) != VHD_FIXED) {
+ bdi->cluster_size = s->block_size;
+ }
+
+ bdi->unallocated_blocks_are_zero = true;
+ return 0;
+}
+
static int vpc_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
@@ -857,6 +870,8 @@ static BlockDriver bdrv_vpc = {
.bdrv_read = vpc_co_read,
.bdrv_write = vpc_co_write,
+ .bdrv_get_info = vpc_get_info,
+
.create_options = vpc_create_options,
.bdrv_has_zero_init = vpc_has_zero_init,
};
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 74e6a14c29..efadfc023f 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -41,6 +41,7 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
#include <scsi/sg.h>
#endif
+#define SCSI_WRITE_SAME_MAX 524288
#define SCSI_DMA_BUF_SIZE 131072
#define SCSI_MAX_INQUIRY_LEN 256
#define SCSI_MAX_MODE_LEN 256
@@ -634,6 +635,8 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
buflen = 0x40;
memset(outbuf + 4, 0, buflen - 4);
+ outbuf[4] = 0x1; /* wsnz */
+
/* optimal transfer length granularity */
outbuf[6] = (min_io_size >> 8) & 0xff;
outbuf[7] = min_io_size & 0xff;
@@ -1543,10 +1546,16 @@ done:
static void scsi_disk_emulate_unmap(SCSIDiskReq *r, uint8_t *inbuf)
{
+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
uint8_t *p = inbuf;
int len = r->req.cmd.xfer;
UnmapCBData *data;
+ /* Reject ANCHOR=1. */
+ if (r->req.cmd.buf[1] & 0x1) {
+ goto invalid_field;
+ }
+
if (len < 8) {
goto invalid_param_len;
}
@@ -1560,6 +1569,11 @@ static void scsi_disk_emulate_unmap(SCSIDiskReq *r, uint8_t *inbuf)
goto invalid_param_len;
}
+ if (bdrv_is_read_only(s->qdev.conf.bs)) {
+ scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
+ return;
+ }
+
data = g_new0(UnmapCBData, 1);
data->r = r;
data->inbuf = &p[8];
@@ -1572,6 +1586,115 @@ static void scsi_disk_emulate_unmap(SCSIDiskReq *r, uint8_t *inbuf)
invalid_param_len:
scsi_check_condition(r, SENSE_CODE(INVALID_PARAM_LEN));
+ return;
+
+invalid_field:
+ scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
+}
+
+typedef struct WriteSameCBData {
+ SCSIDiskReq *r;
+ int64_t sector;
+ int nb_sectors;
+ QEMUIOVector qiov;
+ struct iovec iov;
+} WriteSameCBData;
+
+static void scsi_write_same_complete(void *opaque, int ret)
+{
+ WriteSameCBData *data = opaque;
+ SCSIDiskReq *r = data->r;
+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
+
+ assert(r->req.aiocb != NULL);
+ r->req.aiocb = NULL;
+ bdrv_acct_done(s->qdev.conf.bs, &r->acct);
+ if (r->req.io_canceled) {
+ goto done;
+ }
+
+ if (ret < 0) {
+ if (scsi_handle_rw_error(r, -ret)) {
+ goto done;
+ }
+ }
+
+ data->nb_sectors -= data->iov.iov_len / 512;
+ data->sector += data->iov.iov_len / 512;
+ data->iov.iov_len = MIN(data->nb_sectors * 512, data->iov.iov_len);
+ if (data->iov.iov_len) {
+ bdrv_acct_start(s->qdev.conf.bs, &r->acct, data->iov.iov_len, BDRV_ACCT_WRITE);
+ r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, data->sector,
+ &data->qiov, data->iov.iov_len / 512,
+ scsi_write_same_complete, r);
+ return;
+ }
+
+ scsi_req_complete(&r->req, GOOD);
+
+done:
+ if (!r->req.io_canceled) {
+ scsi_req_unref(&r->req);
+ }
+ qemu_vfree(data->iov.iov_base);
+ g_free(data);
+}
+
+static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf)
+{
+ SCSIRequest *req = &r->req;
+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
+ uint32_t nb_sectors = scsi_data_cdb_length(r->req.cmd.buf);
+ WriteSameCBData *data;
+ uint8_t *buf;
+ int i;
+
+ /* Fail if PBDATA=1 or LBDATA=1 or ANCHOR=1. */
+ if (nb_sectors == 0 || (req->cmd.buf[1] & 0x16)) {
+ scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
+ return;
+ }
+
+ if (bdrv_is_read_only(s->qdev.conf.bs)) {
+ scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
+ return;
+ }
+ if (!check_lba_range(s, r->req.cmd.lba, nb_sectors)) {
+ scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
+ return;
+ }
+
+ if (buffer_is_zero(inbuf, s->qdev.blocksize)) {
+ int flags = (req->cmd.buf[1] & 0x8) ? BDRV_REQ_MAY_UNMAP : 0;
+
+ /* The request is used as the AIO opaque value, so add a ref. */
+ scsi_req_ref(&r->req);
+ bdrv_acct_start(s->qdev.conf.bs, &r->acct, nb_sectors * s->qdev.blocksize,
+ BDRV_ACCT_WRITE);
+ r->req.aiocb = bdrv_aio_write_zeroes(s->qdev.conf.bs,
+ r->req.cmd.lba * (s->qdev.blocksize / 512),
+ nb_sectors * (s->qdev.blocksize / 512),
+ flags, scsi_aio_complete, r);
+ return;
+ }
+
+ data = g_new0(WriteSameCBData, 1);
+ data->r = r;
+ data->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
+ data->nb_sectors = nb_sectors * (s->qdev.blocksize / 512);
+ data->iov.iov_len = MIN(data->nb_sectors * 512, SCSI_WRITE_SAME_MAX);
+ data->iov.iov_base = buf = qemu_blockalign(s->qdev.conf.bs, data->iov.iov_len);
+ qemu_iovec_init_external(&data->qiov, &data->iov, 1);
+
+ for (i = 0; i < data->iov.iov_len; i += s->qdev.blocksize) {
+ memcpy(&buf[i], inbuf, s->qdev.blocksize);
+ }
+
+ scsi_req_ref(&r->req);
+ bdrv_acct_start(s->qdev.conf.bs, &r->acct, data->iov.iov_len, BDRV_ACCT_WRITE);
+ r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, data->sector,
+ &data->qiov, data->iov.iov_len / 512,
+ scsi_write_same_complete, data);
}
static void scsi_disk_emulate_write_data(SCSIRequest *req)
@@ -1597,6 +1720,10 @@ static void scsi_disk_emulate_write_data(SCSIRequest *req)
scsi_disk_emulate_unmap(r, r->iov.iov_base);
break;
+ case WRITE_SAME_10:
+ case WRITE_SAME_16:
+ scsi_disk_emulate_write_same(r, r->iov.iov_base);
+ break;
default:
abort();
}
@@ -1839,29 +1966,10 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
break;
case WRITE_SAME_10:
case WRITE_SAME_16:
- nb_sectors = scsi_data_cdb_length(r->req.cmd.buf);
- if (bdrv_is_read_only(s->qdev.conf.bs)) {
- scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
- return 0;
- }
- if (!check_lba_range(s, r->req.cmd.lba, nb_sectors)) {
- goto illegal_lba;
- }
-
- /*
- * We only support WRITE SAME with the unmap bit set for now.
- */
- if (!(req->cmd.buf[1] & 0x8)) {
- goto illegal_request;
- }
-
- /* The request is used as the AIO opaque value, so add a ref. */
- scsi_req_ref(&r->req);
- r->req.aiocb = bdrv_aio_discard(s->qdev.conf.bs,
- r->req.cmd.lba * (s->qdev.blocksize / 512),
- nb_sectors * (s->qdev.blocksize / 512),
- scsi_aio_complete, r);
- return 0;
+ DPRINTF("WRITE SAME %d (len %lu)\n",
+ req->cmd.buf[0] == WRITE_SAME_10 ? 10 : 16,
+ (long)r->req.cmd.xfer);
+ break;
default:
DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
diff --git a/include/block/block.h b/include/block/block.h
index 5beccbf1cf..36efaeac2d 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -216,6 +216,9 @@ int bdrv_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors);
int bdrv_write_zeroes(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, BdrvRequestFlags flags);
+BlockDriverAIOCB *bdrv_aio_write_zeroes(BlockDriverState *bs, int64_t sector_num,
+ int nb_sectors, BdrvRequestFlags flags,
+ BlockDriverCompletionFunc *cb, void *opaque);
int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags);
int bdrv_writev(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov);
int bdrv_pread(BlockDriverState *bs, int64_t offset,
@@ -311,6 +314,7 @@ typedef struct BlockRequest {
/* Fields to be filled by multiwrite caller */
int64_t sector;
int nb_sectors;
+ int flags;
QEMUIOVector *qiov;
BlockDriverCompletionFunc *cb;
void *opaque;
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 773899b500..8b132d7178 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -176,7 +176,9 @@ struct BlockDriver {
int (*bdrv_snapshot_list)(BlockDriverState *bs,
QEMUSnapshotInfo **psn_info);
int (*bdrv_snapshot_load_tmp)(BlockDriverState *bs,
- const char *snapshot_name);
+ const char *snapshot_id,
+ const char *name,
+ Error **errp);
int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
ImageInfoSpecific *(*bdrv_get_specific_info)(BlockDriverState *bs);
@@ -245,6 +247,9 @@ typedef struct BlockLimits {
/* optimal alignment for write zeroes requests in sectors */
int64_t write_zeroes_alignment;
+
+ /* optimal transfer length in sectors */
+ int opt_transfer_length;
} BlockLimits;
/*
diff --git a/include/block/coroutine.h b/include/block/coroutine.h
index 4d5c0cfdd7..a1797ae3d8 100644
--- a/include/block/coroutine.h
+++ b/include/block/coroutine.h
@@ -105,7 +105,6 @@ bool qemu_in_coroutine(void);
*/
typedef struct CoQueue {
QTAILQ_HEAD(, Coroutine) entries;
- AioContext *ctx;
} CoQueue;
/**
@@ -121,12 +120,6 @@ void qemu_co_queue_init(CoQueue *queue);
void coroutine_fn qemu_co_queue_wait(CoQueue *queue);
/**
- * Adds the current coroutine to the head of the CoQueue and transfers control to the
- * caller of the coroutine.
- */
-void coroutine_fn qemu_co_queue_wait_insert_head(CoQueue *queue);
-
-/**
* Restarts the next coroutine in the CoQueue and removes it from the queue.
*
* Returns true if a coroutine was restarted, false if the queue is empty.
diff --git a/include/block/snapshot.h b/include/block/snapshot.h
index 012bf226d3..770d9bbc8c 100644
--- a/include/block/snapshot.h
+++ b/include/block/snapshot.h
@@ -27,6 +27,14 @@
#include "qemu-common.h"
#include "qapi/error.h"
+#include "qemu/option.h"
+
+
+#define SNAPSHOT_OPT_BASE "snapshot."
+#define SNAPSHOT_OPT_ID "snapshot.id"
+#define SNAPSHOT_OPT_NAME "snapshot.name"
+
+extern QemuOptsList internal_snapshot_opts;
typedef struct QEMUSnapshotInfo {
char id_str[128]; /* unique snapshot id */
@@ -61,5 +69,10 @@ void bdrv_snapshot_delete_by_id_or_name(BlockDriverState *bs,
int bdrv_snapshot_list(BlockDriverState *bs,
QEMUSnapshotInfo **psn_info);
int bdrv_snapshot_load_tmp(BlockDriverState *bs,
- const char *snapshot_name);
+ const char *snapshot_id,
+ const char *name,
+ Error **errp);
+int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs,
+ const char *id_or_name,
+ Error **errp);
#endif
diff --git a/qemu-coroutine-lock.c b/qemu-coroutine-lock.c
index aeb33b9118..e4860ae42f 100644
--- a/qemu-coroutine-lock.c
+++ b/qemu-coroutine-lock.c
@@ -41,14 +41,6 @@ void coroutine_fn qemu_co_queue_wait(CoQueue *queue)
assert(qemu_in_coroutine());
}
-void coroutine_fn qemu_co_queue_wait_insert_head(CoQueue *queue)
-{
- Coroutine *self = qemu_coroutine_self();
- QTAILQ_INSERT_HEAD(&queue->entries, self, co_queue_next);
- qemu_coroutine_yield();
- assert(qemu_in_coroutine());
-}
-
/**
* qemu_co_queue_run_restart:
*
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index da1d965f3e..d02960921a 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -34,9 +34,9 @@ STEXI
ETEXI
DEF("convert", img_convert,
- "convert [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-O output_fmt] [-o options] [-s snapshot_name] [-S sparse_size] filename [filename2 [...]] output_filename")
+ "convert [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-O output_fmt] [-o options] [-s snapshot_id_or_name] [-l snapshot_param] [-S sparse_size] filename [filename2 [...]] output_filename")
STEXI
-@item convert [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
+@item convert [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
ETEXI
DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index dc0c2f0ed3..7dfe982b0c 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -93,6 +93,11 @@ static void help(void)
" 'options' is a comma separated list of format specific options in a\n"
" name=value format. Use -o ? for an overview of the options supported by the\n"
" used format\n"
+ " 'snapshot_param' is param used for internal snapshot, format\n"
+ " is 'snapshot.id=[ID],snapshot.name=[NAME]', or\n"
+ " '[ID_OR_NAME]'\n"
+ " 'snapshot_id_or_name' is deprecated, use 'snapshot_param'\n"
+ " instead\n"
" '-c' indicates that target image must be compressed (qcow format only)\n"
" '-u' enables unsafe rebasing. It is assumed that old and new backing file\n"
" match exactly. The image doesn't need a working backing file before\n"
@@ -105,7 +110,6 @@ static void help(void)
" conversion. If the number of bytes is 0, the source will not be scanned for\n"
" unallocated or zero sectors, and the destination image will always be\n"
" fully allocated\n"
- " images will always be fully allocated\n"
" '--output' takes the format in which the output must be done (human or json)\n"
" '-n' skips the target volume creation (useful if the volume is created\n"
" prior to running qemu-img)\n"
@@ -1125,25 +1129,27 @@ out3:
static int img_convert(int argc, char **argv)
{
- int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size,
- cluster_sectors, skip_create;
+ int c, n, n1, bs_n, bs_i, compress, cluster_sectors, skip_create;
+ int64_t ret = 0;
int progress = 0, flags;
const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
BlockDriver *drv, *proto_drv;
BlockDriverState **bs = NULL, *out_bs = NULL;
- int64_t total_sectors, nb_sectors, sector_num, bs_offset;
+ int64_t total_sectors, nb_sectors, sector_num, bs_offset,
+ sector_num_next_status = 0;
uint64_t bs_sectors;
uint8_t * buf = NULL;
+ size_t bufsectors = IO_BUF_SIZE / BDRV_SECTOR_SIZE;
const uint8_t *buf1;
BlockDriverInfo bdi;
QEMUOptionParameter *param = NULL, *create_options = NULL;
QEMUOptionParameter *out_baseimg_param;
char *options = NULL;
const char *snapshot_name = NULL;
- float local_progress = 0;
int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */
bool quiet = false;
Error *local_err = NULL;
+ QemuOpts *sn_opts = NULL;
fmt = NULL;
out_fmt = "raw";
@@ -1152,7 +1158,7 @@ static int img_convert(int argc, char **argv)
compress = 0;
skip_create = 0;
for(;;) {
- c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:qn");
+ c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:qnl:");
if (c == -1) {
break;
}
@@ -1187,6 +1193,18 @@ static int img_convert(int argc, char **argv)
case 's':
snapshot_name = optarg;
break;
+ case 'l':
+ if (strstart(optarg, SNAPSHOT_OPT_BASE, NULL)) {
+ sn_opts = qemu_opts_parse(&internal_snapshot_opts, optarg, 0);
+ if (!sn_opts) {
+ error_report("Failed in parsing snapshot param '%s'",
+ optarg);
+ return 1;
+ }
+ } else {
+ snapshot_name = optarg;
+ }
+ break;
case 'S':
{
int64_t sval;
@@ -1227,7 +1245,7 @@ static int img_convert(int argc, char **argv)
out_filename = argv[argc - 1];
/* Initialize before goto out */
- qemu_progress_init(progress, 2.0);
+ qemu_progress_init(progress, 1.0);
if (options && is_help_option(options)) {
ret = print_block_option_help(out_filename, out_fmt);
@@ -1258,17 +1276,26 @@ static int img_convert(int argc, char **argv)
total_sectors += bs_sectors;
}
- if (snapshot_name != NULL) {
+ if (sn_opts) {
+ ret = bdrv_snapshot_load_tmp(bs[0],
+ qemu_opt_get(sn_opts, SNAPSHOT_OPT_ID),
+ qemu_opt_get(sn_opts, SNAPSHOT_OPT_NAME),
+ &local_err);
+ } else if (snapshot_name != NULL) {
if (bs_n > 1) {
error_report("No support for concatenating multiple snapshot");
ret = -1;
goto out;
}
- if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
- error_report("Failed to load snapshot");
- ret = -1;
- goto out;
- }
+
+ bdrv_snapshot_load_tmp_by_id_or_name(bs[0], snapshot_name, &local_err);
+ }
+ if (error_is_set(&local_err)) {
+ error_report("Failed to load snapshot: %s",
+ error_get_pretty(local_err));
+ error_free(local_err);
+ ret = -1;
+ goto out;
}
/* Find driver and parse its options */
@@ -1371,7 +1398,16 @@ static int img_convert(int argc, char **argv)
bs_i = 0;
bs_offset = 0;
bdrv_get_geometry(bs[0], &bs_sectors);
- buf = qemu_blockalign(out_bs, IO_BUF_SIZE);
+
+ /* increase bufsectors from the default 4096 (2M) if opt_transfer_length
+ * or discard_alignment of the out_bs is greater. Limit to 32768 (16MB)
+ * as maximum. */
+ bufsectors = MIN(32768,
+ MAX(bufsectors, MAX(out_bs->bl.opt_transfer_length,
+ out_bs->bl.discard_alignment))
+ );
+
+ buf = qemu_blockalign(out_bs, bufsectors * BDRV_SECTOR_SIZE);
if (skip_create) {
int64_t output_length = bdrv_getlength(out_bs);
@@ -1387,26 +1423,26 @@ static int img_convert(int argc, char **argv)
}
}
- if (compress) {
- ret = bdrv_get_info(out_bs, &bdi);
- if (ret < 0) {
+ cluster_sectors = 0;
+ ret = bdrv_get_info(out_bs, &bdi);
+ if (ret < 0) {
+ if (compress) {
error_report("could not get block driver info");
goto out;
}
- cluster_size = bdi.cluster_size;
- if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
+ } else {
+ cluster_sectors = bdi.cluster_size / BDRV_SECTOR_SIZE;
+ }
+
+ if (compress) {
+ if (cluster_sectors <= 0 || cluster_sectors > bufsectors) {
error_report("invalid cluster size");
ret = -1;
goto out;
}
- cluster_sectors = cluster_size >> 9;
sector_num = 0;
nb_sectors = total_sectors;
- if (nb_sectors != 0) {
- local_progress = (float)100 /
- (nb_sectors / MIN(nb_sectors, cluster_sectors));
- }
for(;;) {
int64_t bs_num;
@@ -1464,7 +1500,7 @@ static int img_convert(int argc, char **argv)
}
}
sector_num += n;
- qemu_progress_print(local_progress, 100);
+ qemu_progress_print(100.0 * sector_num / total_sectors, 0);
}
/* signal EOF to align */
bdrv_write_compressed(out_bs, 0, NULL, 0);
@@ -1481,21 +1517,13 @@ static int img_convert(int argc, char **argv)
sector_num = 0; // total number of sectors converted so far
nb_sectors = total_sectors - sector_num;
- if (nb_sectors != 0) {
- local_progress = (float)100 /
- (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));
- }
for(;;) {
nb_sectors = total_sectors - sector_num;
if (nb_sectors <= 0) {
+ ret = 0;
break;
}
- if (nb_sectors >= (IO_BUF_SIZE / 512)) {
- n = (IO_BUF_SIZE / 512);
- } else {
- n = nb_sectors;
- }
while (sector_num - bs_offset >= bs_sectors) {
bs_i ++;
@@ -1507,34 +1535,59 @@ static int img_convert(int argc, char **argv)
sector_num, bs_i, bs_offset, bs_sectors); */
}
- if (n > bs_offset + bs_sectors - sector_num) {
- n = bs_offset + bs_sectors - sector_num;
- }
-
- /* If the output image is being created as a copy on write image,
- assume that sectors which are unallocated in the input image
- are present in both the output's and input's base images (no
- need to copy them). */
- if (out_baseimg) {
- ret = bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
- n, &n1);
+ if ((out_baseimg || has_zero_init) &&
+ sector_num >= sector_num_next_status) {
+ n = nb_sectors > INT_MAX ? INT_MAX : nb_sectors;
+ ret = bdrv_get_block_status(bs[bs_i], sector_num - bs_offset,
+ n, &n1);
if (ret < 0) {
- error_report("error while reading metadata for sector "
- "%" PRId64 ": %s",
- sector_num - bs_offset, strerror(-ret));
+ error_report("error while reading block status of sector %"
+ PRId64 ": %s", sector_num - bs_offset,
+ strerror(-ret));
goto out;
}
- if (!ret) {
+ /* If the output image is zero initialized, we are not working
+ * on a shared base and the input is zero we can skip the next
+ * n1 sectors */
+ if (has_zero_init && !out_baseimg && (ret & BDRV_BLOCK_ZERO)) {
sector_num += n1;
continue;
}
- /* The next 'n1' sectors are allocated in the input image. Copy
- only those as they may be followed by unallocated sectors. */
- n = n1;
- } else {
- n1 = n;
+ /* If the output image is being created as a copy on write
+ * image, assume that sectors which are unallocated in the
+ * input image are present in both the output's and input's
+ * base images (no need to copy them). */
+ if (out_baseimg) {
+ if (!(ret & BDRV_BLOCK_DATA)) {
+ sector_num += n1;
+ continue;
+ }
+ /* The next 'n1' sectors are allocated in the input image.
+ * Copy only those as they may be followed by unallocated
+ * sectors. */
+ nb_sectors = n1;
+ }
+ /* avoid redundant callouts to get_block_status */
+ sector_num_next_status = sector_num + n1;
+ }
+
+ n = MIN(nb_sectors, bufsectors);
+
+ /* round down request length to an aligned sector, but
+ * do not bother doing this on short requests. They happen
+ * when we found an all-zero area, and the next sector to
+ * write will not be sector_num + n. */
+ if (cluster_sectors > 0 && n >= cluster_sectors) {
+ int64_t next_aligned_sector = (sector_num + n);
+ next_aligned_sector -= next_aligned_sector % cluster_sectors;
+ if (sector_num + n > next_aligned_sector) {
+ n = next_aligned_sector - sector_num;
+ }
}
+ n = MIN(n, bs_sectors - (sector_num - bs_offset));
+ n1 = n;
+
ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
if (ret < 0) {
error_report("error while reading sector %" PRId64 ": %s",
@@ -1559,14 +1612,20 @@ static int img_convert(int argc, char **argv)
n -= n1;
buf1 += n1 * 512;
}
- qemu_progress_print(local_progress, 100);
+ qemu_progress_print(100.0 * sector_num / total_sectors, 0);
}
}
out:
+ if (!ret) {
+ qemu_progress_print(100, 0);
+ }
qemu_progress_end();
free_option_parameters(create_options);
free_option_parameters(param);
qemu_vfree(buf);
+ if (sn_opts) {
+ qemu_opts_del(sn_opts);
+ }
if (out_bs) {
bdrv_unref(out_bs);
}
diff --git a/qemu-img.texi b/qemu-img.texi
index da36975d70..be31191e43 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -46,7 +46,11 @@ is the destination disk image filename
is a comma separated list of format specific options in a
name=value format. Use @code{-o ?} for an overview of the options supported
by the used format or see the format descriptions below for details.
-
+@item snapshot_param
+is param used for internal snapshot, format is
+'snapshot.id=[ID],snapshot.name=[NAME]' or '[ID_OR_NAME]'
+@item snapshot_id_or_name
+is deprecated, use snapshot_param instead
@item -c
indicates that target image must be compressed (qcow format only)
@@ -179,10 +183,10 @@ Error on reading data
@end table
-@item convert [-c] [-p] [-n] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
+@item convert [-c] [-p] [-n] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
-Convert the disk image @var{filename} or a snapshot @var{snapshot_name} to disk image @var{output_filename}
-using format @var{output_fmt}. It can be optionally compressed (@code{-c}
+Convert the disk image @var{filename} or a snapshot @var{snapshot_param}(@var{snapshot_id_or_name} is deprecated)
+to disk image @var{output_filename} using format @var{output_fmt}. It can be optionally compressed (@code{-c}
option) or use any format specific options like encryption (@code{-o} option).
Only the formats @code{qcow} and @code{qcow2} support compression. The
diff --git a/qemu-nbd.c b/qemu-nbd.c
index c26c98ef1d..136e8c9c05 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -20,6 +20,7 @@
#include "block/block.h"
#include "block/nbd.h"
#include "qemu/main-loop.h"
+#include "block/snapshot.h"
#include <stdarg.h>
#include <stdio.h>
@@ -78,8 +79,16 @@ static void usage(const char *name)
#endif
"\n"
"Block device options:\n"
+" -f, --format=FORMAT set image format (raw, qcow2, ...)\n"
" -r, --read-only export read-only\n"
-" -s, --snapshot use snapshot file\n"
+" -s, --snapshot use FILE as an external snapshot, create a temporary\n"
+" file with backing_file=FILE, redirect the write to\n"
+" the temporary one\n"
+" -l, --load-snapshot=SNAPSHOT_PARAM\n"
+" load an internal snapshot inside FILE and export it\n"
+" as an read-only device, SNAPSHOT_PARAM format is\n"
+" 'snapshot.id=[ID],snapshot.name=[NAME]', or\n"
+" '[ID_OR_NAME]'\n"
" -n, --nocache disable host cache\n"
" --cache=MODE set cache mode (none, writeback, ...)\n"
#ifdef CONFIG_LINUX_AIO
@@ -315,7 +324,9 @@ int main(int argc, char **argv)
char *device = NULL;
int port = NBD_DEFAULT_PORT;
off_t fd_size;
- const char *sopt = "hVb:o:p:rsnP:c:dvk:e:f:t";
+ QemuOpts *sn_opts = NULL;
+ const char *sn_id_or_name = NULL;
+ const char *sopt = "hVb:o:p:rsnP:c:dvk:e:f:tl:";
struct option lopt[] = {
{ "help", 0, NULL, 'h' },
{ "version", 0, NULL, 'V' },
@@ -328,6 +339,7 @@ int main(int argc, char **argv)
{ "connect", 1, NULL, 'c' },
{ "disconnect", 0, NULL, 'd' },
{ "snapshot", 0, NULL, 's' },
+ { "load-snapshot", 1, NULL, 'l' },
{ "nocache", 0, NULL, 'n' },
{ "cache", 1, NULL, QEMU_NBD_OPT_CACHE },
#ifdef CONFIG_LINUX_AIO
@@ -428,6 +440,17 @@ int main(int argc, char **argv)
errx(EXIT_FAILURE, "Offset must be positive `%s'", optarg);
}
break;
+ case 'l':
+ if (strstart(optarg, SNAPSHOT_OPT_BASE, NULL)) {
+ sn_opts = qemu_opts_parse(&internal_snapshot_opts, optarg, 0);
+ if (!sn_opts) {
+ errx(EXIT_FAILURE, "Failed in parsing snapshot param `%s'",
+ optarg);
+ }
+ } else {
+ sn_id_or_name = optarg;
+ }
+ /* fall through */
case 'r':
nbdflags |= NBD_FLAG_READ_ONLY;
flags &= ~BDRV_O_RDWR;
@@ -581,6 +604,22 @@ int main(int argc, char **argv)
error_get_pretty(local_err));
}
+ if (sn_opts) {
+ ret = bdrv_snapshot_load_tmp(bs,
+ qemu_opt_get(sn_opts, SNAPSHOT_OPT_ID),
+ qemu_opt_get(sn_opts, SNAPSHOT_OPT_NAME),
+ &local_err);
+ } else if (sn_id_or_name) {
+ ret = bdrv_snapshot_load_tmp_by_id_or_name(bs, sn_id_or_name,
+ &local_err);
+ }
+ if (ret < 0) {
+ errno = -ret;
+ err(EXIT_FAILURE,
+ "Failed to load snapshot: %s",
+ error_get_pretty(local_err));
+ }
+
fd_size = bdrv_getlength(bs);
if (partition != -1) {
@@ -641,6 +680,10 @@ int main(int argc, char **argv)
unlink(sockpath);
}
+ if (sn_opts) {
+ qemu_opts_del(sn_opts);
+ }
+
if (device) {
void *ret;
pthread_join(client_thread, &ret);
diff --git a/qemu-nbd.texi b/qemu-nbd.texi
index 6055ec693b..0a7e01385c 100644
--- a/qemu-nbd.texi
+++ b/qemu-nbd.texi
@@ -22,12 +22,20 @@ Export QEMU disk image using NBD protocol.
interface to bind to (default @samp{0.0.0.0})
@item -k, --socket=@var{path}
Use a unix socket with path @var{path}
+@item -f, --format=@var{format}
+ Set image format as @var{format}
@item -r, --read-only
export read-only
@item -P, --partition=@var{num}
only expose partition @var{num}
@item -s, --snapshot
- use snapshot file
+ use @var{filename} as an external snapshot, create a temporary
+ file with backing_file=@var{filename}, redirect the write to
+ the temporary one
+@item -l, --load-snapshot=@var{snapshot_param}
+ load an internal snapshot inside @var{filename} and export it
+ as an read-only device, @var{snapshot_param} format is
+ 'snapshot.id=[ID],snapshot.name=[NAME]' or '[ID_OR_NAME]'
@item -n, --nocache
@itemx --cache=@var{cache}
set cache mode to be used with the file. See the documentation of
diff --git a/tests/qemu-iotests/026 b/tests/qemu-iotests/026
index ebe29d0168..c9c5f83936 100755
--- a/tests/qemu-iotests/026
+++ b/tests/qemu-iotests/026
@@ -44,7 +44,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt qcow2
_supported_proto generic
_supported_os Linux
-
+_default_cache_mode "writethrough"
+_supported_cache_modes "writethrough" "none"
echo "Errors while writing 128 kB"
echo
diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039
index 8bade92a80..6abf47267f 100755
--- a/tests/qemu-iotests/039
+++ b/tests/qemu-iotests/039
@@ -44,7 +44,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt qcow2
_supported_proto generic
_supported_os Linux
-_unsupported_qemu_io_options --nocache
+_default_cache_mode "writethrough"
+_supported_cache_modes "writethrough"
size=128M
diff --git a/tests/qemu-iotests/048 b/tests/qemu-iotests/048
index 9def7fcc8c..65da46d6f5 100755
--- a/tests/qemu-iotests/048
+++ b/tests/qemu-iotests/048
@@ -81,32 +81,5 @@ cp "$TEST_IMG" "$TEST_IMG2"
io_pattern write 512 512 0 1 101
_compare
-# Test cluster allocated in one, with IO error
-cat > "$TEST_DIR/blkdebug.conf"<<EOF
-[inject-error]
-event = "read_aio"
-errno = "5"
-once ="off"
-EOF
-_make_test_img $size
-cp "$TEST_IMG" "$TEST_IMG2"
-io_pattern write 512 512 0 1 102
-TEST_IMG="blkdebug:$TEST_DIR/blkdebug.conf:$TEST_IMG" _compare 2>&1 |\
- _filter_testdir | _filter_imgfmt
-
-# Test cluster allocated in one, with different sizes and IO error in the part
-# that exists only in one image
-cat > "$TEST_DIR/blkdebug.conf"<<EOF
-[inject-error]
-event = "read_aio"
-errno = "5"
-once ="off"
-EOF
-_make_test_img $size
-TEST_IMG="$TEST_IMG2" _make_test_img 0
-io_pattern write 512 512 0 1 102
-TEST_IMG="blkdebug:$TEST_DIR/blkdebug.conf:$TEST_IMG" _compare 2>&1 |\
- _filter_testdir | _filter_imgfmt
-
# Cleanup
status=0
diff --git a/tests/qemu-iotests/048.out b/tests/qemu-iotests/048.out
index 58d03d3d79..c0f380d3a3 100644
--- a/tests/qemu-iotests/048.out
+++ b/tests/qemu-iotests/048.out
@@ -37,20 +37,4 @@ wrote 512/512 bytes at offset 512
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Content mismatch at offset 512!
1
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-=== IO: pattern 102
-wrote 512/512 bytes at offset 512
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-qemu-img: Error while reading offset 0 of blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
-qemu-img: Error while reading offset 0: Input/output error
-4
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
-Formatting 'TEST_DIR/t.IMGFMT.2', fmt=IMGFMT size=0
-=== IO: pattern 102
-wrote 512/512 bytes at offset 512
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-qemu-img: Error while reading offset 0 of blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
-qemu-img: Error while reading offset 0 of blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
-Warning: Image size mismatch!
-4
Cleanup
diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out
index ddef87cb18..49e95a20cf 100644
--- a/tests/qemu-iotests/051.out
+++ b/tests/qemu-iotests/051.out
@@ -39,12 +39,12 @@ ide0-hd0: TEST_DIR/t.qcow2 (qcow2)
=== Enable and disable lazy refcounting on the command line, plus some invalid values ===
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=off
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=: could not open disk image TEST_DIR/t.qcow2: Parameter 'lazy-refcounts' expects 'on' or 'off'
@@ -63,71 +63,71 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on: could not open disk image TEST_DIR/t.qcow2: Lazy refcounts require a qcow2 image with at least qemu 1.1 compatibility level
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=off
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
=== No medium ===
Testing: -drive if=floppy
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive if=ide,media=cdrom
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive if=scsi,media=cdrom
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive if=ide
-QEMU X.Y.Z monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: Device needs media, but drive is empty
QEMU_PROG: Device initialization failed.
QEMU_PROG: Initialization of device ide-hd failed
Testing: -drive if=virtio
-QEMU X.Y.Z monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -drive if=virtio: Device needs media, but drive is empty
QEMU_PROG: -drive if=virtio: Device initialization failed.
QEMU_PROG: -drive if=virtio: Device initialization failed.
QEMU_PROG: -drive if=virtio: Device 'virtio-blk-pci' could not be initialized
Testing: -drive if=scsi
-QEMU X.Y.Z monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -drive if=scsi: Device needs media, but drive is empty
QEMU_PROG: Device initialization failed.
QEMU_PROG: Initialization of device lsi53c895a failed
Testing: -drive if=none,id=disk -device ide-cd,drive=disk
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-cd,drive=disk
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive if=none,id=disk -device ide-drive,drive=disk
-QEMU X.Y.Z monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -device ide-drive,drive=disk: Device needs media, but drive is empty
QEMU_PROG: -device ide-drive,drive=disk: Device initialization failed.
QEMU_PROG: -device ide-drive,drive=disk: Device 'ide-drive' could not be initialized
Testing: -drive if=none,id=disk -device ide-hd,drive=disk
-QEMU X.Y.Z monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -device ide-hd,drive=disk: Device needs media, but drive is empty
QEMU_PROG: -device ide-hd,drive=disk: Device initialization failed.
QEMU_PROG: -device ide-hd,drive=disk: Device 'ide-hd' could not be initialized
Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-disk,drive=disk
-QEMU X.Y.Z monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -device scsi-disk,drive=disk: Device needs media, but drive is empty
QEMU_PROG: -device scsi-disk,drive=disk: Device initialization failed.
QEMU_PROG: -device scsi-disk,drive=disk: Device 'scsi-disk' could not be initialized
Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-hd,drive=disk
-QEMU X.Y.Z monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -device scsi-hd,drive=disk: Device needs media, but drive is empty
QEMU_PROG: -device scsi-hd,drive=disk: Device initialization failed.
QEMU_PROG: -device scsi-hd,drive=disk: Device 'scsi-hd' could not be initialized
@@ -136,81 +136,81 @@ QEMU_PROG: -device scsi-hd,drive=disk: Device 'scsi-hd' could not be initialized
=== Read-only ===
Testing: -drive file=TEST_DIR/t.qcow2,if=floppy,readonly=on
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive file=TEST_DIR/t.qcow2,if=ide,media=cdrom,readonly=on
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,media=cdrom,readonly=on
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on
-QEMU X.Y.Z monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: Can't use a read-only drive
QEMU_PROG: Device initialization failed.
QEMU_PROG: Initialization of device ide-hd failed
Testing: -drive file=TEST_DIR/t.qcow2,if=virtio,readonly=on
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,readonly=on
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-cd,drive=disk
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-cd,drive=disk
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-drive,drive=disk
-QEMU X.Y.Z monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -device ide-drive,drive=disk: Can't use a read-only drive
QEMU_PROG: -device ide-drive,drive=disk: Device initialization failed.
QEMU_PROG: -device ide-drive,drive=disk: Device 'ide-drive' could not be initialized
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-hd,drive=disk
-QEMU X.Y.Z monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -device ide-hd,drive=disk: Can't use a read-only drive
QEMU_PROG: -device ide-hd,drive=disk: Device initialization failed.
QEMU_PROG: -device ide-hd,drive=disk: Device 'ide-hd' could not be initialized
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-disk,drive=disk
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-hd,drive=disk
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
=== Cache modes ===
Testing: -drive media=cdrom,cache=none
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive media=cdrom,cache=directsync
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive media=cdrom,cache=writeback
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive media=cdrom,cache=writethrough
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive media=cdrom,cache=unsafe
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive media=cdrom,cache=invalid_value
QEMU_PROG: -drive media=cdrom,cache=invalid_value: invalid cache option
@@ -219,8 +219,8 @@ QEMU_PROG: -drive media=cdrom,cache=invalid_value: invalid cache option
=== Specifying the protocol layer ===
Testing: -drive file=TEST_DIR/t.qcow2,file.driver=file
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qququiquit
Testing: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2: could not open disk image TEST_DIR/t.qcow2: Can't use 'qcow2' as a block driver for the protocol level
diff --git a/tests/qemu-iotests/052 b/tests/qemu-iotests/052
index f5f9683e68..4d4e411339 100755
--- a/tests/qemu-iotests/052
+++ b/tests/qemu-iotests/052
@@ -41,8 +41,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt generic
_supported_proto generic
_supported_os Linux
-_unsupported_qemu_io_options --nocache
-
+_default_cache_mode "writethrough"
+_supported_cache_modes "writethrough"
size=128M
_make_test_img $size
diff --git a/tests/qemu-iotests/058 b/tests/qemu-iotests/058
new file mode 100755
index 0000000000..14584cdea2
--- /dev/null
+++ b/tests/qemu-iotests/058
@@ -0,0 +1,138 @@
+#!/bin/bash
+#
+# Test export internal snapshot by qemu-nbd, convert it by qemu-img.
+#
+# Copyright (C) 2013 IBM, Inc.
+#
+# Based on 029.
+#
+# 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=xiawenc@linux.vnet.ibm.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+
+nbd_unix_socket=$TEST_DIR/test_qemu_nbd_socket
+nbd_snapshot_img="nbd:unix:$nbd_unix_socket"
+
+_cleanup_nbd()
+{
+ if [ -n "$NBD_SNAPSHOT_PID" ]; then
+ kill "$NBD_SNAPSHOT_PID"
+ fi
+ rm -f "$nbd_unix_socket"
+}
+
+_wait_for_nbd()
+{
+ for ((i = 0; i < 300; i++))
+ do
+ if [ -r "$nbd_unix_socket" ]; then
+ return
+ fi
+ sleep 0.1
+ done
+ echo "Failed in check of unix socket created by qemu-nbd"
+ exit 1
+}
+
+converted_image=$TEST_IMG.converted
+
+_export_nbd_snapshot()
+{
+ _cleanup_nbd
+ $QEMU_NBD -v -t -k "$nbd_unix_socket" "$TEST_IMG" -l $1 &
+ NBD_SNAPSHOT_PID=$!
+ _wait_for_nbd
+}
+
+_export_nbd_snapshot1()
+{
+ _cleanup_nbd
+ $QEMU_NBD -v -t -k "$nbd_unix_socket" "$TEST_IMG" -l snapshot.name=$1 &
+ NBD_SNAPSHOT_PID=$!
+ _wait_for_nbd
+}
+
+_cleanup()
+{
+ _cleanup_nbd
+ _cleanup_test_img
+ rm -f "$converted_image"
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.pattern
+
+_supported_fmt qcow2
+_supported_proto file
+_require_command QEMU_NBD
+
+echo
+echo "== preparing image =="
+_make_test_img 64M
+$QEMU_IO -c 'write -P 0xa 0x1000 0x1000' "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c 'write -P 0xb 0x2000 0x1000' "$TEST_IMG" | _filter_qemu_io
+$QEMU_IMG snapshot -c sn1 "$TEST_IMG"
+$QEMU_IO -c 'write -P 0xc 0x1000 0x1000' "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c 'write -P 0xd 0x2000 0x1000' "$TEST_IMG" | _filter_qemu_io
+_check_test_img
+
+echo
+echo "== verifying the image file with patterns =="
+$QEMU_IO -c 'read -P 0xc 0x1000 0x1000' "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c 'read -P 0xd 0x2000 0x1000' "$TEST_IMG" | _filter_qemu_io
+
+_export_nbd_snapshot sn1
+
+echo
+echo "== verifying the exported snapshot with patterns, method 1 =="
+$QEMU_IO -c 'read -P 0xa 0x1000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
+$QEMU_IO -c 'read -P 0xb 0x2000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
+
+_export_nbd_snapshot1 sn1
+
+echo
+echo "== verifying the exported snapshot with patterns, method 2 =="
+$QEMU_IO -c 'read -P 0xa 0x1000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
+$QEMU_IO -c 'read -P 0xb 0x2000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
+
+$QEMU_IMG convert "$TEST_IMG" -l sn1 -O qcow2 "$converted_image"
+
+echo
+echo "== verifying the converted snapshot with patterns, method 1 =="
+$QEMU_IO -c 'read -P 0xa 0x1000 0x1000' "$converted_image" | _filter_qemu_io
+$QEMU_IO -c 'read -P 0xb 0x2000 0x1000' "$converted_image" | _filter_qemu_io
+
+$QEMU_IMG convert "$TEST_IMG" -l snapshot.name=sn1 -O qcow2 "$converted_image"
+
+echo
+echo "== verifying the converted snapshot with patterns, method 2 =="
+$QEMU_IO -c 'read -P 0xa 0x1000 0x1000' "$converted_image" | _filter_qemu_io
+$QEMU_IO -c 'read -P 0xb 0x2000 0x1000' "$converted_image" | _filter_qemu_io
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/058.out b/tests/qemu-iotests/058.out
new file mode 100644
index 0000000000..9a69379589
--- /dev/null
+++ b/tests/qemu-iotests/058.out
@@ -0,0 +1,44 @@
+QA output created by 058
+
+== preparing image ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+wrote 4096/4096 bytes at offset 4096
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 4096/4096 bytes at offset 8192
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 4096/4096 bytes at offset 4096
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 4096/4096 bytes at offset 8192
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+No errors were found on the image.
+
+== verifying the image file with patterns ==
+read 4096/4096 bytes at offset 4096
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 4096/4096 bytes at offset 8192
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== verifying the exported snapshot with patterns, method 1 ==
+read 4096/4096 bytes at offset 4096
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 4096/4096 bytes at offset 8192
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== verifying the exported snapshot with patterns, method 2 ==
+read 4096/4096 bytes at offset 4096
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 4096/4096 bytes at offset 8192
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== verifying the converted snapshot with patterns, method 1 ==
+read 4096/4096 bytes at offset 4096
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 4096/4096 bytes at offset 8192
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== verifying the converted snapshot with patterns, method 2 ==
+read 4096/4096 bytes at offset 4096
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 4096/4096 bytes at offset 8192
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+*** done
diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
index 4926645e5e..73941c3e61 100755
--- a/tests/qemu-iotests/059
+++ b/tests/qemu-iotests/059
@@ -76,6 +76,11 @@ echo "=== Testing monolithicFlat with zeroed_grain ==="
IMGOPTS="subformat=monolithicFlat,zeroed_grain=on" _make_test_img 2G
echo
+echo "=== Testing big twoGbMaxExtentFlat ==="
+IMGOPTS="subformat=twoGbMaxExtentFlat" _make_test_img 1000G
+$QEMU_IMG info $TEST_IMG | _filter_testdir | sed -e 's/cid: [0-9]*/cid: XXXXXXXX/'
+
+echo
echo "=== Testing version 3 ==="
_use_sample_img iotest-version3.vmdk.bz2
_img_info
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
index 0aadd569d0..4ff935c6f4 100644
--- a/tests/qemu-iotests/059.out
+++ b/tests/qemu-iotests/059.out
@@ -26,6 +26,2018 @@ virtual size: 2.0G (2147483648 bytes)
qemu-img: TEST_DIR/t.IMGFMT: Flat image can't enable zeroed grain
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648
+=== Testing big twoGbMaxExtentFlat ===
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000
+image: TEST_DIR/t.vmdk
+file format: vmdk
+virtual size: 1.0T (1073741824000 bytes)
+disk size: 16K
+Format specific information:
+ cid: XXXXXXXX
+ parent cid: XXXXXXXX
+ create type: twoGbMaxExtentFlat
+ extents:
+ [0]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f001.vmdk
+ format: FLAT
+ [1]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f002.vmdk
+ format: FLAT
+ [2]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f003.vmdk
+ format: FLAT
+ [3]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f004.vmdk
+ format: FLAT
+ [4]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f005.vmdk
+ format: FLAT
+ [5]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f006.vmdk
+ format: FLAT
+ [6]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f007.vmdk
+ format: FLAT
+ [7]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f008.vmdk
+ format: FLAT
+ [8]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f009.vmdk
+ format: FLAT
+ [9]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f010.vmdk
+ format: FLAT
+ [10]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f011.vmdk
+ format: FLAT
+ [11]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f012.vmdk
+ format: FLAT
+ [12]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f013.vmdk
+ format: FLAT
+ [13]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f014.vmdk
+ format: FLAT
+ [14]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f015.vmdk
+ format: FLAT
+ [15]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f016.vmdk
+ format: FLAT
+ [16]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f017.vmdk
+ format: FLAT
+ [17]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f018.vmdk
+ format: FLAT
+ [18]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f019.vmdk
+ format: FLAT
+ [19]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f020.vmdk
+ format: FLAT
+ [20]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f021.vmdk
+ format: FLAT
+ [21]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f022.vmdk
+ format: FLAT
+ [22]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f023.vmdk
+ format: FLAT
+ [23]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f024.vmdk
+ format: FLAT
+ [24]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f025.vmdk
+ format: FLAT
+ [25]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f026.vmdk
+ format: FLAT
+ [26]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f027.vmdk
+ format: FLAT
+ [27]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f028.vmdk
+ format: FLAT
+ [28]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f029.vmdk
+ format: FLAT
+ [29]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f030.vmdk
+ format: FLAT
+ [30]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f031.vmdk
+ format: FLAT
+ [31]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f032.vmdk
+ format: FLAT
+ [32]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f033.vmdk
+ format: FLAT
+ [33]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f034.vmdk
+ format: FLAT
+ [34]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f035.vmdk
+ format: FLAT
+ [35]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f036.vmdk
+ format: FLAT
+ [36]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f037.vmdk
+ format: FLAT
+ [37]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f038.vmdk
+ format: FLAT
+ [38]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f039.vmdk
+ format: FLAT
+ [39]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f040.vmdk
+ format: FLAT
+ [40]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f041.vmdk
+ format: FLAT
+ [41]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f042.vmdk
+ format: FLAT
+ [42]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f043.vmdk
+ format: FLAT
+ [43]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f044.vmdk
+ format: FLAT
+ [44]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f045.vmdk
+ format: FLAT
+ [45]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f046.vmdk
+ format: FLAT
+ [46]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f047.vmdk
+ format: FLAT
+ [47]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f048.vmdk
+ format: FLAT
+ [48]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f049.vmdk
+ format: FLAT
+ [49]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f050.vmdk
+ format: FLAT
+ [50]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f051.vmdk
+ format: FLAT
+ [51]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f052.vmdk
+ format: FLAT
+ [52]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f053.vmdk
+ format: FLAT
+ [53]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f054.vmdk
+ format: FLAT
+ [54]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f055.vmdk
+ format: FLAT
+ [55]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f056.vmdk
+ format: FLAT
+ [56]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f057.vmdk
+ format: FLAT
+ [57]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f058.vmdk
+ format: FLAT
+ [58]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f059.vmdk
+ format: FLAT
+ [59]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f060.vmdk
+ format: FLAT
+ [60]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f061.vmdk
+ format: FLAT
+ [61]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f062.vmdk
+ format: FLAT
+ [62]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f063.vmdk
+ format: FLAT
+ [63]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f064.vmdk
+ format: FLAT
+ [64]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f065.vmdk
+ format: FLAT
+ [65]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f066.vmdk
+ format: FLAT
+ [66]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f067.vmdk
+ format: FLAT
+ [67]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f068.vmdk
+ format: FLAT
+ [68]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f069.vmdk
+ format: FLAT
+ [69]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f070.vmdk
+ format: FLAT
+ [70]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f071.vmdk
+ format: FLAT
+ [71]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f072.vmdk
+ format: FLAT
+ [72]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f073.vmdk
+ format: FLAT
+ [73]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f074.vmdk
+ format: FLAT
+ [74]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f075.vmdk
+ format: FLAT
+ [75]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f076.vmdk
+ format: FLAT
+ [76]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f077.vmdk
+ format: FLAT
+ [77]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f078.vmdk
+ format: FLAT
+ [78]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f079.vmdk
+ format: FLAT
+ [79]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f080.vmdk
+ format: FLAT
+ [80]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f081.vmdk
+ format: FLAT
+ [81]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f082.vmdk
+ format: FLAT
+ [82]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f083.vmdk
+ format: FLAT
+ [83]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f084.vmdk
+ format: FLAT
+ [84]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f085.vmdk
+ format: FLAT
+ [85]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f086.vmdk
+ format: FLAT
+ [86]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f087.vmdk
+ format: FLAT
+ [87]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f088.vmdk
+ format: FLAT
+ [88]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f089.vmdk
+ format: FLAT
+ [89]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f090.vmdk
+ format: FLAT
+ [90]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f091.vmdk
+ format: FLAT
+ [91]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f092.vmdk
+ format: FLAT
+ [92]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f093.vmdk
+ format: FLAT
+ [93]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f094.vmdk
+ format: FLAT
+ [94]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f095.vmdk
+ format: FLAT
+ [95]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f096.vmdk
+ format: FLAT
+ [96]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f097.vmdk
+ format: FLAT
+ [97]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f098.vmdk
+ format: FLAT
+ [98]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f099.vmdk
+ format: FLAT
+ [99]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f100.vmdk
+ format: FLAT
+ [100]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f101.vmdk
+ format: FLAT
+ [101]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f102.vmdk
+ format: FLAT
+ [102]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f103.vmdk
+ format: FLAT
+ [103]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f104.vmdk
+ format: FLAT
+ [104]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f105.vmdk
+ format: FLAT
+ [105]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f106.vmdk
+ format: FLAT
+ [106]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f107.vmdk
+ format: FLAT
+ [107]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f108.vmdk
+ format: FLAT
+ [108]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f109.vmdk
+ format: FLAT
+ [109]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f110.vmdk
+ format: FLAT
+ [110]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f111.vmdk
+ format: FLAT
+ [111]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f112.vmdk
+ format: FLAT
+ [112]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f113.vmdk
+ format: FLAT
+ [113]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f114.vmdk
+ format: FLAT
+ [114]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f115.vmdk
+ format: FLAT
+ [115]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f116.vmdk
+ format: FLAT
+ [116]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f117.vmdk
+ format: FLAT
+ [117]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f118.vmdk
+ format: FLAT
+ [118]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f119.vmdk
+ format: FLAT
+ [119]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f120.vmdk
+ format: FLAT
+ [120]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f121.vmdk
+ format: FLAT
+ [121]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f122.vmdk
+ format: FLAT
+ [122]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f123.vmdk
+ format: FLAT
+ [123]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f124.vmdk
+ format: FLAT
+ [124]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f125.vmdk
+ format: FLAT
+ [125]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f126.vmdk
+ format: FLAT
+ [126]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f127.vmdk
+ format: FLAT
+ [127]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f128.vmdk
+ format: FLAT
+ [128]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f129.vmdk
+ format: FLAT
+ [129]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f130.vmdk
+ format: FLAT
+ [130]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f131.vmdk
+ format: FLAT
+ [131]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f132.vmdk
+ format: FLAT
+ [132]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f133.vmdk
+ format: FLAT
+ [133]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f134.vmdk
+ format: FLAT
+ [134]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f135.vmdk
+ format: FLAT
+ [135]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f136.vmdk
+ format: FLAT
+ [136]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f137.vmdk
+ format: FLAT
+ [137]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f138.vmdk
+ format: FLAT
+ [138]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f139.vmdk
+ format: FLAT
+ [139]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f140.vmdk
+ format: FLAT
+ [140]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f141.vmdk
+ format: FLAT
+ [141]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f142.vmdk
+ format: FLAT
+ [142]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f143.vmdk
+ format: FLAT
+ [143]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f144.vmdk
+ format: FLAT
+ [144]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f145.vmdk
+ format: FLAT
+ [145]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f146.vmdk
+ format: FLAT
+ [146]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f147.vmdk
+ format: FLAT
+ [147]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f148.vmdk
+ format: FLAT
+ [148]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f149.vmdk
+ format: FLAT
+ [149]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f150.vmdk
+ format: FLAT
+ [150]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f151.vmdk
+ format: FLAT
+ [151]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f152.vmdk
+ format: FLAT
+ [152]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f153.vmdk
+ format: FLAT
+ [153]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f154.vmdk
+ format: FLAT
+ [154]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f155.vmdk
+ format: FLAT
+ [155]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f156.vmdk
+ format: FLAT
+ [156]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f157.vmdk
+ format: FLAT
+ [157]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f158.vmdk
+ format: FLAT
+ [158]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f159.vmdk
+ format: FLAT
+ [159]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f160.vmdk
+ format: FLAT
+ [160]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f161.vmdk
+ format: FLAT
+ [161]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f162.vmdk
+ format: FLAT
+ [162]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f163.vmdk
+ format: FLAT
+ [163]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f164.vmdk
+ format: FLAT
+ [164]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f165.vmdk
+ format: FLAT
+ [165]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f166.vmdk
+ format: FLAT
+ [166]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f167.vmdk
+ format: FLAT
+ [167]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f168.vmdk
+ format: FLAT
+ [168]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f169.vmdk
+ format: FLAT
+ [169]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f170.vmdk
+ format: FLAT
+ [170]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f171.vmdk
+ format: FLAT
+ [171]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f172.vmdk
+ format: FLAT
+ [172]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f173.vmdk
+ format: FLAT
+ [173]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f174.vmdk
+ format: FLAT
+ [174]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f175.vmdk
+ format: FLAT
+ [175]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f176.vmdk
+ format: FLAT
+ [176]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f177.vmdk
+ format: FLAT
+ [177]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f178.vmdk
+ format: FLAT
+ [178]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f179.vmdk
+ format: FLAT
+ [179]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f180.vmdk
+ format: FLAT
+ [180]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f181.vmdk
+ format: FLAT
+ [181]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f182.vmdk
+ format: FLAT
+ [182]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f183.vmdk
+ format: FLAT
+ [183]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f184.vmdk
+ format: FLAT
+ [184]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f185.vmdk
+ format: FLAT
+ [185]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f186.vmdk
+ format: FLAT
+ [186]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f187.vmdk
+ format: FLAT
+ [187]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f188.vmdk
+ format: FLAT
+ [188]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f189.vmdk
+ format: FLAT
+ [189]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f190.vmdk
+ format: FLAT
+ [190]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f191.vmdk
+ format: FLAT
+ [191]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f192.vmdk
+ format: FLAT
+ [192]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f193.vmdk
+ format: FLAT
+ [193]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f194.vmdk
+ format: FLAT
+ [194]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f195.vmdk
+ format: FLAT
+ [195]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f196.vmdk
+ format: FLAT
+ [196]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f197.vmdk
+ format: FLAT
+ [197]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f198.vmdk
+ format: FLAT
+ [198]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f199.vmdk
+ format: FLAT
+ [199]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f200.vmdk
+ format: FLAT
+ [200]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f201.vmdk
+ format: FLAT
+ [201]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f202.vmdk
+ format: FLAT
+ [202]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f203.vmdk
+ format: FLAT
+ [203]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f204.vmdk
+ format: FLAT
+ [204]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f205.vmdk
+ format: FLAT
+ [205]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f206.vmdk
+ format: FLAT
+ [206]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f207.vmdk
+ format: FLAT
+ [207]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f208.vmdk
+ format: FLAT
+ [208]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f209.vmdk
+ format: FLAT
+ [209]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f210.vmdk
+ format: FLAT
+ [210]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f211.vmdk
+ format: FLAT
+ [211]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f212.vmdk
+ format: FLAT
+ [212]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f213.vmdk
+ format: FLAT
+ [213]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f214.vmdk
+ format: FLAT
+ [214]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f215.vmdk
+ format: FLAT
+ [215]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f216.vmdk
+ format: FLAT
+ [216]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f217.vmdk
+ format: FLAT
+ [217]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f218.vmdk
+ format: FLAT
+ [218]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f219.vmdk
+ format: FLAT
+ [219]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f220.vmdk
+ format: FLAT
+ [220]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f221.vmdk
+ format: FLAT
+ [221]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f222.vmdk
+ format: FLAT
+ [222]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f223.vmdk
+ format: FLAT
+ [223]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f224.vmdk
+ format: FLAT
+ [224]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f225.vmdk
+ format: FLAT
+ [225]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f226.vmdk
+ format: FLAT
+ [226]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f227.vmdk
+ format: FLAT
+ [227]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f228.vmdk
+ format: FLAT
+ [228]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f229.vmdk
+ format: FLAT
+ [229]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f230.vmdk
+ format: FLAT
+ [230]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f231.vmdk
+ format: FLAT
+ [231]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f232.vmdk
+ format: FLAT
+ [232]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f233.vmdk
+ format: FLAT
+ [233]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f234.vmdk
+ format: FLAT
+ [234]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f235.vmdk
+ format: FLAT
+ [235]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f236.vmdk
+ format: FLAT
+ [236]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f237.vmdk
+ format: FLAT
+ [237]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f238.vmdk
+ format: FLAT
+ [238]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f239.vmdk
+ format: FLAT
+ [239]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f240.vmdk
+ format: FLAT
+ [240]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f241.vmdk
+ format: FLAT
+ [241]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f242.vmdk
+ format: FLAT
+ [242]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f243.vmdk
+ format: FLAT
+ [243]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f244.vmdk
+ format: FLAT
+ [244]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f245.vmdk
+ format: FLAT
+ [245]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f246.vmdk
+ format: FLAT
+ [246]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f247.vmdk
+ format: FLAT
+ [247]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f248.vmdk
+ format: FLAT
+ [248]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f249.vmdk
+ format: FLAT
+ [249]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f250.vmdk
+ format: FLAT
+ [250]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f251.vmdk
+ format: FLAT
+ [251]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f252.vmdk
+ format: FLAT
+ [252]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f253.vmdk
+ format: FLAT
+ [253]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f254.vmdk
+ format: FLAT
+ [254]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f255.vmdk
+ format: FLAT
+ [255]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f256.vmdk
+ format: FLAT
+ [256]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f257.vmdk
+ format: FLAT
+ [257]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f258.vmdk
+ format: FLAT
+ [258]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f259.vmdk
+ format: FLAT
+ [259]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f260.vmdk
+ format: FLAT
+ [260]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f261.vmdk
+ format: FLAT
+ [261]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f262.vmdk
+ format: FLAT
+ [262]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f263.vmdk
+ format: FLAT
+ [263]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f264.vmdk
+ format: FLAT
+ [264]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f265.vmdk
+ format: FLAT
+ [265]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f266.vmdk
+ format: FLAT
+ [266]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f267.vmdk
+ format: FLAT
+ [267]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f268.vmdk
+ format: FLAT
+ [268]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f269.vmdk
+ format: FLAT
+ [269]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f270.vmdk
+ format: FLAT
+ [270]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f271.vmdk
+ format: FLAT
+ [271]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f272.vmdk
+ format: FLAT
+ [272]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f273.vmdk
+ format: FLAT
+ [273]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f274.vmdk
+ format: FLAT
+ [274]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f275.vmdk
+ format: FLAT
+ [275]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f276.vmdk
+ format: FLAT
+ [276]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f277.vmdk
+ format: FLAT
+ [277]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f278.vmdk
+ format: FLAT
+ [278]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f279.vmdk
+ format: FLAT
+ [279]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f280.vmdk
+ format: FLAT
+ [280]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f281.vmdk
+ format: FLAT
+ [281]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f282.vmdk
+ format: FLAT
+ [282]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f283.vmdk
+ format: FLAT
+ [283]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f284.vmdk
+ format: FLAT
+ [284]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f285.vmdk
+ format: FLAT
+ [285]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f286.vmdk
+ format: FLAT
+ [286]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f287.vmdk
+ format: FLAT
+ [287]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f288.vmdk
+ format: FLAT
+ [288]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f289.vmdk
+ format: FLAT
+ [289]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f290.vmdk
+ format: FLAT
+ [290]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f291.vmdk
+ format: FLAT
+ [291]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f292.vmdk
+ format: FLAT
+ [292]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f293.vmdk
+ format: FLAT
+ [293]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f294.vmdk
+ format: FLAT
+ [294]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f295.vmdk
+ format: FLAT
+ [295]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f296.vmdk
+ format: FLAT
+ [296]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f297.vmdk
+ format: FLAT
+ [297]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f298.vmdk
+ format: FLAT
+ [298]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f299.vmdk
+ format: FLAT
+ [299]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f300.vmdk
+ format: FLAT
+ [300]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f301.vmdk
+ format: FLAT
+ [301]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f302.vmdk
+ format: FLAT
+ [302]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f303.vmdk
+ format: FLAT
+ [303]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f304.vmdk
+ format: FLAT
+ [304]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f305.vmdk
+ format: FLAT
+ [305]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f306.vmdk
+ format: FLAT
+ [306]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f307.vmdk
+ format: FLAT
+ [307]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f308.vmdk
+ format: FLAT
+ [308]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f309.vmdk
+ format: FLAT
+ [309]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f310.vmdk
+ format: FLAT
+ [310]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f311.vmdk
+ format: FLAT
+ [311]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f312.vmdk
+ format: FLAT
+ [312]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f313.vmdk
+ format: FLAT
+ [313]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f314.vmdk
+ format: FLAT
+ [314]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f315.vmdk
+ format: FLAT
+ [315]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f316.vmdk
+ format: FLAT
+ [316]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f317.vmdk
+ format: FLAT
+ [317]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f318.vmdk
+ format: FLAT
+ [318]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f319.vmdk
+ format: FLAT
+ [319]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f320.vmdk
+ format: FLAT
+ [320]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f321.vmdk
+ format: FLAT
+ [321]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f322.vmdk
+ format: FLAT
+ [322]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f323.vmdk
+ format: FLAT
+ [323]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f324.vmdk
+ format: FLAT
+ [324]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f325.vmdk
+ format: FLAT
+ [325]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f326.vmdk
+ format: FLAT
+ [326]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f327.vmdk
+ format: FLAT
+ [327]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f328.vmdk
+ format: FLAT
+ [328]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f329.vmdk
+ format: FLAT
+ [329]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f330.vmdk
+ format: FLAT
+ [330]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f331.vmdk
+ format: FLAT
+ [331]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f332.vmdk
+ format: FLAT
+ [332]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f333.vmdk
+ format: FLAT
+ [333]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f334.vmdk
+ format: FLAT
+ [334]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f335.vmdk
+ format: FLAT
+ [335]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f336.vmdk
+ format: FLAT
+ [336]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f337.vmdk
+ format: FLAT
+ [337]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f338.vmdk
+ format: FLAT
+ [338]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f339.vmdk
+ format: FLAT
+ [339]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f340.vmdk
+ format: FLAT
+ [340]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f341.vmdk
+ format: FLAT
+ [341]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f342.vmdk
+ format: FLAT
+ [342]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f343.vmdk
+ format: FLAT
+ [343]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f344.vmdk
+ format: FLAT
+ [344]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f345.vmdk
+ format: FLAT
+ [345]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f346.vmdk
+ format: FLAT
+ [346]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f347.vmdk
+ format: FLAT
+ [347]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f348.vmdk
+ format: FLAT
+ [348]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f349.vmdk
+ format: FLAT
+ [349]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f350.vmdk
+ format: FLAT
+ [350]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f351.vmdk
+ format: FLAT
+ [351]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f352.vmdk
+ format: FLAT
+ [352]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f353.vmdk
+ format: FLAT
+ [353]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f354.vmdk
+ format: FLAT
+ [354]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f355.vmdk
+ format: FLAT
+ [355]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f356.vmdk
+ format: FLAT
+ [356]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f357.vmdk
+ format: FLAT
+ [357]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f358.vmdk
+ format: FLAT
+ [358]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f359.vmdk
+ format: FLAT
+ [359]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f360.vmdk
+ format: FLAT
+ [360]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f361.vmdk
+ format: FLAT
+ [361]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f362.vmdk
+ format: FLAT
+ [362]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f363.vmdk
+ format: FLAT
+ [363]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f364.vmdk
+ format: FLAT
+ [364]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f365.vmdk
+ format: FLAT
+ [365]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f366.vmdk
+ format: FLAT
+ [366]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f367.vmdk
+ format: FLAT
+ [367]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f368.vmdk
+ format: FLAT
+ [368]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f369.vmdk
+ format: FLAT
+ [369]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f370.vmdk
+ format: FLAT
+ [370]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f371.vmdk
+ format: FLAT
+ [371]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f372.vmdk
+ format: FLAT
+ [372]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f373.vmdk
+ format: FLAT
+ [373]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f374.vmdk
+ format: FLAT
+ [374]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f375.vmdk
+ format: FLAT
+ [375]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f376.vmdk
+ format: FLAT
+ [376]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f377.vmdk
+ format: FLAT
+ [377]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f378.vmdk
+ format: FLAT
+ [378]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f379.vmdk
+ format: FLAT
+ [379]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f380.vmdk
+ format: FLAT
+ [380]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f381.vmdk
+ format: FLAT
+ [381]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f382.vmdk
+ format: FLAT
+ [382]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f383.vmdk
+ format: FLAT
+ [383]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f384.vmdk
+ format: FLAT
+ [384]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f385.vmdk
+ format: FLAT
+ [385]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f386.vmdk
+ format: FLAT
+ [386]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f387.vmdk
+ format: FLAT
+ [387]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f388.vmdk
+ format: FLAT
+ [388]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f389.vmdk
+ format: FLAT
+ [389]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f390.vmdk
+ format: FLAT
+ [390]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f391.vmdk
+ format: FLAT
+ [391]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f392.vmdk
+ format: FLAT
+ [392]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f393.vmdk
+ format: FLAT
+ [393]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f394.vmdk
+ format: FLAT
+ [394]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f395.vmdk
+ format: FLAT
+ [395]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f396.vmdk
+ format: FLAT
+ [396]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f397.vmdk
+ format: FLAT
+ [397]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f398.vmdk
+ format: FLAT
+ [398]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f399.vmdk
+ format: FLAT
+ [399]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f400.vmdk
+ format: FLAT
+ [400]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f401.vmdk
+ format: FLAT
+ [401]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f402.vmdk
+ format: FLAT
+ [402]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f403.vmdk
+ format: FLAT
+ [403]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f404.vmdk
+ format: FLAT
+ [404]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f405.vmdk
+ format: FLAT
+ [405]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f406.vmdk
+ format: FLAT
+ [406]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f407.vmdk
+ format: FLAT
+ [407]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f408.vmdk
+ format: FLAT
+ [408]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f409.vmdk
+ format: FLAT
+ [409]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f410.vmdk
+ format: FLAT
+ [410]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f411.vmdk
+ format: FLAT
+ [411]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f412.vmdk
+ format: FLAT
+ [412]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f413.vmdk
+ format: FLAT
+ [413]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f414.vmdk
+ format: FLAT
+ [414]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f415.vmdk
+ format: FLAT
+ [415]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f416.vmdk
+ format: FLAT
+ [416]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f417.vmdk
+ format: FLAT
+ [417]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f418.vmdk
+ format: FLAT
+ [418]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f419.vmdk
+ format: FLAT
+ [419]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f420.vmdk
+ format: FLAT
+ [420]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f421.vmdk
+ format: FLAT
+ [421]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f422.vmdk
+ format: FLAT
+ [422]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f423.vmdk
+ format: FLAT
+ [423]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f424.vmdk
+ format: FLAT
+ [424]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f425.vmdk
+ format: FLAT
+ [425]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f426.vmdk
+ format: FLAT
+ [426]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f427.vmdk
+ format: FLAT
+ [427]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f428.vmdk
+ format: FLAT
+ [428]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f429.vmdk
+ format: FLAT
+ [429]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f430.vmdk
+ format: FLAT
+ [430]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f431.vmdk
+ format: FLAT
+ [431]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f432.vmdk
+ format: FLAT
+ [432]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f433.vmdk
+ format: FLAT
+ [433]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f434.vmdk
+ format: FLAT
+ [434]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f435.vmdk
+ format: FLAT
+ [435]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f436.vmdk
+ format: FLAT
+ [436]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f437.vmdk
+ format: FLAT
+ [437]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f438.vmdk
+ format: FLAT
+ [438]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f439.vmdk
+ format: FLAT
+ [439]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f440.vmdk
+ format: FLAT
+ [440]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f441.vmdk
+ format: FLAT
+ [441]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f442.vmdk
+ format: FLAT
+ [442]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f443.vmdk
+ format: FLAT
+ [443]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f444.vmdk
+ format: FLAT
+ [444]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f445.vmdk
+ format: FLAT
+ [445]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f446.vmdk
+ format: FLAT
+ [446]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f447.vmdk
+ format: FLAT
+ [447]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f448.vmdk
+ format: FLAT
+ [448]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f449.vmdk
+ format: FLAT
+ [449]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f450.vmdk
+ format: FLAT
+ [450]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f451.vmdk
+ format: FLAT
+ [451]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f452.vmdk
+ format: FLAT
+ [452]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f453.vmdk
+ format: FLAT
+ [453]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f454.vmdk
+ format: FLAT
+ [454]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f455.vmdk
+ format: FLAT
+ [455]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f456.vmdk
+ format: FLAT
+ [456]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f457.vmdk
+ format: FLAT
+ [457]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f458.vmdk
+ format: FLAT
+ [458]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f459.vmdk
+ format: FLAT
+ [459]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f460.vmdk
+ format: FLAT
+ [460]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f461.vmdk
+ format: FLAT
+ [461]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f462.vmdk
+ format: FLAT
+ [462]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f463.vmdk
+ format: FLAT
+ [463]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f464.vmdk
+ format: FLAT
+ [464]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f465.vmdk
+ format: FLAT
+ [465]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f466.vmdk
+ format: FLAT
+ [466]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f467.vmdk
+ format: FLAT
+ [467]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f468.vmdk
+ format: FLAT
+ [468]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f469.vmdk
+ format: FLAT
+ [469]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f470.vmdk
+ format: FLAT
+ [470]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f471.vmdk
+ format: FLAT
+ [471]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f472.vmdk
+ format: FLAT
+ [472]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f473.vmdk
+ format: FLAT
+ [473]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f474.vmdk
+ format: FLAT
+ [474]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f475.vmdk
+ format: FLAT
+ [475]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f476.vmdk
+ format: FLAT
+ [476]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f477.vmdk
+ format: FLAT
+ [477]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f478.vmdk
+ format: FLAT
+ [478]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f479.vmdk
+ format: FLAT
+ [479]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f480.vmdk
+ format: FLAT
+ [480]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f481.vmdk
+ format: FLAT
+ [481]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f482.vmdk
+ format: FLAT
+ [482]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f483.vmdk
+ format: FLAT
+ [483]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f484.vmdk
+ format: FLAT
+ [484]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f485.vmdk
+ format: FLAT
+ [485]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f486.vmdk
+ format: FLAT
+ [486]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f487.vmdk
+ format: FLAT
+ [487]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f488.vmdk
+ format: FLAT
+ [488]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f489.vmdk
+ format: FLAT
+ [489]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f490.vmdk
+ format: FLAT
+ [490]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f491.vmdk
+ format: FLAT
+ [491]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f492.vmdk
+ format: FLAT
+ [492]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f493.vmdk
+ format: FLAT
+ [493]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f494.vmdk
+ format: FLAT
+ [494]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f495.vmdk
+ format: FLAT
+ [495]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f496.vmdk
+ format: FLAT
+ [496]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f497.vmdk
+ format: FLAT
+ [497]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f498.vmdk
+ format: FLAT
+ [498]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f499.vmdk
+ format: FLAT
+ [499]:
+ virtual size: 2147483648
+ filename: TEST_DIR/t-f500.vmdk
+ format: FLAT
+
=== Testing version 3 ===
image: TEST_DIR/iotest-version3.IMGFMT
file format: IMGFMT
diff --git a/tests/qemu-iotests/074 b/tests/qemu-iotests/074
new file mode 100755
index 0000000000..aba126cb69
--- /dev/null
+++ b/tests/qemu-iotests/074
@@ -0,0 +1,86 @@
+#!/bin/bash
+##
+## qemu-img compare test (qcow2 only ones)
+##
+##
+## Copyright (C) 2013 Red Hat, Inc.
+##
+## 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=famz@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+status=1 # failure is the default!
+
+_cleanup()
+{
+ echo "Cleanup"
+ _cleanup_test_img
+ rm "${TEST_IMG2}"
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_compare()
+{
+ $QEMU_IMG compare "$@" "$TEST_IMG" "${TEST_IMG2}"
+ echo $?
+}
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.pattern
+
+_supported_fmt qcow2
+_supported_proto file
+_supported_os Linux
+
+# Setup test basic parameters
+TEST_IMG2=$TEST_IMG.2
+CLUSTER_SIZE=4096
+size=1024M
+
+# Test cluster allocated in one, with IO error
+cat > "$TEST_DIR/blkdebug.conf"<<EOF
+[inject-error]
+event = "read_aio"
+errno = "5"
+once ="off"
+EOF
+_make_test_img $size
+cp "$TEST_IMG" "$TEST_IMG2"
+io_pattern write 512 512 0 1 102
+TEST_IMG="blkdebug:$TEST_DIR/blkdebug.conf:$TEST_IMG" _compare 2>&1 |\
+ _filter_testdir | _filter_imgfmt
+
+# Test cluster allocated in one, with different sizes and IO error in the part
+# that exists only in one image
+cat > "$TEST_DIR/blkdebug.conf"<<EOF
+[inject-error]
+event = "read_aio"
+errno = "5"
+once ="off"
+EOF
+_make_test_img $size
+TEST_IMG="$TEST_IMG2" _make_test_img 0
+io_pattern write 512 512 0 1 102
+TEST_IMG="blkdebug:$TEST_DIR/blkdebug.conf:$TEST_IMG" _compare 2>&1 |\
+ _filter_testdir | _filter_imgfmt
+
+# Cleanup
+status=0
diff --git a/tests/qemu-iotests/074.out b/tests/qemu-iotests/074.out
new file mode 100644
index 0000000000..8fba5aea9c
--- /dev/null
+++ b/tests/qemu-iotests/074.out
@@ -0,0 +1,18 @@
+QA output created by 074
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+=== IO: pattern 102
+wrote 512/512 bytes at offset 512
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-img: Error while reading offset 0 of blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
+qemu-img: Error while reading offset 0: Input/output error
+4
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/t.IMGFMT.2', fmt=IMGFMT size=0
+=== IO: pattern 102
+wrote 512/512 bytes at offset 512
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-img: Error while reading offset 0 of blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
+qemu-img: Error while reading offset 0 of blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
+Warning: Image size mismatch!
+4
+Cleanup
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index f5f328f5f5..e2ed5a95f8 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -161,6 +161,7 @@ cat <<EOF
QEMU -- $QEMU
QEMU_IMG -- $QEMU_IMG
QEMU_IO -- $QEMU_IO
+QEMU_NBD -- $QEMU_NBD
IMGFMT -- $FULL_IMGFMT_DETAILS
IMGPROTO -- $FULL_IMGPROTO_DETAILS
PLATFORM -- $FULL_HOST_DETAILS
@@ -242,7 +243,7 @@ do
fi
reference=$seq.out
- if (echo $QEMU_IO_OPTIONS | grep -s -- '--nocache' > /dev/null); then
+ if [ "$CACHEMODE" = "none" ]; then
[ -f $seq.out.nocache ] && reference=$seq.out.nocache
fi
diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common
index 8cde7f11fa..8b4e22c856 100644
--- a/tests/qemu-iotests/common
+++ b/tests/qemu-iotests/common
@@ -42,13 +42,16 @@ expunge=true
have_test_arg=false
randomize=false
valgrind=false
+cachemode=false
rm -f $tmp.list $tmp.tmp $tmp.sed
export IMGFMT=raw
export IMGFMT_GENERIC=true
export IMGPROTO=file
export IMGOPTS=""
+export CACHEMODE="writeback"
export QEMU_IO_OPTIONS=""
+export CACHEMODE_IS_DEFAULT=true
for r
do
@@ -113,7 +116,12 @@ s/ .*//p
IMGOPTS="$r"
imgopts=false
continue
-
+ elif $cachemode
+ then
+ CACHEMODE="$r"
+ CACHEMODE_IS_DEFAULT=false
+ cachemode=false
+ continue
fi
xpand=true
@@ -124,7 +132,7 @@ s/ .*//p
echo "Usage: $0 [options] [testlist]"'
common options
- -v verbose
+ -v verbose
check options
-raw test raw (default)
@@ -140,19 +148,20 @@ check options
-sheepdog test sheepdog
-nbd test nbd
-ssh test ssh
- -xdiff graphical mode diff
- -nocache use O_DIRECT on backing file
- -misalign misalign memory allocations
- -n show me, do not run tests
+ -xdiff graphical mode diff
+ -nocache use O_DIRECT on backing file
+ -misalign misalign memory allocations
+ -n show me, do not run tests
-o options -o options to pass to qemu-img create/convert
- -T output timestamps
- -r randomize test order
+ -T output timestamps
+ -r randomize test order
+ -c mode cache mode
testlist options
-g group[,group...] include tests from these groups
-x group[,group...] exclude tests from these groups
NNN include test NNN
- NNN-NNN include test range (eg. 012-021)
+ NNN-NNN include test range (eg. 012-021)
'
exit 0
;;
@@ -219,7 +228,8 @@ testlist options
xpand=false
;;
-nocache)
- QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --nocache"
+ CACHEMODE="none"
+ CACHEMODE_IS_DEFAULT=false
xpand=false
;;
@@ -258,6 +268,10 @@ testlist options
imgopts=true
xpand=false
;;
+ -c)
+ cachemode=true
+ xpand=false
+ ;;
-r) # randomize test order
randomize=true
xpand=false
@@ -334,6 +348,9 @@ BEGIN { for (t='$start'; t<='$end'; t++) printf "%03d\n",t }' \
done
+# Set qemu-io cache mode with $CACHEMODE we have
+QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --cache $CACHEMODE"
+
# Set default options for qemu-img create -o if they were not specified
_set_default_imgopts
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
index 9c82c77a81..776985d15e 100644
--- a/tests/qemu-iotests/common.filter
+++ b/tests/qemu-iotests/common.filter
@@ -157,7 +157,8 @@ _filter_qemu_io()
_filter_qemu()
{
sed -e "s#\\(^\\|(qemu) \\)$(basename $QEMU_PROG):#\1QEMU_PROG:#" \
- -e 's#^QEMU [0-9]\+\.[0-9]\+\.[0-9]\+ monitor#QEMU X.Y.Z monitor#'
+ -e 's#^QEMU [0-9]\+\.[0-9]\+\.[0-9]\+ monitor#QEMU X.Y.Z monitor#' \
+ -e $'s#\r##' # QEMU monitor uses \r\n line endings
}
# replace problematic QMP output like timestamps
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 7f6245770a..28ba0d9ad5 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -387,25 +387,31 @@ _supported_os()
_notrun "not suitable for this OS: $HOSTOS"
}
-_unsupported_qemu_io_options()
+_supported_cache_modes()
{
- for bad_opt
- do
- for opt in $QEMU_IO_OPTIONS
- do
- if [ "$bad_opt" = "$opt" ]
- then
- _notrun "not suitable for qemu-io option: $bad_opt"
- fi
- done
+ for mode; do
+ if [ "$mode" = "$CACHEMODE" ]; then
+ return
+ fi
done
+ _notrun "not suitable for cache mode: $CACHEMODE"
+}
+
+_default_cache_mode()
+{
+ if $CACHEMODE_IS_DEFAULT; then
+ CACHEMODE="$1"
+ QEMU_IO="$QEMU_IO --cache $1"
+ return
+ fi
}
# this test requires that a specified command (executable) exists
#
_require_command()
{
- [ -x "$1" ] || _notrun "$1 utility required, skipped this test"
+ eval c=\$$1
+ [ -x "$c" ] || _notrun "$1 utility required, skipped this test"
}
_full_imgfmt_details()
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index b63b18c7aa..cc750c986e 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -39,7 +39,7 @@
030 rw auto backing
031 rw auto quick
032 rw auto
-033 rw auto
+033 rw auto quick
034 rw auto backing
035 rw auto quick
036 rw auto quick
@@ -64,6 +64,7 @@
055 rw auto
056 rw auto backing
057 rw auto
+058 rw auto
059 rw auto
060 rw auto
061 rw auto
@@ -77,3 +78,4 @@
069 rw auto
070 rw auto
073 rw auto
+074 rw auto
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 10c9a99e3a..e4fa9af714 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -37,6 +37,7 @@ qemu_args = os.environ.get('QEMU', 'qemu').strip().split(' ')
imgfmt = os.environ.get('IMGFMT', 'raw')
imgproto = os.environ.get('IMGPROTO', 'file')
test_dir = os.environ.get('TEST_DIR', '/var/tmp')
+cachemode = os.environ.get('CACHEMODE')
socket_scm_helper = os.environ.get('SOCKET_SCM_HELPER', 'socket_scm_helper')
@@ -96,7 +97,7 @@ class VM(object):
'''Add a virtio-blk drive to the VM'''
options = ['if=virtio',
'format=%s' % imgfmt,
- 'cache=none',
+ 'cache=%s' % cachemode,
'file=%s' % path,
'id=drive%d' % self._num_drives]
if opts:
diff --git a/tests/test-aio.c b/tests/test-aio.c
index c4fe0fc3b7..592721ed3f 100644
--- a/tests/test-aio.c
+++ b/tests/test-aio.c
@@ -195,7 +195,6 @@ static void test_bh_delete_from_cb(void)
g_assert(data1.bh == NULL);
g_assert(!aio_poll(ctx, false));
- g_assert(!aio_poll(ctx, true));
}
static void test_bh_delete_from_cb_many(void)
diff --git a/trace-events b/trace-events
index e78a8d3017..9f4456a82e 100644
--- a/trace-events
+++ b/trace-events
@@ -60,11 +60,12 @@ bdrv_aio_discard(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs
bdrv_aio_flush(void *bs, void *opaque) "bs %p opaque %p"
bdrv_aio_readv(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
bdrv_aio_writev(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
+bdrv_aio_write_zeroes(void *bs, int64_t sector_num, int nb_sectors, int flags, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d flags %#x opaque %p"
bdrv_lock_medium(void *bs, bool locked) "bs %p locked %d"
bdrv_co_readv(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
bdrv_co_copy_on_readv(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
bdrv_co_writev(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
-bdrv_co_write_zeroes(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
+bdrv_co_write_zeroes(void *bs, int64_t sector_num, int nb_sector, int flags) "bs %p sector_num %"PRId64" nb_sectors %d flags %#x"
bdrv_co_io_em(void *bs, int64_t sector_num, int nb_sectors, int is_write, void *acb) "bs %p sector_num %"PRId64" nb_sectors %d is_write %d acb %p"
bdrv_co_do_copy_on_readv(void *bs, int64_t sector_num, int nb_sectors, int64_t cluster_sector_num, int cluster_nb_sectors) "bs %p sector_num %"PRId64" nb_sectors %d cluster_sector_num %"PRId64" cluster_nb_sectors %d"
@@ -127,6 +128,7 @@ thread_pool_cancel(void *req, void *opaque) "req %p opaque %p"
# block/raw-win32.c
# block/raw-posix.c
+paio_submit_co(int64_t sector_num, int nb_sectors, int type) "sector_num %"PRId64" nb_sectors %d type %d"
paio_submit(void *acb, void *opaque, int64_t sector_num, int nb_sectors, int type) "acb %p opaque %p sector_num %"PRId64" nb_sectors %d type %d"
# ioport.c