[PATCH 6/6] [Target_Core_Mod/ConfigFS]: Add support for $STORAGE_OBJECT EVPD Unit Serial Number emulation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>From a50c8a50550ab3d41f716711e08ec6f116a45f28 Mon Sep 17 00:00:00 2001
From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>
Date: Fri, 23 Jan 2009 17:34:14 -0800
Subject: [PATCH 6/6] [Target_Core_Mod/ConfigFS]: Add support for $STORAGE_OBJECT EVPD Unit Serial Number emulation

This patch support for writeable EVPD Unit Serial configfs attribute at:

/sys/kernel/config/target/core/$HBA/$STORAGE_OBJECT/wwn/evpd_unit_serial

It works with Linux/Block and Linux/FILEIO $STORAGE_OBJECTS, as well as through
target_core_mod/RAMDISK subsystem plugins.

This logic checks se_subsystem_dev_t->su_dev_flags & SDF_FIRMWARE_EVPD_UNIT_SERIAL
to see if SCSI firmware (or software emulation for non SCSI devices) is being
handled by Linux/SCSI for us.  It does right by the firmware and if said device
reports EVPD INQUIRY response payload information see target_core_pscsi.c:
pscsi_transport_complete()

The changing of configfs evpd_unit_serial with this patch is limited to only while
said $STORAGE_OBJECT is *NOT* in use by $FABRIC_MOD exports.  This is mentioned
in the comment in target_core_dev_wwn_store_attr_evpd_unit_serial():

	<SNIP>
       /*
        * Check to see if any active $FABRIC_MOD exports exist.  If they
        * do exist, fail here as changing this information on the fly
        * (underneath the initiator side OS dependent multipath code)
        * could cause negative effects.
        */
       if ((dev = su_dev->se_dev_ptr)) {
               if (DEV_OBJ_API(dev)->check_count(&dev->dev_export_obj)) {
                       printk(KERN_ERR "Unable to set EVPD Unit Serial while"
                               " active %d $FABRIC_MOD exports exist\n",
                               DEV_OBJ_API(dev)->check_count(
                                       &dev->dev_access_obj));
                       return(-EINVAL);
               }
       }
	<SNIP>

This logic may end up allowing to be overwritten for those who
"really know what they are doing" and to allow RAMDISK and IBLOCK/FILEIO
exports for the EVPD information that has no assoicated underlying
device firmware.  For now, this assoicated target_core_mod subsystem
plugin logic just disables emulation when firmware and Linux/SCSI LLDs
report EVPD to us upon $HBA/$STORAGE_OBJECT enablement.

Signed-off-by: Nicholas A. Bellinger <nab@xxxxxxxxxxxxxxx>
---
 drivers/lio-core/target_core_configfs.c |   59 +++++++++++++++++++++++++++++-
 1 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/drivers/lio-core/target_core_configfs.c b/drivers/lio-core/target_core_configfs.c
index 5b1d275..1788fbb 100644
--- a/drivers/lio-core/target_core_configfs.c
+++ b/drivers/lio-core/target_core_configfs.c
@@ -38,6 +38,7 @@
 #include <target_core_device.h>
 #include <target_core_hba.h>
 #include <target_core_plugin.h>
+#include <target_core_seobj.h>
 #include <target_core_transport.h>
 
 #ifdef SNMP_SUPPORT
@@ -536,7 +537,7 @@ static ssize_t target_core_dev_wwn_show_attr_evpd_unit_serial (
         if (!(dev = se_dev->se_dev_ptr)) 
                 return(-ENODEV);
 
-	return(sprintf(page, "T10 EVPD Unit Serial Number:: %s\n",
+	return(sprintf(page, "T10 EVPD Unit Serial Number: %s\n",
 		&t10_wwn->unit_serial[0]));
 }
 
@@ -545,7 +546,61 @@ static ssize_t target_core_dev_wwn_store_attr_evpd_unit_serial (
 	const char *page,
 	size_t count)
 {
-	return(-ENOMEM);
+	se_subsystem_dev_t *su_dev = t10_wwn->t10_sub_dev;
+	se_device_t *dev;
+	unsigned char buf[INQUIRY_EVPD_SERIAL_LEN];
+
+	/*
+	 * If Linux/SCSI subsystem_api_t plugin got a EVPD Unit Serial
+	 * from the struct scsi_device level firmware, do not allow
+	 * EVPD Unit Serial to be emulated.
+	 *
+	 * Note this struct scsi_device could also be emulating EVPD
+	 * information from its drivers/scsi LLD.  But for now we assume
+	 * it is doing 'the right thing' wrt a world wide unique
+	 * EVPD Unit Serial Number that OS dependent multipath can depend on.
+	 */
+	if (su_dev->su_dev_flags & SDF_FIRMWARE_EVPD_UNIT_SERIAL) {
+		printk(KERN_ERR "Underlying SCSI device firmware provided EVPD"
+			" Unit Serial, ignoring request\n");
+		return(-EOPNOTSUPP);
+	}
+
+	if ((strlen(page) + 1) > INQUIRY_EVPD_SERIAL_LEN) {
+		printk(KERN_ERR "Emulated EVPD Unit Serial exceeds"
+		" INQUIRY_EVPD_SERIAL_LEN: %d\n", INQUIRY_EVPD_SERIAL_LEN);
+		return(-EOVERFLOW);
+	}
+	/*
+	 * Check to see if any active $FABRIC_MOD exports exist.  If they
+	 * do exist, fail here as changing this information on the fly 
+	 * (underneath the initiator side OS dependent multipath code)
+	 * could cause negative effects.
+	 */
+	if ((dev = su_dev->se_dev_ptr)) {
+		if (DEV_OBJ_API(dev)->check_count(&dev->dev_export_obj)) {
+			printk(KERN_ERR "Unable to set EVPD Unit Serial while"
+				" active %d $FABRIC_MOD exports exist\n",
+				DEV_OBJ_API(dev)->check_count(
+					&dev->dev_access_obj));
+			return(-EINVAL);
+		}
+	}
+	/*
+	 * This currently assumes ASCII encoding for emulated EVPD Unit Serial.
+	 *
+	 * Also, strip any newline added from the userspace
+	 * echo $UUID > $TARGET/$HBA/$STORAGE_OBJECT/wwn/evpd_unit_serial
+	 */
+	memset(buf, 0, INQUIRY_EVPD_SERIAL_LEN);
+	snprintf(buf, INQUIRY_EVPD_SERIAL_LEN, "%s", page);
+	snprintf(su_dev->t10_wwn.unit_serial, INQUIRY_EVPD_SERIAL_LEN,
+			"%s", strstrip(buf));
+	su_dev->su_dev_flags |= SDF_EMULATED_EVPD_UNIT_SERIAL;
+
+	printk("Target_Core_ConfigFS: Set emulated EVPD Unit Serial: %s\n",
+			su_dev->t10_wwn.unit_serial);
+	return(count);
 }
 
 SE_DEV_WWN_ATTR(evpd_unit_serial, S_IRUGO | S_IWUSR);
-- 
1.5.4.1



--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux