diff options
-rw-r--r-- | block.c | 20 | ||||
-rw-r--r-- | block/file-posix.c | 8 | ||||
-rw-r--r-- | block/io.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/trace-events | 4 | ||||
-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-- | hw/arm/virt.c | 19 | ||||
-rw-r--r-- | hw/cpu/core.c | 5 | ||||
-rw-r--r-- | hw/i386/acpi-build.c | 4 | ||||
-rw-r--r-- | include/block/block.h | 3 | ||||
-rw-r--r-- | include/block/block_int.h | 1 | ||||
-rw-r--r-- | include/qom/cpu.h | 31 | ||||
-rw-r--r-- | qemu-io-cmds.c | 19 | ||||
-rw-r--r-- | qom/cpu.c | 34 | ||||
-rw-r--r-- | target/s390x/mem_helper.c | 1 | ||||
-rw-r--r-- | tcg/arm/tcg-target.inc.c | 2 | ||||
-rw-r--r-- | tcg/tcg.h | 5 | ||||
-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 |
28 files changed, 400 insertions, 60 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/io.c b/block/io.c index d9dc822173..26003814eb 100644 --- a/block/io.c +++ b/block/io.c @@ -1135,6 +1135,8 @@ int coroutine_fn bdrv_co_preadv(BdrvChild *child, bool use_local_qiov = false; int ret; + trace_bdrv_co_preadv(child->bs, offset, bytes, flags); + if (!drv) { return -ENOMEDIUM; } @@ -1207,8 +1209,6 @@ static int coroutine_fn bdrv_co_do_readv(BdrvChild *child, int coroutine_fn bdrv_co_readv(BdrvChild *child, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) { - trace_bdrv_co_readv(child->bs, sector_num, nb_sectors); - return bdrv_co_do_readv(child, sector_num, nb_sectors, qiov, 0); } @@ -1526,6 +1526,8 @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child, bool use_local_qiov = false; int ret; + trace_bdrv_co_pwritev(child->bs, offset, bytes, flags); + if (!bs->drv) { return -ENOMEDIUM; } @@ -1660,8 +1662,6 @@ static int coroutine_fn bdrv_co_do_writev(BdrvChild *child, int coroutine_fn bdrv_co_writev(BdrvChild *child, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) { - trace_bdrv_co_writev(child->bs, sector_num, nb_sectors); - return bdrv_co_do_writev(child, sector_num, nb_sectors, qiov, 0); } 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/trace-events b/block/trace-events index 071a8d77ba..25dd5a3026 100644 --- a/block/trace-events +++ b/block/trace-events @@ -9,8 +9,8 @@ blk_co_preadv(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags blk_co_pwritev(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags) "blk %p bs %p offset %"PRId64" bytes %u flags 0x%x" # block/io.c -bdrv_co_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_preadv(void *bs, int64_t offset, int64_t nbytes, unsigned int flags) "bs %p offset %"PRId64" nbytes %"PRId64" flags 0x%x" +bdrv_co_pwritev(void *bs, int64_t offset, int64_t nbytes, unsigned int flags) "bs %p offset %"PRId64" nbytes %"PRId64" flags 0x%x" bdrv_co_pwrite_zeroes(void *bs, int64_t offset, int count, int flags) "bs %p offset %"PRId64" count %d flags 0x%x" bdrv_co_do_copy_on_readv(void *bs, int64_t offset, unsigned int bytes, int64_t cluster_offset, unsigned int cluster_bytes) "bs %p offset %"PRId64" bytes %u cluster_offset %"PRId64" cluster_bytes %u" 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/hw/arm/virt.c b/hw/arm/virt.c index 31739d75a3..6b7a0fefc4 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1639,7 +1639,7 @@ static void machvirt_machine_init(void) } type_init(machvirt_machine_init); -static void virt_2_9_instance_init(Object *obj) +static void virt_2_10_instance_init(Object *obj) { VirtMachineState *vms = VIRT_MACHINE(obj); VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); @@ -1699,10 +1699,25 @@ static void virt_2_9_instance_init(Object *obj) vms->irqmap = a15irqmap; } +static void virt_machine_2_10_options(MachineClass *mc) +{ +} +DEFINE_VIRT_MACHINE_AS_LATEST(2, 10) + +#define VIRT_COMPAT_2_9 \ + HW_COMPAT_2_9 + +static void virt_2_9_instance_init(Object *obj) +{ + virt_2_10_instance_init(obj); +} + static void virt_machine_2_9_options(MachineClass *mc) { + virt_machine_2_10_options(mc); + SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_9); } -DEFINE_VIRT_MACHINE_AS_LATEST(2, 9) +DEFINE_VIRT_MACHINE(2, 9) #define VIRT_COMPAT_2_8 \ HW_COMPAT_2_8 diff --git a/hw/cpu/core.c b/hw/cpu/core.c index 2bf960d6a8..bd578ab80c 100644 --- a/hw/cpu/core.c +++ b/hw/cpu/core.c @@ -33,6 +33,11 @@ static void core_prop_set_core_id(Object *obj, Visitor *v, const char *name, return; } + if (value < 0) { + error_setg(errp, "Invalid core id %"PRId64, value); + return; + } + core->core_id = value; } diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index b9c245c9bb..98dd424678 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1862,9 +1862,9 @@ static Aml *build_q35_osc_method(void) /* * Always allow native PME, AER (no dependencies) - * Never allow SHPC (no SHPC controller in this system) + * Allow SHPC (PCI bridges can have SHPC controller) */ - aml_append(if_ctx, aml_and(a_ctrl, aml_int(0x1D), a_ctrl)); + aml_append(if_ctx, aml_and(a_ctrl, aml_int(0x1F), a_ctrl)); if_ctx2 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1)))); /* Unknown revision */ 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/include/qom/cpu.h b/include/qom/cpu.h index 25eefea7ab..e9d30c52b4 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -162,6 +162,10 @@ typedef struct CPUClass { void (*dump_statistics)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); int64_t (*get_arch_id)(CPUState *cpu); + void * (*alloc_env)(CPUState *cpu); + void (*get_env)(CPUState *cpu, void *env); + void (*set_env)(CPUState *cpu, void *env); + void (*free_env)(CPUState *cpu, void *env); bool (*get_paging_enabled)(const CPUState *cpu); void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list, Error **errp); @@ -440,6 +444,33 @@ extern bool mttcg_enabled; #define qemu_tcg_mttcg_enabled() (mttcg_enabled) /** + * cpu_alloc_env: allocate CPU environment structure + * @cpu: allocate environment structure for this CPU + */ +void *cpu_alloc_env(CPUState *cpu); + +/** + * cpu_get_env: retrieve CPU environment structure + * @cpu: CPU to use + * @env: environment structure to use + */ +void cpu_get_env(CPUState *cpu, void *env); + +/** + * cpu_set_env: switch to given CPU environment + * @cpu: CPU to use + * @env: environment structure to use + */ +void cpu_set_env(CPUState *cpu, void *env); + +/** + * cpu_free_env: free CPU environment structure + * @cpu: free environment structure for this CPU + * @env: structure to free + */ +void cpu_free_env(CPUState *cpu, void *env); + +/** * cpu_paging_enabled: * @cpu: The CPU whose state is to be inspected. * 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); @@ -89,6 +89,40 @@ out: return cpu; } +void *cpu_alloc_env(CPUState *cpu) +{ + CPUClass *cc = CPU_GET_CLASS(cpu); + + return cc->alloc_env ? cc->alloc_env(cpu) : NULL; +} + +void cpu_get_env(CPUState *cpu, void *env) +{ + CPUClass *cc = CPU_GET_CLASS(cpu); + + if (cc->get_env) { + cc->get_env(cpu, env); + } +} + +void cpu_set_env(CPUState *cpu, void *env) +{ + CPUClass *cc = CPU_GET_CLASS(cpu); + + if (cc->set_env) { + cc->set_env(cpu, env); + } +} + +void cpu_free_env(CPUState *cpu, void *env) +{ + CPUClass *cc = CPU_GET_CLASS(cpu); + + if (cc->free_env) { + cc->free_env(cpu, env); + } +} + bool cpu_paging_enabled(const CPUState *cpu) { CPUClass *cc = CPU_GET_CLASS(cpu); diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index cdc78aa3d4..c71dce4b1e 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -1580,6 +1580,7 @@ uint32_t HELPER(csst)(CPUS390XState *env, uint32_t r3, uint64_t a1, uint64_t a2) cpu_stq_data_ra(env, a2 + 0, svh, ra); cpu_stq_data_ra(env, a2 + 8, svl, ra); } + break; default: g_assert_not_reached(); } diff --git a/tcg/arm/tcg-target.inc.c b/tcg/arm/tcg-target.inc.c index d1793ec77d..37efcf06af 100644 --- a/tcg/arm/tcg-target.inc.c +++ b/tcg/arm/tcg-target.inc.c @@ -1223,7 +1223,7 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, TCGReg addrlo, TCGReg addrhi, /* Load the tlb addend. */ tcg_out_ld32_12(s, COND_AL, TCG_REG_R2, TCG_REG_R2, add_off); - tcg_out_dat_reg(s, (s_bits ? COND_EQ : COND_AL), ARITH_CMP, 0, + tcg_out_dat_reg(s, (a_bits ? COND_EQ : COND_AL), ARITH_CMP, 0, TCG_REG_R0, TCG_REG_TMP, SHIFT_IMM_LSL(TARGET_PAGE_BITS)); if (TARGET_LONG_BITS == 64) { @@ -762,7 +762,10 @@ static inline void *tcg_malloc(int size) { TCGContext *s = &tcg_ctx; uint8_t *ptr, *ptr_end; - size = (size + sizeof(long) - 1) & ~(sizeof(long) - 1); + + /* ??? This is a weak placeholder for minimum malloc alignment. */ + size = QEMU_ALIGN_UP(size, 8); + ptr = s->pool_cur; ptr_end = ptr + size; if (unlikely(ptr_end > s->pool_end)) { 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 |