diff options
author | Anthony Liguori <aliguori@amazon.com> | 2013-12-07 07:35:31 -0800 |
---|---|---|
committer | Anthony Liguori <aliguori@amazon.com> | 2013-12-07 07:35:31 -0800 |
commit | 93531372f0f74bb4d886480c0c8aa0e4ca6f5423 (patch) | |
tree | be13df35b2e689f031eef40bc06311b91bfc3548 | |
parent | 0c0cb6a2378f937410f5f55cbf3e3b2c20f293c6 (diff) | |
parent | ac9524dc55dc32e492ac3e6fbc9785be7168f8a2 (diff) |
Merge remote-tracking branch 'stefanha/block' into staging
# By Paolo Bonzini (17) and others
# Via Stefan Hajnoczi
* stefanha/block: (48 commits)
qemu-iotests: filter QEMU monitor \r\n
aio: make aio_poll(ctx, true) block with no fds
block: clean up bdrv_drain_all() throttling comments
qcow2: use start_of_cluster() and offset_into_cluster() everywhere
qemu-img: decrease progress update interval on convert
qemu-img: round down request length to an aligned sector
qemu-img: dynamically adjust iobuffer size during convert
block/iscsi: set bs->bl.opt_transfer_length
block: add opt_transfer_length to BlockLimits
block/iscsi: set bdi->cluster_size
qemu-img: fix usage instruction for qemu-img convert
qemu-img: add support for skipping zeroes in input during convert
qemu-nbd: add doc for option -f
qemu-iotests: add test for snapshot in qemu-img convert
qemu-img: add -l for snapshot in convert
qemu-iotests: add 058 internal snapshot export with qemu-nbd case
qemu-nbd: support internal snapshot export
snapshot: distinguish id and name in load_tmp
qemu-iotests: Split qcow2 only cases in 048
qemu-iotests: Clean up spaces in usage output
...
Message-id: 1386347807-27359-1-git-send-email-stefanha@redhat.com
Signed-off-by: Anthony Liguori <aliguori@amazon.com>
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; @@ -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) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=off -QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K 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) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K === No medium === Testing: -drive if=floppy -QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K Testing: -drive if=ide,media=cdrom -QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K Testing: -drive if=scsi,media=cdrom -QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K 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) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-cd,drive=disk -QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K 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) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K Testing: -drive file=TEST_DIR/t.qcow2,if=ide,media=cdrom,readonly=on -QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,media=cdrom,readonly=on -QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K 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) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,readonly=on -QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K 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) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K 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) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K 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) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K 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) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K === Cache modes === Testing: -drive media=cdrom,cache=none -QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K Testing: -drive media=cdrom,cache=directsync -QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K Testing: -drive media=cdrom,cache=writeback -QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K Testing: -drive media=cdrom,cache=writethrough -QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K Testing: -drive media=cdrom,cache=unsafe -QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K 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) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
+QEMU X.Y.Z monitor - type 'help' for more information +(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K 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 |