From nobody Mon Apr 29 07:01:27 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1513265176051957.7729934891764; Thu, 14 Dec 2017 07:26:16 -0800 (PST) Received: from localhost ([::1]:41567 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ePVOk-0005IO-B6 for importer@patchew.org; Thu, 14 Dec 2017 10:26:10 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45923) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ePVLc-00031n-Ji for qemu-devel@nongnu.org; Thu, 14 Dec 2017 10:22:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ePVLY-00032R-GZ for qemu-devel@nongnu.org; Thu, 14 Dec 2017 10:22:56 -0500 Received: from mx2.suse.de ([195.135.220.15]:32862) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ePVLY-000310-7o for qemu-devel@nongnu.org; Thu, 14 Dec 2017 10:22:52 -0500 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 749CEAE9F; Thu, 14 Dec 2017 15:22:50 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Hannes Reinecke To: Paolo Bonzini Date: Thu, 14 Dec 2017 16:22:45 +0100 Message-Id: <20171214152246.17503-2-hare@suse.de> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171214152246.17503-1-hare@suse.de> References: <20171214152246.17503-1-hare@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Received-From: 195.135.220.15 Subject: [Qemu-devel] [PATCH 1/2] block: implement shared block device count X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Hannes Reinecke , qemu-devel@nongnu.org, Hannes Reinecke Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" By setting 'locking=3Doff' when creating a 'file' format drive one can simulate a multipath setup. This patch adds infrastructure for tracking shared block devices. Signed-off-by: Hannes Reinecke --- block.c | 36 ++++++++++++++++++++++++++++++++++++ hw/scsi/scsi-disk.c | 6 ++++++ include/block/block.h | 2 ++ include/block/block_int.h | 2 ++ 4 files changed, 46 insertions(+) diff --git a/block.c b/block.c index 9a1a0d1e73..cf8b94252c 100644 --- a/block.c +++ b/block.c @@ -3801,6 +3801,42 @@ BlockDriverState *bdrv_find_node(const char *node_na= me) return NULL; } =20 +void bdrv_find_shared(BlockDriverState *bs) +{ + BlockDriverState *tmp_bs; + int max_shared_no =3D 0; + unsigned long shared_bits =3D 0; + + if (!bs->filename) + return; + QTAILQ_FOREACH(tmp_bs, &graph_bdrv_states, node_list) { + if (tmp_bs =3D=3D bs) + continue; + if (!strcmp(bs->filename, tmp_bs->filename)) { + if (tmp_bs->shared_no > 0) { + set_bit(tmp_bs->shared_no - 1, &shared_bits); + } + max_shared_no++; + } + } + if (max_shared_no > 0) { + int bit; + + QTAILQ_FOREACH(tmp_bs, &graph_bdrv_states, node_list) { + if (!strcmp(bs->filename, tmp_bs->filename) && !tmp_bs->shared= _no) { + bit =3D find_first_zero_bit(&shared_bits, sizeof(unsigned = long)); + tmp_bs->shared_no =3D bit + 1; + set_bit(bit, &shared_bits); + } + } + } +} + +int bdrv_get_shared(BlockDriverState *bs) +{ + return bs->shared_no; +} + /* Put this QMP function here so it can access the static graph_bdrv_state= s. */ BlockDeviceInfoList *bdrv_named_nodes_list(Error **errp) { diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index 12431177a7..32c1d656b1 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -2333,6 +2333,7 @@ static void scsi_realize(SCSIDevice *dev, Error **err= p) { SCSIDiskState *s =3D DO_UPCAST(SCSIDiskState, qdev, dev); Error *err =3D NULL; + int port_no; =20 if (!s->qdev.conf.blk) { error_setg(errp, "drive property not set"); @@ -2396,6 +2397,11 @@ static void scsi_realize(SCSIDevice *dev, Error **er= rp) blk_set_guest_block_size(s->qdev.conf.blk, s->qdev.blocksize); =20 blk_iostatus_enable(s->qdev.conf.blk); + bdrv_find_shared(blk_bs(s->qdev.conf.blk)); + port_no =3D bdrv_get_shared(blk_bs(s->qdev.conf.blk)); + if (port_no && !s->port_index) { + s->port_index =3D port_no; + } } =20 static void scsi_hd_realize(SCSIDevice *dev, Error **errp) diff --git a/include/block/block.h b/include/block/block.h index c05cac57e5..5c03c1acfa 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -443,6 +443,8 @@ void bdrv_lock_medium(BlockDriverState *bs, bool locked= ); void bdrv_eject(BlockDriverState *bs, bool eject_flag); const char *bdrv_get_format_name(BlockDriverState *bs); BlockDriverState *bdrv_find_node(const char *node_name); +void bdrv_find_shared(BlockDriverState *bs); +int bdrv_get_shared(BlockDriverState *bs); BlockDeviceInfoList *bdrv_named_nodes_list(Error **errp); BlockDriverState *bdrv_lookup_bs(const char *device, const char *node_name, diff --git a/include/block/block_int.h b/include/block/block_int.h index a5482775ec..79c9c3a3aa 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -634,6 +634,8 @@ struct BlockDriverState { /* Flags honored during pwrite_zeroes (so far: BDRV_REQ_FUA, * BDRV_REQ_MAY_UNMAP) */ unsigned int supported_zero_flags; + /* Shared instance count */ + unsigned int shared_no; =20 /* the following member gives a name to every node on the bs graph. */ char node_name[32]; --=20 2.12.3 From nobody Mon Apr 29 07:01:27 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1513265107067169.57662684990396; Thu, 14 Dec 2017 07:25:07 -0800 (PST) Received: from localhost ([::1]:41552 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ePVNa-0004Jb-DO for importer@patchew.org; Thu, 14 Dec 2017 10:24:58 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45921) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ePVLc-00031k-JY for qemu-devel@nongnu.org; Thu, 14 Dec 2017 10:22:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ePVLY-00032W-Gu for qemu-devel@nongnu.org; Thu, 14 Dec 2017 10:22:56 -0500 Received: from mx2.suse.de ([195.135.220.15]:32861) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ePVLY-000311-7t for qemu-devel@nongnu.org; Thu, 14 Dec 2017 10:22:52 -0500 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 6EBB5ADF3; Thu, 14 Dec 2017 15:22:50 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Hannes Reinecke To: Paolo Bonzini Date: Thu, 14 Dec 2017 16:22:46 +0100 Message-Id: <20171214152246.17503-3-hare@suse.de> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171214152246.17503-1-hare@suse.de> References: <20171214152246.17503-1-hare@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Received-From: 195.135.220.15 Subject: [Qemu-devel] [PATCH 2/2] scsi: Implement multipath support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Hannes Reinecke , qemu-devel@nongnu.org, Hannes Reinecke Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Implement simple multipath support based on the shared block device feature. Whenever a shared device is detected the scsi-disk driver will report a simple ALUA setup with all paths in active/optimized. Signed-off-by: Hannes Reinecke --- block.c | 15 +++++++++++ hw/scsi/scsi-disk.c | 66 ++++++++++++++++++++++++++++++++++++++++++++= ++++ include/block/block.h | 1 + include/scsi/constants.h | 5 ++++ 4 files changed, 87 insertions(+) diff --git a/block.c b/block.c index cf8b94252c..e0643989e5 100644 --- a/block.c +++ b/block.c @@ -3837,6 +3837,21 @@ int bdrv_get_shared(BlockDriverState *bs) return bs->shared_no; } =20 +void bdrv_shared_mask(BlockDriverState *bs, unsigned long *shared_mask) +{ + BlockDriverState *tmp_bs; + + if (!bs->filename || !shared_mask) + return; + QTAILQ_FOREACH(tmp_bs, &graph_bdrv_states, node_list) { + if (!strcmp(bs->filename, tmp_bs->filename)) { + if (tmp_bs->shared_no > 0) { + set_bit(tmp_bs->shared_no - 1, shared_mask); + } + } + } +} + /* Put this QMP function here so it can access the static graph_bdrv_state= s. */ BlockDeviceInfoList *bdrv_named_nodes_list(Error **errp) { diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index 32c1d656b1..b73fcafc29 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -676,6 +676,13 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req,= uint8_t *outbuf) buflen +=3D 8; } =20 + if (bdrv_get_shared(blk_bs(s->qdev.conf.blk))) { + outbuf[buflen++] =3D 0x61; // SAS / Binary + outbuf[buflen++] =3D 0x95; // PIV / Target port / target p= ort group + outbuf[buflen++] =3D 0; // reserved + outbuf[buflen++] =3D 4; + buflen +=3D 4; + } if (s->port_index) { outbuf[buflen++] =3D 0x61; // SAS / Binary outbuf[buflen++] =3D 0x94; // PIV / Target port / relative= target port @@ -819,6 +826,11 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req,= uint8_t *outbuf) outbuf[4] =3D 36 - 5; } =20 + /* Enable TGPS bit */ + if (bdrv_get_shared(blk_bs(s->qdev.conf.blk))) { + outbuf[5] =3D 0x10; + } + /* Sync data transfer and TCQ. */ outbuf[7] =3D 0x10 | (req->bus->info->tcq ? 0x02 : 0); return buflen; @@ -1869,6 +1881,47 @@ static void scsi_disk_emulate_write_data(SCSIRequest= *req) } } =20 +static int scsi_emulate_report_target_port_groups(SCSIDiskState *s, + uint8_t *inbuf) +{ + uint8_t *p, *pg; + int buflen =3D 0, i, count =3D 0; + unsigned long shared_mask =3D 0; + + if (!bdrv_get_shared(blk_bs(s->qdev.conf.blk))) { + return -1; + } + + bdrv_shared_mask(blk_bs(s->qdev.conf.blk), &shared_mask); + if (!shared_mask) { + return -1; + } + + pg =3D &inbuf[4]; + pg[0] =3D 0; /* Active/Optimized */ + pg[1] =3D 0x1; /* Only Active/Optimized is supported */ + + p =3D &pg[8]; + buflen +=3D 8; + for (i =3D 0; i < 32; i++) { + if (!test_bit(i, &shared_mask)) + continue; + p[2] =3D (i + 1) >> 8; + p[3] =3D (i + 1) & 0xFF; + p +=3D 4; + buflen +=3D 4; + count++; + } + pg[7] =3D count; + + inbuf[0] =3D (buflen >> 24) & 0xff; + inbuf[1] =3D (buflen >> 16) & 0xff; + inbuf[2] =3D (buflen >> 8) & 0xff; + inbuf[3] =3D buflen & 0xff; + + return buflen + 4; +} + static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf) { SCSIDiskReq *r =3D DO_UPCAST(SCSIDiskReq, req, req); @@ -2010,6 +2063,19 @@ static int32_t scsi_disk_emulate_command(SCSIRequest= *req, uint8_t *buf) goto illegal_request; } break; + case MAINTENANCE_IN: + if ((req->cmd.buf[1] & 31) =3D=3D MI_REPORT_TARGET_PORT_GROUPS) { + DPRINTF("MI REPORT TARGET PORT GROUPS\n"); + memset(outbuf, 0, req->cmd.xfer); + buflen =3D scsi_emulate_report_target_port_groups(s, outbuf); + if (buflen < 0) { + goto illegal_request; + } + break; + } + DPRINTF("Unsupported Maintenance In\n"); + goto illegal_request; + break; case MECHANISM_STATUS: buflen =3D scsi_emulate_mechanism_status(s, outbuf); if (buflen < 0) { diff --git a/include/block/block.h b/include/block/block.h index 5c03c1acfa..b31e033702 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -445,6 +445,7 @@ const char *bdrv_get_format_name(BlockDriverState *bs); BlockDriverState *bdrv_find_node(const char *node_name); void bdrv_find_shared(BlockDriverState *bs); int bdrv_get_shared(BlockDriverState *bs); +void bdrv_shared_mask(BlockDriverState *bs, unsigned long *shared_mask); BlockDeviceInfoList *bdrv_named_nodes_list(Error **errp); BlockDriverState *bdrv_lookup_bs(const char *device, const char *node_name, diff --git a/include/scsi/constants.h b/include/scsi/constants.h index a141dd71f8..38ed4b35e4 100644 --- a/include/scsi/constants.h +++ b/include/scsi/constants.h @@ -156,6 +156,11 @@ #define SAI_READ_CAPACITY_16 0x10 =20 /* + * MAINTENANCE IN subcodes + */ +#define MI_REPORT_TARGET_PORT_GROUPS 0xa + +/* * READ POSITION service action codes */ #define SHORT_FORM_BLOCK_ID 0x00 --=20 2.12.3