yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone

Blame SOURCES/kvm-scsi-disk-Acquire-the-AioContext-in-scsi_-_realize.patch

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