9ae3a8
From 6048f02ce5388f14c0ff1a77122d26be9dffcac0 Mon Sep 17 00:00:00 2001
9ae3a8
From: Kevin Wolf <kwolf@redhat.com>
9ae3a8
Date: Thu, 7 Nov 2013 12:41:46 +0100
9ae3a8
Subject: [PATCH 57/87] blockdev: Remove IF_* check for read-only blockdev_init
9ae3a8
9ae3a8
RH-Author: Kevin Wolf <kwolf@redhat.com>
9ae3a8
Message-id: <1383660558-32096-17-git-send-email-kwolf@redhat.com>
9ae3a8
Patchwork-id: 55395
9ae3a8
O-Subject: [RHEL-7.0 qemu-kvm PATCH 16/24] blockdev: Remove IF_* check for read-only blockdev_init
9ae3a8
Bugzilla: 978402
9ae3a8
RH-Acked-by: Fam Zheng <famz@redhat.com>
9ae3a8
RH-Acked-by: Max Reitz <mreitz@redhat.com>
9ae3a8
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
9ae3a8
9ae3a8
IF_NONE allows read-only, which makes forbidding it in this place
9ae3a8
for other types pretty much pointless.
9ae3a8
9ae3a8
Instead, make sure that all devices for which the check would have
9ae3a8
errored out check in their init function that they don't get a read-only
9ae3a8
BlockDriverState. This catches even cases where IF_NONE and -device is
9ae3a8
used.
9ae3a8
9ae3a8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9ae3a8
Reviewed-by: Eric Blake <eblake@redhat.com>
9ae3a8
(cherry picked from commit 4f8a066b5fc254eeaabbbde56ba4f5b29cc68fdf)
9ae3a8
9ae3a8
Conflicts:
9ae3a8
	hw/block/xen_disk.c
9ae3a8
	hw/sd/milkymist-memcard.c
9ae3a8
	hw/sd/omap_mmc.c
9ae3a8
	hw/sd/pl181.c
9ae3a8
	hw/sd/pxa2xx_mmci.c
9ae3a8
	hw/sd/sdhci.c
9ae3a8
	hw/sd/ssi-sd.c
9ae3a8
9ae3a8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 blockdev.c                 |    6 ------
9ae3a8
 hw/block/m25p80.c          |    5 +++++
9ae3a8
 hw/block/xen_disk.c        |    5 +++++
9ae3a8
 hw/sd/milkymist-memcard.c  |    4 ++++
9ae3a8
 hw/sd/omap_mmc.c           |    6 ++++++
9ae3a8
 hw/sd/pl181.c              |    4 ++++
9ae3a8
 hw/sd/pxa2xx_mmci.c        |    3 +++
9ae3a8
 hw/sd/sd.c                 |    5 +++++
9ae3a8
 hw/sd/sdhci.c              |    3 +++
9ae3a8
 hw/sd/ssi-sd.c             |    3 +++
9ae3a8
 tests/qemu-iotests/051.out |    5 ++++-
9ae3a8
 11 files changed, 42 insertions(+), 7 deletions(-)
9ae3a8
9ae3a8
diff --git a/blockdev.c b/blockdev.c
9ae3a8
index 14b357a..680ba22 100644
9ae3a8
--- a/blockdev.c
9ae3a8
+++ b/blockdev.c
9ae3a8
@@ -529,12 +529,6 @@ static DriveInfo *blockdev_init(QDict *bs_opts,
9ae3a8
     if (media == MEDIA_CDROM) {
9ae3a8
         /* CDROM is fine for any interface, don't check.  */
9ae3a8
         ro = 1;
9ae3a8
-    } else if (ro == 1) {
9ae3a8
-        if (type != IF_SCSI && type != IF_VIRTIO && type != IF_FLOPPY &&
9ae3a8
-            type != IF_NONE && type != IF_PFLASH) {
9ae3a8
-            error_report("read-only not supported by this bus type");
9ae3a8
-            goto err;
9ae3a8
-        }
9ae3a8
     }
9ae3a8
 
9ae3a8
     bdrv_flags |= ro ? 0 : BDRV_O_RDWR;
9ae3a8
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
9ae3a8
index 759c84d..ccec5ab 100644
9ae3a8
--- a/hw/block/m25p80.c
9ae3a8
+++ b/hw/block/m25p80.c
9ae3a8
@@ -619,6 +619,11 @@ static int m25p80_init(SSISlave *ss)
9ae3a8
     if (dinfo && dinfo->bdrv) {
9ae3a8
         DB_PRINT_L(0, "Binding to IF_MTD drive\n");
9ae3a8
         s->bdrv = dinfo->bdrv;
9ae3a8
+        if (bdrv_is_read_only(s->bdrv)) {
9ae3a8
+            fprintf(stderr, "Can't use a read-only drive");
9ae3a8
+            return 1;
9ae3a8
+        }
9ae3a8
+
9ae3a8
         /* FIXME: Move to late init */
9ae3a8
         if (bdrv_read(s->bdrv, 0, s->storage, DIV_ROUND_UP(s->size,
9ae3a8
                                                     BDRV_SECTOR_SIZE))) {
9ae3a8
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
9ae3a8
index 2d4d263..498f2e9 100644
9ae3a8
--- a/hw/block/xen_disk.c
9ae3a8
+++ b/hw/block/xen_disk.c
9ae3a8
@@ -817,6 +817,11 @@ static int blk_connect(struct XenDevice *xendev)
9ae3a8
         /* setup via qemu cmdline -> already setup for us */
9ae3a8
         xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n");
9ae3a8
         blkdev->bs = blkdev->dinfo->bdrv;
9ae3a8
+        if (bdrv_is_read_only(blkdev->bs) && !readonly) {
9ae3a8
+            xen_be_printf(&blkdev->xendev, 0, "Unexpected read-only drive");
9ae3a8
+            blkdev->bs = NULL;
9ae3a8
+            return -1;
9ae3a8
+        }
9ae3a8
     }
9ae3a8
     bdrv_attach_dev_nofail(blkdev->bs, blkdev);
9ae3a8
     blkdev->file_size = bdrv_getlength(blkdev->bs);
9ae3a8
diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c
9ae3a8
index d5944bc..a7dfbff 100644
9ae3a8
--- a/hw/sd/milkymist-memcard.c
9ae3a8
+++ b/hw/sd/milkymist-memcard.c
9ae3a8
@@ -251,6 +251,10 @@ static int milkymist_memcard_init(SysBusDevice *dev)
9ae3a8
 
9ae3a8
     dinfo = drive_get_next(IF_SD);
9ae3a8
     s->card = sd_init(dinfo ? dinfo->bdrv : NULL, 0);
9ae3a8
+    if (s->card == NULL) {
9ae3a8
+        return -1;
9ae3a8
+    }
9ae3a8
+
9ae3a8
     s->enabled = dinfo ? bdrv_is_inserted(dinfo->bdrv) : 0;
9ae3a8
 
9ae3a8
     memory_region_init_io(&s->regs_region, &memcard_mmio_ops, s,
9ae3a8
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
9ae3a8
index d4079cd..aefdc3e 100644
9ae3a8
--- a/hw/sd/omap_mmc.c
9ae3a8
+++ b/hw/sd/omap_mmc.c
9ae3a8
@@ -593,6 +593,9 @@ struct omap_mmc_s *omap_mmc_init(hwaddr base,
9ae3a8
 
9ae3a8
     /* Instantiate the storage */
9ae3a8
     s->card = sd_init(bd, 0);
9ae3a8
+    if (s->card == NULL) {
9ae3a8
+        exit(1);
9ae3a8
+    }
9ae3a8
 
9ae3a8
     return s;
9ae3a8
 }
9ae3a8
@@ -618,6 +621,9 @@ struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
9ae3a8
 
9ae3a8
     /* Instantiate the storage */
9ae3a8
     s->card = sd_init(bd, 0);
9ae3a8
+    if (s->card == NULL) {
9ae3a8
+        exit(1);
9ae3a8
+    }
9ae3a8
 
9ae3a8
     s->cdet = qemu_allocate_irqs(omap_mmc_cover_cb, s, 1)[0];
9ae3a8
     sd_set_cb(s->card, NULL, s->cdet);
9ae3a8
diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
9ae3a8
index c5ad890..a7f85b8 100644
9ae3a8
--- a/hw/sd/pl181.c
9ae3a8
+++ b/hw/sd/pl181.c
9ae3a8
@@ -486,6 +486,10 @@ static int pl181_init(SysBusDevice *dev)
9ae3a8
     qdev_init_gpio_out(&s->busdev.qdev, s->cardstatus, 2);
9ae3a8
     dinfo = drive_get_next(IF_SD);
9ae3a8
     s->card = sd_init(dinfo ? dinfo->bdrv : NULL, 0);
9ae3a8
+    if (s->card == NULL) {
9ae3a8
+        return -1;
9ae3a8
+    }
9ae3a8
+
9ae3a8
     return 0;
9ae3a8
 }
9ae3a8
 
9ae3a8
diff --git a/hw/sd/pxa2xx_mmci.c b/hw/sd/pxa2xx_mmci.c
9ae3a8
index 2db1cab..066d523 100644
9ae3a8
--- a/hw/sd/pxa2xx_mmci.c
9ae3a8
+++ b/hw/sd/pxa2xx_mmci.c
9ae3a8
@@ -539,6 +539,9 @@ PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,
9ae3a8
 
9ae3a8
     /* Instantiate the actual storage */
9ae3a8
     s->card = sd_init(bd, 0);
9ae3a8
+    if (s->card == NULL) {
9ae3a8
+        exit(1);
9ae3a8
+    }
9ae3a8
 
9ae3a8
     register_savevm(NULL, "pxa2xx_mmci", 0, 0,
9ae3a8
                     pxa2xx_mmci_save, pxa2xx_mmci_load, s);
9ae3a8
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
9ae3a8
index 2e0ef3e..e816c78 100644
9ae3a8
--- a/hw/sd/sd.c
9ae3a8
+++ b/hw/sd/sd.c
9ae3a8
@@ -492,6 +492,11 @@ SDState *sd_init(BlockDriverState *bs, bool is_spi)
9ae3a8
 {
9ae3a8
     SDState *sd;
9ae3a8
 
9ae3a8
+    if (bdrv_is_read_only(bs)) {
9ae3a8
+        fprintf(stderr, "sd_init: Cannot use read-only drive\n");
9ae3a8
+        return NULL;
9ae3a8
+    }
9ae3a8
+
9ae3a8
     sd = (SDState *) g_malloc0(sizeof(SDState));
9ae3a8
     sd->buf = qemu_blockalign(bs, 512);
9ae3a8
     sd->spi = is_spi;
9ae3a8
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
9ae3a8
index 91dc9b0..d8a4987 100644
9ae3a8
--- a/hw/sd/sdhci.c
9ae3a8
+++ b/hw/sd/sdhci.c
9ae3a8
@@ -1166,6 +1166,9 @@ static void sdhci_initfn(Object *obj)
9ae3a8
 
9ae3a8
     di = drive_get_next(IF_SD);
9ae3a8
     s->card = sd_init(di ? di->bdrv : NULL, 0);
9ae3a8
+    if (s->card == NULL) {
9ae3a8
+        exit(1);
9ae3a8
+    }
9ae3a8
     s->eject_cb = qemu_allocate_irqs(sdhci_insert_eject_cb, s, 1)[0];
9ae3a8
     s->ro_cb = qemu_allocate_irqs(sdhci_card_readonly_cb, s, 1)[0];
9ae3a8
     sd_set_cb(s->card, s->ro_cb, s->eject_cb);
9ae3a8
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
9ae3a8
index 4d3c4f6..79ec51a 100644
9ae3a8
--- a/hw/sd/ssi-sd.c
9ae3a8
+++ b/hw/sd/ssi-sd.c
9ae3a8
@@ -246,6 +246,9 @@ static int ssi_sd_init(SSISlave *dev)
9ae3a8
     s->mode = SSI_SD_CMD;
9ae3a8
     dinfo = drive_get_next(IF_SD);
9ae3a8
     s->sd = sd_init(dinfo ? dinfo->bdrv : NULL, 1);
9ae3a8
+    if (s->sd == NULL) {
9ae3a8
+        return -1;
9ae3a8
+    }
9ae3a8
     register_savevm(&dev->qdev, "ssi_sd", -1, 1, ssi_sd_save, ssi_sd_load, s);
9ae3a8
     return 0;
9ae3a8
 }
9ae3a8
diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out
9ae3a8
index 54a6b3a..4fca1ca 100644
9ae3a8
--- a/tests/qemu-iotests/051.out
9ae3a8
+++ b/tests/qemu-iotests/051.out
9ae3a8
@@ -98,7 +98,10 @@ QEMU X.Y.Z monitor - type 'help' for more information
9ae3a8
 (qemu) q?[K?[Dqu?[K?[D?[Dqui?[K?[D?[D?[Dquit?[K
9ae3a8
 
9ae3a8
 Testing: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on
9ae3a8
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on: read-only not supported by this bus type
9ae3a8
+QEMU X.Y.Z monitor - type 'help' for more information
9ae3a8
+(qemu) QEMU_PROG: Can't use a read-only drive
9ae3a8
+QEMU_PROG: Device initialization failed.
9ae3a8
+QEMU_PROG: Initialization of device ide-hd failed
9ae3a8
 
9ae3a8
 Testing: -drive file=TEST_DIR/t.qcow2,if=virtio,readonly=on
9ae3a8
 QEMU X.Y.Z monitor - type 'help' for more information
9ae3a8
-- 
9ae3a8
1.7.1
9ae3a8