diff --git a/block/qcow.c b/block/qcow.c index 9569deeaf0f1c03cae34649f1fd8fb63fd6323b8..d552a6eba876273397dde69ae9934266bcfba044 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -379,6 +379,7 @@ static int get_cluster_offset(BlockDriverState *bs, /* update the L1 entry */ s->l1_table[l1_index] = l2_offset; tmp = cpu_to_be64(l2_offset); + BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE); ret = bdrv_pwrite_sync(bs->file, s->l1_table_offset + l1_index * sizeof(tmp), &tmp, sizeof(tmp)); @@ -409,6 +410,7 @@ static int get_cluster_offset(BlockDriverState *bs, } } l2_table = s->l2_cache + (min_index << s->l2_bits); + BLKDBG_EVENT(bs->file, BLKDBG_L2_LOAD); if (new_l2_table) { memset(l2_table, 0, s->l2_size * sizeof(uint64_t)); ret = bdrv_pwrite_sync(bs->file, l2_offset, l2_table, @@ -432,6 +434,7 @@ static int get_cluster_offset(BlockDriverState *bs, ((cluster_offset & QCOW_OFLAG_COMPRESSED) && allocate == 1)) { if (!allocate) return 0; + BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC); /* allocate a new cluster */ if ((cluster_offset & QCOW_OFLAG_COMPRESSED) && (n_end - n_start) < s->cluster_sectors) { @@ -447,6 +450,7 @@ static int get_cluster_offset(BlockDriverState *bs, } cluster_offset = QEMU_ALIGN_UP(cluster_offset, s->cluster_size); /* write the cluster content */ + BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); ret = bdrv_pwrite(bs->file, cluster_offset, s->cluster_cache, s->cluster_size); if (ret < 0) { @@ -486,6 +490,7 @@ static int get_cluster_offset(BlockDriverState *bs, NULL) < 0) { return -EIO; } + BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); ret = bdrv_pwrite(bs->file, cluster_offset + i * 512, s->cluster_data, 512); @@ -503,6 +508,11 @@ static int get_cluster_offset(BlockDriverState *bs, /* update L2 table */ tmp = cpu_to_be64(cluster_offset); l2_table[l2_index] = tmp; + if (allocate == 2) { + BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED); + } else { + BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE); + } ret = bdrv_pwrite_sync(bs->file, l2_offset + l2_index * sizeof(tmp), &tmp, sizeof(tmp)); if (ret < 0) { @@ -579,6 +589,7 @@ static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset) if (s->cluster_cache_offset != coffset) { csize = cluster_offset >> (63 - s->cluster_bits); csize &= (s->cluster_size - 1); + BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED); ret = bdrv_pread(bs->file, coffset, s->cluster_data, csize); if (ret != csize) return -1; @@ -635,6 +646,8 @@ static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num, hd_iov.iov_len = n * 512; qemu_iovec_init_external(&hd_qiov, &hd_iov, 1); qemu_co_mutex_unlock(&s->lock); + /* qcow2 emits this on bs->file instead of bs->backing */ + BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO); ret = bdrv_co_readv(bs->backing, sector_num, n, &hd_qiov); qemu_co_mutex_lock(&s->lock); if (ret < 0) { @@ -661,6 +674,7 @@ static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num, hd_iov.iov_len = n * 512; qemu_iovec_init_external(&hd_qiov, &hd_iov, 1); qemu_co_mutex_unlock(&s->lock); + BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO); ret = bdrv_co_readv(bs->file, (cluster_offset >> 9) + index_in_cluster, n, &hd_qiov); @@ -754,6 +768,7 @@ static coroutine_fn int qcow_co_writev(BlockDriverState *bs, int64_t sector_num, hd_iov.iov_len = n * 512; qemu_iovec_init_external(&hd_qiov, &hd_iov, 1); qemu_co_mutex_unlock(&s->lock); + BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); ret = bdrv_co_writev(bs->file, (cluster_offset >> 9) + index_in_cluster, n, &hd_qiov); @@ -1048,6 +1063,7 @@ qcow_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset, .iov_len = out_len, }; qemu_iovec_init_external(&hd_qiov, &iov, 1); + BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED); ret = bdrv_co_pwritev(bs->file, cluster_offset, out_len, &hd_qiov, 0); if (ret < 0) { goto fail; diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c index f45e46cfbd8f05aa4aa6ed7fa56fda804cee4c6c..efa10c666356de60db05a9b4488a9be35fb97916 100644 --- a/block/qcow2-bitmap.c +++ b/block/qcow2-bitmap.c @@ -1449,6 +1449,16 @@ bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs, bool found; Qcow2BitmapList *bm_list; + if (s->qcow_version < 3) { + /* Without autoclear_features, we would always have to assume + * that a program without persistent dirty bitmap support has + * accessed this qcow2 file when opening it, and would thus + * have to drop all dirty bitmaps (defeating their purpose). + */ + error_setg(errp, "Cannot store dirty bitmaps in qcow2 v2 files"); + goto fail; + } + if (check_constraints_on_bitmap(bs, name, granularity, errp) != 0) { goto fail; } diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 3de1ab51ba34f7688c54cc664e579afee30d7265..92701ab7af936a7ef5da7131c993c599380303c0 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -1508,7 +1508,7 @@ enum { static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, void **refcount_table, int64_t *refcount_table_size, int64_t l2_offset, - int flags) + int flags, BdrvCheckMode fix) { BDRVQcow2State *s = bs->opaque; uint64_t *l2_table, l2_entry; @@ -1579,6 +1579,57 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, next_contiguous_offset = offset + s->cluster_size; } + /* Correct offsets are cluster aligned */ + if (offset_into_cluster(s, offset)) { + if (qcow2_get_cluster_type(l2_entry) == + QCOW2_CLUSTER_ZERO_ALLOC) + { + fprintf(stderr, "%s offset=%" PRIx64 ": Preallocated zero " + "cluster is not properly aligned; L2 entry " + "corrupted.\n", + fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR", + offset); + if (fix & BDRV_FIX_ERRORS) { + uint64_t l2e_offset = + l2_offset + (uint64_t)i * sizeof(uint64_t); + + l2_entry = QCOW_OFLAG_ZERO; + l2_table[i] = cpu_to_be64(l2_entry); + ret = qcow2_pre_write_overlap_check(bs, + QCOW2_OL_ACTIVE_L2 | QCOW2_OL_INACTIVE_L2, + l2e_offset, sizeof(uint64_t)); + if (ret < 0) { + fprintf(stderr, "ERROR: Overlap check failed\n"); + res->check_errors++; + /* Something is seriously wrong, so abort checking + * this L2 table */ + goto fail; + } + + ret = bdrv_pwrite_sync(bs->file, l2e_offset, + &l2_table[i], sizeof(uint64_t)); + if (ret < 0) { + fprintf(stderr, "ERROR: Failed to overwrite L2 " + "table entry: %s\n", strerror(-ret)); + res->check_errors++; + /* Do not abort, continue checking the rest of this + * L2 table's entries */ + } else { + res->corruptions_fixed++; + /* Skip marking the cluster as used + * (it is unused now) */ + continue; + } + } else { + res->corruptions++; + } + } else { + fprintf(stderr, "ERROR offset=%" PRIx64 ": Data cluster is " + "not properly aligned; L2 entry corrupted.\n", offset); + res->corruptions++; + } + } + /* Mark cluster as used */ ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, refcount_table_size, @@ -1586,13 +1637,6 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, if (ret < 0) { goto fail; } - - /* Correct offsets are cluster aligned */ - if (offset_into_cluster(s, offset)) { - fprintf(stderr, "ERROR offset=%" PRIx64 ": Cluster is not " - "properly aligned; L2 entry corrupted.\n", offset); - res->corruptions++; - } break; } @@ -1626,7 +1670,7 @@ static int check_refcounts_l1(BlockDriverState *bs, void **refcount_table, int64_t *refcount_table_size, int64_t l1_table_offset, int l1_size, - int flags) + int flags, BdrvCheckMode fix) { BDRVQcow2State *s = bs->opaque; uint64_t *l1_table = NULL, l2_offset, l1_size2; @@ -1681,7 +1725,8 @@ static int check_refcounts_l1(BlockDriverState *bs, /* Process and check L2 entries */ ret = check_refcounts_l2(bs, res, refcount_table, - refcount_table_size, l2_offset, flags); + refcount_table_size, l2_offset, flags, + fix); if (ret < 0) { goto fail; } @@ -1957,7 +2002,8 @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res, /* current L1 table */ ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters, - s->l1_table_offset, s->l1_size, CHECK_FRAG_INFO); + s->l1_table_offset, s->l1_size, CHECK_FRAG_INFO, + fix); if (ret < 0) { return ret; } @@ -1966,7 +2012,7 @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res, for (i = 0; i < s->nb_snapshots; i++) { sn = s->snapshots + i; ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters, - sn->l1_table_offset, sn->l1_size, 0); + sn->l1_table_offset, sn->l1_size, 0, fix); if (ret < 0) { return ret; } diff --git a/block/qcow2.c b/block/qcow2.c index 4348b2c0c580aab05711accd7f9c10a8744e3d7a..1f80961e1b97bc315c04da298f1be02e893d6ef0 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -302,9 +302,17 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset, } if (!(s->autoclear_features & QCOW2_AUTOCLEAR_BITMAPS)) { - warn_report("a program lacking bitmap support " - "modified this file, so all bitmaps are now " - "considered inconsistent"); + if (s->qcow_version < 3) { + /* Let's be a bit more specific */ + warn_report("This qcow2 v2 image contains bitmaps, but " + "they may have been modified by a program " + "without persistent bitmap support; so now " + "they must all be considered inconsistent"); + } else { + warn_report("a program lacking bitmap support " + "modified this file, so all bitmaps are now " + "considered inconsistent"); + } error_printf("Some clusters may be leaked, " "run 'qemu-img check -r' on the image " "file to fix."); diff --git a/block/vmdk.c b/block/vmdk.c index c665bcc977252a84d4858f175cacfa0118069c60..d71cec4f31babbb3ba73ec66a2ea424b0c8c8777 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1075,6 +1075,8 @@ static int get_whole_cluster(BlockDriverState *bs, /* Read backing data before skip range */ if (skip_start_bytes > 0) { if (bs->backing) { + /* qcow2 emits this on bs->file instead of bs->backing */ + BLKDBG_EVENT(extent->file, BLKDBG_COW_READ); ret = bdrv_pread(bs->backing, offset, whole_grain, skip_start_bytes); if (ret < 0) { @@ -1082,6 +1084,7 @@ static int get_whole_cluster(BlockDriverState *bs, goto exit; } } + BLKDBG_EVENT(extent->file, BLKDBG_COW_WRITE); ret = bdrv_pwrite(extent->file, cluster_offset, whole_grain, skip_start_bytes); if (ret < 0) { @@ -1092,6 +1095,8 @@ static int get_whole_cluster(BlockDriverState *bs, /* Read backing data after skip range */ if (skip_end_bytes < cluster_bytes) { if (bs->backing) { + /* qcow2 emits this on bs->file instead of bs->backing */ + BLKDBG_EVENT(extent->file, BLKDBG_COW_READ); ret = bdrv_pread(bs->backing, offset + skip_end_bytes, whole_grain + skip_end_bytes, cluster_bytes - skip_end_bytes); @@ -1100,6 +1105,7 @@ static int get_whole_cluster(BlockDriverState *bs, goto exit; } } + BLKDBG_EVENT(extent->file, BLKDBG_COW_WRITE); ret = bdrv_pwrite(extent->file, cluster_offset + skip_end_bytes, whole_grain + skip_end_bytes, cluster_bytes - skip_end_bytes); @@ -1120,6 +1126,7 @@ static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data, { offset = cpu_to_le32(offset); /* update L2 table */ + BLKDBG_EVENT(extent->file, BLKDBG_L2_UPDATE); if (bdrv_pwrite_sync(extent->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(offset)), @@ -1218,6 +1225,7 @@ static int get_cluster_offset(BlockDriverState *bs, } } l2_table = extent->l2_cache + (min_index * extent->l2_size); + BLKDBG_EVENT(extent->file, BLKDBG_L2_LOAD); if (bdrv_pread(extent->file, (int64_t)l2_offset * 512, l2_table, @@ -1393,12 +1401,16 @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset, .iov_len = n_bytes, }; qemu_iovec_init_external(&local_qiov, &iov, 1); + + BLKDBG_EVENT(extent->file, BLKDBG_WRITE_COMPRESSED); } else { qemu_iovec_init(&local_qiov, qiov->niov); qemu_iovec_concat(&local_qiov, qiov, qiov_offset, n_bytes); + + BLKDBG_EVENT(extent->file, BLKDBG_WRITE_AIO); } - write_offset = cluster_offset + offset_in_cluster, + write_offset = cluster_offset + offset_in_cluster; ret = bdrv_co_pwritev(extent->file, write_offset, n_bytes, &local_qiov, 0); @@ -1437,6 +1449,7 @@ static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset, if (!extent->compressed) { + BLKDBG_EVENT(extent->file, BLKDBG_READ_AIO); ret = bdrv_co_preadv(extent->file, cluster_offset + offset_in_cluster, bytes, qiov, 0); @@ -1450,6 +1463,7 @@ static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset, buf_bytes = cluster_bytes * 2; cluster_buf = g_malloc(buf_bytes); uncomp_buf = g_malloc(cluster_bytes); + BLKDBG_EVENT(extent->file, BLKDBG_READ_COMPRESSED); ret = bdrv_pread(extent->file, cluster_offset, cluster_buf, buf_bytes); @@ -1527,6 +1541,8 @@ vmdk_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes, qemu_iovec_reset(&local_qiov); qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes); + /* qcow2 emits this on bs->file instead of bs->backing */ + BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO); ret = bdrv_co_preadv(bs->backing, offset, n_bytes, &local_qiov, 0); if (ret < 0) { diff --git a/blockdev.c b/blockdev.c index 29d569a24e1a2145397c269beb15b8cec136052f..8e977eef11f38a50acd736b9c9e37c4fade6cedb 100644 --- a/blockdev.c +++ b/blockdev.c @@ -60,6 +60,11 @@ static QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states = static int do_open_tray(const char *blk_name, const char *qdev_id, bool force, Error **errp); +static void blockdev_remove_medium(bool has_device, const char *device, + bool has_id, const char *id, Error **errp); +static void blockdev_insert_medium(bool has_device, const char *device, + bool has_id, const char *id, + const char *node_name, Error **errp); static const char *const if_name[IF_COUNT] = { [IF_NONE] = "none", @@ -2323,7 +2328,7 @@ void qmp_eject(bool has_device, const char *device, } error_free(local_err); - qmp_x_blockdev_remove_medium(has_device, device, has_id, id, errp); + blockdev_remove_medium(has_device, device, has_id, id, errp); } void qmp_block_passwd(bool has_device, const char *device, @@ -2446,8 +2451,8 @@ void qmp_blockdev_close_tray(bool has_device, const char *device, } } -void qmp_x_blockdev_remove_medium(bool has_device, const char *device, - bool has_id, const char *id, Error **errp) +static void blockdev_remove_medium(bool has_device, const char *device, + bool has_id, const char *id, Error **errp) { BlockBackend *blk; BlockDriverState *bs; @@ -2503,6 +2508,11 @@ out: aio_context_release(aio_context); } +void qmp_blockdev_remove_medium(const char *id, Error **errp) +{ + blockdev_remove_medium(false, NULL, true, id, errp); +} + static void qmp_blockdev_insert_anon_medium(BlockBackend *blk, BlockDriverState *bs, Error **errp) { @@ -2548,9 +2558,9 @@ static void qmp_blockdev_insert_anon_medium(BlockBackend *blk, } } -void qmp_x_blockdev_insert_medium(bool has_device, const char *device, - bool has_id, const char *id, - const char *node_name, Error **errp) +static void blockdev_insert_medium(bool has_device, const char *device, + bool has_id, const char *id, + const char *node_name, Error **errp) { BlockBackend *blk; BlockDriverState *bs; @@ -2576,6 +2586,12 @@ void qmp_x_blockdev_insert_medium(bool has_device, const char *device, qmp_blockdev_insert_anon_medium(blk, bs, errp); } +void qmp_blockdev_insert_medium(const char *id, const char *node_name, + Error **errp) +{ + blockdev_insert_medium(false, NULL, true, id, node_name, errp); +} + void qmp_blockdev_change_medium(bool has_device, const char *device, bool has_id, const char *id, const char *filename, @@ -2650,7 +2666,7 @@ void qmp_blockdev_change_medium(bool has_device, const char *device, error_free(err); err = NULL; - qmp_x_blockdev_remove_medium(has_device, device, has_id, id, &err); + blockdev_remove_medium(has_device, device, has_id, id, &err); if (err) { error_propagate(errp, err); goto fail; diff --git a/hw/block/nvme.c b/hw/block/nvme.c index 1ac356d3a5c63f8946fa8771d9c8916d2b531639..51a58fefba5c835cd95555fa592a950010013725 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -91,7 +91,19 @@ static uint8_t nvme_sq_empty(NvmeSQueue *sq) return sq->head == sq->tail; } -static void nvme_isr_notify(NvmeCtrl *n, NvmeCQueue *cq) +static void nvme_irq_check(NvmeCtrl *n) +{ + if (msix_enabled(&(n->parent_obj))) { + return; + } + if (~n->bar.intms & n->irq_status) { + pci_irq_assert(&n->parent_obj); + } else { + pci_irq_deassert(&n->parent_obj); + } +} + +static void nvme_irq_assert(NvmeCtrl *n, NvmeCQueue *cq) { if (cq->irq_enabled) { if (msix_enabled(&(n->parent_obj))) { @@ -99,13 +111,28 @@ static void nvme_isr_notify(NvmeCtrl *n, NvmeCQueue *cq) msix_notify(&(n->parent_obj), cq->vector); } else { trace_nvme_irq_pin(); - pci_irq_pulse(&n->parent_obj); + assert(cq->cqid < 64); + n->irq_status |= 1 << cq->cqid; + nvme_irq_check(n); } } else { trace_nvme_irq_masked(); } } +static void nvme_irq_deassert(NvmeCtrl *n, NvmeCQueue *cq) +{ + if (cq->irq_enabled) { + if (msix_enabled(&(n->parent_obj))) { + return; + } else { + assert(cq->cqid < 64); + n->irq_status &= ~(1 << cq->cqid); + nvme_irq_check(n); + } + } +} + static uint16_t nvme_map_prp(QEMUSGList *qsg, QEMUIOVector *iov, uint64_t prp1, uint64_t prp2, uint32_t len, NvmeCtrl *n) { @@ -242,7 +269,7 @@ static void nvme_post_cqes(void *opaque) sizeof(req->cqe)); QTAILQ_INSERT_TAIL(&sq->req_list, req, entry); } - nvme_isr_notify(n, cq); + nvme_irq_assert(n, cq); } static void nvme_enqueue_req_completion(NvmeCQueue *cq, NvmeRequest *req) @@ -905,6 +932,7 @@ static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data, n->bar.intmc = n->bar.intms; trace_nvme_mmio_intm_set(data & 0xffffffff, n->bar.intmc); + nvme_irq_check(n); break; case 0x10: /* INTMC */ if (unlikely(msix_enabled(&(n->parent_obj)))) { @@ -917,6 +945,7 @@ static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data, n->bar.intmc = n->bar.intms; trace_nvme_mmio_intm_clr(data & 0xffffffff, n->bar.intmc); + nvme_irq_check(n); break; case 0x14: /* CC */ trace_nvme_mmio_cfg(data & 0xffffffff); @@ -1085,8 +1114,8 @@ static void nvme_process_db(NvmeCtrl *n, hwaddr addr, int val) timer_mod(cq->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 500); } - if (cq->tail != cq->head) { - nvme_isr_notify(n, cq); + if (cq->tail == cq->head) { + nvme_irq_deassert(n, cq); } } else { /* Submission queue doorbell write */ diff --git a/hw/block/nvme.h b/hw/block/nvme.h index 6aab338ff52db1066ef21bf5a38929bc12be7791..7b62dad072c015e40168ef1626c6fe245ee7f177 100644 --- a/hw/block/nvme.h +++ b/hw/block/nvme.h @@ -775,6 +775,7 @@ typedef struct NvmeCtrl { uint32_t cmbsz; uint32_t cmbloc; uint8_t *cmbuf; + uint64_t irq_status; char *serial; NvmeNamespace *namespaces; diff --git a/qapi/block-core.json b/qapi/block-core.json index 4e84cf29dbd0fd941938bb64064d2c1d6782d580..8225308904a5a2aa0e1eac5e30cf96d3693b9420 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -3421,7 +3421,7 @@ '*id': 'str' } } ## -# @x-blockdev-remove-medium: +# @blockdev-remove-medium: # # Removes a medium (a block driver state tree) from a block device. That block # device's tray must currently be open (unless there is no attached guest @@ -3429,18 +3429,13 @@ # # If the tray is open and there is no medium inserted, this will be a no-op. # -# @device: Block device name (deprecated, use @id instead) -# -# @id: The name or QOM path of the guest device (since: 2.8) -# -# Note: This command is still a work in progress and is considered experimental. -# Stay away from it unless you want to help with its development. +# @id: The name or QOM path of the guest device # -# Since: 2.5 +# Since: 2.12 # # Example: # -# -> { "execute": "x-blockdev-remove-medium", +# -> { "execute": "blockdev-remove-medium", # "arguments": { "id": "ide0-1-0" } } # # <- { "error": { "class": "GenericError", @@ -3458,33 +3453,27 @@ # # <- { "return": {} } # -# -> { "execute": "x-blockdev-remove-medium", +# -> { "execute": "blockdev-remove-medium", # "arguments": { "id": "ide0-1-0" } } # # <- { "return": {} } # ## -{ 'command': 'x-blockdev-remove-medium', - 'data': { '*device': 'str', - '*id': 'str' } } +{ 'command': 'blockdev-remove-medium', + 'data': { 'id': 'str' } } ## -# @x-blockdev-insert-medium: +# @blockdev-insert-medium: # # Inserts a medium (a block driver state tree) into a block device. That block # device's tray must currently be open (unless there is no attached guest # device) and there must be no medium inserted already. # -# @device: Block device name (deprecated, use @id instead) -# -# @id: The name or QOM path of the guest device (since: 2.8) +# @id: The name or QOM path of the guest device # # @node-name: name of a node in the block driver state graph # -# Note: This command is still a work in progress and is considered experimental. -# Stay away from it unless you want to help with its development. -# -# Since: 2.5 +# Since: 2.12 # # Example: # @@ -3496,16 +3485,15 @@ # "filename": "fedora.iso" } } } # <- { "return": {} } # -# -> { "execute": "x-blockdev-insert-medium", +# -> { "execute": "blockdev-insert-medium", # "arguments": { "id": "ide0-1-0", # "node-name": "node0" } } # # <- { "return": {} } # ## -{ 'command': 'x-blockdev-insert-medium', - 'data': { '*device': 'str', - '*id': 'str', +{ 'command': 'blockdev-insert-medium', + 'data': { 'id': 'str', 'node-name': 'str'} } @@ -3533,8 +3521,8 @@ # # Changes the medium inserted into a block device by ejecting the current medium # and loading a new image file which is inserted as the new medium (this command -# combines blockdev-open-tray, x-blockdev-remove-medium, -# x-blockdev-insert-medium and blockdev-close-tray). +# combines blockdev-open-tray, blockdev-remove-medium, blockdev-insert-medium +# and blockdev-close-tray). # # @device: Block device name (deprecated, use @id instead) # diff --git a/tests/.gitignore b/tests/.gitignore index 74e55d7264333e101c6512f48993cb7da5aff1c5..e5c744b7ed6c51618c4b5a4536afde3a388d25b0 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -18,6 +18,7 @@ test-aio test-aio-multithread test-arm-mptimer test-base64 +test-bdrv-drain test-bitops test-bitcnt test-blockjob diff --git a/tests/ahci-test.c b/tests/ahci-test.c index cb84edc8fbab4e41d31ee8758c1802aa247833a9..3934e62ef7cdb717e19cc82859cd886cd46cd60c 100644 --- a/tests/ahci-test.c +++ b/tests/ahci-test.c @@ -1578,9 +1578,9 @@ static void test_atapi_tray(void) QDict *rsp; fd = prepare_iso(iso_size, &tx, &iso); - ahci = ahci_boot_and_enable("-drive if=none,id=drive0,file=%s,format=raw " + ahci = ahci_boot_and_enable("-blockdev node-name=drive0,driver=file,filename=%s " "-M q35 " - "-device ide-cd,drive=drive0 ", iso); + "-device ide-cd,id=cd0,drive=drive0 ", iso); port = ahci_port_select(ahci); ahci_atapi_eject(ahci, port); @@ -1591,13 +1591,13 @@ static void test_atapi_tray(void) /* Remove media */ qmp_async("{'execute': 'blockdev-open-tray', " - "'arguments': {'device': 'drive0'}}"); + "'arguments': {'id': 'cd0'}}"); atapi_wait_tray(true); rsp = qmp_receive(); QDECREF(rsp); - qmp_discard_response("{'execute': 'x-blockdev-remove-medium', " - "'arguments': {'device': 'drive0'}}"); + qmp_discard_response("{'execute': 'blockdev-remove-medium', " + "'arguments': {'id': 'cd0'}}"); /* Test the tray without a medium */ ahci_atapi_load(ahci, port); @@ -1612,13 +1612,13 @@ static void test_atapi_tray(void) "'driver': 'raw', " "'file': { 'driver': 'file', " "'filename': %s }}}", iso); - qmp_discard_response("{'execute': 'x-blockdev-insert-medium'," - "'arguments': { 'device': 'drive0', " + qmp_discard_response("{'execute': 'blockdev-insert-medium'," + "'arguments': { 'id': 'cd0', " "'node-name': 'node0' }}"); /* Again, the event shows up first */ qmp_async("{'execute': 'blockdev-close-tray', " - "'arguments': {'device': 'drive0'}}"); + "'arguments': {'id': 'cd0'}}"); atapi_wait_tray(false); rsp = qmp_receive(); QDECREF(rsp); diff --git a/tests/qemu-iotests/020 b/tests/qemu-iotests/020 index cefe3a830e38831f6ea8269ac8c4e09573a4e7b4..eac5080f83c8146d4f4114b0ff3d8bd8e00d8aa2 100755 --- a/tests/qemu-iotests/020 +++ b/tests/qemu-iotests/020 @@ -42,18 +42,12 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 # Any format supporting backing files _supported_fmt qcow qcow2 vmdk qed -_supported_proto generic -_unsupported_proto vxhs +_supported_proto file _supported_os Linux _unsupported_imgopts "subformat=monolithicFlat" \ "subformat=twoGbMaxExtentFlat" \ "subformat=twoGbMaxExtentSparse" -# NFS does not support bdrv_reopen_prepare thus qemu-img commit fails. -if [ "$IMGPROTO" = "nfs" ]; then - _notrun "image protocol $IMGPROTO does not support bdrv_commit" -fi - TEST_OFFSETS="0 4294967296" TEST_IMG_SAVE="$TEST_IMG" @@ -117,10 +111,12 @@ echo echo 'Testing failing commit' echo +TEST_IMG="$TEST_IMG.base" _make_test_img 1M + # Create an image with a null backing file to which committing will fail (with # ENOSPC so we can distinguish the result from some generic EIO which may be # generated anywhere in the block layer) -_make_test_img -b "json:{'driver': 'raw', +_make_test_img -b "json:{'driver': '$IMGFMT', 'file': { 'driver': 'blkdebug', 'inject-error': [{ @@ -129,14 +125,15 @@ _make_test_img -b "json:{'driver': 'raw', 'once': true }], 'image': { - 'driver': 'null-co' + 'driver': 'file', + 'filename': '$TEST_IMG.base' }}}" # Just write anything so committing will not be a no-op $QEMU_IO -c 'writev 0 64k' "$TEST_IMG" | _filter_qemu_io $QEMU_IMG commit "$TEST_IMG" -_cleanup_test_img +_cleanup # success, all done echo "*** done" diff --git a/tests/qemu-iotests/020.out b/tests/qemu-iotests/020.out index 165b70aa49e03b6f1d141128767db1277c62d083..4b722b2dd022862127a611e37d6d65720cf405ab 100644 --- a/tests/qemu-iotests/020.out +++ b/tests/qemu-iotests/020.out @@ -1078,7 +1078,8 @@ No errors were found on the image. Testing failing commit -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 backing_file=json:{'driver': 'raw',, +Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=1048576 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=json:{'driver': 'IMGFMT',, 'file': { 'driver': 'blkdebug',, 'inject-error': [{ @@ -1087,7 +1088,8 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 backing_file=json:{'d 'once': true }],, 'image': { - 'driver': 'null-co' + 'driver': 'file',, + 'filename': 'TEST_DIR/t.IMGFMT.base' }}} wrote 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051 index dba8816c9f7192b687fb8e95eba2ed4c633de1b2..0c3be16489cfad087b553fdfa8c8e9359b74a151 100755 --- a/tests/qemu-iotests/051 +++ b/tests/qemu-iotests/051 @@ -131,6 +131,8 @@ echo echo === Enable and disable lazy refcounting on the command line, plus some invalid values === echo +_make_test_img -o compat=1.1 "$size" + run_qemu -drive file="$TEST_IMG",format=qcow2,lazy-refcounts=on run_qemu -drive file="$TEST_IMG",format=qcow2,lazy-refcounts=off run_qemu -drive file="$TEST_IMG",format=qcow2,lazy-refcounts= diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out index e3c6eaba57a5db79d2dcd8175cf09f6a063a645f..dd9846d1ce595362cdf9a049740431d3560c6302 100644 --- a/tests/qemu-iotests/051.out +++ b/tests/qemu-iotests/051.out @@ -77,6 +77,7 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.backing.driver=qcow2,file.backing.f === Enable and disable lazy refcounting on the command line, plus some invalid values === +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on QEMU X.Y.Z monitor - type 'help' for more information (qemu) quit diff --git a/tests/qemu-iotests/051.pc.out b/tests/qemu-iotests/051.pc.out index f2c5622ceeff7ee9ac6dcd878744548ed08d64a2..830c11880a419081ab5372846b244969081f8038 100644 --- a/tests/qemu-iotests/051.pc.out +++ b/tests/qemu-iotests/051.pc.out @@ -77,6 +77,7 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.backing.driver=qcow2,file.backing.f === Enable and disable lazy refcounting on the command line, plus some invalid values === +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on QEMU X.Y.Z monitor - type 'help' for more information (qemu) quit diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059 index a1c34eeb7c7640a622eb2302d79fda8496a8e78c..40f89eae18b879dbfa683b32081efe1d793ed5d0 100755 --- a/tests/qemu-iotests/059 +++ b/tests/qemu-iotests/059 @@ -152,7 +152,9 @@ done echo echo "=== Testing afl image with a very large capacity ===" _use_sample_img afl9.vmdk.bz2 -_img_info +# The sed makes this test pass on machines with little RAM +# (and also with 32 bit builds) +_img_info | sed -e 's/Cannot allocate memory/Invalid argument/' _cleanup_test_img # success, all done diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out index f6dce7947c95c7b47981bd53af7476d64493fa80..1ac5d5623357e6340046d955cfd56acf67613e11 100644 --- a/tests/qemu-iotests/059.out +++ b/tests/qemu-iotests/059.out @@ -2358,5 +2358,5 @@ Offset Length Mapped to File 0x140000000 0x10000 0x50000 TEST_DIR/t-s003.vmdk === Testing afl image with a very large capacity === -qemu-img: Can't get image size 'TEST_DIR/afl9.IMGFMT': File too large +qemu-img: Could not open 'TEST_DIR/afl9.IMGFMT': Could not open 'TEST_DIR/afl9.IMGFMT': Invalid argument *** done diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060 index 14797dd3b0e74c452c1b3963c7f9d40bed89cd60..6c7407f499fae5f89f44e7e26f1f6b8cc44e7612 100755 --- a/tests/qemu-iotests/060 +++ b/tests/qemu-iotests/060 @@ -335,7 +335,8 @@ poke_file "$TEST_IMG" "$l2_offset" "\x80\x00\x00\x00\x00\x00\x2a\x01" # Let's write to it! $QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io -# Can't repair this yet (TODO: We can just deallocate the cluster) +echo '--- Repairing ---' +_check_test_img -r all echo echo '=== Discarding with an unaligned refblock ===' diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out index c4cb7c665e90007d0e883a96eeac450c3f21cb78..25d5c3938b76dafe2ca23a69401509e7420dc135 100644 --- a/tests/qemu-iotests/060.out +++ b/tests/qemu-iotests/060.out @@ -317,6 +317,15 @@ discard 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) qcow2: Marking image as corrupt: Preallocated zero cluster offset 0x2a00 unaligned (guest offset: 0); further corruption events will be suppressed write failed: Input/output error +--- Repairing --- +Repairing offset=2a00: Preallocated zero cluster is not properly aligned; L2 entry corrupted. +The following inconsistencies were found and repaired: + + 0 leaked clusters + 1 corruptions + +Double checking the fixed image now... +No errors were found on the image. === Discarding with an unaligned refblock === diff --git a/tests/qemu-iotests/067 b/tests/qemu-iotests/067 index 9d561ef7861693b454478ad7abd679f536eca155..fe259f61654de2dcb932a90b745c0236c29a9f0a 100755 --- a/tests/qemu-iotests/067 +++ b/tests/qemu-iotests/067 @@ -57,7 +57,8 @@ function run_qemu() { do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp | _filter_qemu \ | _filter_actual_image_size \ - | _filter_generated_node_ids | _filter_qmp_events + | _filter_generated_node_ids | _filter_qmp_events \ + | _filter_img_info } size=128M diff --git a/tests/qemu-iotests/067.out b/tests/qemu-iotests/067.out index 58e83c4505e94411b2bafb118ba21e37cc64a012..2e71cff3ce091a0aff262ef47d6f02614affbba1 100644 --- a/tests/qemu-iotests/067.out +++ b/tests/qemu-iotests/067.out @@ -3,7 +3,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 === -drive/-device and device_del === -Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virtio-blk,drive=disk,id=virtio0 +Testing: -drive file=TEST_DIR/t.IMGFMT,format=IMGFMT,if=none,id=disk -device virtio-blk,drive=disk,id=virtio0 { QMP_VERSION } @@ -23,26 +23,17 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virti "detect_zeroes": "off", "image": { "virtual-size": 134217728, - "filename": "TEST_DIR/t.qcow2", + "filename": "TEST_DIR/t.IMGFMT", "cluster-size": 65536, - "format": "qcow2", + "format": "IMGFMT", "actual-size": SIZE, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "refcount-bits": 16, - "corrupt": false - } - }, "dirty-flag": false }, "iops_wr": 0, "ro": false, "node-name": "NODE_NAME", "backing_file_depth": 0, - "drv": "qcow2", + "drv": "IMGFMT", "iops": 0, "bps_wr": 0, "write_threshold": 0, @@ -54,7 +45,7 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virti "direct": false, "writeback": true }, - "file": "TEST_DIR/t.qcow2", + "file": "TEST_DIR/t.IMGFMT", "encryption_key_missing": false }, "qdev": "/machine/peripheral/virtio0/virtio-backend", @@ -81,7 +72,7 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virti === -drive/device_add and device_del === -Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk +Testing: -drive file=TEST_DIR/t.IMGFMT,format=IMGFMT,if=none,id=disk { QMP_VERSION } @@ -100,26 +91,17 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk "detect_zeroes": "off", "image": { "virtual-size": 134217728, - "filename": "TEST_DIR/t.qcow2", + "filename": "TEST_DIR/t.IMGFMT", "cluster-size": 65536, - "format": "qcow2", + "format": "IMGFMT", "actual-size": SIZE, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "refcount-bits": 16, - "corrupt": false - } - }, "dirty-flag": false }, "iops_wr": 0, "ro": false, "node-name": "NODE_NAME", "backing_file_depth": 0, - "drv": "qcow2", + "drv": "IMGFMT", "iops": 0, "bps_wr": 0, "write_threshold": 0, @@ -131,7 +113,7 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk "direct": false, "writeback": true }, - "file": "TEST_DIR/t.qcow2", + "file": "TEST_DIR/t.IMGFMT", "encryption_key_missing": false }, "type": "unknown" @@ -183,26 +165,17 @@ Testing: "detect_zeroes": "off", "image": { "virtual-size": 134217728, - "filename": "TEST_DIR/t.qcow2", + "filename": "TEST_DIR/t.IMGFMT", "cluster-size": 65536, - "format": "qcow2", + "format": "IMGFMT", "actual-size": SIZE, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "refcount-bits": 16, - "corrupt": false - } - }, "dirty-flag": false }, "iops_wr": 0, "ro": false, "node-name": "NODE_NAME", "backing_file_depth": 0, - "drv": "qcow2", + "drv": "IMGFMT", "iops": 0, "bps_wr": 0, "write_threshold": 0, @@ -214,7 +187,7 @@ Testing: "direct": false, "writeback": true }, - "file": "TEST_DIR/t.qcow2", + "file": "TEST_DIR/t.IMGFMT", "encryption_key_missing": false }, "type": "unknown" @@ -263,26 +236,17 @@ Testing: "detect_zeroes": "off", "image": { "virtual-size": 134217728, - "filename": "TEST_DIR/t.qcow2", + "filename": "TEST_DIR/t.IMGFMT", "cluster-size": 65536, - "format": "qcow2", + "format": "IMGFMT", "actual-size": SIZE, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "refcount-bits": 16, - "corrupt": false - } - }, "dirty-flag": false }, "iops_wr": 0, "ro": false, "node-name": "disk", "backing_file_depth": 0, - "drv": "qcow2", + "drv": "IMGFMT", "iops": 0, "bps_wr": 0, "write_threshold": 0, @@ -294,7 +258,7 @@ Testing: "direct": false, "writeback": true }, - "file": "TEST_DIR/t.qcow2", + "file": "TEST_DIR/t.IMGFMT", "encryption_key_missing": false }, { @@ -302,7 +266,7 @@ Testing: "detect_zeroes": "off", "image": { "virtual-size": 197120, - "filename": "TEST_DIR/t.qcow2", + "filename": "TEST_DIR/t.IMGFMT", "format": "file", "actual-size": SIZE, "dirty-flag": false @@ -323,7 +287,7 @@ Testing: "direct": false, "writeback": true }, - "file": "TEST_DIR/t.qcow2", + "file": "TEST_DIR/t.IMGFMT", "encryption_key_missing": false } ] @@ -347,26 +311,17 @@ Testing: "detect_zeroes": "off", "image": { "virtual-size": 134217728, - "filename": "TEST_DIR/t.qcow2", + "filename": "TEST_DIR/t.IMGFMT", "cluster-size": 65536, - "format": "qcow2", + "format": "IMGFMT", "actual-size": SIZE, - "format-specific": { - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "refcount-bits": 16, - "corrupt": false - } - }, "dirty-flag": false }, "iops_wr": 0, "ro": false, "node-name": "disk", "backing_file_depth": 0, - "drv": "qcow2", + "drv": "IMGFMT", "iops": 0, "bps_wr": 0, "write_threshold": 0, @@ -378,7 +333,7 @@ Testing: "direct": false, "writeback": true }, - "file": "TEST_DIR/t.qcow2", + "file": "TEST_DIR/t.IMGFMT", "encryption_key_missing": false }, { @@ -386,7 +341,7 @@ Testing: "detect_zeroes": "off", "image": { "virtual-size": 197120, - "filename": "TEST_DIR/t.qcow2", + "filename": "TEST_DIR/t.IMGFMT", "format": "file", "actual-size": SIZE, "dirty-flag": false @@ -407,7 +362,7 @@ Testing: "direct": false, "writeback": true }, - "file": "TEST_DIR/t.qcow2", + "file": "TEST_DIR/t.IMGFMT", "encryption_key_missing": false } ] diff --git a/tests/qemu-iotests/080 b/tests/qemu-iotests/080 index 55044c700bedce5571076319822b20ead8b45a5d..1c2bd85742a68aa4853387247b642849a699f9e5 100755 --- a/tests/qemu-iotests/080 +++ b/tests/qemu-iotests/080 @@ -41,8 +41,9 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow2 _supported_proto file _supported_os Linux -# Internal snapshots are (currently) impossible with refcount_bits=1 -_unsupported_imgopts 'refcount_bits=1[^0-9]' +# - Internal snapshots are (currently) impossible with refcount_bits=1 +# - This is generally a test for compat=1.1 images +_unsupported_imgopts 'refcount_bits=1[^0-9]' 'compat=0.10' header_size=104 diff --git a/tests/qemu-iotests/089 b/tests/qemu-iotests/089 index 9bfe2307b3da5337861da2a71d731c076a571f89..0b059aba905c1f9da5921833e4c1e634ba42dd25 100755 --- a/tests/qemu-iotests/089 +++ b/tests/qemu-iotests/089 @@ -119,11 +119,11 @@ echo # Both options given directly and those given in the filename should be used $QEMU_IO -c "open -o driver=qcow2 json:{\"file.filename\":\"$TEST_IMG\"}" \ - -c "info" 2>&1 | _filter_testdir | _filter_imgfmt + -c "info" 2>&1 | _filter_img_info # Options given directly should be prioritized over those given in the filename $QEMU_IO -c "open -o driver=qcow2 json:{\"driver\":\"raw\",\"file.filename\":\"$TEST_IMG\"}" \ - -c "info" 2>&1 | _filter_testdir | _filter_imgfmt + -c "info" 2>&1 | _filter_img_info # success, all done diff --git a/tests/qemu-iotests/089.out b/tests/qemu-iotests/089.out index 18f5fdda7add7eb8dd225574ad82d177c7d64259..0bf5a13ec18c0ff4ba0b8ea60f7afcdf41de4da2 100644 --- a/tests/qemu-iotests/089.out +++ b/tests/qemu-iotests/089.out @@ -38,17 +38,7 @@ cluster_size: 65536 format name: IMGFMT cluster size: 64 KiB vm state offset: 512 MiB -Format specific information: - compat: 1.1 - lazy refcounts: false - refcount bits: 16 - corrupt: false format name: IMGFMT cluster size: 64 KiB vm state offset: 512 MiB -Format specific information: - compat: 1.1 - lazy refcounts: false - refcount bits: 16 - corrupt: false *** done diff --git a/tests/qemu-iotests/093 b/tests/qemu-iotests/093 index 5c36a5fb4d7d1a7f6328fe5ae1a443ccca993fa8..c3404a3171bc4947bff445631a5ce6550234e31d 100755 --- a/tests/qemu-iotests/093 +++ b/tests/qemu-iotests/093 @@ -348,9 +348,9 @@ class ThrottleTestRemovableMedia(iotests.QMPTestCase): # Now eject cd0 and insert cd1 result = self.vm.qmp("blockdev-open-tray", id='dev0') self.assert_qmp(result, 'return', {}) - result = self.vm.qmp("x-blockdev-remove-medium", id='dev0') + result = self.vm.qmp("blockdev-remove-medium", id='dev0') self.assert_qmp(result, 'return', {}) - result = self.vm.qmp("x-blockdev-insert-medium", id='dev0', node_name='cd1') + result = self.vm.qmp("blockdev-insert-medium", id='dev0', node_name='cd1') self.assert_qmp(result, 'return', {}) # Check that the I/O limits are still the same @@ -359,7 +359,7 @@ class ThrottleTestRemovableMedia(iotests.QMPTestCase): self.assert_qmp(result, 'return[0]/inserted/bps', 50) # Eject cd1 - result = self.vm.qmp("x-blockdev-remove-medium", id='dev0') + result = self.vm.qmp("blockdev-remove-medium", id='dev0') self.assert_qmp(result, 'return', {}) # Check that we can't set limits if the device has no medium diff --git a/tests/qemu-iotests/102 b/tests/qemu-iotests/102 index d7ad8d984021ee52a5401a3d0101040cada26bd7..04b3f284456c8070dd3eef183ffd908d950113dd 100755 --- a/tests/qemu-iotests/102 +++ b/tests/qemu-iotests/102 @@ -69,7 +69,12 @@ $QEMU_IO -c 'write 0 64k' "$TEST_IMG" | _filter_qemu_io qemu_comm_method=monitor _launch_qemu -drive if=none,file="$TEST_IMG",id=drv0 -$QEMU_IMG resize -f raw --shrink "$TEST_IMG" $((5 * 64 * 1024)) +# Wait for a prompt to appear (so we know qemu has opened the image) +_send_qemu_cmd '' '(qemu)' + +$QEMU_IMG resize --shrink --image-opts \ + "driver=raw,file.driver=file,file.filename=$TEST_IMG,file.locking=off" \ + $((5 * 64 * 1024)) _send_qemu_cmd $QEMU_HANDLE 'qemu-io drv0 map' 'allocated' \ | sed -e 's/^(qemu).*qemu-io drv0 map...$/(qemu) qemu-io drv0 map/' diff --git a/tests/qemu-iotests/102.out b/tests/qemu-iotests/102.out index ccf172abd91ec89d2153d6c267a3e62412a6d4d9..4401b08feef6d7fe4fca492b3e0a30056566aace 100644 --- a/tests/qemu-iotests/102.out +++ b/tests/qemu-iotests/102.out @@ -14,8 +14,9 @@ Offset Length Mapped to File Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65536 wrote 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -Image resized. QEMU X.Y.Z monitor - type 'help' for more information +Image resized. +(qemu) (qemu) qemu-io drv0 map 64 KiB (0x10000) bytes allocated at offset 0 bytes (0x0) *** done diff --git a/tests/qemu-iotests/103 b/tests/qemu-iotests/103 index ecbd8ebd71de750b0d117779006530a23e3865d7..d0cfab88441ac2cc23a68b9f00dedddec1e5f52e 100755 --- a/tests/qemu-iotests/103 +++ b/tests/qemu-iotests/103 @@ -40,6 +40,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow2 _supported_proto file nfs _supported_os Linux +# Internal snapshots are (currently) impossible with refcount_bits=1 +_unsupported_imgopts 'refcount_bits=1[^0-9]' IMG_SIZE=64K diff --git a/tests/qemu-iotests/118 b/tests/qemu-iotests/118 index 8a9e838c900050b5c45a3e57a5952e07be63feb8..a0469b570ef614f8aa23ec78d3e584fbec347aea 100755 --- a/tests/qemu-iotests/118 +++ b/tests/qemu-iotests/118 @@ -28,6 +28,14 @@ from iotests import qemu_img old_img = os.path.join(iotests.test_dir, 'test0.img') new_img = os.path.join(iotests.test_dir, 'test1.img') +def interface_to_device_name(interface): + if interface == 'ide': + return 'ide-cd' + elif interface == 'floppy': + return 'floppy' + else: + return None + class ChangeBaseClass(iotests.QMPTestCase): has_opened = False has_closed = False @@ -63,7 +71,7 @@ class ChangeBaseClass(iotests.QMPTestCase): class GeneralChangeTestsBaseClass(ChangeBaseClass): - device_name = None + device_name = 'qdev0' def test_change(self): result = self.vm.qmp('change', device='drive0', target=new_img, @@ -79,14 +87,9 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass): self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) def test_blockdev_change_medium(self): - if self.device_name is not None: - result = self.vm.qmp('blockdev-change-medium', - id=self.device_name, filename=new_img, - format=iotests.imgfmt) - else: - result = self.vm.qmp('blockdev-change-medium', - device='drive0', filename=new_img, - format=iotests.imgfmt) + result = self.vm.qmp('blockdev-change-medium', + id=self.device_name, filename=new_img, + format=iotests.imgfmt) self.assert_qmp(result, 'return', {}) @@ -99,10 +102,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass): self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) def test_eject(self): - if self.device_name is not None: - result = self.vm.qmp('eject', id=self.device_name, force=True) - else: - result = self.vm.qmp('eject', device='drive0', force=True) + result = self.vm.qmp('eject', id=self.device_name, force=True) self.assert_qmp(result, 'return', {}) self.wait_for_open() @@ -113,10 +113,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass): self.assert_qmp_absent(result, 'return[0]/inserted') def test_tray_eject_change(self): - if self.device_name is not None: - result = self.vm.qmp('eject', id=self.device_name, force=True) - else: - result = self.vm.qmp('eject', device='drive0', force=True) + result = self.vm.qmp('eject', id=self.device_name, force=True) self.assert_qmp(result, 'return', {}) self.wait_for_open() @@ -126,12 +123,8 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass): self.assert_qmp(result, 'return[0]/tray_open', True) self.assert_qmp_absent(result, 'return[0]/inserted') - if self.device_name is not None: - result = self.vm.qmp('blockdev-change-medium', id=self.device_name, - filename=new_img, format=iotests.imgfmt) - else: - result = self.vm.qmp('blockdev-change-medium', device='drive0', - filename=new_img, format=iotests.imgfmt) + result = self.vm.qmp('blockdev-change-medium', id=self.device_name, + filename=new_img, format=iotests.imgfmt) self.assert_qmp(result, 'return', {}) self.wait_for_close() @@ -142,12 +135,8 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass): self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) def test_tray_open_close(self): - if self.device_name is not None: - result = self.vm.qmp('blockdev-open-tray', - id=self.device_name, force=True) - else: - result = self.vm.qmp('blockdev-open-tray', - device='drive0', force=True) + result = self.vm.qmp('blockdev-open-tray', + id=self.device_name, force=True) self.assert_qmp(result, 'return', {}) self.wait_for_open() @@ -160,10 +149,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass): else: self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) - if self.device_name is not None: - result = self.vm.qmp('blockdev-close-tray', id=self.device_name) - else: - result = self.vm.qmp('blockdev-close-tray', device='drive0') + result = self.vm.qmp('blockdev-close-tray', id=self.device_name) self.assert_qmp(result, 'return', {}) if self.has_real_tray or not self.was_empty: @@ -178,7 +164,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass): self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) def test_tray_eject_close(self): - result = self.vm.qmp('eject', device='drive0', force=True) + result = self.vm.qmp('eject', id=self.device_name, force=True) self.assert_qmp(result, 'return', {}) self.wait_for_open() @@ -188,10 +174,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass): self.assert_qmp(result, 'return[0]/tray_open', True) self.assert_qmp_absent(result, 'return[0]/inserted') - if self.device_name is not None: - result = self.vm.qmp('blockdev-close-tray', id=self.device_name) - else: - result = self.vm.qmp('blockdev-close-tray', device='drive0') + result = self.vm.qmp('blockdev-close-tray', id=self.device_name) self.assert_qmp(result, 'return', {}) self.wait_for_close() @@ -202,7 +185,8 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass): self.assert_qmp_absent(result, 'return[0]/inserted') def test_tray_open_change(self): - result = self.vm.qmp('blockdev-open-tray', device='drive0', force=True) + result = self.vm.qmp('blockdev-open-tray', id=self.device_name, + force=True) self.assert_qmp(result, 'return', {}) self.wait_for_open() @@ -215,7 +199,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass): else: self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) - result = self.vm.qmp('blockdev-change-medium', device='drive0', + result = self.vm.qmp('blockdev-change-medium', id=self.device_name, filename=new_img, format=iotests.imgfmt) self.assert_qmp(result, 'return', {}) @@ -235,12 +219,8 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass): 'driver': 'file'}) self.assert_qmp(result, 'return', {}) - if self.device_name is not None: - result = self.vm.qmp('blockdev-open-tray', - id=self.device_name, force=True) - else: - result = self.vm.qmp('blockdev-open-tray', - device='drive0', force=True) + result = self.vm.qmp('blockdev-open-tray', + id=self.device_name, force=True) self.assert_qmp(result, 'return', {}) self.wait_for_open() @@ -253,11 +233,8 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass): else: self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) - if self.device_name is not None: - result = self.vm.qmp('x-blockdev-remove-medium', - id=self.device_name) - else: - result = self.vm.qmp('x-blockdev-remove-medium', device='drive0') + result = self.vm.qmp('blockdev-remove-medium', + id=self.device_name) self.assert_qmp(result, 'return', {}) result = self.vm.qmp('query-block') @@ -265,12 +242,8 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass): self.assert_qmp(result, 'return[0]/tray_open', True) self.assert_qmp_absent(result, 'return[0]/inserted') - if self.device_name is not None: - result = self.vm.qmp('x-blockdev-insert-medium', - id=self.device_name, node_name='new') - else: - result = self.vm.qmp('x-blockdev-insert-medium', - device='drive0', node_name='new') + result = self.vm.qmp('blockdev-insert-medium', + id=self.device_name, node_name='new') self.assert_qmp(result, 'return', {}) result = self.vm.qmp('query-block') @@ -278,10 +251,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass): self.assert_qmp(result, 'return[0]/tray_open', True) self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) - if self.device_name is not None: - result = self.vm.qmp('blockdev-close-tray', id=self.device_name) - else: - result = self.vm.qmp('blockdev-close-tray', device='drive0') + result = self.vm.qmp('blockdev-close-tray', id=self.device_name) self.assert_qmp(result, 'return', {}) self.wait_for_close() @@ -292,7 +262,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass): self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) def test_close_on_closed(self): - result = self.vm.qmp('blockdev-close-tray', device='drive0') + result = self.vm.qmp('blockdev-close-tray', id=self.device_name) # Should be a no-op self.assert_qmp(result, 'return', {}) self.assertEquals(self.vm.get_qmp_events(wait=False), []) @@ -301,7 +271,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass): if not self.has_real_tray: return - result = self.vm.qmp('x-blockdev-remove-medium', device='drive0') + result = self.vm.qmp('blockdev-remove-medium', id=self.device_name) self.assert_qmp(result, 'error/class', 'GenericError') def test_insert_on_closed(self): @@ -315,7 +285,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass): 'driver': 'file'}) self.assert_qmp(result, 'return', {}) - result = self.vm.qmp('x-blockdev-insert-medium', device='drive0', + result = self.vm.qmp('blockdev-insert-medium', id=self.device_name, node_name='new') self.assert_qmp(result, 'error/class', 'GenericError') @@ -326,12 +296,10 @@ class TestInitiallyFilled(GeneralChangeTestsBaseClass): qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k') qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k') self.vm = iotests.VM() - if interface == 'ide': - self.device_name = 'qdev0' - self.vm.add_drive(old_img, 'media=%s' % media, 'none') - self.vm.add_device('ide-cd,drive=drive0,id=%s' % self.device_name) - else: - self.vm.add_drive(old_img, 'media=%s' % media, interface) + self.vm.add_drive(old_img, 'media=%s' % media, 'none') + self.vm.add_device('%s,drive=drive0,id=%s' % + (interface_to_device_name(interface), + self.device_name)) self.vm.launch() def tearDown(self): @@ -347,12 +315,12 @@ class TestInitiallyFilled(GeneralChangeTestsBaseClass): 'driver': 'file'}) self.assert_qmp(result, 'return', {}) - result = self.vm.qmp('blockdev-open-tray', device='drive0') + result = self.vm.qmp('blockdev-open-tray', id=self.device_name) self.assert_qmp(result, 'return', {}) self.wait_for_open() - result = self.vm.qmp('x-blockdev-insert-medium', device='drive0', + result = self.vm.qmp('blockdev-insert-medium', id=self.device_name, node_name='new') self.assert_qmp(result, 'error/class', 'GenericError') @@ -361,7 +329,10 @@ class TestInitiallyEmpty(GeneralChangeTestsBaseClass): def setUp(self, media, interface): qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k') - self.vm = iotests.VM().add_drive(None, 'media=%s' % media, interface) + self.vm = iotests.VM().add_drive(None, 'media=%s' % media, 'none') + self.vm.add_device('%s,drive=drive0,id=%s' % + (interface_to_device_name(interface), + self.device_name)) self.vm.launch() def tearDown(self): @@ -369,12 +340,12 @@ class TestInitiallyEmpty(GeneralChangeTestsBaseClass): os.remove(new_img) def test_remove_on_empty(self): - result = self.vm.qmp('blockdev-open-tray', device='drive0') + result = self.vm.qmp('blockdev-open-tray', id=self.device_name) self.assert_qmp(result, 'return', {}) self.wait_for_open() - result = self.vm.qmp('x-blockdev-remove-medium', device='drive0') + result = self.vm.qmp('blockdev-remove-medium', id=self.device_name) # Should be a no-op self.assert_qmp(result, 'return', {}) @@ -410,6 +381,8 @@ class TestFloppyInitiallyEmpty(TestInitiallyEmpty): self.has_opened = True class TestChangeReadOnly(ChangeBaseClass): + device_name = 'qdev0' + def setUp(self): qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k') qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k') @@ -425,14 +398,15 @@ class TestChangeReadOnly(ChangeBaseClass): def test_ro_ro_retain(self): os.chmod(old_img, 0444) os.chmod(new_img, 0444) - self.vm.add_drive(old_img, 'media=disk,read-only=on', 'floppy') + self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none') + self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) self.vm.launch() result = self.vm.qmp('query-block') self.assert_qmp(result, 'return[0]/inserted/ro', True) self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) - result = self.vm.qmp('blockdev-change-medium', device='drive0', + result = self.vm.qmp('blockdev-change-medium', id=self.device_name, filename=new_img, format=iotests.imgfmt, read_only_mode='retain') @@ -444,14 +418,15 @@ class TestChangeReadOnly(ChangeBaseClass): def test_ro_rw_retain(self): os.chmod(old_img, 0444) - self.vm.add_drive(old_img, 'media=disk,read-only=on', 'floppy') + self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none') + self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) self.vm.launch() result = self.vm.qmp('query-block') self.assert_qmp(result, 'return[0]/inserted/ro', True) self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) - result = self.vm.qmp('blockdev-change-medium', device='drive0', + result = self.vm.qmp('blockdev-change-medium', id=self.device_name, filename=new_img, format=iotests.imgfmt, read_only_mode='retain') @@ -463,14 +438,15 @@ class TestChangeReadOnly(ChangeBaseClass): def test_rw_ro_retain(self): os.chmod(new_img, 0444) - self.vm.add_drive(old_img, 'media=disk', 'floppy') + self.vm.add_drive(old_img, 'media=disk', 'none') + self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) self.vm.launch() result = self.vm.qmp('query-block') self.assert_qmp(result, 'return[0]/inserted/ro', False) self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) - result = self.vm.qmp('blockdev-change-medium', device='drive0', + result = self.vm.qmp('blockdev-change-medium', id=self.device_name, filename=new_img, format=iotests.imgfmt, read_only_mode='retain') @@ -484,7 +460,8 @@ class TestChangeReadOnly(ChangeBaseClass): def test_ro_rw(self): os.chmod(old_img, 0444) - self.vm.add_drive(old_img, 'media=disk,read-only=on', 'floppy') + self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none') + self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) self.vm.launch() result = self.vm.qmp('query-block') @@ -492,7 +469,7 @@ class TestChangeReadOnly(ChangeBaseClass): self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) result = self.vm.qmp('blockdev-change-medium', - device='drive0', + id=self.device_name, filename=new_img, format=iotests.imgfmt, read_only_mode='read-write') @@ -504,7 +481,8 @@ class TestChangeReadOnly(ChangeBaseClass): def test_rw_ro(self): os.chmod(new_img, 0444) - self.vm.add_drive(old_img, 'media=disk', 'floppy') + self.vm.add_drive(old_img, 'media=disk', 'none') + self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) self.vm.launch() result = self.vm.qmp('query-block') @@ -512,7 +490,7 @@ class TestChangeReadOnly(ChangeBaseClass): self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) result = self.vm.qmp('blockdev-change-medium', - device='drive0', + id=self.device_name, filename=new_img, format=iotests.imgfmt, read_only_mode='read-only') @@ -523,7 +501,8 @@ class TestChangeReadOnly(ChangeBaseClass): self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) def test_make_rw_ro(self): - self.vm.add_drive(old_img, 'media=disk', 'floppy') + self.vm.add_drive(old_img, 'media=disk', 'none') + self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) self.vm.launch() result = self.vm.qmp('query-block') @@ -531,7 +510,7 @@ class TestChangeReadOnly(ChangeBaseClass): self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) result = self.vm.qmp('blockdev-change-medium', - device='drive0', + id=self.device_name, filename=new_img, format=iotests.imgfmt, read_only_mode='read-only') @@ -543,7 +522,8 @@ class TestChangeReadOnly(ChangeBaseClass): def test_make_ro_rw(self): os.chmod(new_img, 0444) - self.vm.add_drive(old_img, 'media=disk', 'floppy') + self.vm.add_drive(old_img, 'media=disk', 'none') + self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) self.vm.launch() result = self.vm.qmp('query-block') @@ -551,7 +531,7 @@ class TestChangeReadOnly(ChangeBaseClass): self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) result = self.vm.qmp('blockdev-change-medium', - device='drive0', + id=self.device_name, filename=new_img, format=iotests.imgfmt, read_only_mode='read-write') @@ -563,14 +543,15 @@ class TestChangeReadOnly(ChangeBaseClass): def test_make_rw_ro_by_retain(self): os.chmod(old_img, 0444) - self.vm.add_drive(old_img, 'media=disk,read-only=on', 'floppy') + self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none') + self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) self.vm.launch() result = self.vm.qmp('query-block') self.assert_qmp(result, 'return[0]/inserted/ro', True) self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) - result = self.vm.qmp('blockdev-change-medium', device='drive0', + result = self.vm.qmp('blockdev-change-medium', id=self.device_name, filename=new_img, format=iotests.imgfmt, read_only_mode='retain') @@ -582,14 +563,15 @@ class TestChangeReadOnly(ChangeBaseClass): def test_make_ro_rw_by_retain(self): os.chmod(new_img, 0444) - self.vm.add_drive(old_img, 'media=disk', 'floppy') + self.vm.add_drive(old_img, 'media=disk', 'none') + self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) self.vm.launch() result = self.vm.qmp('query-block') self.assert_qmp(result, 'return[0]/inserted/ro', False) self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) - result = self.vm.qmp('blockdev-change-medium', device='drive0', + result = self.vm.qmp('blockdev-change-medium', id=self.device_name, filename=new_img, format=iotests.imgfmt, read_only_mode='retain') @@ -601,7 +583,8 @@ class TestChangeReadOnly(ChangeBaseClass): def test_rw_ro_cycle(self): os.chmod(new_img, 0444) - self.vm.add_drive(old_img, 'media=disk', 'floppy') + self.vm.add_drive(old_img, 'media=disk', 'none') + self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) self.vm.launch() result = self.vm.qmp('query-block') @@ -620,13 +603,13 @@ class TestChangeReadOnly(ChangeBaseClass): self.assert_qmp(result, 'return[0]/inserted/ro', False) self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) - result = self.vm.qmp('x-blockdev-remove-medium', device='drive0') + result = self.vm.qmp('blockdev-remove-medium', id=self.device_name) self.assert_qmp(result, 'return', {}) result = self.vm.qmp('query-block') self.assert_qmp_absent(result, 'return[0]/inserted') - result = self.vm.qmp('x-blockdev-insert-medium', device='drive0', + result = self.vm.qmp('blockdev-insert-medium', id=self.device_name, node_name='new') self.assert_qmp(result, 'return', {}) @@ -644,11 +627,14 @@ TestInitiallyEmpty = None class TestBlockJobsAfterCycle(ChangeBaseClass): + device_name = 'qdev0' + def setUp(self): - qemu_img('create', '-f', iotests.imgfmt, old_img, '1M') + qemu_img('create', '-f', iotests.imgfmt, old_img, '1440K') self.vm = iotests.VM() self.vm.add_drive_raw("id=drive0,driver=null-co,if=none") + self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) self.vm.launch() result = self.vm.qmp('query-block') @@ -656,7 +642,7 @@ class TestBlockJobsAfterCycle(ChangeBaseClass): # For device-less BBs, calling blockdev-open-tray or blockdev-close-tray # is not necessary - result = self.vm.qmp('x-blockdev-remove-medium', device='drive0') + result = self.vm.qmp('blockdev-remove-medium', id=self.device_name) self.assert_qmp(result, 'return', {}) result = self.vm.qmp('query-block') @@ -669,7 +655,7 @@ class TestBlockJobsAfterCycle(ChangeBaseClass): 'driver': 'file'}) self.assert_qmp(result, 'return', {}) - result = self.vm.qmp('x-blockdev-insert-medium', device='drive0', + result = self.vm.qmp('blockdev-insert-medium', id=self.device_name, node_name='node0') self.assert_qmp(result, 'return', {}) diff --git a/tests/qemu-iotests/130 b/tests/qemu-iotests/130 index e7e43de6d607cce6b9e64505063cc9eed9b3dd3a..2c4b94da1bf567ed0537804a4f5d3a7b311c541e 100755 --- a/tests/qemu-iotests/130 +++ b/tests/qemu-iotests/130 @@ -45,6 +45,8 @@ _supported_fmt qcow2 _supported_proto generic _unsupported_proto vxhs _supported_os Linux +# We are going to use lazy-refcounts +_unsupported_imgopts 'compat=0.10' qemu_comm_method="monitor" diff --git a/tests/qemu-iotests/137 b/tests/qemu-iotests/137 index eb91e517d7d4ac2a15eddb5f3182c1478f686a82..5a01250005f1ebfecfdcdb1a3e3ee64e3d70731b 100755 --- a/tests/qemu-iotests/137 +++ b/tests/qemu-iotests/137 @@ -41,6 +41,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow2 _supported_proto file _supported_os Linux +# We are going to use lazy-refcounts +_unsupported_imgopts 'compat=0.10' _make_test_img 64M diff --git a/tests/qemu-iotests/139 b/tests/qemu-iotests/139 index f8f02808a9b33d069de5e402b27d233447f0f6c2..cc7fe337f3bdc71711965cb90e08a14100b8d0d1 100644 --- a/tests/qemu-iotests/139 +++ b/tests/qemu-iotests/139 @@ -133,7 +133,7 @@ class TestBlockdevDel(iotests.QMPTestCase): # Insert a BlockDriverState def insertDrive(self, device, node): self.checkBlockDriverState(node) - result = self.vm.qmp('x-blockdev-insert-medium', + result = self.vm.qmp('blockdev-insert-medium', id = device, node_name = node) self.assert_qmp(result, 'return', {}) self.checkBlockDriverState(node) diff --git a/tests/qemu-iotests/155 b/tests/qemu-iotests/155 index 0b86ea4e5c847c61f8494d329b2c06c08a6cc257..fc9fa975be1776994d4dbda37a14efae36e9476c 100755 --- a/tests/qemu-iotests/155 +++ b/tests/qemu-iotests/155 @@ -51,36 +51,30 @@ class BaseClass(iotests.QMPTestCase): target_real_backing = None def setUp(self): - qemu_img('create', '-f', iotests.imgfmt, back0_img, '1M') + qemu_img('create', '-f', iotests.imgfmt, back0_img, '1440K') qemu_img('create', '-f', iotests.imgfmt, '-b', back0_img, back1_img) qemu_img('create', '-f', iotests.imgfmt, '-b', back1_img, back2_img) qemu_img('create', '-f', iotests.imgfmt, '-b', back2_img, source_img) self.vm = iotests.VM() - self.vm.add_drive(None, '', 'none') - self.vm.launch() - # Add the BDS via blockdev-add so it stays around after the mirror block # job has been completed - result = self.vm.qmp('blockdev-add', - node_name='source', - driver=iotests.imgfmt, - file={'driver': 'file', - 'filename': source_img}) - self.assert_qmp(result, 'return', {}) - - result = self.vm.qmp('x-blockdev-insert-medium', - device='drive0', node_name='source') - self.assert_qmp(result, 'return', {}) + blockdev = {'node-name': 'source', + 'driver': iotests.imgfmt, + 'file': {'driver': 'file', + 'filename': source_img}} + self.vm.add_blockdev(self.qmp_to_opts(blockdev)) + self.vm.add_device('floppy,id=qdev0,drive=source') + self.vm.launch() self.assertIntactSourceBackingChain() if self.existing: if self.target_backing: qemu_img('create', '-f', iotests.imgfmt, - '-b', self.target_backing, target_img, '1M') + '-b', self.target_backing, target_img, '1440K') else: - qemu_img('create', '-f', iotests.imgfmt, target_img, '1M') + qemu_img('create', '-f', iotests.imgfmt, target_img, '1440K') if self.cmd == 'blockdev-mirror': options = { 'node-name': 'target', @@ -104,11 +98,11 @@ class BaseClass(iotests.QMPTestCase): except OSError: pass - def findBlockNode(self, node_name, id=None): - if id: + def findBlockNode(self, node_name, qdev=None): + if qdev: result = self.vm.qmp('query-block') for device in result['return']: - if device['device'] == id: + if device['qdev'] == qdev: if node_name: self.assert_qmp(device, 'inserted/node-name', node_name) return device['inserted'] @@ -118,7 +112,7 @@ class BaseClass(iotests.QMPTestCase): if node['node-name'] == node_name: return node - self.fail('Cannot find node %s/%s' % (id, node_name)) + self.fail('Cannot find node %s/%s' % (qdev, node_name)) def assertIntactSourceBackingChain(self): node = self.findBlockNode('source') @@ -155,22 +149,23 @@ class BaseClass(iotests.QMPTestCase): class MirrorBaseClass(BaseClass): def runMirror(self, sync): if self.cmd == 'blockdev-mirror': - result = self.vm.qmp(self.cmd, device='drive0', sync=sync, - target='target') + result = self.vm.qmp(self.cmd, job_id='mirror-job', device='source', + sync=sync, target='target') else: if self.existing: mode = 'existing' else: mode = 'absolute-paths' - result = self.vm.qmp(self.cmd, device='drive0', sync=sync, - target=target_img, format=iotests.imgfmt, - mode=mode, node_name='target') + result = self.vm.qmp(self.cmd, job_id='mirror-job', device='source', + sync=sync, target=target_img, + format=iotests.imgfmt, mode=mode, + node_name='target') self.assert_qmp(result, 'return', {}) self.vm.event_wait('BLOCK_JOB_READY') - result = self.vm.qmp('block-job-complete', device='drive0') + result = self.vm.qmp('block-job-complete', device='mirror-job') self.assert_qmp(result, 'return', {}) self.vm.event_wait('BLOCK_JOB_COMPLETED') @@ -178,21 +173,21 @@ class MirrorBaseClass(BaseClass): def testFull(self): self.runMirror('full') - node = self.findBlockNode('target', 'drive0') + node = self.findBlockNode('target', 'qdev0') self.assertCorrectBackingImage(node, None) self.assertIntactSourceBackingChain() def testTop(self): self.runMirror('top') - node = self.findBlockNode('target', 'drive0') + node = self.findBlockNode('target', 'qdev0') self.assertCorrectBackingImage(node, back2_img) self.assertIntactSourceBackingChain() def testNone(self): self.runMirror('none') - node = self.findBlockNode('target', 'drive0') + node = self.findBlockNode('target', 'qdev0') self.assertCorrectBackingImage(node, source_img) self.assertIntactSourceBackingChain() @@ -233,17 +228,18 @@ class TestCommit(BaseClass): existing = False def testCommit(self): - result = self.vm.qmp('block-commit', device='drive0', base=back1_img) + result = self.vm.qmp('block-commit', job_id='commit-job', + device='source', base=back1_img) self.assert_qmp(result, 'return', {}) self.vm.event_wait('BLOCK_JOB_READY') - result = self.vm.qmp('block-job-complete', device='drive0') + result = self.vm.qmp('block-job-complete', device='commit-job') self.assert_qmp(result, 'return', {}) self.vm.event_wait('BLOCK_JOB_COMPLETED') - node = self.findBlockNode(None, 'drive0') + node = self.findBlockNode(None, 'qdev0') self.assert_qmp(node, 'image' + '/backing-image' * 0 + '/filename', back1_img) self.assert_qmp(node, 'image' + '/backing-image' * 1 + '/filename', diff --git a/tests/qemu-iotests/176 b/tests/qemu-iotests/176 index b8dc17c59205d2a8a44e3a6d79b035cf09503ac8..d38b3aeb919b8d73efeec19cdb585871e09f2bcf 100755 --- a/tests/qemu-iotests/176 +++ b/tests/qemu-iotests/176 @@ -48,6 +48,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow2 _supported_proto file _supported_os Linux +# Persistent dirty bitmaps require compat=1.1 +_unsupported_imgopts 'compat=0.10' function run_qemu() { diff --git a/tests/qemu-iotests/177 b/tests/qemu-iotests/177 index 28990977f1a42f99e9a91b50fa971aef47c7e15a..396986da8941ae3d1508fe9114d615daf887de1a 100755 --- a/tests/qemu-iotests/177 +++ b/tests/qemu-iotests/177 @@ -2,7 +2,7 @@ # # Test corner cases with unusual block geometries # -# Copyright (C) 2016-2017 Red Hat, Inc. +# Copyright (C) 2016-2018 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 @@ -37,13 +37,15 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 . ./common.rc . ./common.filter +# This test is runnable under compat=0.10; see test 204 for additional +# tests specific to compat=1.1. + _supported_fmt qcow2 _supported_proto file CLUSTER_SIZE=1M size=128M options=driver=blkdebug,image.driver=qcow2 -nested_opts=image.file.driver=file,image.file.filename=$TEST_IMG echo echo "== setting up files ==" @@ -51,7 +53,7 @@ echo "== setting up files ==" TEST_IMG="$TEST_IMG.base" _make_test_img $size $QEMU_IO -c "write -P 11 0 $size" "$TEST_IMG.base" | _filter_qemu_io _make_test_img -b "$TEST_IMG.base" -$QEMU_IO -c "write -P 22 0 110M" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "write -P 22 0 $size" "$TEST_IMG" | _filter_qemu_io # Limited to 64k max-transfer echo @@ -81,13 +83,6 @@ limits=align=512,opt-write-zero=15M,max-write-zero=15M,opt-discard=15M,max-disca $QEMU_IO -c "open -o $options,$limits blkdebug::$TEST_IMG" \ -c "discard 80000001 30M" | _filter_qemu_io -echo -echo "== block status smaller than alignment ==" -limits=align=4k -$QEMU_IO -c "open -o $options,$limits blkdebug::$TEST_IMG" \ - -c "alloc 1 1" -c "alloc 0x6dffff0 1000" -c "alloc 127m 5P" \ - -c map | _filter_qemu_io - echo echo "== verify image content ==" @@ -110,13 +105,10 @@ function verify_io() echo read -P 0 32M 32M echo read -P 22 64M 13M echo read -P $discarded 77M 29M - echo read -P 22 106M 4M - echo read -P 11 110M 18M + echo read -P 22 106M 22M } verify_io | $QEMU_IO -r "$TEST_IMG" | _filter_qemu_io -$QEMU_IMG map --image-opts "$options,$nested_opts,align=4k" \ - | _filter_qemu_img_map _check_test_img diff --git a/tests/qemu-iotests/177.out b/tests/qemu-iotests/177.out index f788b55e20f8c37661fa56e3654b6fcb43a066ed..e887542678ba0ea6cc869fdc7c9703b671564b2c 100644 --- a/tests/qemu-iotests/177.out +++ b/tests/qemu-iotests/177.out @@ -5,8 +5,8 @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728 wrote 134217728/134217728 bytes at offset 0 128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base -wrote 115343360/115343360 bytes at offset 0 -110 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 134217728/134217728 bytes at offset 0 +128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) == constrained alignment and max-transfer == wrote 131072/131072 bytes at offset 1000 @@ -26,13 +26,6 @@ wrote 33554432/33554432 bytes at offset 33554432 discard 31457280/31457280 bytes at offset 80000001 30 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -== block status smaller than alignment == -1/1 bytes allocated at offset 1 bytes -16/1000 bytes allocated at offset 110 MiB -0/1048576 bytes allocated at offset 127 MiB -110 MiB (0x6e00000) bytes allocated at offset 0 bytes (0x0) -18 MiB (0x1200000) bytes not allocated at offset 110 MiB (0x6e00000) - == verify image content == read 1000/1000 bytes at offset 0 1000 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -50,14 +43,7 @@ read 13631488/13631488 bytes at offset 67108864 13 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) read 30408704/30408704 bytes at offset 80740352 29 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -read 4194304/4194304 bytes at offset 111149056 -4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -read 18874368/18874368 bytes at offset 115343360 -18 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -Offset Length File -0 0x800000 TEST_DIR/t.IMGFMT -0x900000 0x2400000 TEST_DIR/t.IMGFMT -0x3c00000 0x1100000 TEST_DIR/t.IMGFMT -0x6a00000 0x400000 TEST_DIR/t.IMGFMT +read 23068672/23068672 bytes at offset 111149056 +22 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) No errors were found on the image. *** done diff --git a/tests/qemu-iotests/184 b/tests/qemu-iotests/184 index ee96c99af33bc689e6dcf1ffd4194e260a4176ed..2b68284d58faa89ae09a99f802760357dcfa58f9 100755 --- a/tests/qemu-iotests/184 +++ b/tests/qemu-iotests/184 @@ -27,18 +27,12 @@ echo "QA output created by $seq" here=`pwd` status=1 # failure is the default! -_cleanup() -{ - _cleanup_test_img -} -trap "_cleanup; exit \$status" 0 1 2 3 15 +trap "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 function do_run_qemu() @@ -55,7 +49,6 @@ function run_qemu() | _filter_actual_image_size } -_make_test_img 64M test_throttle=$($QEMU_IMG --help|grep throttle) [ "$test_throttle" = "" ] && _supported_fmt throttle @@ -66,12 +59,8 @@ run_qemu <. + +seq=`basename $0` +echo "QA output created by $seq" + +status=1 # failure is the default! + +MIG_SOCKET="${TEST_DIR}/migrate" + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter +. ./common.qemu + +_cleanup() +{ + rm -f "${MIG_SOCKET}" + _cleanup_test_img + _cleanup_qemu +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_supported_fmt qcow2 +_supported_proto generic +_supported_os Linux + +# Internal snapshots are (currently) impossible with refcount_bits=1 +# This was taken from test 080 +_unsupported_imgopts 'refcount_bits=1[^0-9]' + +size=64M +_make_test_img $size + +echo +echo === Starting VMs === +echo + +qemu_comm_method="monitor" + +if [ "$IMGOPTSSYNTAX" = "true" ]; then + _launch_qemu \ + -drive "${TEST_IMG}",cache=${CACHEMODE},id=disk +else + _launch_qemu \ + -drive file="${TEST_IMG}",cache=${CACHEMODE},driver=$IMGFMT,id=disk +fi +src=$QEMU_HANDLE + +if [ "$IMGOPTSSYNTAX" = "true" ]; then + _launch_qemu \ + -drive "${TEST_IMG}",cache=${CACHEMODE},id=disk \ + -incoming "unix:${MIG_SOCKET}" +else + _launch_qemu \ + -drive file="${TEST_IMG}",cache=${CACHEMODE},driver=$IMGFMT,id=disk \ + -incoming "unix:${MIG_SOCKET}" +fi +dest=$QEMU_HANDLE + +echo +echo === Set \'migrate_set_capability postcopy-ram on\' and migrate === +echo + +silent=yes +_send_qemu_cmd $dest 'migrate_set_capability postcopy-ram on' "(qemu)" +_send_qemu_cmd $src 'migrate_set_capability postcopy-ram on' "(qemu)" +_send_qemu_cmd $src "migrate -d unix:${MIG_SOCKET}" "(qemu)" + +QEMU_COMM_TIMEOUT=1 qemu_cmd_repeat=10 silent=yes \ + _send_qemu_cmd $src "info migrate" "completed\|failed" +silent=yes _send_qemu_cmd $src "" "(qemu)" + +echo +echo === Check if migration was successful === +echo + +QEMU_COMM_TIMEOUT=1 silent=yes \ + _send_qemu_cmd $src "info migrate" "completed" +silent=yes _send_qemu_cmd $src "" "(qemu)" + +echo +echo === On destination, execute savevm and loadvm === +echo + +silent= +_send_qemu_cmd $dest 'savevm state1' "(qemu)" +_send_qemu_cmd $dest 'loadvm state1' "(qemu)" + +echo +echo === Shut down and check image === +echo + +_send_qemu_cmd $src 'quit' "" +_send_qemu_cmd $dest 'quit' "" +wait=1 _cleanup_qemu + +_check_test_img + +# success, all done +echo "*** done" +status=0 diff --git a/tests/qemu-iotests/201.out b/tests/qemu-iotests/201.out new file mode 100644 index 0000000000000000000000000000000000000000..9faf06f996a0cf732c459a2ad5600e40e63187af --- /dev/null +++ b/tests/qemu-iotests/201.out @@ -0,0 +1,23 @@ +QA output created by 201 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 + +=== Starting VMs === + + +=== Set 'migrate_set_capability postcopy-ram on' and migrate === + + +=== Check if migration was successful === + + +=== On destination, execute savevm and loadvm === + +(qemu) savevm state1 +(qemu) loadvm state1 + +=== Shut down and check image === + +(qemu) quit +(qemu) quit +No errors were found on the image. +*** done diff --git a/tests/qemu-iotests/204 b/tests/qemu-iotests/204 new file mode 100755 index 0000000000000000000000000000000000000000..feb69d2ada6b132ef4789d1e69cf30f92d709ada --- /dev/null +++ b/tests/qemu-iotests/204 @@ -0,0 +1,119 @@ +#!/bin/bash +# +# Test corner cases with unusual block geometries +# +# Copyright (C) 2016-2018 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 . +# + +# creator +owner=eblake@redhat.com + +seq=`basename $0` +echo "QA output created by $seq" + +here=`pwd` +status=1 # failure is the default! + +_cleanup() +{ + _cleanup_test_img +} +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 +# This test assumes that discard leaves zero clusters; see test 177 for +# other tests that also work in older images +_unsupported_imgopts 'compat=0.10' + +CLUSTER_SIZE=1M +size=128M +options=driver=blkdebug,image.driver=qcow2 +nested_opts=image.file.driver=file,image.file.filename=$TEST_IMG + +echo +echo "== setting up files ==" + +TEST_IMG="$TEST_IMG.base" _make_test_img $size +$QEMU_IO -c "write -P 11 0 $size" "$TEST_IMG.base" | _filter_qemu_io +_make_test_img -b "$TEST_IMG.base" +$QEMU_IO -c "write -P 22 0 110M" "$TEST_IMG" | _filter_qemu_io + +# Limited to 64k max-transfer +echo +echo "== constrained alignment and max-transfer ==" +limits=align=4k,max-transfer=64k +$QEMU_IO -c "open -o $options,$limits blkdebug::$TEST_IMG" \ + -c "write -P 33 1000 128k" -c "read -P 33 1000 128k" | _filter_qemu_io + +echo +echo "== write zero with constrained max-transfer ==" +limits=align=512,max-transfer=64k,opt-write-zero=$CLUSTER_SIZE +$QEMU_IO -c "open -o $options,$limits blkdebug::$TEST_IMG" \ + -c "write -z 8003584 2093056" | _filter_qemu_io + +# non-power-of-2 write-zero/discard alignments +echo +echo "== non-power-of-2 write zeroes limits ==" + +limits=align=512,opt-write-zero=15M,max-write-zero=15M,opt-discard=15M,max-discard=15M +$QEMU_IO -c "open -o $options,$limits blkdebug::$TEST_IMG" \ + -c "write -z 32M 32M" | _filter_qemu_io + +echo +echo "== non-power-of-2 discard limits ==" + +limits=align=512,opt-write-zero=15M,max-write-zero=15M,opt-discard=15M,max-discard=15M +$QEMU_IO -c "open -o $options,$limits blkdebug::$TEST_IMG" \ + -c "discard 80000001 30M" | _filter_qemu_io + +echo +echo "== block status smaller than alignment ==" +limits=align=4k +$QEMU_IO -c "open -o $options,$limits blkdebug::$TEST_IMG" \ + -c "alloc 1 1" -c "alloc 0x6dffff0 1000" -c "alloc 127m 5P" \ + -c map | _filter_qemu_io + +echo +echo "== verify image content ==" + +function verify_io() +{ + echo read -P 22 0 1000 + echo read -P 33 1000 128k + echo read -P 22 132072 7871512 + echo read -P 0 8003584 2093056 + echo read -P 22 10096640 23457792 + echo read -P 0 32M 32M + echo read -P 22 64M 13M + echo read -P 0 77M 29M + echo read -P 22 106M 4M + echo read -P 11 110M 18M +} + +verify_io | $QEMU_IO -r "$TEST_IMG" | _filter_qemu_io +$QEMU_IMG map --image-opts "$options,$nested_opts,align=4k" \ + | _filter_qemu_img_map + +_check_test_img + +# success, all done +echo "*** done" +status=0 diff --git a/tests/qemu-iotests/204.out b/tests/qemu-iotests/204.out new file mode 100644 index 0000000000000000000000000000000000000000..f3a10fbe90356f707efd209c682b557ed9005920 --- /dev/null +++ b/tests/qemu-iotests/204.out @@ -0,0 +1,63 @@ +QA output created by 204 + +== setting up files == +Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728 +wrote 134217728/134217728 bytes at offset 0 +128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base +wrote 115343360/115343360 bytes at offset 0 +110 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +== constrained alignment and max-transfer == +wrote 131072/131072 bytes at offset 1000 +128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 131072/131072 bytes at offset 1000 +128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +== write zero with constrained max-transfer == +wrote 2093056/2093056 bytes at offset 8003584 +1.996 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +== non-power-of-2 write zeroes limits == +wrote 33554432/33554432 bytes at offset 33554432 +32 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +== non-power-of-2 discard limits == +discard 31457280/31457280 bytes at offset 80000001 +30 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +== block status smaller than alignment == +1/1 bytes allocated at offset 1 bytes +16/1000 bytes allocated at offset 110 MiB +0/1048576 bytes allocated at offset 127 MiB +110 MiB (0x6e00000) bytes allocated at offset 0 bytes (0x0) +18 MiB (0x1200000) bytes not allocated at offset 110 MiB (0x6e00000) + +== verify image content == +read 1000/1000 bytes at offset 0 +1000 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 131072/131072 bytes at offset 1000 +128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 7871512/7871512 bytes at offset 132072 +7.507 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 2093056/2093056 bytes at offset 8003584 +1.996 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 23457792/23457792 bytes at offset 10096640 +22.371 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 33554432/33554432 bytes at offset 33554432 +32 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 13631488/13631488 bytes at offset 67108864 +13 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 30408704/30408704 bytes at offset 80740352 +29 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 4194304/4194304 bytes at offset 111149056 +4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 18874368/18874368 bytes at offset 115343360 +18 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +Offset Length File +0 0x800000 TEST_DIR/t.IMGFMT +0x900000 0x2400000 TEST_DIR/t.IMGFMT +0x3c00000 0x1100000 TEST_DIR/t.IMGFMT +0x6a00000 0x400000 TEST_DIR/t.IMGFMT +No errors were found on the image. +*** done diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter index f08248bfd9387ef387b8568c508299ca212ae611..cb2be23340f60ef3a09a73444f3634228546ecd5 100644 --- a/tests/qemu-iotests/common.filter +++ b/tests/qemu-iotests/common.filter @@ -140,6 +140,15 @@ _filter_img_create() _filter_img_info() { + if [[ "$1" == "--format-specific" ]]; then + local format_specific=1 + shift + else + local format_specific=0 + fi + + discard=0 + regex_json_spec_start='^ *"format-specific": \{' sed -e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \ -e "s#$TEST_DIR#TEST_DIR#g" \ -e "s#$IMGFMT#IMGFMT#g" \ @@ -160,7 +169,25 @@ _filter_img_info() -e "/block_state_zero: \\(on\\|off\\)/d" \ -e "/log_size: [0-9]\\+/d" \ -e "s/iters: [0-9]\\+/iters: 1024/" \ - -e "s/uuid: [-a-f0-9]\\+/uuid: 00000000-0000-0000-0000-000000000000/" + -e "s/uuid: [-a-f0-9]\\+/uuid: 00000000-0000-0000-0000-000000000000/" | \ + while IFS='' read -r line; do + if [[ $format_specific == 1 ]]; then + discard=0 + elif [[ $line == "Format specific information:" ]]; then + discard=1 + elif [[ $line =~ $regex_json_spec_start ]]; then + discard=2 + regex_json_spec_end="^${line%%[^ ]*}\\},? *$" + fi + if [[ $discard == 0 ]]; then + echo "$line" + elif [[ $discard == 1 && ! $line ]]; then + echo + discard=0 + elif [[ $discard == 2 && $line =~ $regex_json_spec_end ]]; then + discard=0 + fi + done } # filter out offsets and file names from qemu-img map; good for both diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc index dbae7d74ba082800e9b586dbba89abd70054eefa..6fa0495e10c84f97d320bc52cb33db65f73b063f 100644 --- a/tests/qemu-iotests/common.rc +++ b/tests/qemu-iotests/common.rc @@ -338,7 +338,7 @@ _img_info() -e "s#$IMGFMT#IMGFMT#g" \ -e "/^disk size:/ D" \ -e "/actual-size/ D" | \ - while IFS='' read line; do + while IFS='' read -r line; do if [[ $format_specific == 1 ]]; then discard=0 elif [[ $line == "Format specific information:" ]]; then diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 93d96fb22fdb974e447350a9c10340f357ffa630..8fc4f62cca6906487581c7a8e31900015e791297 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -197,5 +197,7 @@ 197 rw auto quick 198 rw auto 200 rw auto +201 rw auto migration 202 rw auto quick 203 rw auto +204 rw auto quick diff --git a/util/osdep.c b/util/osdep.c index 1231f9f8768cc817ef3bee406ef25b0f517ba23e..a73de0e1ba0d126481e980e0d3039d347dd24f86 100644 --- a/util/osdep.c +++ b/util/osdep.c @@ -244,7 +244,9 @@ static int qemu_lock_fcntl(int fd, int64_t start, int64_t len, int fl_type) .l_type = fl_type, }; qemu_probe_lock_ops(); - ret = fcntl(fd, fcntl_op_setlk, &fl); + do { + ret = fcntl(fd, fcntl_op_setlk, &fl); + } while (ret == -1 && errno == EINTR); return ret == -1 ? -errno : 0; }