diff options
47 files changed, 473 insertions, 262 deletions
diff --git a/block.c b/block.c index 1dbc060c3f..743c349100 100644 --- a/block.c +++ b/block.c @@ -3145,6 +3145,7 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, int is_protocol = 0; BlockDriverState *curr_bs = NULL; BlockDriverState *retval = NULL; + Error *local_error = NULL; if (!bs || !bs->drv || !backing_file) { return NULL; @@ -3165,6 +3166,18 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, retval = curr_bs->backing->bs; break; } + /* Also check against the full backing filename for the image */ + bdrv_get_full_backing_filename(curr_bs, backing_file_full, PATH_MAX, + &local_error); + if (local_error == NULL) { + if (strcmp(backing_file, backing_file_full) == 0) { + retval = curr_bs->backing->bs; + break; + } + } else { + error_free(local_error); + local_error = NULL; + } } else { /* If not an absolute filename path, make it relative to the current * image's filename path */ @@ -3235,19 +3248,18 @@ void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp) if (!(bs->open_flags & BDRV_O_INACTIVE)) { return; } - bs->open_flags &= ~BDRV_O_INACTIVE; - if (bs->drv->bdrv_invalidate_cache) { - bs->drv->bdrv_invalidate_cache(bs, &local_err); + QLIST_FOREACH(child, &bs->children, next) { + bdrv_invalidate_cache(child->bs, &local_err); if (local_err) { - bs->open_flags |= BDRV_O_INACTIVE; error_propagate(errp, local_err); return; } } - QLIST_FOREACH(child, &bs->children, next) { - bdrv_invalidate_cache(child->bs, &local_err); + bs->open_flags &= ~BDRV_O_INACTIVE; + if (bs->drv->bdrv_invalidate_cache) { + bs->drv->bdrv_invalidate_cache(bs, &local_err); if (local_err) { bs->open_flags |= BDRV_O_INACTIVE; error_propagate(errp, local_err); diff --git a/block/nfs.c b/block/nfs.c index a564340d15..689eaa792e 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -108,12 +108,13 @@ static int nfs_parse_uri(const char *filename, QDict *options, Error **errp) qdict_put(options, "path", qstring_from_str(uri->path)); for (i = 0; i < qp->n; i++) { + unsigned long long val; if (!qp->p[i].value) { error_setg(errp, "Value for NFS parameter expected: %s", qp->p[i].name); goto out; } - if (parse_uint_full(qp->p[i].value, NULL, 0)) { + if (parse_uint_full(qp->p[i].value, &val, 0)) { error_setg(errp, "Illegal value for NFS parameter: %s", qp->p[i].name); goto out; @@ -358,27 +359,27 @@ static QemuOptsList runtime_opts = { .help = "Path of the image on the host", }, { - .name = "uid", + .name = "user", .type = QEMU_OPT_NUMBER, .help = "UID value to use when talking to the server", }, { - .name = "gid", + .name = "group", .type = QEMU_OPT_NUMBER, .help = "GID value to use when talking to the server", }, { - .name = "tcp-syncnt", + .name = "tcp-syn-count", .type = QEMU_OPT_NUMBER, .help = "Number of SYNs to send during the session establish", }, { - .name = "readahead", + .name = "readahead-size", .type = QEMU_OPT_NUMBER, .help = "Set the readahead size in bytes", }, { - .name = "pagecache", + .name = "page-cache-size", .type = QEMU_OPT_NUMBER, .help = "Set the pagecache size in bytes", }, @@ -507,29 +508,29 @@ static int64_t nfs_client_open(NFSClient *client, QDict *options, goto fail; } - if (qemu_opt_get(opts, "uid")) { - client->uid = qemu_opt_get_number(opts, "uid", 0); + if (qemu_opt_get(opts, "user")) { + client->uid = qemu_opt_get_number(opts, "user", 0); nfs_set_uid(client->context, client->uid); } - if (qemu_opt_get(opts, "gid")) { - client->gid = qemu_opt_get_number(opts, "gid", 0); + if (qemu_opt_get(opts, "group")) { + client->gid = qemu_opt_get_number(opts, "group", 0); nfs_set_gid(client->context, client->gid); } - if (qemu_opt_get(opts, "tcp-syncnt")) { - client->tcp_syncnt = qemu_opt_get_number(opts, "tcp-syncnt", 0); + if (qemu_opt_get(opts, "tcp-syn-count")) { + client->tcp_syncnt = qemu_opt_get_number(opts, "tcp-syn-count", 0); nfs_set_tcp_syncnt(client->context, client->tcp_syncnt); } #ifdef LIBNFS_FEATURE_READAHEAD - if (qemu_opt_get(opts, "readahead")) { + if (qemu_opt_get(opts, "readahead-size")) { if (open_flags & BDRV_O_NOCACHE) { error_setg(errp, "Cannot enable NFS readahead " "if cache.direct = on"); goto fail; } - client->readahead = qemu_opt_get_number(opts, "readahead", 0); + client->readahead = qemu_opt_get_number(opts, "readahead-size", 0); if (client->readahead > QEMU_NFS_MAX_READAHEAD_SIZE) { error_report("NFS Warning: Truncating NFS readahead " "size to %d", QEMU_NFS_MAX_READAHEAD_SIZE); @@ -544,13 +545,13 @@ static int64_t nfs_client_open(NFSClient *client, QDict *options, #endif #ifdef LIBNFS_FEATURE_PAGECACHE - if (qemu_opt_get(opts, "pagecache")) { + if (qemu_opt_get(opts, "page-cache-size")) { if (open_flags & BDRV_O_NOCACHE) { error_setg(errp, "Cannot enable NFS pagecache " "if cache.direct = on"); goto fail; } - client->pagecache = qemu_opt_get_number(opts, "pagecache", 0); + client->pagecache = qemu_opt_get_number(opts, "page-cache-size", 0); if (client->pagecache > QEMU_NFS_MAX_PAGECACHE_SIZE) { error_report("NFS Warning: Truncating NFS pagecache " "size to %d pages", QEMU_NFS_MAX_PAGECACHE_SIZE); @@ -803,22 +804,22 @@ static void nfs_refresh_filename(BlockDriverState *bs, QDict *options) qdict_put(opts, "path", qstring_from_str(client->path)); if (client->uid) { - qdict_put(opts, "uid", qint_from_int(client->uid)); + qdict_put(opts, "user", qint_from_int(client->uid)); } if (client->gid) { - qdict_put(opts, "gid", qint_from_int(client->gid)); + qdict_put(opts, "group", qint_from_int(client->gid)); } if (client->tcp_syncnt) { - qdict_put(opts, "tcp-syncnt", - qint_from_int(client->tcp_syncnt)); + qdict_put(opts, "tcp-syn-cnt", + qint_from_int(client->tcp_syncnt)); } if (client->readahead) { - qdict_put(opts, "readahead", - qint_from_int(client->readahead)); + qdict_put(opts, "readahead-size", + qint_from_int(client->readahead)); } if (client->pagecache) { - qdict_put(opts, "pagecache", - qint_from_int(client->pagecache)); + qdict_put(opts, "page-cache-size", + qint_from_int(client->pagecache)); } if (client->debug) { qdict_put(opts, "debug", qint_from_int(client->debug)); diff --git a/block/qapi.c b/block/qapi.c index a62e862f3c..ac480aa93c 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -237,8 +237,8 @@ void bdrv_query_image_info(BlockDriverState *bs, size = bdrv_getlength(bs); if (size < 0) { - error_setg_errno(errp, -size, "Can't get size of device '%s'", - bdrv_get_device_name(bs)); + error_setg_errno(errp, -size, "Can't get image size '%s'", + bs->exact_filename); goto out; } @@ -357,10 +357,6 @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info, qapi_free_BlockInfo(info); } -static BlockStats *bdrv_query_stats(BlockBackend *blk, - const BlockDriverState *bs, - bool query_backing); - static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk) { BlockAcctStats *stats = blk_get_stats(blk); @@ -428,9 +424,18 @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk) } } -static void bdrv_query_bds_stats(BlockStats *s, const BlockDriverState *bs, +static BlockStats *bdrv_query_bds_stats(const BlockDriverState *bs, bool query_backing) { + BlockStats *s = NULL; + + s = g_malloc0(sizeof(*s)); + s->stats = g_malloc0(sizeof(*s->stats)); + + if (!bs) { + return s; + } + if (bdrv_get_node_name(bs)[0]) { s->has_node_name = true; s->node_name = g_strdup(bdrv_get_node_name(bs)); @@ -440,32 +445,12 @@ static void bdrv_query_bds_stats(BlockStats *s, const BlockDriverState *bs, if (bs->file) { s->has_parent = true; - s->parent = bdrv_query_stats(NULL, bs->file->bs, query_backing); + s->parent = bdrv_query_bds_stats(bs->file->bs, query_backing); } if (query_backing && bs->backing) { s->has_backing = true; - s->backing = bdrv_query_stats(NULL, bs->backing->bs, query_backing); - } - -} - -static BlockStats *bdrv_query_stats(BlockBackend *blk, - const BlockDriverState *bs, - bool query_backing) -{ - BlockStats *s; - - s = g_malloc0(sizeof(*s)); - s->stats = g_malloc0(sizeof(*s->stats)); - - if (blk) { - s->has_device = true; - s->device = g_strdup(blk_name(blk)); - bdrv_query_blk_stats(s->stats, blk); - } - if (bs) { - bdrv_query_bds_stats(s, bs, query_backing); + s->backing = bdrv_query_bds_stats(bs->backing->bs, query_backing); } return s; @@ -494,42 +479,44 @@ BlockInfoList *qmp_query_block(Error **errp) return head; } -static bool next_query_bds(BlockBackend **blk, BlockDriverState **bs, - bool query_nodes) -{ - if (query_nodes) { - *bs = bdrv_next_node(*bs); - return !!*bs; - } - - *blk = blk_next(*blk); - *bs = *blk ? blk_bs(*blk) : NULL; - - return !!*blk; -} - BlockStatsList *qmp_query_blockstats(bool has_query_nodes, bool query_nodes, Error **errp) { BlockStatsList *head = NULL, **p_next = &head; - BlockBackend *blk = NULL; - BlockDriverState *bs = NULL; + BlockBackend *blk; + BlockDriverState *bs; /* Just to be safe if query_nodes is not always initialized */ - query_nodes = has_query_nodes && query_nodes; - - while (next_query_bds(&blk, &bs, query_nodes)) { - BlockStatsList *info = g_malloc0(sizeof(*info)); - AioContext *ctx = blk ? blk_get_aio_context(blk) - : bdrv_get_aio_context(bs); + if (has_query_nodes && query_nodes) { + for (bs = bdrv_next_node(NULL); bs; bs = bdrv_next_node(bs)) { + BlockStatsList *info = g_malloc0(sizeof(*info)); + AioContext *ctx = bdrv_get_aio_context(bs); - aio_context_acquire(ctx); - info->value = bdrv_query_stats(blk, bs, !query_nodes); - aio_context_release(ctx); + aio_context_acquire(ctx); + info->value = bdrv_query_bds_stats(bs, false); + aio_context_release(ctx); - *p_next = info; - p_next = &info->next; + *p_next = info; + p_next = &info->next; + } + } else { + for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { + BlockStatsList *info = g_malloc0(sizeof(*info)); + AioContext *ctx = blk_get_aio_context(blk); + BlockStats *s; + + aio_context_acquire(ctx); + s = bdrv_query_bds_stats(blk_bs(blk), true); + s->has_device = true; + s->device = g_strdup(blk_name(blk)); + bdrv_query_blk_stats(s->stats, blk); + aio_context_release(ctx); + + info->value = s; + *p_next = info; + p_next = &info->next; + } } return head; diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index cbfb3fe064..3dbde18612 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -83,6 +83,16 @@ static Qcow2SetRefcountFunc *const set_refcount_funcs[] = { /*********************************************************/ /* refcount handling */ +static void update_max_refcount_table_index(BDRVQcow2State *s) +{ + unsigned i = s->refcount_table_size - 1; + while (i > 0 && (s->refcount_table[i] & REFT_OFFSET_MASK) == 0) { + i--; + } + /* Set s->max_refcount_table_index to the index of the last used entry */ + s->max_refcount_table_index = i; +} + int qcow2_refcount_init(BlockDriverState *bs) { BDRVQcow2State *s = bs->opaque; @@ -111,6 +121,7 @@ int qcow2_refcount_init(BlockDriverState *bs) } for(i = 0; i < s->refcount_table_size; i++) be64_to_cpus(&s->refcount_table[i]); + update_max_refcount_table_index(s); } return 0; fail: @@ -439,6 +450,10 @@ static int alloc_refcount_block(BlockDriverState *bs, } s->refcount_table[refcount_table_index] = new_block; + /* If there's a hole in s->refcount_table then it can happen + * that refcount_table_index < s->max_refcount_table_index */ + s->max_refcount_table_index = + MAX(s->max_refcount_table_index, refcount_table_index); /* The new refcount block may be where the caller intended to put its * data, so let it restart the search. */ @@ -580,6 +595,7 @@ static int alloc_refcount_block(BlockDriverState *bs, s->refcount_table = new_table; s->refcount_table_size = table_size; s->refcount_table_offset = table_offset; + update_max_refcount_table_index(s); /* Free old table. */ qcow2_free_clusters(bs, old_table_offset, old_table_size * sizeof(uint64_t), @@ -2171,6 +2187,7 @@ write_refblocks: s->refcount_table = on_disk_reftable; s->refcount_table_offset = reftable_offset; s->refcount_table_size = reftable_size; + update_max_refcount_table_index(s); return 0; @@ -2383,7 +2400,11 @@ int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset, } if ((chk & QCOW2_OL_REFCOUNT_BLOCK) && s->refcount_table) { - for (i = 0; i < s->refcount_table_size; i++) { + unsigned last_entry = s->max_refcount_table_index; + assert(last_entry < s->refcount_table_size); + assert(last_entry + 1 == s->refcount_table_size || + (s->refcount_table[last_entry + 1] & REFT_OFFSET_MASK) == 0); + for (i = 0; i <= last_entry; i++) { if ((s->refcount_table[i] & REFT_OFFSET_MASK) && overlaps_with(s->refcount_table[i] & REFT_OFFSET_MASK, s->cluster_size)) { @@ -2871,6 +2892,7 @@ int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order, /* Now update the rest of the in-memory information */ old_reftable = s->refcount_table; s->refcount_table = new_reftable; + update_max_refcount_table_index(s); s->refcount_bits = 1 << refcount_order; s->refcount_max = UINT64_C(1) << (s->refcount_bits - 1); diff --git a/block/qcow2.c b/block/qcow2.c index 96fb8a8f16..3e274bd1ba 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2743,6 +2743,7 @@ static int make_completely_empty(BlockDriverState *bs) s->refcount_table_offset = s->cluster_size; s->refcount_table_size = s->cluster_size / sizeof(uint64_t); + s->max_refcount_table_index = 0; g_free(s->refcount_table); s->refcount_table = new_reftable; diff --git a/block/qcow2.h b/block/qcow2.h index 182341483a..f8aeb08794 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -251,6 +251,7 @@ typedef struct BDRVQcow2State { uint64_t *refcount_table; uint64_t refcount_table_offset; uint32_t refcount_table_size; + uint32_t max_refcount_table_index; /* Last used entry in refcount_table */ uint64_t free_cluster_index; uint64_t free_byte_offset; diff --git a/block/vmdk.c b/block/vmdk.c index 7750212969..393c84d8b1 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1361,8 +1361,8 @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset, goto out; } - data->lba = offset >> BDRV_SECTOR_BITS; - data->size = buf_len; + data->lba = cpu_to_le64(offset >> BDRV_SECTOR_BITS); + data->size = cpu_to_le32(buf_len); n_bytes = buf_len + sizeof(VmdkGrainMarker); iov = (struct iovec) { diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index 824fa71ba9..fdf40893aa 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -95,6 +95,8 @@ CONFIG_VERSATILE_PCI=y CONFIG_VERSATILE_I2C=y CONFIG_PCI_GENERIC=y +CONFIG_VFIO_XGMAC=y +CONFIG_VFIO_AMD_XGBE=y CONFIG_SDHCI=y CONFIG_INTEGRATOR_DEBUG=y diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index a92c2f1c36..283c038814 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -113,9 +113,19 @@ static void write_boot_rom(DriveInfo *dinfo, hwaddr addr, size_t rom_size, { BlockBackend *blk = blk_by_legacy_dinfo(dinfo); uint8_t *storage; + int64_t size; - if (rom_size > blk_getlength(blk)) { - rom_size = blk_getlength(blk); + /* The block backend size should have already been 'validated' by + * the creation of the m25p80 object. + */ + size = blk_getlength(blk); + if (size <= 0) { + error_setg(errp, "failed to get flash size"); + return; + } + + if (rom_size > size) { + rom_size = size; } storage = g_new0(uint8_t, rom_size); @@ -138,10 +148,6 @@ static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype, DriveInfo *dinfo = drive_get_next(IF_MTD); qemu_irq cs_line; - /* - * FIXME: check that we are not using a flash module exceeding - * the controller segment size - */ fl->flash = ssi_create_slave_no_init(s->spi, flashtype); if (dinfo) { qdev_prop_set_drive(fl->flash, "drive", blk_by_legacy_dinfo(dinfo), @@ -200,7 +206,9 @@ static void aspeed_board_init(MachineState *machine, /* * create a ROM region using the default mapping window size of - * the flash module. + * the flash module. The window size is 64MB for the AST2400 + * SoC and 128MB for the AST2500 SoC, which is twice as big as + * needed by the flash modules of the Aspeed machines. */ memory_region_init_rom(boot_rom, OBJECT(bmc), "aspeed.boot_rom", fl->size, &error_abort); diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c index 58760f40ca..e05756846e 100644 --- a/hw/arm/vexpress.c +++ b/hw/arm/vexpress.c @@ -452,6 +452,7 @@ static int add_virtio_mmio_node(void *fdt, uint32_t acells, uint32_t scells, acells, addr, scells, size); qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", intc); qemu_fdt_setprop_cells(fdt, nodename, "interrupts", 0, irq, 1); + qemu_fdt_setprop(fdt, nodename, "dma-coherent", NULL, 0); g_free(nodename); if (rc) { return -1; diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 07a10aca40..0835e59bb2 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -90,6 +90,7 @@ static void acpi_dsdt_add_fw_cfg(Aml *scope, const MemMapEntry *fw_cfg_memmap) aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002"))); /* device present, functioning, decoding, not shown in UI */ aml_append(dev, aml_name_decl("_STA", aml_int(0xB))); + aml_append(dev, aml_name_decl("_CCA", aml_int(1))); Aml *crs = aml_resource_template(); aml_append(crs, aml_memory32_fixed(fw_cfg_memmap->base, @@ -135,6 +136,7 @@ static void acpi_dsdt_add_virtio(Aml *scope, Aml *dev = aml_device("VR%02u", i); aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0005"))); aml_append(dev, aml_name_decl("_UID", aml_int(i))); + aml_append(dev, aml_name_decl("_CCA", aml_int(1))); Aml *crs = aml_resource_template(); aml_append(crs, aml_memory32_fixed(base, size, AML_READ_WRITE)); diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 1f216cf3b1..f3440f2ccb 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -471,7 +471,7 @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms) CPU_FOREACH(cpu) { armcpu = ARM_CPU(cpu); if (!arm_feature(&armcpu->env, ARM_FEATURE_PMU) || - !kvm_arm_pmu_create(cpu, PPI(VIRTUAL_PMU_IRQ))) { + (kvm_enabled() && !kvm_arm_pmu_create(cpu, PPI(VIRTUAL_PMU_IRQ)))) { return; } } @@ -797,6 +797,7 @@ static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic) qemu_fdt_setprop_cells(vms->fdt, nodename, "interrupts", GIC_FDT_IRQ_TYPE_SPI, irq, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI); + qemu_fdt_setprop(vms->fdt, nodename, "dma-coherent", NULL, 0); g_free(nodename); } } @@ -928,6 +929,7 @@ static FWCfgState *create_fw_cfg(const VirtMachineState *vms, AddressSpace *as) "compatible", "qemu,fw-cfg-mmio"); qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", 2, base, 2, size); + qemu_fdt_setprop(vms->fdt, nodename, "dma-coherent", NULL, 0); g_free(nodename); return fw_cfg; } diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index 3c19bdadc5..6a17acf639 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -488,7 +488,7 @@ static void ahci_reg_init(AHCIState *s) s->control_regs.cap = (s->ports - 1) | (AHCI_NUM_COMMAND_SLOTS << 8) | (AHCI_SUPPORTED_SPEED_GEN1 << AHCI_SUPPORTED_SPEED) | - HOST_CAP_NCQ | HOST_CAP_AHCI; + HOST_CAP_NCQ | HOST_CAP_AHCI | HOST_CAP_64; s->control_regs.impl = (1 << s->ports) - 1; diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index 087b29e8da..cb515730c5 100644 --- a/hw/ssi/aspeed_smc.c +++ b/hw/ssi/aspeed_smc.c @@ -475,15 +475,15 @@ static uint32_t aspeed_smc_check_segment_addr(const AspeedSMCFlash *fl, AspeedSegments seg; aspeed_smc_reg_to_segment(s->regs[R_SEG_ADDR0 + fl->id], &seg); - if ((addr & (seg.size - 1)) != addr) { + if ((addr % seg.size) != addr) { qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid address 0x%08x for CS%d segment : " "[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n", s->ctrl->name, addr, fl->id, seg.addr, seg.addr + seg.size); + addr %= seg.size; } - addr &= seg.size - 1; return addr; } @@ -536,10 +536,13 @@ static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size) /* * Use fake transfers to model dummy bytes. The value should * be configured to some non-zero value in fast read mode and - * zero in read mode. + * zero in read mode. But, as the HW allows inconsistent + * settings, let's check for fast read mode. */ - for (i = 0; i < aspeed_smc_flash_dummies(fl); i++) { - ssi_transfer(fl->controller->spi, 0xFF); + if (aspeed_smc_flash_mode(fl) == CTRL_FREADMODE) { + for (i = 0; i < aspeed_smc_flash_dummies(fl); i++) { + ssi_transfer(fl->controller->spi, 0xFF); + } } for (i = 0; i < size; i++) { diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs index c25e32b029..05e7fbb93f 100644 --- a/hw/vfio/Makefile.objs +++ b/hw/vfio/Makefile.objs @@ -2,7 +2,7 @@ ifeq ($(CONFIG_LINUX), y) obj-$(CONFIG_SOFTMMU) += common.o obj-$(CONFIG_PCI) += pci.o pci-quirks.o obj-$(CONFIG_SOFTMMU) += platform.o -obj-$(CONFIG_SOFTMMU) += calxeda-xgmac.o -obj-$(CONFIG_SOFTMMU) += amd-xgbe.o +obj-$(CONFIG_VFIO_XGMAC) += calxeda-xgmac.o +obj-$(CONFIG_VFIO_AMD_XGBE) += amd-xgbe.o obj-$(CONFIG_SOFTMMU) += spapr.o endif diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c index 6c771f778b..e9b493b939 100644 --- a/hw/vfio/pci-quirks.c +++ b/hw/vfio/pci-quirks.c @@ -1041,6 +1041,7 @@ static int igd_gen(VFIOPCIDevice *vdev) typedef struct VFIOIGDQuirk { struct VFIOPCIDevice *vdev; uint32_t index; + uint32_t bdsm; } VFIOIGDQuirk; #define IGD_GMCH 0x50 /* Graphics Control Register */ @@ -1185,6 +1186,7 @@ static void vfio_pci_igd_lpc_bridge_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); dc->desc = "VFIO dummy ISA/LPC bridge for IGD assignment"; dc->hotpluggable = false; k->realize = vfio_pci_igd_lpc_bridge_realize; @@ -1304,7 +1306,7 @@ static void vfio_igd_quirk_data_write(void *opaque, hwaddr addr, "BIOS reserved stolen memory. Unsupported BIOS?"); } - val = base | (data & ((1 << 20) - 1)); + val = data - igd->bdsm + base; } else { val = 0; /* upper 32bits of pte, we only enable below 4G PTEs */ } @@ -1503,6 +1505,8 @@ static void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr) igd = quirk->data = g_malloc0(sizeof(*igd)); igd->vdev = vdev; igd->index = ~0; + igd->bdsm = vfio_pci_read_config(&vdev->pdev, IGD_BDSM, 4); + igd->bdsm &= ~((1 << 20) - 1); /* 1MB aligned */ memory_region_init_io(&quirk->mem[0], OBJECT(vdev), &vfio_igd_index_quirk, igd, "vfio-igd-index-quirk", 4); diff --git a/qemu-img.c b/qemu-img.c index 74e3362653..cff22e3005 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -912,7 +912,9 @@ static int img_commit(int argc, char **argv) if (base) { base_bs = bdrv_find_backing_image(bs, base); if (!base_bs) { - error_setg(&local_err, QERR_BASE_NOT_FOUND, base); + error_setg(&local_err, + "Did not find '%s' in the backing chain of '%s'", + base, filename); goto done; } } else { @@ -1966,10 +1968,10 @@ static int img_convert(int argc, char **argv) } if (sn_opts) { - ret = bdrv_snapshot_load_tmp(bs[0], - qemu_opt_get(sn_opts, SNAPSHOT_OPT_ID), - qemu_opt_get(sn_opts, SNAPSHOT_OPT_NAME), - &local_err); + bdrv_snapshot_load_tmp(bs[0], + qemu_opt_get(sn_opts, SNAPSHOT_OPT_ID), + qemu_opt_get(sn_opts, SNAPSHOT_OPT_NAME), + &local_err); } else if (snapshot_name != NULL) { if (bs_n > 1) { error_report("No support for concatenating multiple snapshot"); @@ -3621,24 +3623,24 @@ static int img_bench(int argc, char **argv) break; case 'c': { - char *end; - errno = 0; - count = strtoul(optarg, &end, 0); - if (errno || *end || count > INT_MAX) { + unsigned long res; + + if (qemu_strtoul(optarg, NULL, 0, &res) < 0 || res > INT_MAX) { error_report("Invalid request count specified"); return 1; } + count = res; break; } case 'd': { - char *end; - errno = 0; - depth = strtoul(optarg, &end, 0); - if (errno || *end || depth > INT_MAX) { + unsigned long res; + + if (qemu_strtoul(optarg, NULL, 0, &res) < 0 || res > INT_MAX) { error_report("Invalid queue depth specified"); return 1; } + depth = res; break; } case 'f': @@ -3705,24 +3707,24 @@ static int img_bench(int argc, char **argv) break; case OPTION_PATTERN: { - char *end; - errno = 0; - pattern = strtoul(optarg, &end, 0); - if (errno || *end || pattern > 0xff) { + unsigned long res; + + if (qemu_strtoul(optarg, NULL, 0, &res) < 0 || res > 0xff) { error_report("Invalid pattern byte specified"); return 1; } + pattern = res; break; } case OPTION_FLUSH_INTERVAL: { - char *end; - errno = 0; - flush_interval = strtoul(optarg, &end, 0); - if (errno || *end || flush_interval > INT_MAX) { + unsigned long res; + + if (qemu_strtoul(optarg, NULL, 0, &res) < 0 || res > INT_MAX) { error_report("Invalid flush interval specified"); return 1; } + flush_interval = res; break; } case OPTION_NO_DRAIN: diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c index 95bcde1d88..e415b03cd0 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -388,9 +388,15 @@ create_iovec(BlockBackend *blk, QEMUIOVector *qiov, char **argv, int nr_iov, goto fail; } - if (len > SIZE_MAX) { - printf("Argument '%s' exceeds maximum size %llu\n", arg, - (unsigned long long)SIZE_MAX); + if (len > BDRV_REQUEST_MAX_BYTES) { + printf("Argument '%s' exceeds maximum size %" PRIu64 "\n", arg, + (uint64_t)BDRV_REQUEST_MAX_BYTES); + goto fail; + } + + if (count > BDRV_REQUEST_MAX_BYTES - len) { + printf("The total number of bytes exceed the maximum size %" PRIu64 + "\n", (uint64_t)BDRV_REQUEST_MAX_BYTES); goto fail; } @@ -682,9 +688,9 @@ static int read_f(BlockBackend *blk, int argc, char **argv) if (count < 0) { print_cvtnum_err(count, argv[optind]); return 0; - } else if (count > SIZE_MAX) { + } else if (count > BDRV_REQUEST_MAX_BYTES) { printf("length cannot exceed %" PRIu64 ", given %s\n", - (uint64_t) SIZE_MAX, argv[optind]); + (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]); return 0; } @@ -1004,9 +1010,9 @@ static int write_f(BlockBackend *blk, int argc, char **argv) if (count < 0) { print_cvtnum_err(count, argv[optind]); return 0; - } else if (count > SIZE_MAX) { + } else if (count > BDRV_REQUEST_MAX_BYTES) { printf("length cannot exceed %" PRIu64 ", given %s\n", - (uint64_t) SIZE_MAX, argv[optind]); + (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]); return 0; } diff --git a/qemu-io.c b/qemu-io.c index 23a229f880..427cbaef57 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -595,13 +595,17 @@ int main(int argc, char **argv) exit(1); } opts = qemu_opts_to_qdict(qopts, NULL); - openfile(NULL, flags, writethrough, opts); + if (openfile(NULL, flags, writethrough, opts)) { + exit(1); + } } else { if (format) { opts = qdict_new(); qdict_put(opts, "driver", qstring_from_str(format)); } - openfile(argv[optind], flags, writethrough, opts); + if (openfile(argv[optind], flags, writethrough, opts)) { + exit(1); + } } } command_loop(); diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 4ee250cec6..4a069f6985 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -781,7 +781,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) unset_feature(env, ARM_FEATURE_EL2); } - if (!cpu->has_pmu || !kvm_enabled()) { + if (!cpu->has_pmu) { cpu->has_pmu = false; unset_feature(env, ARM_FEATURE_PMU); } diff --git a/target/arm/cpu.h b/target/arm/cpu.h index c0b3832d74..0956a54e89 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -307,9 +307,9 @@ typedef struct CPUARMState { uint64_t c9_pmcr; /* performance monitor control register */ uint64_t c9_pmcnten; /* perf monitor counter enables */ uint32_t c9_pmovsr; /* perf monitor overflow status */ - uint32_t c9_pmxevtyper; /* perf monitor event type */ uint32_t c9_pmuserenr; /* perf monitor user enable */ - uint32_t c9_pminten; /* perf monitor interrupt enables */ + uint64_t c9_pmselr; /* perf monitor counter selection register */ + uint64_t c9_pminten; /* perf monitor interrupt enables */ union { /* Memory attribute redirection */ struct { #ifdef HOST_WORDS_BIGENDIAN diff --git a/target/arm/helper.c b/target/arm/helper.c index c23df1b133..47250bcf16 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -975,6 +975,17 @@ static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri) return total_ticks - env->cp15.c15_ccnt; } +static void pmselr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* The value of PMSELR.SEL affects the behavior of PMXEVTYPER and + * PMXEVCNTR. We allow [0..31] to be written to PMSELR here; in the + * meanwhile, we check PMSELR.SEL when PMXEVTYPER and PMXEVCNTR are + * accessed. + */ + env->cp15.c9_pmselr = value & 0x1f; +} + static void pmccntr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { @@ -1043,7 +1054,25 @@ static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri, static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { - env->cp15.c9_pmxevtyper = value & 0xff; + /* Attempts to access PMXEVTYPER are CONSTRAINED UNPREDICTABLE when + * PMSELR value is equal to or greater than the number of implemented + * counters, but not equal to 0x1f. We opt to behave as a RAZ/WI. + */ + if (env->cp15.c9_pmselr == 0x1f) { + pmccfiltr_write(env, ri, value); + } +} + +static uint64_t pmxevtyper_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + /* We opt to behave as a RAZ/WI when attempts to access PMXEVTYPER + * are CONSTRAINED UNPREDICTABLE. See comments in pmxevtyper_write(). + */ + if (env->cp15.c9_pmselr == 0x1f) { + return env->cp15.pmccfiltr_el0; + } else { + return 0; + } } static void pmuserenr_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -1194,13 +1223,17 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { /* Unimplemented so WI. */ { .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4, .access = PL0_W, .accessfn = pmreg_access, .type = ARM_CP_NOP }, - /* Since we don't implement any events, writing to PMSELR is UNPREDICTABLE. - * We choose to RAZ/WI. - */ - { .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5, - .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0, - .accessfn = pmreg_access }, #ifndef CONFIG_USER_ONLY + { .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5, + .access = PL0_RW, .type = ARM_CP_ALIAS, + .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmselr), + .accessfn = pmreg_access, .writefn = pmselr_write, + .raw_writefn = raw_write}, + { .name = "PMSELR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 5, + .access = PL0_RW, .accessfn = pmreg_access, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pmselr), + .writefn = pmselr_write, .raw_writefn = raw_write, }, { .name = "PMCCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 0, .access = PL0_RW, .resetvalue = 0, .type = ARM_CP_IO, .readfn = pmccntr_read, .writefn = pmccntr_write32, @@ -1219,10 +1252,12 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0), .resetvalue = 0, }, { .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1, - .access = PL0_RW, - .fieldoffset = offsetof(CPUARMState, cp15.c9_pmxevtyper), - .accessfn = pmreg_access, .writefn = pmxevtyper_write, - .raw_writefn = raw_write }, + .access = PL0_RW, .type = ARM_CP_NO_RAW, .accessfn = pmreg_access, + .writefn = pmxevtyper_write, .readfn = pmxevtyper_read }, + { .name = "PMXEVTYPER_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 1, + .access = PL0_RW, .type = ARM_CP_NO_RAW, .accessfn = pmreg_access, + .writefn = pmxevtyper_write, .readfn = pmxevtyper_read }, /* Unimplemented, RAZ/WI. */ { .name = "PMXEVCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 2, .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0, @@ -1240,9 +1275,17 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .writefn = pmuserenr_write, .raw_writefn = raw_write }, { .name = "PMINTENSET", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 1, .access = PL1_RW, .accessfn = access_tpm, - .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), + .type = ARM_CP_ALIAS, + .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pminten), .resetvalue = 0, .writefn = pmintenset_write, .raw_writefn = raw_write }, + { .name = "PMINTENSET_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 1, + .access = PL1_RW, .accessfn = access_tpm, + .type = ARM_CP_IO, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), + .writefn = pmintenset_write, .raw_writefn = raw_write, + .resetvalue = 0x0 }, { .name = "PMINTENCLR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 2, .access = PL1_RW, .accessfn = access_tpm, .type = ARM_CP_ALIAS, .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), @@ -4590,12 +4633,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) { .name = "ID_AA64DFR0_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0, .access = PL1_R, .type = ARM_CP_CONST, - /* We mask out the PMUVer field, because we don't currently - * implement the PMU. Not advertising it prevents the guest - * from trying to use it and getting UNDEFs on registers we - * don't implement. - */ - .resetvalue = cpu->id_aa64dfr0 & ~0xf00 }, + .resetvalue = cpu->id_aa64dfr0 }, { .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1, .access = PL1_R, .type = ARM_CP_CONST, diff --git a/tests/prom-env-test.c b/tests/prom-env-test.c index 0ba6f48607..bd33bc353d 100644 --- a/tests/prom-env-test.c +++ b/tests/prom-env-test.c @@ -30,8 +30,8 @@ static void check_guest_memory(void) uint32_t signature; int i; - /* Poll until code has run and modified memory. Wait at most 30 seconds */ - for (i = 0; i < 10000; ++i) { + /* Poll until code has run and modified memory. Wait at most 120 seconds */ + for (i = 0; i < 12000; ++i) { signature = readl(ADDRESS); if (signature == MAGIC) { break; @@ -45,9 +45,14 @@ static void check_guest_memory(void) static void test_machine(const void *machine) { char *args; + const char *extra_args; - args = g_strdup_printf("-M %s,accel=tcg -prom-env 'boot-command=%x %x l!'", - (const char *)machine, MAGIC, ADDRESS); + /* The pseries firmware boots much faster without the default devices */ + extra_args = strcmp(machine, "pseries") == 0 ? "-nodefaults" : ""; + + args = g_strdup_printf("-M %s,accel=tcg %s -prom-env 'use-nvramrc?=true' " + "-prom-env 'nvramrc=%x %x l!' ", + (const char *)machine, extra_args, MAGIC, ADDRESS); qtest_start(args); check_guest_memory(); diff --git a/tests/qemu-iotests/.gitignore b/tests/qemu-iotests/.gitignore index 0711cbdbf3..da62054000 100644 --- a/tests/qemu-iotests/.gitignore +++ b/tests/qemu-iotests/.gitignore @@ -1,5 +1,5 @@ check.log -check.time +check.time* common.env *.out.bad *.notrun diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out index 678adb4379..6154509bc3 100644 --- a/tests/qemu-iotests/059.out +++ b/tests/qemu-iotests/059.out @@ -3,17 +3,14 @@ QA output created by 059 === Testing invalid granularity === Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 can't open device TEST_DIR/t.vmdk: Invalid granularity, image may be corrupt -no file open, try 'help open' === Testing too big L2 table size === Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 can't open device TEST_DIR/t.vmdk: L2 table size too big -no file open, try 'help open' === Testing too big L1 table size === Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 can't open device TEST_DIR/t.vmdk: L1 size too big -no file open, try 'help open' === Testing monolithicFlat creation and opening === Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 subformat=monolithicFlat @@ -2361,5 +2358,5 @@ Offset Length Mapped to File 0x140000000 0x10000 0x50000 TEST_DIR/iotest-version3-s003.vmdk === Testing afl image with a very large capacity === -qemu-img: Can't get size of device 'image': File too large +qemu-img: Can't get image size 'TEST_DIR/afl9.IMGFMT': File too large *** done diff --git a/tests/qemu-iotests/070.out b/tests/qemu-iotests/070.out index 131a5b17dc..c269d99483 100644 --- a/tests/qemu-iotests/070.out +++ b/tests/qemu-iotests/070.out @@ -4,7 +4,6 @@ QA output created by 070 can't open device TEST_DIR/iotest-dirtylog-10G-4M.vhdx: VHDX image file 'TEST_DIR/iotest-dirtylog-10G-4M.vhdx' opened read-only, but contains a log that needs to be replayed To replay the log, run: qemu-img check -r all 'TEST_DIR/iotest-dirtylog-10G-4M.vhdx' - no file open, try 'help open' === Verify open image replays log === read 18874368/18874368 bytes at offset 0 18 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) diff --git a/tests/qemu-iotests/075.out b/tests/qemu-iotests/075.out index 87beae4e3c..b234b758e0 100644 --- a/tests/qemu-iotests/075.out +++ b/tests/qemu-iotests/075.out @@ -10,29 +10,22 @@ read 512/512 bytes at offset 1048064 == block_size must be a multiple of 512 == can't open device TEST_DIR/simple-pattern.cloop: block_size 513 must be a multiple of 512 -no file open, try 'help open' == block_size cannot be zero == can't open device TEST_DIR/simple-pattern.cloop: block_size cannot be zero -no file open, try 'help open' == huge block_size === can't open device TEST_DIR/simple-pattern.cloop: block_size 4294966784 must be 64 MB or less -no file open, try 'help open' == offsets_size overflow === can't open device TEST_DIR/simple-pattern.cloop: n_blocks 4294967295 must be 536870911 or less -no file open, try 'help open' == refuse images that require too many offsets === can't open device TEST_DIR/simple-pattern.cloop: image requires too many offsets, try increasing block size -no file open, try 'help open' == refuse images with non-monotonically increasing offsets == can't open device TEST_DIR/simple-pattern.cloop: offsets not monotonically increasing at index 1, image file is corrupt -no file open, try 'help open' == refuse images with invalid compressed block size == can't open device TEST_DIR/simple-pattern.cloop: invalid compressed block size at index 1, image file is corrupt -no file open, try 'help open' *** done diff --git a/tests/qemu-iotests/076.out b/tests/qemu-iotests/076.out index 72645b2522..9c66c5fb46 100644 --- a/tests/qemu-iotests/076.out +++ b/tests/qemu-iotests/076.out @@ -6,15 +6,12 @@ read 65536/65536 bytes at offset 0 == Negative catalog size == can't open device TEST_DIR/parallels-v1: Catalog too large -no file open, try 'help open' == Overflow in catalog allocation == can't open device TEST_DIR/parallels-v1: Catalog too large -no file open, try 'help open' == Zero sectors per track == can't open device TEST_DIR/parallels-v1: Invalid image: Zero sectors per track -no file open, try 'help open' == Read from a valid v2 image == read 65536/65536 bytes at offset 0 diff --git a/tests/qemu-iotests/078.out b/tests/qemu-iotests/078.out index 42b8a83015..c3d6aa4fe4 100644 --- a/tests/qemu-iotests/078.out +++ b/tests/qemu-iotests/078.out @@ -6,23 +6,17 @@ read 512/512 bytes at offset 0 == Negative catalog size == can't open device TEST_DIR/empty.bochs: Catalog size is too large -no file open, try 'help open' == Overflow for catalog size * sizeof(uint32_t) == can't open device TEST_DIR/empty.bochs: Catalog size is too large -no file open, try 'help open' == Too small catalog bitmap for image size == can't open device TEST_DIR/empty.bochs: Catalog size is too small for this disk size -no file open, try 'help open' can't open device TEST_DIR/empty.bochs: Catalog size is too small for this disk size -no file open, try 'help open' == Negative extent size == can't open device TEST_DIR/empty.bochs: Extent size 2147483648 is too large -no file open, try 'help open' == Zero extent size == can't open device TEST_DIR/empty.bochs: Extent size must be at least 512 -no file open, try 'help open' *** done diff --git a/tests/qemu-iotests/080.out b/tests/qemu-iotests/080.out index 0daac48b12..6a7fda1356 100644 --- a/tests/qemu-iotests/080.out +++ b/tests/qemu-iotests/080.out @@ -3,46 +3,33 @@ QA output created by 080 == Huge header size == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 can't open device TEST_DIR/t.qcow2: qcow2 header exceeds cluster size -no file open, try 'help open' can't open device TEST_DIR/t.qcow2: qcow2 header exceeds cluster size -no file open, try 'help open' == Huge unknown header extension == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 can't open device TEST_DIR/t.qcow2: Invalid backing file offset -no file open, try 'help open' can't open device TEST_DIR/t.qcow2: Header extension too large -no file open, try 'help open' can't open device TEST_DIR/t.qcow2: Header extension too large -no file open, try 'help open' == Huge refcount table size == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 can't open device TEST_DIR/t.qcow2: Reference count table too large -no file open, try 'help open' can't open device TEST_DIR/t.qcow2: Reference count table too large -no file open, try 'help open' == Misaligned refcount table == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 can't open device TEST_DIR/t.qcow2: Invalid reference count table offset -no file open, try 'help open' == Huge refcount offset == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 can't open device TEST_DIR/t.qcow2: Invalid reference count table offset -no file open, try 'help open' == Invalid snapshot table == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 can't open device TEST_DIR/t.qcow2: Too many snapshots -no file open, try 'help open' can't open device TEST_DIR/t.qcow2: Too many snapshots -no file open, try 'help open' can't open device TEST_DIR/t.qcow2: Invalid snapshot table offset -no file open, try 'help open' can't open device TEST_DIR/t.qcow2: Invalid snapshot table offset -no file open, try 'help open' == Hitting snapshot table size limit == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 @@ -53,13 +40,9 @@ read 512/512 bytes at offset 0 == Invalid L1 table == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 can't open device TEST_DIR/t.qcow2: Active L1 table too large -no file open, try 'help open' can't open device TEST_DIR/t.qcow2: Active L1 table too large -no file open, try 'help open' can't open device TEST_DIR/t.qcow2: Invalid L1 table offset -no file open, try 'help open' can't open device TEST_DIR/t.qcow2: Invalid L1 table offset -no file open, try 'help open' == Invalid L1 table (with internal snapshot in the image) == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 @@ -68,7 +51,6 @@ qemu-img: Could not open 'TEST_DIR/t.IMGFMT': L1 table is too small == Invalid backing file size == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 can't open device TEST_DIR/t.qcow2: Backing file name too long -no file open, try 'help open' == Invalid L2 entry (huge physical offset) == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 diff --git a/tests/qemu-iotests/083.out b/tests/qemu-iotests/083.out index ef3d1e32a5..0c13888ba1 100644 --- a/tests/qemu-iotests/083.out +++ b/tests/qemu-iotests/083.out @@ -2,52 +2,42 @@ QA output created by 083 === Check disconnect before neg1 === can't open device nbd:127.0.0.1:PORT:exportname=foo -no file open, try 'help open' === Check disconnect after neg1 === can't open device nbd:127.0.0.1:PORT:exportname=foo -no file open, try 'help open' === Check disconnect 8 neg1 === can't open device nbd:127.0.0.1:PORT:exportname=foo -no file open, try 'help open' === Check disconnect 16 neg1 === can't open device nbd:127.0.0.1:PORT:exportname=foo -no file open, try 'help open' === Check disconnect before export === can't open device nbd:127.0.0.1:PORT:exportname=foo -no file open, try 'help open' === Check disconnect after export === can't open device nbd:127.0.0.1:PORT:exportname=foo -no file open, try 'help open' === Check disconnect 4 export === can't open device nbd:127.0.0.1:PORT:exportname=foo -no file open, try 'help open' === Check disconnect 12 export === can't open device nbd:127.0.0.1:PORT:exportname=foo -no file open, try 'help open' === Check disconnect 16 export === can't open device nbd:127.0.0.1:PORT:exportname=foo -no file open, try 'help open' === Check disconnect before neg2 === can't open device nbd:127.0.0.1:PORT:exportname=foo -no file open, try 'help open' === Check disconnect after neg2 === @@ -56,12 +46,10 @@ read failed: Input/output error === Check disconnect 8 neg2 === can't open device nbd:127.0.0.1:PORT:exportname=foo -no file open, try 'help open' === Check disconnect 10 neg2 === can't open device nbd:127.0.0.1:PORT:exportname=foo -no file open, try 'help open' === Check disconnect before request === @@ -99,27 +87,22 @@ read 512/512 bytes at offset 0 === Check disconnect before neg-classic === can't open device nbd:127.0.0.1:PORT -no file open, try 'help open' === Check disconnect 8 neg-classic === can't open device nbd:127.0.0.1:PORT -no file open, try 'help open' === Check disconnect 16 neg-classic === can't open device nbd:127.0.0.1:PORT -no file open, try 'help open' === Check disconnect 24 neg-classic === can't open device nbd:127.0.0.1:PORT -no file open, try 'help open' === Check disconnect 28 neg-classic === can't open device nbd:127.0.0.1:PORT -no file open, try 'help open' === Check disconnect after neg-classic === diff --git a/tests/qemu-iotests/088.out b/tests/qemu-iotests/088.out index a2a83b8a1c..1f6bcf0abc 100644 --- a/tests/qemu-iotests/088.out +++ b/tests/qemu-iotests/088.out @@ -3,15 +3,9 @@ QA output created by 088 == Invalid block size == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 can't open device TEST_DIR/t.vpc: Invalid block size 0 -no file open, try 'help open' can't open device TEST_DIR/t.vpc: Invalid block size 0 -no file open, try 'help open' can't open device TEST_DIR/t.vpc: Invalid block size 128 -no file open, try 'help open' can't open device TEST_DIR/t.vpc: Invalid block size 128 -no file open, try 'help open' can't open device TEST_DIR/t.vpc: Invalid block size 305419896 -no file open, try 'help open' can't open device TEST_DIR/t.vpc: Invalid block size 305419896 -no file open, try 'help open' *** done diff --git a/tests/qemu-iotests/092.out b/tests/qemu-iotests/092.out index e18f54c200..6eda321fc6 100644 --- a/tests/qemu-iotests/092.out +++ b/tests/qemu-iotests/092.out @@ -3,36 +3,24 @@ QA output created by 092 == Invalid cluster size == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 can't open device TEST_DIR/t.qcow: Cluster size must be between 512 and 64k -no file open, try 'help open' can't open device TEST_DIR/t.qcow: Cluster size must be between 512 and 64k -no file open, try 'help open' can't open device TEST_DIR/t.qcow: Cluster size must be between 512 and 64k -no file open, try 'help open' can't open device TEST_DIR/t.qcow: Cluster size must be between 512 and 64k -no file open, try 'help open' == Invalid L2 table size == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 can't open device TEST_DIR/t.qcow: L2 table size must be between 512 and 64k -no file open, try 'help open' can't open device TEST_DIR/t.qcow: L2 table size must be between 512 and 64k -no file open, try 'help open' can't open device TEST_DIR/t.qcow: L2 table size must be between 512 and 64k -no file open, try 'help open' can't open device TEST_DIR/t.qcow: L2 table size must be between 512 and 64k -no file open, try 'help open' == Invalid size == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 can't open device TEST_DIR/t.qcow: Image too large -no file open, try 'help open' can't open device TEST_DIR/t.qcow: Image too large -no file open, try 'help open' == Invalid backing file length == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 can't open device TEST_DIR/t.qcow: Backing file name too long -no file open, try 'help open' can't open device TEST_DIR/t.qcow: Backing file name too long -no file open, try 'help open' *** done diff --git a/tests/qemu-iotests/116.out b/tests/qemu-iotests/116.out index 1f11d4446d..24bee57783 100644 --- a/tests/qemu-iotests/116.out +++ b/tests/qemu-iotests/116.out @@ -3,35 +3,28 @@ QA output created by 116 == truncated header cluster == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument -no file open, try 'help open' == invalid header magic == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 can't open device TEST_DIR/t.qed: Image not in QED format -no file open, try 'help open' == invalid cluster size == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument -no file open, try 'help open' == invalid table size == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument -no file open, try 'help open' == invalid header size == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument -no file open, try 'help open' == invalid L1 table offset == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument -no file open, try 'help open' == invalid image size == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument -no file open, try 'help open' *** done diff --git a/tests/qemu-iotests/131.out b/tests/qemu-iotests/131.out index ae2412ebf7..27c2c5389b 100644 --- a/tests/qemu-iotests/131.out +++ b/tests/qemu-iotests/131.out @@ -23,7 +23,6 @@ read 32768/32768 bytes at offset 0 32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) == Corrupt image == can't open device TEST_DIR/t.parallels: parallels: Image was not closed correctly; cannot be opened read/write -no file open, try 'help open' ERROR image was not closed correctly 1 errors were found on the image. diff --git a/tests/qemu-iotests/140.out b/tests/qemu-iotests/140.out index 0409cd0174..6c0445603a 100644 --- a/tests/qemu-iotests/140.out +++ b/tests/qemu-iotests/140.out @@ -9,7 +9,6 @@ read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": {}} can't open device nbd+unix:///drv?socket=TEST_DIR/nbd: No export with name 'drv' available -no file open, try 'help open' {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"} *** done diff --git a/tests/qemu-iotests/173 b/tests/qemu-iotests/173 new file mode 100755 index 0000000000..bdaa092979 --- /dev/null +++ b/tests/qemu-iotests/173 @@ -0,0 +1,97 @@ +#!/bin/bash +# +# Test QAPI commands looking up protocol based images with relative +# filename backing strings +# +# 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=jcody@redhat.com + +seq=`basename $0` +echo "QA output created by $seq" + +here=`pwd` +status=1 # failure is the default! + +_cleanup() +{ + _cleanup_qemu + rm -f "${QEMU_TEST_DIR}/image.base" "${QEMU_TEST_DIR}/image.snp1" + _cleanup_test_img +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter +. ./common.qemu + +_supported_fmt qcow2 +_supported_proto nfs +_supported_os Linux + +size=100M + +BASE_IMG="${TEST_DIR}/image.base" +TOP_IMG="${TEST_DIR}/image.snp1" + +TEST_IMG="${BASE_IMG}" _make_test_img $size + +TEST_IMG="${TOP_IMG}" _make_test_img $size + +echo +echo === Running QEMU, using block-stream to find backing image === +echo + +qemu_comm_method="qmp" +_launch_qemu -drive file="${BASE_IMG}",if=virtio,id=disk2 +h=$QEMU_HANDLE + +_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" "return" + +_send_qemu_cmd $h "{ 'arguments': { + 'device': 'disk2', + 'format': '${IMGFMT}', + 'mode': 'existing', + 'snapshot-file': '${TOP_IMG}', + 'snapshot-node-name': 'snp1' + }, + 'execute': 'blockdev-snapshot-sync' + }" "return" + + +_send_qemu_cmd $h "{ 'arguments': { + 'backing-file': 'image.base', + 'device': 'disk2', + 'image-node-name': 'snp1' + }, + 'execute': 'change-backing-file' + }" "return" + +_send_qemu_cmd $h "{ 'arguments': { + 'base': '${BASE_IMG}', + 'device': 'disk2' + }, + 'execute': 'block-stream' + }" "BLOCK_JOB_COMPLETED" + +_cleanup_qemu + +# success, all done +echo "*** done" +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/173.out b/tests/qemu-iotests/173.out new file mode 100644 index 0000000000..f477a0099a --- /dev/null +++ b/tests/qemu-iotests/173.out @@ -0,0 +1,12 @@ +QA output created by 173 +Formatting 'TEST_DIR/image.base', fmt=IMGFMT size=104857600 +Formatting 'TEST_DIR/image.snp1', fmt=IMGFMT size=104857600 + +=== Running QEMU, using block-stream to find backing image === + +{"return": {}} +{"return": {}} +{"return": {}} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "disk2", "len": 104857600, "offset": 104857600, "speed": 0, "type": "stream"}} +*** done diff --git a/tests/qemu-iotests/174 b/tests/qemu-iotests/174 new file mode 100755 index 0000000000..c1c20a1a57 --- /dev/null +++ b/tests/qemu-iotests/174 @@ -0,0 +1,59 @@ +#!/bin/bash +# +# Test that qemu-io fail with non-zero exit code +# +# Copyright (C) 2017 Nir Soffer <nirsof@gmail.com> +# +# 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=nirsof@gmail.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 + +_unsupported_fmt raw + + +size=256K +IMGFMT=raw IMGOPTS= _make_test_img $size | _filter_imgfmt + +echo +echo "== reading wrong format should fail ==" +$QEMU_IO -f $IMGFMT -c "read 0 $size" "$TEST_IMG" 2>/dev/null +test $? -eq 1 || _fail "did not fail" + +echo +echo "== reading missing file should fail ==" +$QEMU_IO -c "read 0 $size" "$TEST_DIR/missing" 2>/dev/null +test $? -eq 1 || _fail "did not fail" + +# success, all done +echo "*** done" +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/174.out b/tests/qemu-iotests/174.out new file mode 100644 index 0000000000..a06d23792e --- /dev/null +++ b/tests/qemu-iotests/174.out @@ -0,0 +1,7 @@ +QA output created by 174 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=262144 + +== reading wrong format should fail == + +== reading missing file should fail == +*** done diff --git a/tests/qemu-iotests/Makefile b/tests/qemu-iotests/Makefile index 2fb527c5b5..27380e60c1 100644 --- a/tests/qemu-iotests/Makefile +++ b/tests/qemu-iotests/Makefile @@ -1,5 +1,5 @@ -CLEANFILES= *.out.bad *.notrun check.log check.time +CLEANFILES= *.out.bad *.notrun check.log check.time* # no default target default: diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check index 4cba2151e4..4b1c6749b7 100755 --- a/tests/qemu-iotests/check +++ b/tests/qemu-iotests/check @@ -129,6 +129,8 @@ fi # exit 1 #fi +TIMESTAMP_FILE=check.time-$IMGPROTO-$IMGFMT + tmp="${TEST_DIR}"/$$ _wallclock() @@ -155,9 +157,9 @@ _wrapup() : elif $needwrap then - if [ -f check.time -a -f $tmp.time ] + if [ -f $TIMESTAMP_FILE -a -f $tmp.time ] then - cat check.time $tmp.time \ + cat $TIMESTAMP_FILE $tmp.time \ | $AWK_PROG ' { t[$1] = $2 } END { if (NR > 0) { @@ -165,7 +167,7 @@ END { if (NR > 0) { } }' \ | sort -n >$tmp.out - mv $tmp.out check.time + mv $tmp.out $TIMESTAMP_FILE fi if [ -f $tmp.expunged ] @@ -223,7 +225,7 @@ echo "preamble" > "${TEST_DIR}"/check.sts # don't leave old full output behind on a clean run rm -f check.full -[ -f check.time ] || touch check.time +[ -f $TIMESTAMP_FILE ] || touch $TIMESTAMP_FILE FULL_IMGFMT_DETAILS=`_full_imgfmt_details` FULL_IMGPROTO_DETAILS=`_full_imgproto_details` @@ -277,7 +279,7 @@ do # really going to try and run this one # rm -f $seq.out.bad - lasttime=`sed -n -e "/^$seq /s/.* //p" <check.time` + lasttime=`sed -n -e "/^$seq /s/.* //p" <$TIMESTAMP_FILE` if [ "X$lasttime" != X ]; then echo -n " ${lasttime}s ..." else diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config index f6384fbae7..55527aac87 100644 --- a/tests/qemu-iotests/common.config +++ b/tests/qemu-iotests/common.config @@ -109,7 +109,7 @@ _qemu_wrapper() { ( if [ -n "${QEMU_NEED_PID}" ]; then - echo $BASHPID > "${TEST_DIR}/qemu-${_QEMU_HANDLE}.pid" + echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid" fi exec "$QEMU_PROG" $QEMU_OPTIONS "$@" ) @@ -151,7 +151,7 @@ _qemu_io_wrapper() _qemu_nbd_wrapper() { ( - echo $BASHPID > "${TEST_DIR}/qemu-nbd.pid" + echo $BASHPID > "${QEMU_TEST_DIR}/qemu-nbd.pid" exec "$QEMU_NBD_PROG" $QEMU_NBD_OPTIONS "$@" ) } @@ -186,6 +186,8 @@ if [ -z "$TEST_DIR" ]; then TEST_DIR=`pwd`/scratch fi +QEMU_TEST_DIR="${TEST_DIR}" + if [ ! -e "$TEST_DIR" ]; then mkdir "$TEST_DIR" fi diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter index 240ed0697a..4befd865f4 100644 --- a/tests/qemu-iotests/common.filter +++ b/tests/qemu-iotests/common.filter @@ -35,7 +35,7 @@ _filter_generated_node_ids() # replace occurrences of the actual TEST_DIR value with TEST_DIR _filter_testdir() { - sed -e "s#$TEST_DIR#TEST_DIR#g" + sed -e "s#$TEST_DIR/#TEST_DIR/#g" } # replace occurrences of the actual IMGFMT value with IMGFMT diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu index e657361790..42787896af 100644 --- a/tests/qemu-iotests/common.qemu +++ b/tests/qemu-iotests/common.qemu @@ -27,8 +27,8 @@ QEMU_COMM_TIMEOUT=10 -QEMU_FIFO_IN="${TEST_DIR}/qmp-in-$$" -QEMU_FIFO_OUT="${TEST_DIR}/qmp-out-$$" +QEMU_FIFO_IN="${QEMU_TEST_DIR}/qmp-in-$$" +QEMU_FIFO_OUT="${QEMU_TEST_DIR}/qmp-out-$$" QEMU_HANDLE=0 @@ -204,9 +204,9 @@ function _cleanup_qemu() for i in "${!QEMU_OUT[@]}" do local QEMU_PID - if [ -f "${TEST_DIR}/qemu-${i}.pid" ]; then - read QEMU_PID < "${TEST_DIR}/qemu-${i}.pid" - rm -f "${TEST_DIR}/qemu-${i}.pid" + if [ -f "${QEMU_TEST_DIR}/qemu-${i}.pid" ]; then + read QEMU_PID < "${QEMU_TEST_DIR}/qemu-${i}.pid" + rm -f "${QEMU_TEST_DIR}/qemu-${i}.pid" if [ -z "${wait}" ] && [ -n "${QEMU_PID}" ]; then kill -KILL ${QEMU_PID} 2>/dev/null fi diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc index 3213765f4e..a3d904fc22 100644 --- a/tests/qemu-iotests/common.rc +++ b/tests/qemu-iotests/common.rc @@ -193,11 +193,11 @@ _cleanup_test_img() case "$IMGPROTO" in nbd) - if [ -f "${TEST_DIR}/qemu-nbd.pid" ]; then + if [ -f "${QEMU_TEST_DIR}/qemu-nbd.pid" ]; then local QEMU_NBD_PID - read QEMU_NBD_PID < "${TEST_DIR}/qemu-nbd.pid" + read QEMU_NBD_PID < "${QEMU_TEST_DIR}/qemu-nbd.pid" kill ${QEMU_NBD_PID} - rm -f "${TEST_DIR}/qemu-nbd.pid" + rm -f "${QEMU_TEST_DIR}/qemu-nbd.pid" fi rm -f "$TEST_IMG_FILE" ;; @@ -355,6 +355,17 @@ _supported_fmt() _notrun "not suitable for this image format: $IMGFMT" } +# tests whether $IMGFMT is one of the unsupported image format for a test +# +_unsupported_fmt() +{ + for f; do + if [ "$f" = "$IMGFMT" ]; then + _notrun "not suitable for this image format: $IMGFMT" + fi + done +} + # tests whether $IMGPROTO is one of the supported image protocols for a test # _supported_proto() diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 866c1a032d..985b9a6a36 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -165,3 +165,5 @@ 170 rw auto quick 171 rw auto quick 172 auto +173 rw auto +174 auto |