[PATCH 4/4] [LIO-Target/PERSISTENT-RESERVATION]: Add support foriSCSI Transport IDs

From: Nicholas A. Bellinger
Date: Fri Jan 30 2009 - 04:36:35 EST


>From df842680009acc0b2bf8a2e593c05df7429af9e9 Mon Sep 17 00:00:00 2001
From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>
Date: Fri, 30 Jan 2009 00:35:37 -0800
Subject: [PATCH 4/4] [LIO-Target/PERSISTENT-RESERVATION]: Add support for iSCSI Transport IDs

This patch adds support for the following SPC-4 defined TransportIDs to
LIO-Target/ConfigFS v3.0:

*) iSCSI Initiator device TransportID format (iSCSI Initiator IQN)
*) iSCSI Initiator port TransportID format (iSCSI Initiator IQN + ISID)

The latter is avaiable when there is an active I_T Nexus (iSCSI Session)
via SPC-3 compliant PRIN SA READ_FULL_STATUS.

Tested using sg_persist on v2.6.29-rc2 32-bit HVM.

Signed-off-by: Nicholas A. Bellinger <nab@xxxxxxxxxxxxxxx>
---
drivers/lio-core/iscsi_target_configfs.c | 2 +
drivers/lio-core/iscsi_target_tpg.c | 142 +++++++++++++++++++++++++++++-
drivers/lio-core/iscsi_target_tpg.h | 4 +-
3 files changed, 146 insertions(+), 2 deletions(-)

diff --git a/drivers/lio-core/iscsi_target_configfs.c b/drivers/lio-core/iscsi_target_configfs.c
index 9906ad8..9e136ea 100644
--- a/drivers/lio-core/iscsi_target_configfs.c
+++ b/drivers/lio-core/iscsi_target_configfs.c
@@ -2291,6 +2291,8 @@ extern int iscsi_target_register_configfs (void)
fabric->tf_ops.tpg_get_wwn = &lio_tpg_get_endpoint_wwn;
fabric->tf_ops.tpg_get_tag = &lio_tpg_get_tag;
fabric->tf_ops.tpg_get_default_depth = &lio_tpg_get_default_depth;
+ fabric->tf_ops.tpg_get_pr_transport_id = &lio_tpg_get_pr_transport_id;
+ fabric->tf_ops.tpg_get_pr_transport_id_len = &lio_tpg_get_pr_transport_id_len;
fabric->tf_ops.tpg_check_demo_mode = &lio_tpg_check_demo_mode;
fabric->tf_ops.tpg_check_demo_mode_cache = &lio_tpg_check_demo_mode_cache;
fabric->tf_ops.tpg_check_demo_mode_write_protect = &lio_tpg_check_demo_mode_write_protect;
diff --git a/drivers/lio-core/iscsi_target_tpg.c b/drivers/lio-core/iscsi_target_tpg.c
index 3068aba..b5a7480 100644
--- a/drivers/lio-core/iscsi_target_tpg.c
+++ b/drivers/lio-core/iscsi_target_tpg.c
@@ -86,7 +86,7 @@ extern char *lio_tpg_get_endpoint_wwn (se_portal_group_t *se_tpg)
return(&tpg->tpg_tiqn->tiqn[0]);
}

-extern u32 lio_tpg_get_tag (se_portal_group_t *se_tpg)
+extern u16 lio_tpg_get_tag (se_portal_group_t *se_tpg)
{
iscsi_portal_group_t *tpg = (iscsi_portal_group_t *)se_tpg->se_tpg_fabric_ptr;

@@ -100,6 +100,146 @@ extern u32 lio_tpg_get_default_depth (se_portal_group_t *se_tpg)
return(ISCSI_TPG_ATTRIB(tpg)->default_cmdsn_depth);
}

+extern u32 lio_tpg_get_pr_transport_id (
+ se_portal_group_t *se_tpg,
+ se_node_acl_t *se_nacl,
+ int *format_code,
+ unsigned char *buf)
+{
+ iscsi_session_t *sess;
+ se_session_t *se_sess;
+ u32 off = 4, padding = 0;
+ u16 len = 0;
+
+ spin_lock(&se_nacl->nacl_sess_lock);
+ /*
+ * Set PROTOCOL IDENTIFIER to 5h for iSCSI
+ */
+ buf[0] = 0x05;
+ /*
+ * From spc4r17 Section 7.5.4.6: TransportID for initiator
+ * ports using SCSI over iSCSI.
+ *
+ * The null-terminated, null-padded (see 4.4.2) ISCSI NAME field
+ * shall contain the iSCSI name of an iSCSI initiator node (see
+ * RFC 3720). The first ISCSI NAME field byte containing an ASCII
+ * null character terminates the ISCSI NAME field without regard for
+ * the specified length of the iSCSI TransportID or the contents of
+ * the ADDITIONAL LENGTH field.
+ */
+ len = sprintf(&buf[off], "%s", se_nacl->initiatorname);
+ /*
+ * Add Extra byte for NULL terminator
+ */
+ len++;
+ /*
+ * If there is an active iSCSI session, and *format code == 1
+ * 1, use iSCSI Initiator port TransportID format.
+ *
+ * Otherwise use iSCSI Initiator device TransportID format that
+ * does not contain the ASCII encoded iSCSI Initiator iSID value
+ * provied by the iSCSi Initiator during the iSCSI login process.
+ */
+ if ((*format_code == 1) && (se_sess = se_nacl->nacl_sess)) {
+ /*
+ * Set FORMAT CODE 01b for iSCSI Initiator port TransportID
+ * format.
+ */
+ buf[0] |= 0x40;
+ /*
+ * From spc4r17 Section 7.5.4.6: TransportID for initiator
+ * ports using SCSI over iSCSI. Table 390
+ *
+ * The SEPARATOR field shall contain the five ASCII
+ * characters ",i,0x".
+ *
+ * The null-terminated, null-padded ISCSI INITIATOR SESSION ID
+ * field shall contain the iSCSI initiator session identifier
+ * (see RFC 3720) in the form of ASCII characters that are the
+ * hexadecimal digits converted from the binary iSCSI initiator
+ * session identifier value. The first ISCSI INITIATOR SESSION
+ * ID field byte containing an ASCII null character
+ */
+ sess = (iscsi_session_t *)se_sess->fabric_sess_ptr;
+ buf[off+len] = 0x2c; off++; // ASCII Character: ","
+ buf[off+len] = 0x69; off++; // ASCII Character: "i"
+ buf[off+len] = 0x2c; off++; // ASCII Character: ","
+ buf[off+len] = 0x30; off++; // ASCII Character: "0"
+ buf[off+len] = 0x78; off++; // ASCII Character: "x"
+ len += 5;
+ buf[off+len] = sess->isid[0]; off++;
+ buf[off+len] = sess->isid[1]; off++;
+ buf[off+len] = sess->isid[2]; off++;
+ buf[off+len] = sess->isid[3]; off++;
+ buf[off+len] = sess->isid[4]; off++;
+ buf[off+len] = sess->isid[5]; off++;
+ buf[off+len] = '\0'; off++;
+ len += 7;
+ }
+ spin_unlock(&se_nacl->nacl_sess_lock);
+ /*
+ * The ADDITIONAL LENGTH field specifies the number of bytes that follow
+ * in the TransportID. The additional length shall be at least 20 and
+ * shall be a multiple of four.
+ */
+ if ((padding = ((-len) & 3)) != 0)
+ len += padding;
+
+ buf[2] = ((len >> 8) & 0xff);
+ buf[3] = (len & 0xff);
+ /*
+ * Increment value for total payload + header length for
+ * full status descriptor
+ */
+ len += 4;
+
+ return(len);
+}
+
+extern u32 lio_tpg_get_pr_transport_id_len (
+ se_portal_group_t *se_tpg,
+ se_node_acl_t *se_nacl,
+ int *format_code)
+{
+ se_session_t *se_sess;
+ u32 len = 0, padding = 0;
+
+ spin_lock(&se_nacl->nacl_sess_lock);
+ len = strlen(se_nacl->initiatorname);
+ /*
+ * Add extra byte for NULL terminator
+ */
+ len++;
+ /*
+ * If there is an active iSCSI session, use format code:
+ * 01b: iSCSI Initiator port TransportID format
+ *
+ * If there is not an active iSCSI session, use format code:
+ * 00b: iSCSI Initiator device TransportID format
+ */
+ if ((se_sess = se_nacl->nacl_sess)) {
+ len += 5; /* For ",i,0x" ASCII seperator */
+ len += 7; /* For iSCSI Initiator Session ID + Null terminator */
+ *format_code = 1;
+ } else
+ *format_code = 0;
+ spin_unlock(&se_nacl->nacl_sess_lock);
+ /*
+ * The ADDITIONAL LENGTH field specifies the number of bytes that follow
+ * in the TransportID. The additional length shall be at least 20 and
+ * shall be a multiple of four.
+ */
+ if ((padding = ((-len) & 3)) != 0)
+ len += padding;
+ /*
+ * Increment value for total payload + header length for
+ * full status descriptor
+ */
+ len += 4;
+
+ return(len);
+}
+
extern int lio_tpg_check_demo_mode (se_portal_group_t *se_tpg)
{
iscsi_portal_group_t *tpg = (iscsi_portal_group_t *)se_tpg->se_tpg_fabric_ptr;
diff --git a/drivers/lio-core/iscsi_target_tpg.h b/drivers/lio-core/iscsi_target_tpg.h
index 68fb2a8..749e148 100644
--- a/drivers/lio-core/iscsi_target_tpg.h
+++ b/drivers/lio-core/iscsi_target_tpg.h
@@ -30,8 +30,10 @@
#define ISCSI_TARGET_TPG_H

extern char *lio_tpg_get_endpoint_wwn (struct se_portal_group_s *);
-extern u32 lio_tpg_get_tag (struct se_portal_group_s *);
+extern u16 lio_tpg_get_tag (struct se_portal_group_s *);
extern u32 lio_tpg_get_default_depth (struct se_portal_group_s *);
+extern u32 lio_tpg_get_pr_transport_id (struct se_portal_group_s *, struct se_node_acl_s *, int *, unsigned char *);
+extern u32 lio_tpg_get_pr_transport_id_len (struct se_portal_group_s *, struct se_node_acl_s *, int *);
extern int lio_tpg_check_demo_mode (struct se_portal_group_s *);
extern int lio_tpg_check_demo_mode_cache (struct se_portal_group_s *);
extern int lio_tpg_check_demo_mode_write_protect (struct se_portal_group_s *);
--
1.5.4.1



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