Blob Blame Raw
From 6048f02ce5388f14c0ff1a77122d26be9dffcac0 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Thu, 7 Nov 2013 12:41:46 +0100
Subject: [PATCH 57/87] blockdev: Remove IF_* check for read-only blockdev_init

RH-Author: Kevin Wolf <kwolf@redhat.com>
Message-id: <1383660558-32096-17-git-send-email-kwolf@redhat.com>
Patchwork-id: 55395
O-Subject: [RHEL-7.0 qemu-kvm PATCH 16/24] blockdev: Remove IF_* check for read-only blockdev_init
Bugzilla: 978402
RH-Acked-by: Fam Zheng <famz@redhat.com>
RH-Acked-by: Max Reitz <mreitz@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>

IF_NONE allows read-only, which makes forbidding it in this place
for other types pretty much pointless.

Instead, make sure that all devices for which the check would have
errored out check in their init function that they don't get a read-only
BlockDriverState. This catches even cases where IF_NONE and -device is
used.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 4f8a066b5fc254eeaabbbde56ba4f5b29cc68fdf)

Conflicts:
	hw/block/xen_disk.c
	hw/sd/milkymist-memcard.c
	hw/sd/omap_mmc.c
	hw/sd/pl181.c
	hw/sd/pxa2xx_mmci.c
	hw/sd/sdhci.c
	hw/sd/ssi-sd.c

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 blockdev.c                 |    6 ------
 hw/block/m25p80.c          |    5 +++++
 hw/block/xen_disk.c        |    5 +++++
 hw/sd/milkymist-memcard.c  |    4 ++++
 hw/sd/omap_mmc.c           |    6 ++++++
 hw/sd/pl181.c              |    4 ++++
 hw/sd/pxa2xx_mmci.c        |    3 +++
 hw/sd/sd.c                 |    5 +++++
 hw/sd/sdhci.c              |    3 +++
 hw/sd/ssi-sd.c             |    3 +++
 tests/qemu-iotests/051.out |    5 ++++-
 11 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 14b357a..680ba22 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -529,12 +529,6 @@ static DriveInfo *blockdev_init(QDict *bs_opts,
     if (media == MEDIA_CDROM) {
         /* CDROM is fine for any interface, don't check.  */
         ro = 1;
-    } else if (ro == 1) {
-        if (type != IF_SCSI && type != IF_VIRTIO && type != IF_FLOPPY &&
-            type != IF_NONE && type != IF_PFLASH) {
-            error_report("read-only not supported by this bus type");
-            goto err;
-        }
     }
 
     bdrv_flags |= ro ? 0 : BDRV_O_RDWR;
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 759c84d..ccec5ab 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -619,6 +619,11 @@ static int m25p80_init(SSISlave *ss)
     if (dinfo && dinfo->bdrv) {
         DB_PRINT_L(0, "Binding to IF_MTD drive\n");
         s->bdrv = dinfo->bdrv;
+        if (bdrv_is_read_only(s->bdrv)) {
+            fprintf(stderr, "Can't use a read-only drive");
+            return 1;
+        }
+
         /* FIXME: Move to late init */
         if (bdrv_read(s->bdrv, 0, s->storage, DIV_ROUND_UP(s->size,
                                                     BDRV_SECTOR_SIZE))) {
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 2d4d263..498f2e9 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -817,6 +817,11 @@ static int blk_connect(struct XenDevice *xendev)
         /* setup via qemu cmdline -> already setup for us */
         xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n");
         blkdev->bs = blkdev->dinfo->bdrv;
+        if (bdrv_is_read_only(blkdev->bs) && !readonly) {
+            xen_be_printf(&blkdev->xendev, 0, "Unexpected read-only drive");
+            blkdev->bs = NULL;
+            return -1;
+        }
     }
     bdrv_attach_dev_nofail(blkdev->bs, blkdev);
     blkdev->file_size = bdrv_getlength(blkdev->bs);
diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c
index d5944bc..a7dfbff 100644
--- a/hw/sd/milkymist-memcard.c
+++ b/hw/sd/milkymist-memcard.c
@@ -251,6 +251,10 @@ static int milkymist_memcard_init(SysBusDevice *dev)
 
     dinfo = drive_get_next(IF_SD);
     s->card = sd_init(dinfo ? dinfo->bdrv : NULL, 0);
+    if (s->card == NULL) {
+        return -1;
+    }
+
     s->enabled = dinfo ? bdrv_is_inserted(dinfo->bdrv) : 0;
 
     memory_region_init_io(&s->regs_region, &memcard_mmio_ops, s,
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
index d4079cd..aefdc3e 100644
--- a/hw/sd/omap_mmc.c
+++ b/hw/sd/omap_mmc.c
@@ -593,6 +593,9 @@ struct omap_mmc_s *omap_mmc_init(hwaddr base,
 
     /* Instantiate the storage */
     s->card = sd_init(bd, 0);
+    if (s->card == NULL) {
+        exit(1);
+    }
 
     return s;
 }
@@ -618,6 +621,9 @@ struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
 
     /* Instantiate the storage */
     s->card = sd_init(bd, 0);
+    if (s->card == NULL) {
+        exit(1);
+    }
 
     s->cdet = qemu_allocate_irqs(omap_mmc_cover_cb, s, 1)[0];
     sd_set_cb(s->card, NULL, s->cdet);
diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
index c5ad890..a7f85b8 100644
--- a/hw/sd/pl181.c
+++ b/hw/sd/pl181.c
@@ -486,6 +486,10 @@ static int pl181_init(SysBusDevice *dev)
     qdev_init_gpio_out(&s->busdev.qdev, s->cardstatus, 2);
     dinfo = drive_get_next(IF_SD);
     s->card = sd_init(dinfo ? dinfo->bdrv : NULL, 0);
+    if (s->card == NULL) {
+        return -1;
+    }
+
     return 0;
 }
 
diff --git a/hw/sd/pxa2xx_mmci.c b/hw/sd/pxa2xx_mmci.c
index 2db1cab..066d523 100644
--- a/hw/sd/pxa2xx_mmci.c
+++ b/hw/sd/pxa2xx_mmci.c
@@ -539,6 +539,9 @@ PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,
 
     /* Instantiate the actual storage */
     s->card = sd_init(bd, 0);
+    if (s->card == NULL) {
+        exit(1);
+    }
 
     register_savevm(NULL, "pxa2xx_mmci", 0, 0,
                     pxa2xx_mmci_save, pxa2xx_mmci_load, s);
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 2e0ef3e..e816c78 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -492,6 +492,11 @@ SDState *sd_init(BlockDriverState *bs, bool is_spi)
 {
     SDState *sd;
 
+    if (bdrv_is_read_only(bs)) {
+        fprintf(stderr, "sd_init: Cannot use read-only drive\n");
+        return NULL;
+    }
+
     sd = (SDState *) g_malloc0(sizeof(SDState));
     sd->buf = qemu_blockalign(bs, 512);
     sd->spi = is_spi;
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 91dc9b0..d8a4987 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1166,6 +1166,9 @@ static void sdhci_initfn(Object *obj)
 
     di = drive_get_next(IF_SD);
     s->card = sd_init(di ? di->bdrv : NULL, 0);
+    if (s->card == NULL) {
+        exit(1);
+    }
     s->eject_cb = qemu_allocate_irqs(sdhci_insert_eject_cb, s, 1)[0];
     s->ro_cb = qemu_allocate_irqs(sdhci_card_readonly_cb, s, 1)[0];
     sd_set_cb(s->card, s->ro_cb, s->eject_cb);
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index 4d3c4f6..79ec51a 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -246,6 +246,9 @@ static int ssi_sd_init(SSISlave *dev)
     s->mode = SSI_SD_CMD;
     dinfo = drive_get_next(IF_SD);
     s->sd = sd_init(dinfo ? dinfo->bdrv : NULL, 1);
+    if (s->sd == NULL) {
+        return -1;
+    }
     register_savevm(&dev->qdev, "ssi_sd", -1, 1, ssi_sd_save, ssi_sd_load, s);
     return 0;
 }
diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out
index 54a6b3a..4fca1ca 100644
--- a/tests/qemu-iotests/051.out
+++ b/tests/qemu-iotests/051.out
@@ -98,7 +98,10 @@ QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on: read-only not supported by this bus type
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) QEMU_PROG: Can't use a read-only drive
+QEMU_PROG: Device initialization failed.
+QEMU_PROG: Initialization of device ide-hd failed
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=virtio,readonly=on
 QEMU X.Y.Z monitor - type 'help' for more information
-- 
1.7.1