summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-02-01 17:58:27 +0000
committerPeter Maydell <peter.maydell@linaro.org>2019-02-01 17:58:27 +0000
commitb3fc0af1ff5e922d4dd7c875394dbd26dc7313b4 (patch)
tree2c59c91e8112e0be05a43543f7d11394f2d52653 /hw
parente83d74286cad2b9b967e1ba0ce5c8d16cba9679f (diff)
parent7471a649fc3a391dd497297013fb2525ca9821ba (diff)
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches: - vmdk: Support for blockdev-create - block: Apply auto-read-only for ro-whitelist drivers - virtio-scsi: Fixes related to attaching/detaching iothreads - scsi-disk: Fixed erroneously detected multipath setup with multiple disks created with node-names. Added device_id property. - block: Fix hangs in synchronous APIs with iothreads - block: Fix invalidate_cache error path for parent activation - block-backend, mirror, qcow2, vpc, vdi, qemu-iotests: Minor fixes and code improvements # gpg: Signature made Fri 01 Feb 2019 15:23:10 GMT # gpg: using RSA key 7F09B272C88F2FD6 # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full] # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * remotes/kevin/tags/for-upstream: (27 commits) scsi-disk: Add device_id property scsi-disk: Don't use empty string as device id qtest.py: Wait for the result of qtest commands block: Fix invalidate_cache error path for parent activation iotests/236: fix transaction kwarg order iotests: Filter second BLOCK_JOB_ERROR from 229 virtio-scsi: Forbid devices with different iothreads sharing a blockdev scsi-disk: Acquire the AioContext in scsi_*_realize() virtio-scsi: Move BlockBackend back to the main AioContext on unplug block: Eliminate the S_1KiB, S_2KiB, ... macros block: Remove blk_attach_dev_legacy() / legacy_dev code block: Apply auto-read-only for ro-whitelist drivers uuid: Make qemu_uuid_bswap() take and return a QemuUUID block/vdi: Don't take address of fields in packed structs block/vpc: Don't take address of fields in packed structs vmdk: Reject excess extents in blockdev-create iotests: Add VMDK tests for blockdev-create iotests: Filter cid numbers in VMDK extent info vmdk: Implement .bdrv_co_create callback vmdk: Refactor vmdk_create_extent ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/acpi/vmgenid.c6
-rw-r--r--hw/scsi/scsi-disk.c59
-rw-r--r--hw/scsi/virtio-scsi.c13
3 files changed, 58 insertions, 20 deletions
diff --git a/hw/acpi/vmgenid.c b/hw/acpi/vmgenid.c
index d78b579a20..02717a8b0d 100644
--- a/hw/acpi/vmgenid.c
+++ b/hw/acpi/vmgenid.c
@@ -30,8 +30,7 @@ void vmgenid_build_acpi(VmGenIdState *vms, GArray *table_data, GArray *guid,
* first, since that's what the guest expects
*/
g_array_set_size(guid, VMGENID_FW_CFG_SIZE - ARRAY_SIZE(guid_le.data));
- guid_le = vms->guid;
- qemu_uuid_bswap(&guid_le);
+ guid_le = qemu_uuid_bswap(vms->guid);
/* The GUID is written at a fixed offset into the fw_cfg file
* in order to implement the "OVMF SDT Header probe suppressor"
* see docs/specs/vmgenid.txt for more details
@@ -149,8 +148,7 @@ static void vmgenid_update_guest(VmGenIdState *vms)
* however, will expect the fields to be little-endian.
* Perform a byte swap immediately before writing.
*/
- guid_le = vms->guid;
- qemu_uuid_bswap(&guid_le);
+ guid_le = qemu_uuid_bswap(vms->guid);
/* The GUID is written at a fixed offset into the fw_cfg file
* in order to implement the "OVMF SDT Header probe suppressor"
* see docs/specs/vmgenid.txt for more details.
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 0e9027c8f3..e6db6d7c15 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -104,6 +104,7 @@ typedef struct SCSIDiskState
char *serial;
char *vendor;
char *product;
+ char *device_id;
bool tray_open;
bool tray_locked;
/*
@@ -642,22 +643,19 @@ static int scsi_disk_emulate_vpd_page(SCSIRequest *req, uint8_t *outbuf)
case 0x83: /* Device identification page, mandatory */
{
- const char *str = s->serial ?: blk_name(s->qdev.conf.blk);
- int max_len = s->serial ? 20 : 255 - 8;
- int id_len = strlen(str);
+ int id_len = s->device_id ? MIN(strlen(s->device_id), 255 - 8) : 0;
- if (id_len > max_len) {
- id_len = max_len;
- }
DPRINTF("Inquiry EVPD[Device identification] "
"buffer size %zd\n", req->cmd.xfer);
- outbuf[buflen++] = 0x2; /* ASCII */
- outbuf[buflen++] = 0; /* not officially assigned */
- outbuf[buflen++] = 0; /* reserved */
- outbuf[buflen++] = id_len; /* length of data following */
- memcpy(outbuf + buflen, str, id_len);
- buflen += id_len;
+ if (id_len) {
+ outbuf[buflen++] = 0x2; /* ASCII */
+ outbuf[buflen++] = 0; /* not officially assigned */
+ outbuf[buflen++] = 0; /* reserved */
+ outbuf[buflen++] = id_len; /* length of data following */
+ memcpy(outbuf + buflen, s->device_id, id_len);
+ buflen += id_len;
+ }
if (s->qdev.wwn) {
outbuf[buflen++] = 0x1; /* Binary */
@@ -2361,6 +2359,16 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
if (!s->vendor) {
s->vendor = g_strdup("QEMU");
}
+ if (!s->device_id) {
+ if (s->serial) {
+ s->device_id = g_strdup_printf("%.20s", s->serial);
+ } else {
+ const char *str = blk_name(s->qdev.conf.blk);
+ if (str && *str) {
+ s->device_id = g_strdup(str);
+ }
+ }
+ }
if (blk_is_sg(s->qdev.conf.blk)) {
error_setg(errp, "unwanted /dev/sg*");
@@ -2381,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;
@@ -2393,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) {
@@ -2408,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;
@@ -2415,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)
@@ -2553,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;
@@ -2567,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) {
@@ -2574,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.
@@ -2605,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 {
@@ -2902,7 +2927,9 @@ static const TypeInfo scsi_disk_base_info = {
DEFINE_PROP_STRING("ver", SCSIDiskState, version), \
DEFINE_PROP_STRING("serial", SCSIDiskState, serial), \
DEFINE_PROP_STRING("vendor", SCSIDiskState, vendor), \
- DEFINE_PROP_STRING("product", SCSIDiskState, product)
+ DEFINE_PROP_STRING("product", SCSIDiskState, product), \
+ DEFINE_PROP_STRING("device_id", SCSIDiskState, device_id)
+
static Property scsi_hd_properties[] = {
DEFINE_SCSI_DISK_PROPERTIES(),
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 3aa99717e2..eb90288f47 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -791,9 +791,16 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
SCSIDevice *sd = SCSI_DEVICE(dev);
if (s->ctx && !s->dataplane_fenced) {
+ AioContext *ctx;
if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) {
return;
}
+ ctx = blk_get_aio_context(sd->conf.blk);
+ if (ctx != s->ctx && ctx != qemu_get_aio_context()) {
+ error_setg(errp, "Cannot attach a blockdev that is using "
+ "a different iothread");
+ return;
+ }
virtio_scsi_acquire(s);
blk_set_aio_context(sd->conf.blk, s->ctx);
virtio_scsi_release(s);
@@ -824,6 +831,12 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,
virtio_scsi_release(s);
}
+ if (s->ctx) {
+ virtio_scsi_acquire(s);
+ blk_set_aio_context(sd->conf.blk, qemu_get_aio_context());
+ virtio_scsi_release(s);
+ }
+
qdev_simple_device_unplug_cb(hotplug_dev, dev, errp);
}