diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-08-08 15:23:21 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-08-08 15:23:21 +0100 |
commit | 53b080fa83c35d22cc94c730346fb2c53138d786 (patch) | |
tree | 48064249926a702c1d7181e1406957573215acb7 | |
parent | b4174c4b08a719e7df7e4f35c29f44b7c2517237 (diff) | |
parent | 113fe792fd4931dd0538f03859278b8719ee4fa2 (diff) |
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches for 2.10.0-rc2
# gpg: Signature made Tue 08 Aug 2017 14:56:15 BST
# gpg: using RSA key 0x7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6
* remotes/kevin/tags/for-upstream:
block/nfs: fix mutex assertion in nfs_file_close()
qemu-iotests: Test reopen between read-only and read-write
qemu-io: Allow reopen read-write
block: Set BDRV_O_ALLOW_RDWR during rw reopen
block: Allow reopen rw without BDRV_O_ALLOW_RDWR
block: Fix order in bdrv_replace_child()
parallels: drop check that bdrv_truncate() is working
parallels: respect error code of bdrv_getlength() in allocate_clusters()
block: respect error code from bdrv_getlength in handle_aiocb_write_zeroes
vmdk: Fix error handling/reporting of vmdk_check
block/null: Remove 'filename' option
block: drop bdrv_set_key from BlockDriver
block/vhdx: check error return of bdrv_truncate()
block/vhdx: check error return of bdrv_flush()
block/vhdx: check for offset overflow to bdrv_truncate()
block/vhdx: check error return of bdrv_getlength()
quorum: Set sectors-count to 0 when reporting a flush error
qemu-iotests/109: Fix lock race condition
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | block.c | 20 | ||||
-rw-r--r-- | block/file-posix.c | 8 | ||||
-rw-r--r-- | block/nfs.c | 11 | ||||
-rw-r--r-- | block/null.c | 31 | ||||
-rw-r--r-- | block/parallels.c | 12 | ||||
-rw-r--r-- | block/quorum.c | 3 | ||||
-rw-r--r-- | block/vhdx-log.c | 52 | ||||
-rw-r--r-- | block/vhdx.c | 12 | ||||
-rw-r--r-- | block/vmdk.c | 26 | ||||
-rw-r--r-- | include/block/block.h | 3 | ||||
-rw-r--r-- | include/block/block_int.h | 1 | ||||
-rw-r--r-- | qemu-io-cmds.c | 19 | ||||
-rwxr-xr-x | tests/qemu-iotests/109 | 3 | ||||
-rw-r--r-- | tests/qemu-iotests/109.out | 56 | ||||
-rw-r--r-- | tests/qemu-iotests/136 | 2 | ||||
-rwxr-xr-x | tests/qemu-iotests/187 | 69 | ||||
-rw-r--r-- | tests/qemu-iotests/187.out | 18 | ||||
-rw-r--r-- | tests/qemu-iotests/group | 1 |
18 files changed, 299 insertions, 48 deletions
@@ -246,7 +246,8 @@ bool bdrv_is_writable(BlockDriverState *bs) return !bdrv_is_read_only(bs) && !(bs->open_flags & BDRV_O_INACTIVE); } -int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, Error **errp) +int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, + bool ignore_allow_rdw, Error **errp) { /* Do not set read_only if copy_on_read is enabled */ if (bs->copy_on_read && read_only) { @@ -256,7 +257,9 @@ int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, Error **errp) } /* Do not clear read_only if it is prohibited */ - if (!read_only && !(bs->open_flags & BDRV_O_ALLOW_RDWR)) { + if (!read_only && !(bs->open_flags & BDRV_O_ALLOW_RDWR) && + !ignore_allow_rdw) + { error_setg(errp, "Node '%s' is read only", bdrv_get_device_or_node_name(bs)); return -EPERM; @@ -269,7 +272,7 @@ int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp) { int ret = 0; - ret = bdrv_can_set_read_only(bs, read_only, errp); + ret = bdrv_can_set_read_only(bs, read_only, false, errp); if (ret < 0) { return ret; } @@ -1933,6 +1936,8 @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs) BlockDriverState *old_bs = child->bs; uint64_t perm, shared_perm; + bdrv_replace_child_noperm(child, new_bs); + if (old_bs) { /* Update permissions for old node. This is guaranteed to succeed * because we're just taking a parent away, so we're loosening @@ -1942,8 +1947,6 @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs) bdrv_set_perm(old_bs, perm, shared_perm); } - bdrv_replace_child_noperm(child, new_bs); - if (new_bs) { bdrv_get_cumulative_perm(new_bs, &perm, &shared_perm); bdrv_set_perm(new_bs, perm, shared_perm); @@ -2726,8 +2729,11 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue, bdrv_join_options(bs, options, old_options); QDECREF(old_options); - /* bdrv_open() masks this flag out */ + /* bdrv_open_inherit() sets and clears some additional flags internally */ flags &= ~BDRV_O_PROTOCOL; + if (flags & BDRV_O_RDWR) { + flags |= BDRV_O_ALLOW_RDWR; + } QLIST_FOREACH(child, &bs->children, next) { QDict *new_child_options; @@ -2907,7 +2913,7 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue, * to r/w. Attempting to set to r/w may fail if either BDRV_O_ALLOW_RDWR is * not set, or if the BDS still has copy_on_read enabled */ read_only = !(reopen_state->flags & BDRV_O_RDWR); - ret = bdrv_can_set_read_only(reopen_state->bs, read_only, &local_err); + ret = bdrv_can_set_read_only(reopen_state->bs, read_only, true, &local_err); if (local_err) { error_propagate(errp, local_err); goto error; diff --git a/block/file-posix.c b/block/file-posix.c index cfbb236f6f..f4de022ae0 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -1339,6 +1339,9 @@ static ssize_t handle_aiocb_write_zeroes(RawPosixAIOData *aiocb) #if defined(CONFIG_FALLOCATE) || defined(CONFIG_XFS) BDRVRawState *s = aiocb->bs->opaque; #endif +#ifdef CONFIG_FALLOCATE + int64_t len; +#endif if (aiocb->aio_type & QEMU_AIO_BLKDEV) { return handle_aiocb_write_zeroes_block(aiocb); @@ -1381,7 +1384,10 @@ static ssize_t handle_aiocb_write_zeroes(RawPosixAIOData *aiocb) #endif #ifdef CONFIG_FALLOCATE - if (s->has_fallocate && aiocb->aio_offset >= bdrv_getlength(aiocb->bs)) { + /* Last resort: we are trying to extend the file with zeroed data. This + * can be done via fallocate(fd, 0) */ + len = bdrv_getlength(aiocb->bs); + if (s->has_fallocate && len >= 0 && aiocb->aio_offset >= len) { int ret = do_fallocate(s->fd, 0, aiocb->aio_offset, aiocb->aio_nbytes); if (ret == 0 || ret != -ENOTSUP) { return ret; diff --git a/block/nfs.c b/block/nfs.c index d8db419957..bec16b72a6 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -433,19 +433,23 @@ static void nfs_client_close(NFSClient *client) if (client->context) { if (client->fh) { nfs_close(client->context, client->fh); + client->fh = NULL; } aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context), false, NULL, NULL, NULL, NULL); nfs_destroy_context(client->context); + client->context = NULL; } - memset(client, 0, sizeof(NFSClient)); + g_free(client->path); + qemu_mutex_destroy(&client->mutex); + qapi_free_NFSServer(client->server); + client->server = NULL; } static void nfs_file_close(BlockDriverState *bs) { NFSClient *client = bs->opaque; nfs_client_close(client); - qemu_mutex_destroy(&client->mutex); } static NFSServer *nfs_config(QDict *options, Error **errp) @@ -498,6 +502,7 @@ static int64_t nfs_client_open(NFSClient *client, QDict *options, struct stat st; char *file = NULL, *strp = NULL; + qemu_mutex_init(&client->mutex); opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); qemu_opts_absorb_qdict(opts, options, &local_err); if (local_err) { @@ -660,7 +665,7 @@ static int nfs_file_open(BlockDriverState *bs, QDict *options, int flags, if (ret < 0) { return ret; } - qemu_mutex_init(&client->mutex); + bs->total_sectors = ret; ret = 0; return ret; diff --git a/block/null.c b/block/null.c index 876f90965b..dd9c13f9ba 100644 --- a/block/null.c +++ b/block/null.c @@ -30,11 +30,6 @@ static QemuOptsList runtime_opts = { .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head), .desc = { { - .name = "filename", - .type = QEMU_OPT_STRING, - .help = "", - }, - { .name = BLOCK_OPT_SIZE, .type = QEMU_OPT_SIZE, .help = "size of the null block", @@ -54,6 +49,30 @@ static QemuOptsList runtime_opts = { }, }; +static void null_co_parse_filename(const char *filename, QDict *options, + Error **errp) +{ + /* This functions only exists so that a null-co:// filename is accepted + * with the null-co driver. */ + if (strcmp(filename, "null-co://")) { + error_setg(errp, "The only allowed filename for this driver is " + "'null-co://'"); + return; + } +} + +static void null_aio_parse_filename(const char *filename, QDict *options, + Error **errp) +{ + /* This functions only exists so that a null-aio:// filename is accepted + * with the null-aio driver. */ + if (strcmp(filename, "null-aio://")) { + error_setg(errp, "The only allowed filename for this driver is " + "'null-aio://'"); + return; + } +} + static int null_file_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { @@ -242,6 +261,7 @@ static BlockDriver bdrv_null_co = { .instance_size = sizeof(BDRVNullState), .bdrv_file_open = null_file_open, + .bdrv_parse_filename = null_co_parse_filename, .bdrv_close = null_close, .bdrv_getlength = null_getlength, @@ -261,6 +281,7 @@ static BlockDriver bdrv_null_aio = { .instance_size = sizeof(BDRVNullState), .bdrv_file_open = null_file_open, + .bdrv_parse_filename = null_aio_parse_filename, .bdrv_close = null_close, .bdrv_getlength = null_getlength, diff --git a/block/parallels.c b/block/parallels.c index 5bbdfabb7a..e1e06d23cc 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -192,7 +192,7 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum) { BDRVParallelsState *s = bs->opaque; - int64_t pos, space, idx, to_allocate, i; + int64_t pos, space, idx, to_allocate, i, len; pos = block_status(s, sector_num, nb_sectors, pnum); if (pos > 0) { @@ -214,7 +214,11 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num, assert(idx < s->bat_size && idx + to_allocate <= s->bat_size); space = to_allocate * s->tracks; - if (s->data_end + space > bdrv_getlength(bs->file->bs) >> BDRV_SECTOR_BITS) { + len = bdrv_getlength(bs->file->bs); + if (len < 0) { + return len; + } + if (s->data_end + space > (len >> BDRV_SECTOR_BITS)) { int ret; space += s->prealloc_size; if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE) { @@ -699,9 +703,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags, goto fail_options; } - if (!(flags & BDRV_O_RESIZE) || !bdrv_has_zero_init(bs->file->bs) || - bdrv_truncate(bs->file, bdrv_getlength(bs->file->bs), - PREALLOC_MODE_OFF, NULL) != 0) { + if (!bdrv_has_zero_init(bs->file->bs)) { s->prealloc_mode = PRL_PREALLOC_MODE_FALLOCATE; } diff --git a/block/quorum.c b/block/quorum.c index 55ba916655..d04da4f430 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -785,8 +785,7 @@ static coroutine_fn int quorum_co_flush(BlockDriverState *bs) for (i = 0; i < s->num_children; i++) { result = bdrv_co_flush(s->children[i]->bs); if (result) { - quorum_report_bad(QUORUM_OP_TYPE_FLUSH, 0, - bdrv_getlength(s->children[i]->bs), + quorum_report_bad(QUORUM_OP_TYPE_FLUSH, 0, 0, s->children[i]->bs->node_name, result); result_value.l = result; quorum_count_vote(&error_votes, &result_value, i); diff --git a/block/vhdx-log.c b/block/vhdx-log.c index 01278f3fc9..14b724ef7b 100644 --- a/block/vhdx-log.c +++ b/block/vhdx-log.c @@ -491,6 +491,7 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s, uint32_t cnt, sectors_read; uint64_t new_file_size; void *data = NULL; + int64_t file_length; VHDXLogDescEntries *desc_entries = NULL; VHDXLogEntryHeader hdr_tmp = { 0 }; @@ -510,10 +511,15 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s, if (ret < 0) { goto exit; } + file_length = bdrv_getlength(bs->file->bs); + if (file_length < 0) { + ret = file_length; + goto exit; + } /* if the log shows a FlushedFileOffset larger than our current file * size, then that means the file has been truncated / corrupted, and * we must refused to open it / use it */ - if (hdr_tmp.flushed_file_offset > bdrv_getlength(bs->file->bs)) { + if (hdr_tmp.flushed_file_offset > file_length) { ret = -EINVAL; goto exit; } @@ -543,19 +549,30 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s, goto exit; } } - if (bdrv_getlength(bs->file->bs) < desc_entries->hdr.last_file_offset) { + if (file_length < desc_entries->hdr.last_file_offset) { new_file_size = desc_entries->hdr.last_file_offset; if (new_file_size % (1024*1024)) { /* round up to nearest 1MB boundary */ - new_file_size = ((new_file_size >> 20) + 1) << 20; - bdrv_truncate(bs->file, new_file_size, PREALLOC_MODE_OFF, NULL); + new_file_size = QEMU_ALIGN_UP(new_file_size, MiB); + if (new_file_size > INT64_MAX) { + ret = -EINVAL; + goto exit; + } + ret = bdrv_truncate(bs->file, new_file_size, PREALLOC_MODE_OFF, + NULL); + if (ret < 0) { + goto exit; + } } } qemu_vfree(desc_entries); desc_entries = NULL; } - bdrv_flush(bs); + ret = bdrv_flush(bs); + if (ret < 0) { + goto exit; + } /* once the log is fully flushed, indicate that we have an empty log * now. This also sets the log guid to 0, to indicate an empty log */ vhdx_log_reset(bs, s); @@ -851,6 +868,7 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s, uint32_t partial_sectors = 0; uint32_t bytes_written = 0; uint64_t file_offset; + int64_t file_length; VHDXHeader *header; VHDXLogEntryHeader new_hdr; VHDXLogDescriptor *new_desc = NULL; @@ -904,6 +922,12 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s, sectors += partial_sectors; + file_length = bdrv_getlength(bs->file->bs); + if (file_length < 0) { + ret = file_length; + goto exit; + } + /* sectors is now how many sectors the data itself takes, not * including the header and descriptor metadata */ @@ -913,11 +937,11 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s, .sequence_number = s->log.sequence, .descriptor_count = sectors, .reserved = 0, - .flushed_file_offset = bdrv_getlength(bs->file->bs), - .last_file_offset = bdrv_getlength(bs->file->bs), + .flushed_file_offset = file_length, + .last_file_offset = file_length, + .log_guid = header->log_guid, }; - new_hdr.log_guid = header->log_guid; desc_sectors = vhdx_compute_desc_sectors(new_hdr.descriptor_count); @@ -1022,7 +1046,11 @@ int vhdx_log_write_and_flush(BlockDriverState *bs, BDRVVHDXState *s, /* Make sure data written (new and/or changed blocks) is stable * on disk, before creating log entry */ - bdrv_flush(bs); + ret = bdrv_flush(bs); + if (ret < 0) { + goto exit; + } + ret = vhdx_log_write(bs, s, data, length, offset); if (ret < 0) { goto exit; @@ -1030,7 +1058,11 @@ int vhdx_log_write_and_flush(BlockDriverState *bs, BDRVVHDXState *s, logs.log = s->log; /* Make sure log is stable on disk */ - bdrv_flush(bs); + ret = bdrv_flush(bs); + if (ret < 0) { + goto exit; + } + ret = vhdx_log_flush(bs, s, &logs); if (ret < 0) { goto exit; diff --git a/block/vhdx.c b/block/vhdx.c index a9cecd2773..7ae4589879 100644 --- a/block/vhdx.c +++ b/block/vhdx.c @@ -1166,10 +1166,20 @@ exit: static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s, uint64_t *new_offset) { - *new_offset = bdrv_getlength(bs->file->bs); + int64_t current_len; + + current_len = bdrv_getlength(bs->file->bs); + if (current_len < 0) { + return current_len; + } + + *new_offset = current_len; /* per the spec, the address for a block is in units of 1MB */ *new_offset = ROUND_UP(*new_offset, 1024 * 1024); + if (*new_offset > INT64_MAX) { + return -EINVAL; + } return bdrv_truncate(bs->file, *new_offset + s->block_size, PREALLOC_MODE_OFF, NULL); diff --git a/block/vmdk.c b/block/vmdk.c index 0fc97391a6..c665bcc977 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -2236,6 +2236,7 @@ static int vmdk_check(BlockDriverState *bs, BdrvCheckResult *result, fprintf(stderr, "ERROR: could not find extent for sector %" PRId64 "\n", sector_num); + ret = -EINVAL; break; } ret = get_cluster_offset(bs, extent, NULL, @@ -2247,19 +2248,28 @@ static int vmdk_check(BlockDriverState *bs, BdrvCheckResult *result, PRId64 "\n", sector_num); break; } - if (ret == VMDK_OK && - cluster_offset >= bdrv_getlength(extent->file->bs)) - { - fprintf(stderr, - "ERROR: cluster offset for sector %" - PRId64 " points after EOF\n", sector_num); - break; + if (ret == VMDK_OK) { + int64_t extent_len = bdrv_getlength(extent->file->bs); + if (extent_len < 0) { + fprintf(stderr, + "ERROR: could not get extent file length for sector %" + PRId64 "\n", sector_num); + ret = extent_len; + break; + } + if (cluster_offset >= extent_len) { + fprintf(stderr, + "ERROR: cluster offset for sector %" + PRId64 " points after EOF\n", sector_num); + ret = -EINVAL; + break; + } } sector_num += extent->cluster_sectors; } result->corruptions++; - return 0; + return ret; } static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs) diff --git a/include/block/block.h b/include/block/block.h index 34770bb33a..ab80195378 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -436,7 +436,8 @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base, bool bdrv_is_read_only(BlockDriverState *bs); bool bdrv_is_writable(BlockDriverState *bs); -int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, Error **errp); +int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, + bool ignore_allow_rdw, Error **errp); int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp); bool bdrv_is_sg(BlockDriverState *bs); bool bdrv_is_inserted(BlockDriverState *bs); diff --git a/include/block/block_int.h b/include/block/block_int.h index d4f4ea7584..7571c0aaaf 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -127,7 +127,6 @@ struct BlockDriver { Error **errp); void (*bdrv_close)(BlockDriverState *bs); int (*bdrv_create)(const char *filename, QemuOpts *opts, Error **errp); - int (*bdrv_set_key)(BlockDriverState *bs, const char *key); int (*bdrv_make_empty)(BlockDriverState *bs); void (*bdrv_refresh_filename)(BlockDriverState *bs, QDict *options); diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c index 3eb42c6728..2811a89099 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -1920,6 +1920,7 @@ static void reopen_help(void) " 'reopen -o lazy-refcounts=on' - activates lazy refcount writeback on a qcow2 image\n" "\n" " -r, -- Reopen the image read-only\n" +" -w, -- Reopen the image read-write\n" " -c, -- Change the cache mode to the given value\n" " -o, -- Changes block driver options (cf. 'open' command)\n" "\n"); @@ -1942,7 +1943,7 @@ static const cmdinfo_t reopen_cmd = { .argmin = 0, .argmax = -1, .cfunc = reopen_f, - .args = "[-r] [-c cache] [-o options]", + .args = "[(-r|-w)] [-c cache] [-o options]", .oneline = "reopens an image with new options", .help = reopen_help, }; @@ -1955,11 +1956,12 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv) int c; int flags = bs->open_flags; bool writethrough = !blk_enable_write_cache(blk); + bool has_rw_option = false; BlockReopenQueue *brq; Error *local_err = NULL; - while ((c = getopt(argc, argv, "c:o:r")) != -1) { + while ((c = getopt(argc, argv, "c:o:rw")) != -1) { switch (c) { case 'c': if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) < 0) { @@ -1974,7 +1976,20 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv) } break; case 'r': + if (has_rw_option) { + error_report("Only one -r/-w option may be given"); + return 0; + } flags &= ~BDRV_O_RDWR; + has_rw_option = true; + break; + case 'w': + if (has_rw_option) { + error_report("Only one -r/-w option may be given"); + return 0; + } + flags |= BDRV_O_RDWR; + has_rw_option = true; break; default: qemu_opts_reset(&reopen_opts); diff --git a/tests/qemu-iotests/109 b/tests/qemu-iotests/109 index 3b496a3918..d70b574d88 100755 --- a/tests/qemu-iotests/109 +++ b/tests/qemu-iotests/109 @@ -67,7 +67,8 @@ function run_qemu() _send_qemu_cmd $QEMU_HANDLE '' "BLOCK_JOB_COMPLETED" fi _send_qemu_cmd $QEMU_HANDLE '{"execute":"query-block-jobs"}' "return" - _cleanup_qemu + _send_qemu_cmd $QEMU_HANDLE '{"execute":"quit"}' "return" + wait=1 _cleanup_qemu } for fmt in qcow qcow2 qed vdi vmdk vpc; do diff --git a/tests/qemu-iotests/109.out b/tests/qemu-iotests/109.out index dc02f9eefa..c189e2833d 100644 --- a/tests/qemu-iotests/109.out +++ b/tests/qemu-iotests/109.out @@ -12,12 +12,17 @@ Specify the 'raw' format explicitly to remove the restrictions. {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"return": []} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": {}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 1024, "offset": 1024, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}} Warning: Image size mismatch! Images are identical. @@ -33,12 +38,17 @@ Specify the 'raw' format explicitly to remove the restrictions. {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 512, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"return": []} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": {}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 197120, "offset": 197120, "speed": 0, "type": "mirror"}} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 197120, "offset": 197120, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 197120, "offset": 197120, "speed": 0, "type": "mirror"}} Warning: Image size mismatch! Images are identical. @@ -54,12 +64,17 @@ Specify the 'raw' format explicitly to remove the restrictions. {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 262144, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"return": []} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": {}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 327680, "offset": 327680, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}} Warning: Image size mismatch! Images are identical. @@ -75,12 +90,17 @@ Specify the 'raw' format explicitly to remove the restrictions. {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"return": []} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": {}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 1024, "offset": 1024, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}} Warning: Image size mismatch! Images are identical. @@ -96,12 +116,17 @@ Specify the 'raw' format explicitly to remove the restrictions. {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"return": []} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": {}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 65536, "offset": 65536, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}} Warning: Image size mismatch! Images are identical. @@ -117,12 +142,17 @@ Specify the 'raw' format explicitly to remove the restrictions. {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"return": []} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": {}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2560, "offset": 2560, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}} Warning: Image size mismatch! Images are identical. @@ -137,12 +167,17 @@ Specify the 'raw' format explicitly to remove the restrictions. {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"return": []} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": {}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2560, "offset": 2560, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}} Warning: Image size mismatch! Images are identical. @@ -157,12 +192,17 @@ Specify the 'raw' format explicitly to remove the restrictions. {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"return": []} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": {}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 31457280, "offset": 31457280, "speed": 0, "type": "mirror"}} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 31457280, "offset": 31457280, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 31457280, "offset": 31457280, "speed": 0, "type": "mirror"}} Warning: Image size mismatch! Images are identical. @@ -177,12 +217,17 @@ Specify the 'raw' format explicitly to remove the restrictions. {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"return": []} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": {}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 327680, "offset": 327680, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}} Warning: Image size mismatch! Images are identical. @@ -197,12 +242,17 @@ Specify the 'raw' format explicitly to remove the restrictions. {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"return": []} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": {}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2048, "offset": 2048, "speed": 0, "type": "mirror"}} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2048, "offset": 2048, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2048, "offset": 2048, "speed": 0, "type": "mirror"}} Warning: Image size mismatch! Images are identical. @@ -216,12 +266,18 @@ Specify the 'raw' format explicitly to remove the restrictions. {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 512, "offset": 512, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}} Warning: Image size mismatch! Images are identical. {"return": {}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 512, "offset": 512, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}} Warning: Image size mismatch! Images are identical. *** done diff --git a/tests/qemu-iotests/136 b/tests/qemu-iotests/136 index 635b977552..4b994897af 100644 --- a/tests/qemu-iotests/136 +++ b/tests/qemu-iotests/136 @@ -75,7 +75,7 @@ sector = "%d" drive_args.append("stats-account-failed=%s" % (self.account_failed and "on" or "off")) self.create_blkdebug_file() - self.vm = iotests.VM().add_drive('blkdebug:%s:%s ' % + self.vm = iotests.VM().add_drive('blkdebug:%s:%s' % (blkdebug_file, self.test_img), ','.join(drive_args)) self.vm.launch() diff --git a/tests/qemu-iotests/187 b/tests/qemu-iotests/187 new file mode 100755 index 0000000000..7bb783363c --- /dev/null +++ b/tests/qemu-iotests/187 @@ -0,0 +1,69 @@ +#!/bin/bash +# +# Test switching between read-only and read-write +# +# Copyright (C) 2017 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=kwolf@redhat.com + +seq=`basename $0` +echo "QA output created by $seq" + +here=`pwd` +status=1 # failure is the default! + +_cleanup() +{ + _cleanup_test_img + rm -f "$TEST_IMG.2" + rm -f "$TEST_IMG.3" +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter + +_supported_fmt qcow2 +_supported_proto file +_supported_os Linux + +size=64M +_make_test_img $size + +echo +echo "Start from read-only" +echo + +$QEMU_IO -r -c 'write 0 64k' $TEST_IMG | _filter_qemu_io +$QEMU_IO -r -c 'reopen -w' -c 'write 0 64k' $TEST_IMG | _filter_qemu_io +$QEMU_IO -r -c 'reopen -w' -c 'reopen -r' -c 'write 0 64k' $TEST_IMG | _filter_qemu_io + +echo +echo "Start from read-write" +echo + +$QEMU_IO -c 'write 0 64k' $TEST_IMG | _filter_qemu_io +$QEMU_IO -c 'reopen -r' -c 'write 0 64k' $TEST_IMG | _filter_qemu_io +$QEMU_IO -c 'reopen -r' -c 'reopen -w' -c 'write 0 64k' $TEST_IMG | _filter_qemu_io + + +# success, all done +echo "*** done" +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/187.out b/tests/qemu-iotests/187.out new file mode 100644 index 0000000000..68fb944cd5 --- /dev/null +++ b/tests/qemu-iotests/187.out @@ -0,0 +1,18 @@ +QA output created by 187 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 + +Start from read-only + +Block node is read-only +wrote 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +Block node is read-only + +Start from read-write + +wrote 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +write failed: Operation not permitted +wrote 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +*** done diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 823811076d..1848077932 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -182,6 +182,7 @@ 183 rw auto migration 185 rw auto 186 rw auto +187 rw auto 188 rw auto quick 189 rw auto 190 rw auto quick |