188 lines
6.1 KiB
Diff
188 lines
6.1 KiB
Diff
|
From acf3927aef42a4a380fa1366b2eca8a8f2b44bc4 Mon Sep 17 00:00:00 2001
|
||
|
From: Markus Armbruster <armbru@redhat.com>
|
||
|
Date: Thu, 7 Feb 2019 12:18:18 +0000
|
||
|
Subject: [PATCH 7/8] scsi-disk: Acquire the AioContext in scsi_*_realize()
|
||
|
|
||
|
RH-Author: Markus Armbruster <armbru@redhat.com>
|
||
|
Message-id: <20190207121819.20092-3-armbru@redhat.com>
|
||
|
Patchwork-id: 84291
|
||
|
O-Subject: [RHEL-8.0/AV qemu-kvm PATCH 2/3] scsi-disk: Acquire the AioContext in scsi_*_realize()
|
||
|
Bugzilla: 1656276 1662508
|
||
|
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||
|
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
||
|
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||
|
|
||
|
From: Alberto Garcia <berto@igalia.com>
|
||
|
|
||
|
This fixes a crash when attaching two disks with the same blockdev to
|
||
|
a SCSI device that is using iothreads. Test case included.
|
||
|
|
||
|
Signed-off-by: Alberto Garcia <berto@igalia.com>
|
||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||
|
(cherry picked from commit 3ff35ba391134e4e43ab96152deb38a62e62f858)
|
||
|
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
||
|
---
|
||
|
hw/scsi/scsi-disk.c | 23 ++++++++++++++++++++---
|
||
|
tests/qemu-iotests/240 | 18 ++++++++++++++++++
|
||
|
tests/qemu-iotests/240.out | 16 ++++++++++++++++
|
||
|
3 files changed, 54 insertions(+), 3 deletions(-)
|
||
|
|
||
|
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
|
||
|
index e74e1e7..e6db6d7 100644
|
||
|
--- a/hw/scsi/scsi-disk.c
|
||
|
+++ b/hw/scsi/scsi-disk.c
|
||
|
@@ -2389,10 +2389,13 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
|
||
|
static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
|
||
|
{
|
||
|
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
|
||
|
+ AioContext *ctx = NULL;
|
||
|
/* can happen for devices without drive. The error message for missing
|
||
|
* backend will be issued in scsi_realize
|
||
|
*/
|
||
|
if (s->qdev.conf.blk) {
|
||
|
+ ctx = blk_get_aio_context(s->qdev.conf.blk);
|
||
|
+ aio_context_acquire(ctx);
|
||
|
blkconf_blocksizes(&s->qdev.conf);
|
||
|
}
|
||
|
s->qdev.blocksize = s->qdev.conf.logical_block_size;
|
||
|
@@ -2401,11 +2404,15 @@ static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
|
||
|
s->product = g_strdup("QEMU HARDDISK");
|
||
|
}
|
||
|
scsi_realize(&s->qdev, errp);
|
||
|
+ if (ctx) {
|
||
|
+ aio_context_release(ctx);
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
|
||
|
{
|
||
|
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
|
||
|
+ AioContext *ctx;
|
||
|
int ret;
|
||
|
|
||
|
if (!dev->conf.blk) {
|
||
|
@@ -2416,6 +2423,8 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
|
||
|
assert(ret == 0);
|
||
|
}
|
||
|
|
||
|
+ ctx = blk_get_aio_context(dev->conf.blk);
|
||
|
+ aio_context_acquire(ctx);
|
||
|
s->qdev.blocksize = 2048;
|
||
|
s->qdev.type = TYPE_ROM;
|
||
|
s->features |= 1 << SCSI_DISK_F_REMOVABLE;
|
||
|
@@ -2423,6 +2432,7 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
|
||
|
s->product = g_strdup("QEMU CD-ROM");
|
||
|
}
|
||
|
scsi_realize(&s->qdev, errp);
|
||
|
+ aio_context_release(ctx);
|
||
|
}
|
||
|
|
||
|
static void scsi_disk_realize(SCSIDevice *dev, Error **errp)
|
||
|
@@ -2561,6 +2571,7 @@ static int get_device_type(SCSIDiskState *s)
|
||
|
static void scsi_block_realize(SCSIDevice *dev, Error **errp)
|
||
|
{
|
||
|
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
|
||
|
+ AioContext *ctx;
|
||
|
int sg_version;
|
||
|
int rc;
|
||
|
|
||
|
@@ -2575,6 +2586,9 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
|
||
|
"be removed in a future version");
|
||
|
}
|
||
|
|
||
|
+ ctx = blk_get_aio_context(s->qdev.conf.blk);
|
||
|
+ aio_context_acquire(ctx);
|
||
|
+
|
||
|
/* check we are using a driver managing SG_IO (version 3 and after) */
|
||
|
rc = blk_ioctl(s->qdev.conf.blk, SG_GET_VERSION_NUM, &sg_version);
|
||
|
if (rc < 0) {
|
||
|
@@ -2582,18 +2596,18 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
|
||
|
if (rc != -EPERM) {
|
||
|
error_append_hint(errp, "Is this a SCSI device?\n");
|
||
|
}
|
||
|
- return;
|
||
|
+ goto out;
|
||
|
}
|
||
|
if (sg_version < 30000) {
|
||
|
error_setg(errp, "scsi generic interface too old");
|
||
|
- return;
|
||
|
+ goto out;
|
||
|
}
|
||
|
|
||
|
/* get device type from INQUIRY data */
|
||
|
rc = get_device_type(s);
|
||
|
if (rc < 0) {
|
||
|
error_setg(errp, "INQUIRY failed");
|
||
|
- return;
|
||
|
+ goto out;
|
||
|
}
|
||
|
|
||
|
/* Make a guess for the block size, we'll fix it when the guest sends.
|
||
|
@@ -2613,6 +2627,9 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
|
||
|
|
||
|
scsi_realize(&s->qdev, errp);
|
||
|
scsi_generic_read_device_inquiry(&s->qdev);
|
||
|
+
|
||
|
+out:
|
||
|
+ aio_context_release(ctx);
|
||
|
}
|
||
|
|
||
|
typedef struct SCSIBlockReq {
|
||
|
diff --git a/tests/qemu-iotests/240 b/tests/qemu-iotests/240
|
||
|
index ead7ee0..5d499c9 100755
|
||
|
--- a/tests/qemu-iotests/240
|
||
|
+++ b/tests/qemu-iotests/240
|
||
|
@@ -83,6 +83,24 @@ run_qemu <<EOF
|
||
|
{ "execute": "quit"}
|
||
|
EOF
|
||
|
|
||
|
+echo
|
||
|
+echo === Attach two SCSI disks using the same block device and the same iothread ===
|
||
|
+echo
|
||
|
+
|
||
|
+run_qemu <<EOF
|
||
|
+{ "execute": "qmp_capabilities" }
|
||
|
+{ "execute": "blockdev-add", "arguments": {"driver": "null-co", "node-name": "hd0", "read-only": true}}
|
||
|
+{ "execute": "object-add", "arguments": {"qom-type": "iothread", "id": "iothread0"}}
|
||
|
+{ "execute": "device_add", "arguments": {"id": "scsi0", "driver": "${virtio_scsi}", "iothread": "iothread0"}}
|
||
|
+{ "execute": "device_add", "arguments": {"id": "scsi-hd0", "driver": "scsi-hd", "drive": "hd0"}}
|
||
|
+{ "execute": "device_add", "arguments": {"id": "scsi-hd1", "driver": "scsi-hd", "drive": "hd0"}}
|
||
|
+{ "execute": "device_del", "arguments": {"id": "scsi-hd0"}}
|
||
|
+{ "execute": "device_del", "arguments": {"id": "scsi-hd1"}}
|
||
|
+{ "execute": "device_del", "arguments": {"id": "scsi0"}}
|
||
|
+{ "execute": "blockdev-del", "arguments": {"node-name": "hd0"}}
|
||
|
+{ "execute": "quit"}
|
||
|
+EOF
|
||
|
+
|
||
|
# success, all done
|
||
|
echo "*** done"
|
||
|
rm -f $seq.full
|
||
|
diff --git a/tests/qemu-iotests/240.out b/tests/qemu-iotests/240.out
|
||
|
index 432d981..701cb5c 100644
|
||
|
--- a/tests/qemu-iotests/240.out
|
||
|
+++ b/tests/qemu-iotests/240.out
|
||
|
@@ -15,4 +15,20 @@ QMP_VERSION
|
||
|
{"return": {}}
|
||
|
{"return": {}}
|
||
|
{"return": {}}
|
||
|
+
|
||
|
+=== Attach two SCSI disks using the same block device and the same iothread ===
|
||
|
+
|
||
|
+Testing:
|
||
|
+QMP_VERSION
|
||
|
+{"return": {}}
|
||
|
+{"return": {}}
|
||
|
+{"return": {}}
|
||
|
+{"return": {}}
|
||
|
+{"return": {}}
|
||
|
+{"return": {}}
|
||
|
+{"return": {}}
|
||
|
+{"return": {}}
|
||
|
+{"return": {}}
|
||
|
+{"return": {}}
|
||
|
+{"return": {}}
|
||
|
*** done
|
||
|
--
|
||
|
1.8.3.1
|
||
|
|