scsi: add iSCSI initiator port TransportID

SCSI persistent reservation feature need to get the TransportID
for the I_T nexus, so when creating initiator port we also
set the TransportID according to the specification, while here,
we use the format code 0x1 for the TransportID.

Change-Id: Ib45bec04bf0e33e2b0f611dd3846597f4176d069
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.gerrithub.io/435212
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
This commit is contained in:
Changpeng Liu 2018-11-27 07:38:35 -05:00 committed by Jim Harris
parent 2a8084018c
commit 38dfce0428
5 changed files with 66 additions and 0 deletions

View File

@ -61,6 +61,7 @@ extern "C" {
#define SPDK_SCSI_DEV_MAX_NAME 255
#define SPDK_SCSI_PORT_MAX_NAME_LENGTH 255
#define SPDK_SCSI_MAX_TRANSPORT_ID_LENGTH 255
enum spdk_scsi_data_dir {
SPDK_SCSI_DIR_NONE = 0,
@ -510,6 +511,16 @@ int spdk_scsi_lun_allocate_io_channel(struct spdk_scsi_desc *desc);
*/
void spdk_scsi_lun_free_io_channel(struct spdk_scsi_desc *desc);
/**
* Set iSCSI Initiator port TransportID
*
* \param port SCSI initiator port.
* \param iscsi_name Initiator name.
* \param isid Session ID.
*/
void spdk_scsi_port_set_iscsi_transport_id(struct spdk_scsi_port *port,
char *iscsi_name, uint64_t isid);
#ifdef __cplusplus
}
#endif

View File

@ -485,6 +485,17 @@ struct spdk_scsi_port_desc {
uint8_t tgt_desc[];
};
/* iSCSI initiator port TransportID header */
struct spdk_scsi_iscsi_transport_id {
uint8_t protocol_id : 4;
uint8_t reserved1 : 2;
uint8_t format : 2;
uint8_t reserved2;
uint16_t additional_len;
uint8_t name[];
};
SPDK_STATIC_ASSERT(sizeof(struct spdk_scsi_iscsi_transport_id) == 4, "Incorrect size");
/* SCSI UNMAP block descriptor */
struct spdk_scsi_unmap_bdesc {
/* UNMAP LOGICAL BLOCK ADDRESS */

View File

@ -1522,6 +1522,10 @@ spdk_iscsi_op_login_set_conn_info(struct spdk_iscsi_conn *conn,
0, initiator_port_name);
conn->sess->isid = spdk_iscsi_get_isid(rsph->isid);
conn->sess->target = target;
/* Initiator port TransportID */
spdk_scsi_port_set_iscsi_transport_id(conn->sess->initiator_port,
conn->initiator_name,
conn->sess->isid);
/* Discovery sessions will not have a target. */
if (target != NULL) {

View File

@ -34,6 +34,8 @@
#include "scsi_internal.h"
#include "spdk/endian.h"
struct spdk_scsi_port *
spdk_scsi_port_create(uint64_t id, uint16_t index, const char *name)
{
@ -94,3 +96,39 @@ spdk_scsi_port_get_name(const struct spdk_scsi_port *port)
{
return port->name;
}
/*
* spc3r23 7.5.4.6 iSCSI initiator port TransportID,
* using code format 0x01.
*/
void
spdk_scsi_port_set_iscsi_transport_id(struct spdk_scsi_port *port, char *iscsi_name,
uint64_t isid)
{
struct spdk_scsi_iscsi_transport_id *data;
uint32_t len;
char *name;
memset(port->transport_id, 0, sizeof(port->transport_id));
port->transport_id_len = 0;
data = (struct spdk_scsi_iscsi_transport_id *)port->transport_id;
data->protocol_id = (uint8_t)SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI;
data->format = 0x1;
name = data->name;
len = snprintf(name, SPDK_SCSI_MAX_TRANSPORT_ID_LENGTH - sizeof(*data),
"%s,i,0x%12.12" PRIx64, iscsi_name, isid);
do {
name[len++] = '\0';
} while (len & 3);
if (len < 20) {
SPDK_ERRLOG("The length of Transport ID should >= 20 bytes\n");
return;
}
to_be16(&data->additional_len, len);
port->transport_id_len = len + sizeof(*data);
}

View File

@ -54,6 +54,8 @@ struct spdk_scsi_port {
uint8_t is_used;
uint64_t id;
uint16_t index;
uint16_t transport_id_len;
char transport_id[SPDK_SCSI_MAX_TRANSPORT_ID_LENGTH];
char name[SPDK_SCSI_PORT_MAX_NAME_LENGTH];
};