[dm-devel] [PATCH 09/13] Use transport identifiers when detecting devices

Hannes Reinecke hare at suse.de
Wed Jan 16 12:14:12 UTC 2013


This patch stores the transport identifiers, allowing
for a simplified dev_loss_tmo setting.

Signed-off-by: Hannes Reinecke <hare at suse.de>
---
 libmultipath/discovery.c |   59 ++++++++++++++++++++++++++-------------------
 libmultipath/structs.h   |   17 +++++++++++-
 2 files changed, 49 insertions(+), 27 deletions(-)

diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index 8b6f74d..3fd33a3 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -207,6 +207,7 @@ sysfs_get_tgt_nodename (struct path *pp, char * node)
 {
 	const char *targetid, *value;
 	struct udev_device *parent, *tgtdev;
+	int host, channel, rport_id = -1;
 
 	parent = udev_device_get_parent_with_subsystem_devtype(pp->udev, "scsi", "scsi_device");
 	if (!parent)
@@ -214,6 +215,7 @@ sysfs_get_tgt_nodename (struct path *pp, char * node)
 	/* Check for SAS */
 	value = udev_device_get_sysattr_value(parent, "sas_address");
 	if (value) {
+		pp->sg_id.proto_id = SCSI_PROTOCOL_SAS;
 		strncpy(node, value, NODE_NAME_SIZE);
 		return 0;
 	}
@@ -221,19 +223,30 @@ sysfs_get_tgt_nodename (struct path *pp, char * node)
 	parent = udev_device_get_parent_with_subsystem_devtype(pp->udev, "scsi", "scsi_target");
 	if (!parent)
 		return 1;
-	tgtdev = udev_device_new_from_subsystem_sysname(conf->udev, "fc_transport", udev_device_get_sysname(parent));
-	/* Check if it's FibreChannel */
-	if (tgtdev) {
-		const char *value;
-
-		value = udev_device_get_sysattr_value(tgtdev, "node_name");
-		if (value) {
-			strncpy(node, value, NODE_NAME_SIZE);
-			udev_device_unref(tgtdev);
-			return 0;
+	/* Check for FibreChannel */
+	tgtdev = udev_device_get_parent(parent);
+	value = udev_device_get_sysname(tgtdev);
+	if (sscanf(value, "rport-%d:%d-%d",
+		   &host, &channel, &rport_id) == 3) {
+		tgtdev = udev_device_new_from_subsystem_sysname(conf->udev,
+				"fc_remote_ports", value);
+		if (tgtdev) {
+			condlog(3, "SCSI target %d:%d:%d -> "
+				"FC rport %d:%d-%d",
+				pp->sg_id.host_no, pp->sg_id.channel,
+				pp->sg_id.scsi_id, host, channel,
+				rport_id);
+			value = udev_device_get_sysattr_value(tgtdev,
+							      "node_name");
+			if (value) {
+				pp->sg_id.proto_id = SCSI_PROTOCOL_FCP;
+				pp->sg_id.transport_id = rport_id;
+				strncpy(node, value, NODE_NAME_SIZE);
+				udev_device_unref(tgtdev);
+				return 0;
+			} else
+				udev_device_unref(tgtdev);
 		}
-		else
-			udev_device_unref(tgtdev);
 	}
 
 	/* Check for iSCSI */
@@ -253,6 +266,7 @@ sysfs_get_tgt_nodename (struct path *pp, char * node)
 
 			value = udev_device_get_sysattr_value(tgtdev, "targetname");
 			if (value) {
+				pp->sg_id.proto_id = SCSI_PROTOCOL_ISCSI;
 				strncpy(node, value, NODE_NAME_SIZE);
 				udev_device_unref(tgtdev);
 				return 0;
@@ -267,25 +281,20 @@ sysfs_get_tgt_nodename (struct path *pp, char * node)
 static void
 sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
 {
-	struct udev_device *parent = pp->udev;
 	struct udev_device *rport_dev = NULL;
 	char value[11];
-	const char *rport_id = NULL;
+	char rport_id[32];
 
-	while (parent) {
-		rport_id = udev_device_get_sysname(parent);
-		if (!strncmp(rport_id, "rport-", 6))
-			break;
-		parent = udev_device_get_parent(parent);
-		rport_id = NULL;
-	}
-	if (!parent || !rport_id) {
-		condlog(0, "%s: rport id not found", pp->dev);
+	if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP) {
+		condlog(3, "%s: Not a FCP device", pp->dev);
 		return;
 	}
-	rport_dev = udev_device_new_from_subsystem_sysname(conf->udev, "fc_remote_ports", rport_id);
+	sprintf(rport_id, "rport-%d:%d-%d",
+		pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id);
+	rport_dev = udev_device_new_from_subsystem_sysname(conf->udev,
+				"fc_remote_ports", rport_id);
 	if (!rport_dev) {
-		condlog(3, "%s: No fc_remote_port device for '%s'", pp->dev,
+		condlog(1, "%s: No fc_remote_port device for '%s'", pp->dev,
 			rport_id);
 		return;
 	}
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
index 4085900..ab05a78 100644
--- a/libmultipath/structs.h
+++ b/libmultipath/structs.h
@@ -113,6 +113,19 @@ enum detect_prio_states {
 	DETECT_PRIO_ON,
 };
 
+enum scsi_protocol {
+	SCSI_PROTOCOL_FCP = 0,	/* Fibre Channel */
+	SCSI_PROTOCOL_SPI = 1,	/* parallel SCSI */
+	SCSI_PROTOCOL_SSA = 2,	/* Serial Storage Architecture - Obsolete */
+	SCSI_PROTOCOL_SBP = 3,	/* firewire */
+	SCSI_PROTOCOL_SRP = 4,	/* Infiniband RDMA */
+	SCSI_PROTOCOL_ISCSI = 5,
+	SCSI_PROTOCOL_SAS = 6,
+	SCSI_PROTOCOL_ADT = 7,	/* Media Changers */
+	SCSI_PROTOCOL_ATA = 8,
+	SCSI_PROTOCOL_UNSPEC = 0xf, /* No specific protocol */
+};
+
 struct sg_id {
 	int host_no;
 	int channel;
@@ -120,8 +133,8 @@ struct sg_id {
 	int lun;
 	short h_cmd_per_lun;
 	short d_queue_depth;
-	int unused1;
-	int unused2;
+	enum scsi_protocol proto_id;
+	int transport_id;
 };
 
 # ifndef HDIO_GETGEO
-- 
1.7.4.2




More information about the dm-devel mailing list