From e47b913ba52ead235fd3a03916d62ce49254c575 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 10 May 2019 13:28:24 +0200 Subject: [PATCH 21/53] scsi-disk: Acquire the AioContext in scsi_*_realize() RH-Author: Markus Armbruster Message-id: <20190510132825.29833-3-armbru@redhat.com> Patchwork-id: 87265 O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH 2/3] scsi-disk: Acquire the AioContext in scsi_*_realize() Bugzilla: 1673397 1673402 RH-Acked-by: Paolo Bonzini RH-Acked-by: Max Reitz RH-Acked-by: Kevin Wolf From: Alberto Garcia 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 Signed-off-by: Kevin Wolf (cherry picked from commit 3ff35ba391134e4e43ab96152deb38a62e62f858) [Trivial conflict in hw/scsi/scsi-disk.c due to lack of commit 51f43d5792e resolved] Signed-off-by: Markus Armbruster Signed-off-by: Miroslav Rezanina --- 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 8033d7e..6cc5ccc 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -2386,10 +2386,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; @@ -2398,11 +2401,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) { @@ -2413,6 +2420,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; @@ -2420,6 +2429,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) @@ -2558,6 +2568,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; @@ -2566,6 +2577,9 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp) return; } + 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) { @@ -2573,18 +2587,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. @@ -2604,6 +2618,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 <