Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into s…
Browse files Browse the repository at this point in the history
…taging

Block layer patches:

- Fix crash on write to read-only devices
- iotests: Rewrite 'check' in Python, get rid of 'groups' and allow
  non-numeric test case names

# gpg: Signature made Wed 27 Jan 2021 19:56:00 GMT
# gpg:                using RSA key DC3DEB159A9AF95D3D7456FE7F09B272C88F2FD6
# gpg:                issuer "kwolf@redhat.com"
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full]
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream:
  iotests: rename and move 169 and 199 tests
  iotests: rewrite check into python
  iotests: add testrunner.py
  iotests: add testenv.py
  iotests: add findtests.py
  iotests: 146: drop extra whitespaces from .out file
  virtio-scsi-test: Test writing to scsi-cd device
  block: Separate blk_is_writable() and blk_supports_write_perm()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Jan 28, 2021
2 parents 091f255 + a44be03 commit 0bcd12f
Show file tree
Hide file tree
Showing 37 changed files with 1,481 additions and 1,729 deletions.
1 change: 0 additions & 1 deletion Makefile
Expand Up @@ -236,7 +236,6 @@ distclean: clean
rm -f config-host.mak config-host.h*
rm -f tests/tcg/config-*.mak
rm -f config-all-disas.mak config.status
rm -f tests/qemu-iotests/common.env
rm -f roms/seabios/config.mak roms/vgabios/config.mak
rm -f qemu-plugins-ld.symbols qemu-plugins-ld64.symbols
rm -f *-config-target.h *-config-devices.mak *-config-devices.h
Expand Down
19 changes: 16 additions & 3 deletions block/block-backend.c
Expand Up @@ -1826,17 +1826,30 @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action,
}
}

bool blk_is_read_only(BlockBackend *blk)
/*
* Returns true if the BlockBackend can support taking write permissions
* (because its root node is not read-only).
*/
bool blk_supports_write_perm(BlockBackend *blk)
{
BlockDriverState *bs = blk_bs(blk);

if (bs) {
return bdrv_is_read_only(bs);
return !bdrv_is_read_only(bs);
} else {
return blk->root_state.read_only;
return !blk->root_state.read_only;
}
}

/*
* Returns true if the BlockBackend can be written to in its current
* configuration (i.e. if write permission have been requested)
*/
bool blk_is_writable(BlockBackend *blk)
{
return blk->perm & BLK_PERM_WRITE;
}

bool blk_is_sg(BlockBackend *blk)
{
BlockDriverState *bs = blk_bs(blk);
Expand Down
50 changes: 49 additions & 1 deletion docs/devel/testing.rst
Expand Up @@ -111,7 +111,7 @@ check-block
-----------

``make check-block`` runs a subset of the block layer iotests (the tests that
are in the "auto" group in ``tests/qemu-iotests/group``).
are in the "auto" group).
See the "QEMU iotests" section below for more information.

GCC gcov support
Expand Down Expand Up @@ -224,6 +224,54 @@ another application on the host may have locked the file, possibly leading to a
test failure. If using such devices are explicitly desired, consider adding
``locking=off`` option to disable image locking.

Test case groups
----------------

"Tests may belong to one or more test groups, which are defined in the form
of a comment in the test source file. By convention, test groups are listed
in the second line of the test file, after the "#!/..." line, like this:

.. code::
#!/usr/bin/env python3
# group: auto quick
#
...
Another way of defining groups is creating the tests/qemu-iotests/group.local
file. This should be used only for downstream (this file should never appear
in upstream). This file may be used for defining some downstream test groups
or for temporarily disabling tests, like this:

.. code::
# groups for some company downstream process
#
# ci - tests to run on build
# down - our downstream tests, not for upstream
#
# Format of each line is:
# TEST_NAME TEST_GROUP [TEST_GROUP ]...
013 ci
210 disabled
215 disabled
our-ugly-workaround-test down ci
Note that the following group names have a special meaning:

- quick: Tests in this group should finish within a few seconds.

- auto: Tests in this group are used during "make check" and should be
runnable in any case. That means they should run with every QEMU binary
(also non-x86), with every QEMU configuration (i.e. must not fail if
an optional feature is not compiled in - but reporting a "skip" is ok),
work at least with the qcow2 file format, work with all kind of host
filesystems and users (e.g. "nobody" or "root") and must not take too
much memory and disk space (since CI pipelines tend to fail otherwise).

- disabled: Tests in this group are disabled and ignored by check.

.. _docker-ref:

Docker based tests
Expand Down
2 changes: 1 addition & 1 deletion hw/block/dataplane/xen-block.c
Expand Up @@ -168,7 +168,7 @@ static int xen_block_parse_request(XenBlockRequest *request)
};

if (request->req.operation != BLKIF_OP_READ &&
blk_is_read_only(dataplane->blk)) {
!blk_is_writable(dataplane->blk)) {
error_report("error: write req for ro device");
goto err;
}
Expand Down
9 changes: 5 additions & 4 deletions hw/block/fdc.c
Expand Up @@ -444,7 +444,7 @@ static void fd_revalidate(FDrive *drv)

FLOPPY_DPRINTF("revalidate\n");
if (drv->blk != NULL) {
drv->ro = blk_is_read_only(drv->blk);
drv->ro = !blk_is_writable(drv->blk);
if (!blk_is_inserted(drv->blk)) {
FLOPPY_DPRINTF("No disk in drive\n");
drv->disk = FLOPPY_DRIVE_TYPE_NONE;
Expand Down Expand Up @@ -479,8 +479,8 @@ static void fd_change_cb(void *opaque, bool load, Error **errp)
blk_set_perm(drive->blk, 0, BLK_PERM_ALL, &error_abort);
} else {
if (!blkconf_apply_backend_options(drive->conf,
blk_is_read_only(drive->blk), false,
errp)) {
!blk_supports_write_perm(drive->blk),
false, errp)) {
return;
}
}
Expand Down Expand Up @@ -553,7 +553,8 @@ static void floppy_drive_realize(DeviceState *qdev, Error **errp)
* read-only node later */
read_only = true;
} else {
read_only = !blk_bs(dev->conf.blk) || blk_is_read_only(dev->conf.blk);
read_only = !blk_bs(dev->conf.blk) ||
!blk_supports_write_perm(dev->conf.blk);
}

if (!blkconf_blocksizes(&dev->conf, errp)) {
Expand Down
6 changes: 3 additions & 3 deletions hw/block/m25p80.c
Expand Up @@ -508,7 +508,7 @@ static void flash_sync_page(Flash *s, int page)
{
QEMUIOVector *iov;

if (!s->blk || blk_is_read_only(s->blk)) {
if (!s->blk || !blk_is_writable(s->blk)) {
return;
}

Expand All @@ -524,7 +524,7 @@ static inline void flash_sync_area(Flash *s, int64_t off, int64_t len)
{
QEMUIOVector *iov;

if (!s->blk || blk_is_read_only(s->blk)) {
if (!s->blk || !blk_is_writable(s->blk)) {
return;
}

Expand Down Expand Up @@ -1434,7 +1434,7 @@ static void m25p80_realize(SSIPeripheral *ss, Error **errp)

if (s->blk) {
uint64_t perm = BLK_PERM_CONSISTENT_READ |
(blk_is_read_only(s->blk) ? 0 : BLK_PERM_WRITE);
(blk_supports_write_perm(s->blk) ? BLK_PERM_WRITE : 0);
ret = blk_set_perm(s->blk, perm, BLK_PERM_ALL, errp);
if (ret < 0) {
return;
Expand Down
2 changes: 1 addition & 1 deletion hw/block/nand.c
Expand Up @@ -400,7 +400,7 @@ static void nand_realize(DeviceState *dev, Error **errp)
pagesize = 1 << s->oob_shift;
s->mem_oob = 1;
if (s->blk) {
if (blk_is_read_only(s->blk)) {
if (!blk_supports_write_perm(s->blk)) {
error_setg(errp, "Can't use a read-only drive");
return;
}
Expand Down
7 changes: 4 additions & 3 deletions hw/block/nvme-ns.c
Expand Up @@ -48,13 +48,14 @@ static void nvme_ns_init(NvmeNamespace *ns)

static int nvme_ns_init_blk(NvmeCtrl *n, NvmeNamespace *ns, Error **errp)
{
bool read_only;

if (!blkconf_blocksizes(&ns->blkconf, errp)) {
return -1;
}

if (!blkconf_apply_backend_options(&ns->blkconf,
blk_is_read_only(ns->blkconf.blk),
false, errp)) {
read_only = !blk_supports_write_perm(ns->blkconf.blk);
if (!blkconf_apply_backend_options(&ns->blkconf, read_only, false, errp)) {
return -1;
}

Expand Down
2 changes: 1 addition & 1 deletion hw/block/onenand.c
Expand Up @@ -797,7 +797,7 @@ static void onenand_realize(DeviceState *dev, Error **errp)
s->image = memset(g_malloc(size + (size >> 5)),
0xff, size + (size >> 5));
} else {
if (blk_is_read_only(s->blk)) {
if (!blk_supports_write_perm(s->blk)) {
error_setg(errp, "Can't use a read-only drive");
return;
}
Expand Down
2 changes: 1 addition & 1 deletion hw/block/pflash_cfi01.c
Expand Up @@ -745,7 +745,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)

if (pfl->blk) {
uint64_t perm;
pfl->ro = blk_is_read_only(pfl->blk);
pfl->ro = !blk_supports_write_perm(pfl->blk);
perm = BLK_PERM_CONSISTENT_READ | (pfl->ro ? 0 : BLK_PERM_WRITE);
ret = blk_set_perm(pfl->blk, perm, BLK_PERM_ALL, errp);
if (ret < 0) {
Expand Down
2 changes: 1 addition & 1 deletion hw/block/pflash_cfi02.c
Expand Up @@ -802,7 +802,7 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp)

if (pfl->blk) {
uint64_t perm;
pfl->ro = blk_is_read_only(pfl->blk);
pfl->ro = !blk_supports_write_perm(pfl->blk);
perm = BLK_PERM_CONSISTENT_READ | (pfl->ro ? 0 : BLK_PERM_WRITE);
ret = blk_set_perm(pfl->blk, perm, BLK_PERM_ALL, errp);
if (ret < 0) {
Expand Down
6 changes: 3 additions & 3 deletions hw/block/swim.c
Expand Up @@ -137,8 +137,8 @@ static void swim_change_cb(void *opaque, bool load, Error **errp)
blk_set_perm(drive->blk, 0, BLK_PERM_ALL, &error_abort);
} else {
if (!blkconf_apply_backend_options(drive->conf,
blk_is_read_only(drive->blk), false,
errp)) {
!blk_supports_write_perm(drive->blk),
false, errp)) {
return;
}
}
Expand Down Expand Up @@ -210,7 +210,7 @@ static void swim_drive_realize(DeviceState *qdev, Error **errp)
dev->conf.werror = BLOCKDEV_ON_ERROR_AUTO;

if (!blkconf_apply_backend_options(&dev->conf,
blk_is_read_only(dev->conf.blk),
!blk_supports_write_perm(dev->conf.blk),
false, errp)) {
return;
}
Expand Down
6 changes: 3 additions & 3 deletions hw/block/virtio-blk.c
Expand Up @@ -1021,7 +1021,7 @@ static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features,
virtio_has_feature(features, VIRTIO_BLK_F_CONFIG_WCE))) {
virtio_add_feature(&features, VIRTIO_BLK_F_WCE);
}
if (blk_is_read_only(s->blk)) {
if (!blk_is_writable(s->blk)) {
virtio_add_feature(&features, VIRTIO_BLK_F_RO);
}
if (s->conf.num_queues > 1) {
Expand Down Expand Up @@ -1175,8 +1175,8 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
}

if (!blkconf_apply_backend_options(&conf->conf,
blk_is_read_only(conf->conf.blk), true,
errp)) {
!blk_supports_write_perm(conf->conf.blk),
true, errp)) {
return;
}
s->original_wce = blk_enable_write_cache(conf->conf.blk);
Expand Down
2 changes: 1 addition & 1 deletion hw/block/xen-block.c
Expand Up @@ -567,7 +567,7 @@ static void xen_disk_realize(XenBlockDevice *blockdev, Error **errp)
return;
}

blockdev->info = blk_is_read_only(conf->blk) ? VDISK_READONLY : 0;
blockdev->info = blk_supports_write_perm(conf->blk) ? 0 : VDISK_READONLY;
}

static void xen_disk_class_init(ObjectClass *class, void *data)
Expand Down
2 changes: 1 addition & 1 deletion hw/ide/core.c
Expand Up @@ -2537,7 +2537,7 @@ int ide_init_drive(IDEState *s, BlockBackend *blk, IDEDriveKind kind,
error_setg(errp, "Device needs media, but drive is empty");
return -1;
}
if (blk_is_read_only(blk)) {
if (!blk_is_writable(blk)) {
error_setg(errp, "Can't use a read-only drive");
return -1;
}
Expand Down
2 changes: 1 addition & 1 deletion hw/misc/sifive_u_otp.c
Expand Up @@ -228,7 +228,7 @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp)

if (s->blk) {
perm = BLK_PERM_CONSISTENT_READ |
(blk_is_read_only(s->blk) ? 0 : BLK_PERM_WRITE);
(blk_supports_write_perm(s->blk) ? BLK_PERM_WRITE : 0);
ret = blk_set_perm(s->blk, perm, BLK_PERM_ALL, errp);
if (ret < 0) {
return;
Expand Down
2 changes: 1 addition & 1 deletion hw/ppc/pnv_pnor.c
Expand Up @@ -86,7 +86,7 @@ static void pnv_pnor_realize(DeviceState *dev, Error **errp)

if (s->blk) {
uint64_t perm = BLK_PERM_CONSISTENT_READ |
(blk_is_read_only(s->blk) ? 0 : BLK_PERM_WRITE);
(blk_supports_write_perm(s->blk) ? BLK_PERM_WRITE : 0);
ret = blk_set_perm(s->blk, perm, BLK_PERM_ALL, errp);
if (ret < 0) {
return;
Expand Down
10 changes: 5 additions & 5 deletions hw/scsi/scsi-disk.c
Expand Up @@ -1270,7 +1270,7 @@ static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf)

if (s->qdev.type == TYPE_DISK) {
dev_specific_param = s->features & (1 << SCSI_DISK_F_DPOFUA) ? 0x10 : 0;
if (blk_is_read_only(s->qdev.conf.blk)) {
if (!blk_is_writable(s->qdev.conf.blk)) {
dev_specific_param |= 0x80; /* Readonly. */
}
} else {
Expand Down Expand Up @@ -1704,7 +1704,7 @@ static void scsi_disk_emulate_unmap(SCSIDiskReq *r, uint8_t *inbuf)
goto invalid_param_len;
}

if (blk_is_read_only(s->qdev.conf.blk)) {
if (!blk_is_writable(s->qdev.conf.blk)) {
block_acct_invalid(blk_get_stats(s->qdev.conf.blk), BLOCK_ACCT_UNMAP);
scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
return;
Expand Down Expand Up @@ -1795,7 +1795,7 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf)
return;
}

if (blk_is_read_only(s->qdev.conf.blk)) {
if (!blk_is_writable(s->qdev.conf.blk)) {
scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
return;
}
Expand Down Expand Up @@ -2207,7 +2207,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
case WRITE_VERIFY_10:
case WRITE_VERIFY_12:
case WRITE_VERIFY_16:
if (blk_is_read_only(s->qdev.conf.blk)) {
if (!blk_is_writable(s->qdev.conf.blk)) {
scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
return 0;
}
Expand Down Expand Up @@ -2380,7 +2380,7 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
}
}

read_only = blk_is_read_only(s->qdev.conf.blk);
read_only = !blk_supports_write_perm(s->qdev.conf.blk);
if (dev->type == TYPE_ROM) {
read_only = true;
}
Expand Down
4 changes: 2 additions & 2 deletions hw/scsi/scsi-generic.c
Expand Up @@ -306,7 +306,7 @@ static void scsi_read_complete(void * opaque, int ret)
* readonly.
*/
if ((s->type == TYPE_DISK || s->type == TYPE_TAPE || s->type == TYPE_ZBC) &&
blk_is_read_only(s->conf.blk) &&
!blk_is_writable(s->conf.blk) &&
(r->req.cmd.buf[0] == MODE_SENSE ||
r->req.cmd.buf[0] == MODE_SENSE_10) &&
(r->req.cmd.buf[1] & 0x8) == 0) {
Expand Down Expand Up @@ -694,7 +694,7 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
return;
}
if (!blkconf_apply_backend_options(&s->conf,
blk_is_read_only(s->conf.blk),
!blk_supports_write_perm(s->conf.blk),
true, errp)) {
return;
}
Expand Down
6 changes: 3 additions & 3 deletions hw/sd/sd.c
Expand Up @@ -567,7 +567,7 @@ static void sd_reset(DeviceState *dev)
sd_set_sdstatus(sd);

g_free(sd->wp_groups);
sd->wp_switch = sd->blk ? blk_is_read_only(sd->blk) : false;
sd->wp_switch = sd->blk ? !blk_is_writable(sd->blk) : false;
sd->wpgrps_size = sect;
sd->wp_groups = bitmap_new(sd->wpgrps_size);
memset(sd->function_group, 0, sizeof(sd->function_group));
Expand Down Expand Up @@ -735,7 +735,7 @@ void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert)
{
sd->readonly_cb = readonly;
sd->inserted_cb = insert;
qemu_set_irq(readonly, sd->blk ? blk_is_read_only(sd->blk) : 0);
qemu_set_irq(readonly, sd->blk ? !blk_is_writable(sd->blk) : 0);
qemu_set_irq(insert, sd->blk ? blk_is_inserted(sd->blk) : 0);
}

Expand Down Expand Up @@ -2131,7 +2131,7 @@ static void sd_realize(DeviceState *dev, Error **errp)
if (sd->blk) {
int64_t blk_size;

if (blk_is_read_only(sd->blk)) {
if (!blk_supports_write_perm(sd->blk)) {
error_setg(errp, "Cannot use read-only drive as SD card");
return;
}
Expand Down

0 comments on commit 0bcd12f

Please sign in to comment.