public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCHv2] Add EVPD page 0x83 entries to sysfs
@ 2014-02-10 11:11 Hannes Reinecke
  2014-02-10 14:15 ` Christoph Hellwig
  2014-02-10 18:06 ` Jeremy Linton
  0 siblings, 2 replies; 8+ messages in thread
From: Hannes Reinecke @ 2014-02-10 11:11 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-scsi, Hannes Reinecke, Jeremy Linton, Doug Gilbert,
	Kai Makisara, Martin K. Petersen

EVPD page 0x83 is used to uniquely identify the device.
So instead of having each and every program issue a separate
SG_IO call to retrieve this information it does make far more
sense to display it in sysfs.

Cc: Jeremy Linton <jlinton@tributary.com>
Cc: Doug Gilbert <dgilbert@interlog.com>
Cc: Kai Makisara <kai.makisara@kolumbus.fi>
Cc: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/scsi/scsi_scan.c   |   3 +
 drivers/scsi/scsi_sysfs.c  | 258 ++++++++++++++++++++++++++++++++++++++++++++-
 include/scsi/scsi.h        |   2 +
 include/scsi/scsi_device.h |   3 +
 4 files changed, 265 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 307a811..073fb84 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -929,6 +929,9 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
 	if (*bflags & BLIST_SKIP_VPD_PAGES)
 		sdev->skip_vpd_pages = 1;
 
+	if (sdev->scsi_level >= SCSI_3)
+		scsi_attach_vpd_ident(sdev);
+
 	transport_configure_device(&sdev->sdev_gendev);
 
 	if (sdev->host->hostt->slave_configure) {
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 9117d0b..5cb0dc1 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -415,6 +415,7 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
 
 	scsi_target_reap(scsi_target(sdev));
 
+	kfree(sdev->vpd_ident);
 	kfree(sdev->inquiry);
 	kfree(sdev);
 
@@ -725,8 +726,261 @@ show_queue_type_field(struct device *dev, struct device_attribute *attr,
 
 static DEVICE_ATTR(queue_type, S_IRUGO, show_queue_type_field, NULL);
 
+void scsi_attach_vpd_ident(struct scsi_device *sdev)
+{
+	int ret;
+	int vpd_len = 255;
+	unsigned char *buffer;
+retry:
+	buffer = kmalloc(vpd_len, GFP_KERNEL);
+	if (!buffer)
+		return;
+
+	ret = scsi_get_vpd_page(sdev, 0x83, buffer, vpd_len);
+	if (ret) {
+		kfree(buffer);
+		return;
+	}
+
+	vpd_len = (buffer[2] << 8) + buffer[3];
+	if (vpd_len > 255) {
+		kfree(buffer);
+		goto retry;
+	}
+	sdev->vpd_ident_len = vpd_len;
+	sdev->vpd_ident = buffer;
+}
+
+#define SCSI_VPD_ASSOC_lun 0x0
+#define SCSI_VPD_ASSOC_port 0x1
+#define SCSI_VPD_ASSOC_target 0x2
+
+#define SCSI_VPD_DESIG_vendor 0x0
+#define SCSI_VPD_DESIG_t10 0x1
+#define SCSI_VPD_DESIG_eui 0x2
+#define SCSI_VPD_DESIG_naa 0x3
+#define SCSI_VPD_DESIG_relport 0x4
+#define SCSI_VPD_DESIG_tpgrp 0x5
+#define SCSI_VPD_DESIG_lugrp 0x6
+#define SCSI_VPD_DESIG_md5 0x7
+#define SCSI_VPD_DESIG_scsi_name 0x8
+#define SCSI_VPD_DESIG_proto 0x9
+
+int scsi_parse_vpd_ident(struct scsi_device *sdev,
+			 int assoc, int desig, char *buf)
+{
+	unsigned char *d;
+	int len = 0, j;
+
+	if (!sdev->vpd_ident)
+		return -EINVAL;
+
+	d = sdev->vpd_ident + 4;
+	while (d < sdev->vpd_ident + sdev->vpd_ident_len) {
+		const char *proto = NULL;
+
+		if (((d[1] >> 4) & 0x3) == assoc &&
+		    (d[1] & 0xf) == desig) {
+			if (d[1] & 0x80) {
+				switch (d[0] >> 4) {
+				case SCSI_PROTOCOL_FCP:
+					proto = "fcp";
+					break;
+				case SCSI_PROTOCOL_SPI:
+					proto = "spi";
+					break;
+				case SCSI_PROTOCOL_SSA:
+					proto = "ssa";
+					break;
+				case SCSI_PROTOCOL_SBP:
+					proto = "sbp";
+					break;
+				case SCSI_PROTOCOL_SRP:
+					proto = "srp";
+					break;
+				case SCSI_PROTOCOL_ISCSI:
+					proto = "iscsi";
+					break;
+				case SCSI_PROTOCOL_SAS:
+					proto = "sas";
+					break;
+				case SCSI_PROTOCOL_ADT:
+					proto = "adt";
+					break;
+				case SCSI_PROTOCOL_ATA:
+					proto = "ata";
+					break;
+				case SCSI_PROTOCOL_UAS:
+					proto = "usb";
+					break;
+				case SCSI_PROTOCOL_SOP:
+					proto = "pcie";
+					break;
+				}
+				if (proto)
+					len += sprintf(buf + len, "%s:",
+						       proto);
+			}
+			switch (d[1] & 0xf) {
+			case SCSI_VPD_DESIG_eui:
+			case SCSI_VPD_DESIG_naa:
+			case SCSI_VPD_DESIG_md5:
+				switch (d[3]) {
+				case 8:
+					len += sprintf(buf + len, "%8phN\n",
+						       d + 4);
+					break;
+				case 12:
+					len += sprintf(buf + len, "%12phN\n",
+						       d + 4);
+					break;
+				case 16:
+					len += sprintf(buf + len, "%16phN\n",
+						       d + 4);
+					break;
+				}
+				break;
+			case SCSI_VPD_DESIG_relport:
+			case SCSI_VPD_DESIG_tpgrp:
+			case SCSI_VPD_DESIG_lugrp:
+				len += sprintf(buf + len, "%d\n",
+					      (int)(d[6] << 8) + d[7]);
+				break;
+			case SCSI_VPD_DESIG_vendor:
+				if ((d[0] & 0xf) == 1) {
+					for (j = 0; j < d[3]; j++) {
+						len += sprintf(buf + len,
+							       "%02x",
+							       d[4 + j]);
+					}
+				} else {
+					snprintf(buf + len, d[3] + 1,
+						 "%s", d + 4);
+					len += d[3];
+				}
+				len += sprintf(buf + len, "\n");
+				break;
+			case SCSI_VPD_DESIG_t10:
+				/* T10 Vendor is always ASCII */
+				snprintf(buf + len, 9, "%s ", d + 4);
+				len += 8;
+				if ((d[0] & 0xf) == 1) {
+					for (j = 0; j < d[3] - 8; j++) {
+						len += sprintf(buf + len,
+							       "%02x",
+							       d[12 + j]);
+					}
+				} else {
+					snprintf(buf + len, d[3] - 7,
+						 "%s", d + 12);
+					len += d[3] - 8;
+				}
+				len += sprintf(buf + len, "\n");
+				break;
+			case SCSI_VPD_DESIG_scsi_name:
+				snprintf(buf + len, d[3] + 2, "%s\n", d + 4);
+				len += d[3] + 1;
+				break;
+			case SCSI_VPD_DESIG_proto:
+				if (d[1] & 80) {
+					if ((d[0] >> 4) == 0x9)
+						len += sprintf(buf + len,
+							       "%d-%d\n",
+							       d[4], d[6]);
+					else if ((d[0] >> 4) == 0xa) {
+						j = (d[4] << 8) + d[5];
+						len += sprintf(buf + len,
+							       "%d\n", j);
+					}
+				}
+				break;
+			}
+		}
+		d += d[3] + 4;
+	}
+
+	return len ? len : -EINVAL;
+}
+
+#define sdev_evpd_ident(assoc,desig)				\
+static ssize_t							\
+sdev_show_evpd_ident_##assoc##_##desig (struct device *dev,		\
+					struct device_attribute *attr,	\
+					char * buf)			\
+{									\
+	struct scsi_device *sdev = to_scsi_device(dev);			\
+	return scsi_parse_vpd_ident(sdev, SCSI_VPD_ASSOC_##assoc,	\
+				    SCSI_VPD_DESIG_##desig, buf);	\
+}
+
+#define sdev_evpd_attr(assoc, desig)					\
+	sdev_evpd_ident(assoc, desig)					\
+static DEVICE_ATTR(ident_##assoc##_##desig, S_IRUGO,			\
+		   sdev_show_evpd_ident_##assoc##_##desig, NULL);
+
+sdev_evpd_attr(lun, vendor);
+sdev_evpd_attr(lun, t10);
+sdev_evpd_attr(lun, eui);
+sdev_evpd_attr(lun, naa);
+sdev_evpd_attr(lun, lugrp);
+sdev_evpd_attr(lun, md5);
+sdev_evpd_attr(lun, scsi_name);
+sdev_evpd_attr(port, relport);
+sdev_evpd_attr(port, tpgrp);
+sdev_evpd_attr(port, eui);
+sdev_evpd_attr(port, naa);
+sdev_evpd_attr(port, scsi_name);
+sdev_evpd_attr(port, proto);
+sdev_evpd_attr(target, eui);
+sdev_evpd_attr(target, naa);
+sdev_evpd_attr(target, scsi_name);
+
+#define sdev_evpd_test_and_add_attr(sdev, assoc, desig, valid)	\
+	if (test_bit(SCSI_VPD_DESIG_##desig, (valid))) \
+		device_create_file(&(sdev)->sdev_gendev, \
+				   &dev_attr_ident_##assoc##_##desig)
+
+static void scsi_sysfs_filter_vpd_ident(struct scsi_device *sdev)
+{
+	unsigned char *d;
+	unsigned long desig = 0, assoc = 0;
+
+	if (!sdev->vpd_ident)
+		return;
+
+	d = sdev->vpd_ident + 4;
+	while (d < sdev->vpd_ident + sdev->vpd_ident_len) {
+		set_bit((d[1] >> 4) & 3, &assoc);
+		set_bit(d[1] & 0xf, &desig);
+		d += d[3] + 4;
+	}
+	if (test_bit(SCSI_VPD_ASSOC_lun, &assoc)) {
+		sdev_evpd_test_and_add_attr(sdev, lun, vendor, &desig);
+		sdev_evpd_test_and_add_attr(sdev, lun, t10, &desig);
+		sdev_evpd_test_and_add_attr(sdev, lun, eui, &desig);
+		sdev_evpd_test_and_add_attr(sdev, lun, naa, &desig);
+		sdev_evpd_test_and_add_attr(sdev, lun, lugrp, &desig);
+		sdev_evpd_test_and_add_attr(sdev, lun, md5, &desig);
+		sdev_evpd_test_and_add_attr(sdev, lun, scsi_name, &desig);
+	}
+	if (test_bit(SCSI_VPD_ASSOC_port, &assoc)) {
+		sdev_evpd_test_and_add_attr(sdev, port, eui, &desig);
+		sdev_evpd_test_and_add_attr(sdev, port, naa, &desig);
+		sdev_evpd_test_and_add_attr(sdev, port, relport, &desig);
+		sdev_evpd_test_and_add_attr(sdev, port, tpgrp, &desig);
+		sdev_evpd_test_and_add_attr(sdev, port, scsi_name, &desig);
+		sdev_evpd_test_and_add_attr(sdev, port, proto, &desig);
+	}
+	if (test_bit(SCSI_VPD_ASSOC_target, &assoc)) {
+		sdev_evpd_test_and_add_attr(sdev, target, eui, &desig);
+		sdev_evpd_test_and_add_attr(sdev, target, naa, &desig);
+		sdev_evpd_test_and_add_attr(sdev, target, scsi_name, &desig);
+	}
+}
+
 static ssize_t
-show_iostat_counterbits(struct device *dev, struct device_attribute *attr, 				char *buf)
+show_iostat_counterbits(struct device *dev, struct device_attribute *attr,
+			char *buf)
 {
 	return snprintf(buf, 20, "%d\n", (int)sizeof(atomic_t) * 8);
 }
@@ -1003,6 +1257,8 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
 	transport_add_device(&sdev->sdev_gendev);
 	sdev->is_visible = 1;
 
+	scsi_sysfs_filter_vpd_ident(sdev);
+
 	/* create queue files, which may be writable, depending on the host */
 	if (sdev->host->hostt->change_queue_depth) {
 		error = device_create_file(&sdev->sdev_gendev,
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index 0a4edfe..0f1e6bd 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -345,6 +345,8 @@ enum scsi_protocol {
 	SCSI_PROTOCOL_SAS = 6,
 	SCSI_PROTOCOL_ADT = 7,	/* Media Changers */
 	SCSI_PROTOCOL_ATA = 8,
+	SCSI_PROTOCOL_UAS = 9,
+	SCSI_PROTOCOL_SOP = 0xa,
 	SCSI_PROTOCOL_UNSPEC = 0xf, /* No specific protocol */
 };
 
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index dcb2b73..81c7900 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -113,6 +113,8 @@ struct scsi_device {
 	const char * vendor;		/* [back_compat] point into 'inquiry' ... */
 	const char * model;		/* ... after scan; point to static string */
 	const char * rev;		/* ... "nullnullnullnull" before scan */
+	unsigned char vpd_ident_len;
+	unsigned char *vpd_ident;
 	struct scsi_target      *sdev_target;   /* used only for single_lun */
 
 	unsigned int	sdev_bflags; /* black/white flags as also found in
@@ -308,6 +310,7 @@ extern int scsi_add_device(struct Scsi_Host *host, uint channel,
 extern int scsi_register_device_handler(struct scsi_device_handler *scsi_dh);
 extern void scsi_remove_device(struct scsi_device *);
 extern int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh);
+void scsi_attach_vpd_ident(struct scsi_device *sdev);
 
 extern int scsi_device_get(struct scsi_device *);
 extern void scsi_device_put(struct scsi_device *);
-- 
1.7.12.4


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCHv2] Add EVPD page 0x83 entries to sysfs
  2014-02-10 11:11 [PATCHv2] Add EVPD page 0x83 entries to sysfs Hannes Reinecke
@ 2014-02-10 14:15 ` Christoph Hellwig
  2014-02-10 14:55   ` Hannes Reinecke
  2014-02-10 18:06 ` Jeremy Linton
  1 sibling, 1 reply; 8+ messages in thread
From: Christoph Hellwig @ 2014-02-10 14:15 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: James Bottomley, linux-scsi, Jeremy Linton, Doug Gilbert,
	Kai Makisara, Martin K. Petersen

On Mon, Feb 10, 2014 at 12:11:39PM +0100, Hannes Reinecke wrote:
> +	int vpd_len = 255;
> +	unsigned char *buffer;
> +retry:
> +	buffer = kmalloc(vpd_len, GFP_KERNEL);
> +	if (!buffer)
> +		return;
> +
> +	ret = scsi_get_vpd_page(sdev, 0x83, buffer, vpd_len);
> +	if (ret) {
> +		kfree(buffer);
> +		return;
> +	}
> +
> +	vpd_len = (buffer[2] << 8) + buffer[3];
> +	if (vpd_len > 255) {
> +		kfree(buffer);
> +		goto retry;

Won't this create an infinite loop if the VPD is longer than 255 bytes?


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCHv2] Add EVPD page 0x83 entries to sysfs
  2014-02-10 14:15 ` Christoph Hellwig
@ 2014-02-10 14:55   ` Hannes Reinecke
  0 siblings, 0 replies; 8+ messages in thread
From: Hannes Reinecke @ 2014-02-10 14:55 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: James Bottomley, linux-scsi, Jeremy Linton, Doug Gilbert,
	Kai Makisara, Martin K. Petersen

On 02/10/2014 03:15 PM, Christoph Hellwig wrote:
> On Mon, Feb 10, 2014 at 12:11:39PM +0100, Hannes Reinecke wrote:
>> +	int vpd_len = 255;
>> +	unsigned char *buffer;
>> +retry:
>> +	buffer = kmalloc(vpd_len, GFP_KERNEL);
>> +	if (!buffer)
>> +		return;
>> +
>> +	ret = scsi_get_vpd_page(sdev, 0x83, buffer, vpd_len);
>> +	if (ret) {
>> +		kfree(buffer);
>> +		return;
>> +	}
>> +
>> +	vpd_len = (buffer[2] << 8) + buffer[3];
>> +	if (vpd_len > 255) {
>> +		kfree(buffer);
>> +		goto retry;
> 
> Won't this create an infinite loop if the VPD is longer than 255 bytes?
> 
Hmm. Sort of.

Gnaa.

Will be redoing the patch.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		      zSeries & Storage
hare@suse.de			      +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCHv2] Add EVPD page 0x83 entries to sysfs
  2014-02-10 11:11 [PATCHv2] Add EVPD page 0x83 entries to sysfs Hannes Reinecke
  2014-02-10 14:15 ` Christoph Hellwig
@ 2014-02-10 18:06 ` Jeremy Linton
  2014-02-10 19:06   ` Douglas Gilbert
  2014-02-11  8:32   ` Hannes Reinecke
  1 sibling, 2 replies; 8+ messages in thread
From: Jeremy Linton @ 2014-02-10 18:06 UTC (permalink / raw)
  To: Hannes Reinecke, James Bottomley
  Cc: linux-scsi@vger.kernel.org, Doug Gilbert, Kai Makisara,
	Martin K. Petersen

On 2/10/2014 5:11 AM, Hannes Reinecke wrote:
> EVPD page 0x83 is used to uniquely identify the device. So instead of
> having each and every program issue a separate SG_IO call to retrieve this
> information it does make far more sense to display it in sysfs.

Tested-by: Jeremy Linton <jlinton@tributary.com>

	So, I just ran it in 3.14-rc2. No OOPS, that is good. It even survived
probing a SPC-2 device without a page 0x83.

I tested it with a fairly narrow set of devices, a couple IBM libraries with
LTO/359x and a VTL.

I did notice this on an old IBM raid adapter running in the machine

cat: ident_lun_scsi_name: Invalid argument

(that came from this device)
sg_inq --page=0x83 --hex /dev/sg2
VPD INQUIRY, page code=0x83:
 00     00 83 00 48 01 03 00 08  50 01 0b 90 00 12 1d 90    ...H....P.......
 10     61 93 00 08 50 01 0b 90  00 12 1d 8e 61 94 00 04    a...P.......a...
 20     00 00 00 01 61 a3 00 08  50 01 0b 90 00 12 1d 8d    ....a...P.......
 30     63 a8 00 18 6e 61 61 2e  35 30 30 31 30 42 39 30    c...naa.50010B90
 40     30 30 31 32 31 44 38 44  00 00 00 00                00121D8D....

And there may be a couple descriptors missing here and there. For example
3592E05 is missing the total port count (I think).

VPD INQUIRY, page code=0x83:
 00     01 83 00 5c 02 01 00 24  49 42 4d 20 20 20 20 20    ...\...$IBM
 10     30 33 35 39 32 45 30 35  20 20 20 20 20 20 20 20    03592E05
 20     30 30 30 30 30 37 38 33  36 33 32 33 01 03 00 08    000007836323....
 30     50 05 07 63 02 41 0c 2c  01 13 00 08 50 05 07 63    P..c.A.,....P..c
 40     02 81 0c 2c 01 14 00 04  00 00 00 02 01 23 00 08    ...,.........#..
 50     50 05 07 63 02 41 0c 2c  01 24 00 04 00 00 00 01    P..c.A.,.$......

/sys/class/scsi_tape/nst14/device # ls ident_*
ident_lun_naa  ident_lun_t10  ident_port_naa  ident_port_relport  ident_target_naa




This almost seems like a case where exporting the raw 0x83 data may be better...


Also, as I stated previously, my personal bias is to include the page 0x80
serial number data for tape devices as well. That seems to be the most
reliable. Mostly because a lot of the VTLs now just give you the same
wwnn/wwpn in 0x83 for multiple LUNs. Meaning you can't uniquely identify the
device over different physical ports.


The IBM devices are nice in that they export a T10 Vendor ID with the
man/model/serial in 0x83, but that is not common in my experience.

For example (old T10k)
VPD INQUIRY, page code=0x83:
 00     01 83 00 20 01 03 00 08  50 01 04 f0 00 93 ac f6    ... ....P.......
 10     01 13 00 08 50 01 04 f0  00 93 ac f7 01 14 00 04    ....P...........
 20     00 00 00 01                                         ....




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCHv2] Add EVPD page 0x83 entries to sysfs
  2014-02-10 18:06 ` Jeremy Linton
@ 2014-02-10 19:06   ` Douglas Gilbert
  2014-02-11 10:52     ` Hannes Reinecke
  2014-02-11  8:32   ` Hannes Reinecke
  1 sibling, 1 reply; 8+ messages in thread
From: Douglas Gilbert @ 2014-02-10 19:06 UTC (permalink / raw)
  To: Jeremy Linton, Hannes Reinecke, James Bottomley
  Cc: linux-scsi@vger.kernel.org, Kai Makisara, Martin K. Petersen

On 14-02-10 01:06 PM, Jeremy Linton wrote:
> On 2/10/2014 5:11 AM, Hannes Reinecke wrote:
>> EVPD page 0x83 is used to uniquely identify the device. So instead of
>> having each and every program issue a separate SG_IO call to retrieve this
>> information it does make far more sense to display it in sysfs.
>
> Tested-by: Jeremy Linton <jlinton@tributary.com>
>
> 	So, I just ran it in 3.14-rc2. No OOPS, that is good. It even survived
> probing a SPC-2 device without a page 0x83.
>
> I tested it with a fairly narrow set of devices, a couple IBM libraries with
> LTO/359x and a VTL.
>
> I did notice this on an old IBM raid adapter running in the machine
>
> cat: ident_lun_scsi_name: Invalid argument
>
> (that came from this device)
> sg_inq --page=0x83 --hex /dev/sg2
> VPD INQUIRY, page code=0x83:
>   00     00 83 00 48 01 03 00 08  50 01 0b 90 00 12 1d 90    ...H....P.......
>   10     61 93 00 08 50 01 0b 90  00 12 1d 8e 61 94 00 04    a...P.......a...
>   20     00 00 00 01 61 a3 00 08  50 01 0b 90 00 12 1d 8d    ....a...P.......
>   30     63 a8 00 18 6e 61 61 2e  35 30 30 31 30 42 39 30    c...naa.50010B90
>   40     30 30 31 32 31 44 38 44  00 00 00 00                00121D8D....
>
> And there may be a couple descriptors missing here and there. For example
> 3592E05 is missing the total port count (I think).
>
> VPD INQUIRY, page code=0x83:
>   00     01 83 00 5c 02 01 00 24  49 42 4d 20 20 20 20 20    ...\...$IBM
>   10     30 33 35 39 32 45 30 35  20 20 20 20 20 20 20 20    03592E05
>   20     30 30 30 30 30 37 38 33  36 33 32 33 01 03 00 08    000007836323....
>   30     50 05 07 63 02 41 0c 2c  01 13 00 08 50 05 07 63    P..c.A.,....P..c
>   40     02 81 0c 2c 01 14 00 04  00 00 00 02 01 23 00 08    ...,.........#..
>   50     50 05 07 63 02 41 0c 2c  01 24 00 04 00 00 00 01    P..c.A.,.$......
>
> /sys/class/scsi_tape/nst14/device # ls ident_*
> ident_lun_naa  ident_lun_t10  ident_port_naa  ident_port_relport  ident_target_naa
>
>
>
>
> This almost seems like a case where exporting the raw 0x83 data may be better...

I have seen corrupted "di" VPD pages as well. So the
order in which you look for designators can be important
(and whether you stop on the first error or continue).

$ sg_vpd -e -p 0x83
Matching standard VPD pages:
   di         0x83      Device identification
   di_asis    0x83      Like 'di' but designators ordered as found
   di_lu      0x83      Device identification, lu only
   di_port    0x83      Device identification, target port only
   di_target  0x83      Device identification, target device only

The difference between --page=di and --page=di_asis is that the
first looks for lu, followed by port, followed by target device
matches. The --page=di_asis prints out the designators as they
are found. Finding and decoding anything beyond a corrupted
designator is hit or miss.

> Also, as I stated previously, my personal bias is to include the page 0x80
> serial number data for tape devices as well. That seems to be the most
> reliable. Mostly because a lot of the VTLs now just give you the same
> wwnn/wwpn in 0x83 for multiple LUNs. Meaning you can't uniquely identify the
> device over different physical ports.

I'm guessing that various companies selling target
capable chips also provide generic target code for those
chips. Then it is up to the OEM to customize that generic
code for their devices. Some do that customization more
thoroughly than others.

Doug Gilbert

> The IBM devices are nice in that they export a T10 Vendor ID with the
> man/model/serial in 0x83, but that is not common in my experience.
>
> For example (old T10k)
> VPD INQUIRY, page code=0x83:
>   00     01 83 00 20 01 03 00 08  50 01 04 f0 00 93 ac f6    ... ....P.......
>   10     01 13 00 08 50 01 04 f0  00 93 ac f7 01 14 00 04    ....P...........
>   20     00 00 00 01                                         ....


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCHv2] Add EVPD page 0x83 entries to sysfs
  2014-02-10 18:06 ` Jeremy Linton
  2014-02-10 19:06   ` Douglas Gilbert
@ 2014-02-11  8:32   ` Hannes Reinecke
  2014-02-11 16:56     ` Jeremy Linton
  1 sibling, 1 reply; 8+ messages in thread
From: Hannes Reinecke @ 2014-02-11  8:32 UTC (permalink / raw)
  To: Jeremy Linton, James Bottomley
  Cc: linux-scsi@vger.kernel.org, Doug Gilbert, Kai Makisara,
	Martin K. Petersen

On 02/10/2014 07:06 PM, Jeremy Linton wrote:
> On 2/10/2014 5:11 AM, Hannes Reinecke wrote:
>> EVPD page 0x83 is used to uniquely identify the device. So instead of
>> having each and every program issue a separate SG_IO call to retrieve this
>> information it does make far more sense to display it in sysfs.
> 
> Tested-by: Jeremy Linton <jlinton@tributary.com>
> 
> 	So, I just ran it in 3.14-rc2. No OOPS, that is good. It even survived
> probing a SPC-2 device without a page 0x83.
> 
> I tested it with a fairly narrow set of devices, a couple IBM libraries with
> LTO/359x and a VTL.
> 
> I did notice this on an old IBM raid adapter running in the machine
> 
> cat: ident_lun_scsi_name: Invalid argument
> 
> (that came from this device)
> sg_inq --page=0x83 --hex /dev/sg2
> VPD INQUIRY, page code=0x83:
>  00     00 83 00 48 01 03 00 08  50 01 0b 90 00 12 1d 90    ...H....P.......
>  10     61 93 00 08 50 01 0b 90  00 12 1d 8e 61 94 00 04    a...P.......a...
>  20     00 00 00 01 61 a3 00 08  50 01 0b 90 00 12 1d 8d    ....a...P.......
>  30     63 a8 00 18 6e 61 61 2e  35 30 30 31 30 42 39 30    c...naa.50010B90
>  40     30 30 31 32 31 44 38 44  00 00 00 00                00121D8D....
> 
Yeah, correct. The selection algorithm is a tad flawed. I'll be
fixing it up.

> And there may be a couple descriptors missing here and there. For example
> 3592E05 is missing the total port count (I think).
> 
> VPD INQUIRY, page code=0x83:
>  00     01 83 00 5c 02 01 00 24  49 42 4d 20 20 20 20 20    ...\...$IBM
>  10     30 33 35 39 32 45 30 35  20 20 20 20 20 20 20 20    03592E05
>  20     30 30 30 30 30 37 38 33  36 33 32 33 01 03 00 08    000007836323....
>  30     50 05 07 63 02 41 0c 2c  01 13 00 08 50 05 07 63    P..c.A.,....P..c
>  40     02 81 0c 2c 01 14 00 04  00 00 00 02 01 23 00 08    ...,.........#..
>  50     50 05 07 63 02 41 0c 2c  01 24 00 04 00 00 00 01    P..c.A.,.$......
> 
> /sys/class/scsi_tape/nst14/device # ls ident_*
> ident_lun_naa  ident_lun_t10  ident_port_naa  ident_port_relport  ident_target_naa
> 
Well, yes, it does, as the missing ident is this:
01 24 00 04 00 00 00 01

Which decodes as 'Association: Target', 'Designator: Relative target
port identifier', and is not defined as per spec
(and it doesn't make sense to boot).

As you might've seen I've included only the valid/defined
association/designator combinations in the patch.

> 
> 
> 
> This almost seems like a case where exporting the raw 0x83 data may be better...
> 
Hmm. I'd rather have the actual strings in sysfs; the whole idea of
this patch was to have strings in sysfs which can be read directly.
Having a binary blob only requires you to have yet another tool for
parsing that data.

And for XCOPY we need the descriptor anyway, so at one point we need
to parse this.

But OTOH there's no reason why we _shouldn't_ export it to sysfs
directly. So let's do both.

> 
> Also, as I stated previously, my personal bias is to include the page 0x80
> serial number data for tape devices as well. That seems to be the most
> reliable. Mostly because a lot of the VTLs now just give you the same
> wwnn/wwpn in 0x83 for multiple LUNs. Meaning you can't uniquely identify the
> device over different physical ports.
> 
The problem with page 0x80 is that (per spec) it's vendor-defined.
So there is no guarantee for it to be unique in any sense.
Which makes it rather impractical for normal use.

Hence we typically rely on page 0x83 to identify a device, be it for
udev or multipath.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		      zSeries & Storage
hare@suse.de			      +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCHv2] Add EVPD page 0x83 entries to sysfs
  2014-02-10 19:06   ` Douglas Gilbert
@ 2014-02-11 10:52     ` Hannes Reinecke
  0 siblings, 0 replies; 8+ messages in thread
From: Hannes Reinecke @ 2014-02-11 10:52 UTC (permalink / raw)
  To: dgilbert
  Cc: Jeremy Linton, James Bottomley, linux-scsi@vger.kernel.org,
	Kai Makisara, Martin K. Petersen

On 02/10/2014 08:06 PM, Douglas Gilbert wrote:
> On 14-02-10 01:06 PM, Jeremy Linton wrote:
>> On 2/10/2014 5:11 AM, Hannes Reinecke wrote:
>>> EVPD page 0x83 is used to uniquely identify the device. So
>>> instead of
>>> having each and every program issue a separate SG_IO call to
>>> retrieve this
>>> information it does make far more sense to display it in sysfs.
>>
>> Tested-by: Jeremy Linton <jlinton@tributary.com>
>>
>>     So, I just ran it in 3.14-rc2. No OOPS, that is good. It even
>> survived
>> probing a SPC-2 device without a page 0x83.
>>
>> I tested it with a fairly narrow set of devices, a couple IBM
>> libraries with
>> LTO/359x and a VTL.
>>
>> I did notice this on an old IBM raid adapter running in the machine
>>
>> cat: ident_lun_scsi_name: Invalid argument
>>
>> (that came from this device)
>> sg_inq --page=0x83 --hex /dev/sg2
>> VPD INQUIRY, page code=0x83:
>>   00     00 83 00 48 01 03 00 08  50 01 0b 90 00 12 1d 90   
>> ...H....P.......
>>   10     61 93 00 08 50 01 0b 90  00 12 1d 8e 61 94 00 04   
>> a...P.......a...
>>   20     00 00 00 01 61 a3 00 08  50 01 0b 90 00 12 1d 8d   
>> ....a...P.......
>>   30     63 a8 00 18 6e 61 61 2e  35 30 30 31 30 42 39 30   
>> c...naa.50010B90
>>   40     30 30 31 32 31 44 38 44  00 00 00 00               
>> 00121D8D....
>>
>> And there may be a couple descriptors missing here and there. For
>> example
>> 3592E05 is missing the total port count (I think).
>>
>> VPD INQUIRY, page code=0x83:
>>   00     01 83 00 5c 02 01 00 24  49 42 4d 20 20 20 20 20   
>> ...\...$IBM
>>   10     30 33 35 39 32 45 30 35  20 20 20 20 20 20 20 20    03592E05
>>   20     30 30 30 30 30 37 38 33  36 33 32 33 01 03 00 08   
>> 000007836323....
>>   30     50 05 07 63 02 41 0c 2c  01 13 00 08 50 05 07 63   
>> P..c.A.,....P..c
>>   40     02 81 0c 2c 01 14 00 04  00 00 00 02 01 23 00 08   
>> ...,.........#..
>>   50     50 05 07 63 02 41 0c 2c  01 24 00 04 00 00 00 01   
>> P..c.A.,.$......
>>
>> /sys/class/scsi_tape/nst14/device # ls ident_*
>> ident_lun_naa  ident_lun_t10  ident_port_naa  ident_port_relport 
>> ident_target_naa
>>
>>
>>
>>
>> This almost seems like a case where exporting the raw 0x83 data
>> may be better...
> 
> I have seen corrupted "di" VPD pages as well. So the
> order in which you look for designators can be important
> (and whether you stop on the first error or continue).
> 
> $ sg_vpd -e -p 0x83
> Matching standard VPD pages:
>   di         0x83      Device identification
>   di_asis    0x83      Like 'di' but designators ordered as found
>   di_lu      0x83      Device identification, lu only
>   di_port    0x83      Device identification, target port only
>   di_target  0x83      Device identification, target device only
> 
> The difference between --page=di and --page=di_asis is that the
> first looks for lu, followed by port, followed by target device
> matches. The --page=di_asis prints out the designators as they
> are found. Finding and decoding anything beyond a corrupted
> designator is hit or miss.
> 
Yep, true. I'll need to add some boundary checks to the parsing
algorithm.

>> Also, as I stated previously, my personal bias is to include the
>> page 0x80
>> serial number data for tape devices as well. That seems to be the
>> most
>> reliable. Mostly because a lot of the VTLs now just give you the same
>> wwnn/wwpn in 0x83 for multiple LUNs. Meaning you can't uniquely
>> identify the
>> device over different physical ports.
> 
> I'm guessing that various companies selling target
> capable chips also provide generic target code for those
> chips. Then it is up to the OEM to customize that generic
> code for their devices. Some do that customization more
> thoroughly than others.
> 
Indeed. Some have odd ideas what can be put in there.
But nevertheless, the page format is reasonably simple,
so adding boundary checks isn't a problem.

And if vendors do not adhere to the spec that's tough,
but nothing we should code for.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		      zSeries & Storage
hare@suse.de			      +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCHv2] Add EVPD page 0x83 entries to sysfs
  2014-02-11  8:32   ` Hannes Reinecke
@ 2014-02-11 16:56     ` Jeremy Linton
  0 siblings, 0 replies; 8+ messages in thread
From: Jeremy Linton @ 2014-02-11 16:56 UTC (permalink / raw)
  To: Hannes Reinecke, James Bottomley
  Cc: linux-scsi@vger.kernel.org, Doug Gilbert, Kai Makisara,
	Martin K. Petersen

On 2/11/2014 2:32 AM, Hannes Reinecke wrote:
> The problem with page 0x80 is that (per spec) it's vendor-defined. So there
> is no guarantee for it to be unique in any sense. Which makes it rather
> impractical for normal use.
> 
> Hence we typically rely on page 0x83 to identify a device, be it for udev
> or multipath.

	AFAIK is not vendor defined page, its just not marked as "mandatory" by T10.
For tape (which I what I thought brought much of this on) it is basically
mandatory. Which is another place where the spec doesn't sync with the real
world.

	That is because it is the _ONLY_ vendor neutral method to autoconfigure tape
libraries. The tape libraries export the drive serial numbers via READ ELEMENT
STATUS, dvcid=1. Which means its the de facto method for backup/media manager
applications. A tape/media changer device that crashes or fails to return useful
0x80 information will have a very short life in the market.

	For sure, it would work better than the existing method being used by udev (for
tape), which fails (per my other posting) because there is often insufficient
information in 0x83 to uniquely identify devices.




	

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-02-11 16:56 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-02-10 11:11 [PATCHv2] Add EVPD page 0x83 entries to sysfs Hannes Reinecke
2014-02-10 14:15 ` Christoph Hellwig
2014-02-10 14:55   ` Hannes Reinecke
2014-02-10 18:06 ` Jeremy Linton
2014-02-10 19:06   ` Douglas Gilbert
2014-02-11 10:52     ` Hannes Reinecke
2014-02-11  8:32   ` Hannes Reinecke
2014-02-11 16:56     ` Jeremy Linton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox