|
|
69f3e1 |
From e0999eaacc6e74f5e56f51fcf3b3d7aeca7d3b04 Mon Sep 17 00:00:00 2001
|
|
|
69f3e1 |
From: Markus Armbruster <armbru@redhat.com>
|
|
|
69f3e1 |
Date: Thu, 6 Jun 2019 19:15:23 +0100
|
|
|
69f3e1 |
Subject: [PATCH 6/7] scsi-disk: Acquire the AioContext in scsi_*_realize()
|
|
|
69f3e1 |
|
|
|
69f3e1 |
RH-Author: Markus Armbruster <armbru@redhat.com>
|
|
|
69f3e1 |
Message-id: <20190606191524.30797-3-armbru@redhat.com>
|
|
|
69f3e1 |
Patchwork-id: 88605
|
|
|
69f3e1 |
O-Subject: [RHEL-8.1.0 qemu-kvm PATCH 2/3] scsi-disk: Acquire the AioContext in scsi_*_realize()
|
|
|
69f3e1 |
Bugzilla: 1718992
|
|
|
69f3e1 |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
69f3e1 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
69f3e1 |
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
69f3e1 |
|
|
|
69f3e1 |
From: Alberto Garcia <berto@igalia.com>
|
|
|
69f3e1 |
|
|
|
69f3e1 |
This fixes a crash when attaching two disks with the same blockdev to
|
|
|
69f3e1 |
a SCSI device that is using iothreads. Test case included.
|
|
|
69f3e1 |
|
|
|
69f3e1 |
Signed-off-by: Alberto Garcia <berto@igalia.com>
|
|
|
69f3e1 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
69f3e1 |
(cherry picked from commit 3ff35ba391134e4e43ab96152deb38a62e62f858)
|
|
|
69f3e1 |
[Trivial conflict in hw/scsi/scsi-disk.c due to lack of commit
|
|
|
69f3e1 |
51f43d5792e resolved]
|
|
|
69f3e1 |
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
|
|
69f3e1 |
|
|
|
69f3e1 |
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
|
|
69f3e1 |
---
|
|
|
69f3e1 |
hw/scsi/scsi-disk.c | 23 ++++++++++++++++++++---
|
|
|
69f3e1 |
tests/qemu-iotests/240 | 18 ++++++++++++++++++
|
|
|
69f3e1 |
tests/qemu-iotests/240.out | 16 ++++++++++++++++
|
|
|
69f3e1 |
3 files changed, 54 insertions(+), 3 deletions(-)
|
|
|
69f3e1 |
|
|
|
69f3e1 |
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
|
|
|
69f3e1 |
index a20ef91..08da23d 100644
|
|
|
69f3e1 |
--- a/hw/scsi/scsi-disk.c
|
|
|
69f3e1 |
+++ b/hw/scsi/scsi-disk.c
|
|
|
69f3e1 |
@@ -2378,10 +2378,13 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
|
|
|
69f3e1 |
static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
|
|
|
69f3e1 |
{
|
|
|
69f3e1 |
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
|
|
|
69f3e1 |
+ AioContext *ctx = NULL;
|
|
|
69f3e1 |
/* can happen for devices without drive. The error message for missing
|
|
|
69f3e1 |
* backend will be issued in scsi_realize
|
|
|
69f3e1 |
*/
|
|
|
69f3e1 |
if (s->qdev.conf.blk) {
|
|
|
69f3e1 |
+ ctx = blk_get_aio_context(s->qdev.conf.blk);
|
|
|
69f3e1 |
+ aio_context_acquire(ctx);
|
|
|
69f3e1 |
blkconf_blocksizes(&s->qdev.conf);
|
|
|
69f3e1 |
}
|
|
|
69f3e1 |
s->qdev.blocksize = s->qdev.conf.logical_block_size;
|
|
|
69f3e1 |
@@ -2390,11 +2393,15 @@ static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
|
|
|
69f3e1 |
s->product = g_strdup("QEMU HARDDISK");
|
|
|
69f3e1 |
}
|
|
|
69f3e1 |
scsi_realize(&s->qdev, errp);
|
|
|
69f3e1 |
+ if (ctx) {
|
|
|
69f3e1 |
+ aio_context_release(ctx);
|
|
|
69f3e1 |
+ }
|
|
|
69f3e1 |
}
|
|
|
69f3e1 |
|
|
|
69f3e1 |
static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
|
|
|
69f3e1 |
{
|
|
|
69f3e1 |
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
|
|
|
69f3e1 |
+ AioContext *ctx;
|
|
|
69f3e1 |
int ret;
|
|
|
69f3e1 |
|
|
|
69f3e1 |
if (!dev->conf.blk) {
|
|
|
69f3e1 |
@@ -2405,6 +2412,8 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
|
|
|
69f3e1 |
assert(ret == 0);
|
|
|
69f3e1 |
}
|
|
|
69f3e1 |
|
|
|
69f3e1 |
+ ctx = blk_get_aio_context(dev->conf.blk);
|
|
|
69f3e1 |
+ aio_context_acquire(ctx);
|
|
|
69f3e1 |
s->qdev.blocksize = 2048;
|
|
|
69f3e1 |
s->qdev.type = TYPE_ROM;
|
|
|
69f3e1 |
s->features |= 1 << SCSI_DISK_F_REMOVABLE;
|
|
|
69f3e1 |
@@ -2412,6 +2421,7 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
|
|
|
69f3e1 |
s->product = g_strdup("QEMU CD-ROM");
|
|
|
69f3e1 |
}
|
|
|
69f3e1 |
scsi_realize(&s->qdev, errp);
|
|
|
69f3e1 |
+ aio_context_release(ctx);
|
|
|
69f3e1 |
}
|
|
|
69f3e1 |
|
|
|
69f3e1 |
static void scsi_disk_realize(SCSIDevice *dev, Error **errp)
|
|
|
69f3e1 |
@@ -2550,6 +2560,7 @@ static int get_device_type(SCSIDiskState *s)
|
|
|
69f3e1 |
static void scsi_block_realize(SCSIDevice *dev, Error **errp)
|
|
|
69f3e1 |
{
|
|
|
69f3e1 |
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
|
|
|
69f3e1 |
+ AioContext *ctx;
|
|
|
69f3e1 |
int sg_version;
|
|
|
69f3e1 |
int rc;
|
|
|
69f3e1 |
|
|
|
69f3e1 |
@@ -2558,6 +2569,9 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
|
|
|
69f3e1 |
return;
|
|
|
69f3e1 |
}
|
|
|
69f3e1 |
|
|
|
69f3e1 |
+ ctx = blk_get_aio_context(s->qdev.conf.blk);
|
|
|
69f3e1 |
+ aio_context_acquire(ctx);
|
|
|
69f3e1 |
+
|
|
|
69f3e1 |
/* check we are using a driver managing SG_IO (version 3 and after) */
|
|
|
69f3e1 |
rc = blk_ioctl(s->qdev.conf.blk, SG_GET_VERSION_NUM, &sg_version);
|
|
|
69f3e1 |
if (rc < 0) {
|
|
|
69f3e1 |
@@ -2565,18 +2579,18 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
|
|
|
69f3e1 |
if (rc != -EPERM) {
|
|
|
69f3e1 |
error_append_hint(errp, "Is this a SCSI device?\n");
|
|
|
69f3e1 |
}
|
|
|
69f3e1 |
- return;
|
|
|
69f3e1 |
+ goto out;
|
|
|
69f3e1 |
}
|
|
|
69f3e1 |
if (sg_version < 30000) {
|
|
|
69f3e1 |
error_setg(errp, "scsi generic interface too old");
|
|
|
69f3e1 |
- return;
|
|
|
69f3e1 |
+ goto out;
|
|
|
69f3e1 |
}
|
|
|
69f3e1 |
|
|
|
69f3e1 |
/* get device type from INQUIRY data */
|
|
|
69f3e1 |
rc = get_device_type(s);
|
|
|
69f3e1 |
if (rc < 0) {
|
|
|
69f3e1 |
error_setg(errp, "INQUIRY failed");
|
|
|
69f3e1 |
- return;
|
|
|
69f3e1 |
+ goto out;
|
|
|
69f3e1 |
}
|
|
|
69f3e1 |
|
|
|
69f3e1 |
/* Make a guess for the block size, we'll fix it when the guest sends.
|
|
|
69f3e1 |
@@ -2596,6 +2610,9 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
|
|
|
69f3e1 |
|
|
|
69f3e1 |
scsi_realize(&s->qdev, errp);
|
|
|
69f3e1 |
scsi_generic_read_device_inquiry(&s->qdev);
|
|
|
69f3e1 |
+
|
|
|
69f3e1 |
+out:
|
|
|
69f3e1 |
+ aio_context_release(ctx);
|
|
|
69f3e1 |
}
|
|
|
69f3e1 |
|
|
|
69f3e1 |
typedef struct SCSIBlockReq {
|
|
|
69f3e1 |
diff --git a/tests/qemu-iotests/240 b/tests/qemu-iotests/240
|
|
|
69f3e1 |
index ead7ee0..5d499c9 100755
|
|
|
69f3e1 |
--- a/tests/qemu-iotests/240
|
|
|
69f3e1 |
+++ b/tests/qemu-iotests/240
|
|
|
69f3e1 |
@@ -83,6 +83,24 @@ run_qemu <
|
|
|
69f3e1 |
{ "execute": "quit"}
|
|
|
69f3e1 |
EOF
|
|
|
69f3e1 |
|
|
|
69f3e1 |
+echo
|
|
|
69f3e1 |
+echo === Attach two SCSI disks using the same block device and the same iothread ===
|
|
|
69f3e1 |
+echo
|
|
|
69f3e1 |
+
|
|
|
69f3e1 |
+run_qemu <
|
|
|
69f3e1 |
+{ "execute": "qmp_capabilities" }
|
|
|
69f3e1 |
+{ "execute": "blockdev-add", "arguments": {"driver": "null-co", "node-name": "hd0", "read-only": true}}
|
|
|
69f3e1 |
+{ "execute": "object-add", "arguments": {"qom-type": "iothread", "id": "iothread0"}}
|
|
|
69f3e1 |
+{ "execute": "device_add", "arguments": {"id": "scsi0", "driver": "${virtio_scsi}", "iothread": "iothread0"}}
|
|
|
69f3e1 |
+{ "execute": "device_add", "arguments": {"id": "scsi-hd0", "driver": "scsi-hd", "drive": "hd0"}}
|
|
|
69f3e1 |
+{ "execute": "device_add", "arguments": {"id": "scsi-hd1", "driver": "scsi-hd", "drive": "hd0"}}
|
|
|
69f3e1 |
+{ "execute": "device_del", "arguments": {"id": "scsi-hd0"}}
|
|
|
69f3e1 |
+{ "execute": "device_del", "arguments": {"id": "scsi-hd1"}}
|
|
|
69f3e1 |
+{ "execute": "device_del", "arguments": {"id": "scsi0"}}
|
|
|
69f3e1 |
+{ "execute": "blockdev-del", "arguments": {"node-name": "hd0"}}
|
|
|
69f3e1 |
+{ "execute": "quit"}
|
|
|
69f3e1 |
+EOF
|
|
|
69f3e1 |
+
|
|
|
69f3e1 |
# success, all done
|
|
|
69f3e1 |
echo "*** done"
|
|
|
69f3e1 |
rm -f $seq.full
|
|
|
69f3e1 |
diff --git a/tests/qemu-iotests/240.out b/tests/qemu-iotests/240.out
|
|
|
69f3e1 |
index 432d981..701cb5c 100644
|
|
|
69f3e1 |
--- a/tests/qemu-iotests/240.out
|
|
|
69f3e1 |
+++ b/tests/qemu-iotests/240.out
|
|
|
69f3e1 |
@@ -15,4 +15,20 @@ QMP_VERSION
|
|
|
69f3e1 |
{"return": {}}
|
|
|
69f3e1 |
{"return": {}}
|
|
|
69f3e1 |
{"return": {}}
|
|
|
69f3e1 |
+
|
|
|
69f3e1 |
+=== Attach two SCSI disks using the same block device and the same iothread ===
|
|
|
69f3e1 |
+
|
|
|
69f3e1 |
+Testing:
|
|
|
69f3e1 |
+QMP_VERSION
|
|
|
69f3e1 |
+{"return": {}}
|
|
|
69f3e1 |
+{"return": {}}
|
|
|
69f3e1 |
+{"return": {}}
|
|
|
69f3e1 |
+{"return": {}}
|
|
|
69f3e1 |
+{"return": {}}
|
|
|
69f3e1 |
+{"return": {}}
|
|
|
69f3e1 |
+{"return": {}}
|
|
|
69f3e1 |
+{"return": {}}
|
|
|
69f3e1 |
+{"return": {}}
|
|
|
69f3e1 |
+{"return": {}}
|
|
|
69f3e1 |
+{"return": {}}
|
|
|
69f3e1 |
*** done
|
|
|
69f3e1 |
--
|
|
|
69f3e1 |
1.8.3.1
|
|
|
69f3e1 |
|