lkml.org 
[lkml]   [2009]   [Jan]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH 6/6] [Target_Core_Mod/ConfigFS]: Add support for $STORAGE_OBJECT EVPD Unit Serial Number emulation
    From
    Date
    >From a50c8a50550ab3d41f716711e08ec6f116a45f28 Mon Sep 17 00:00:00 2001
    From: Nicholas Bellinger <nab@linux-iscsi.org>
    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@linux-iscsi.org>
    ---
    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




    \
     
     \ /
      Last update: 2009-01-24 03:03    [W:0.035 / U:4.760 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site