Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 15 Jul 2014 17:06:11 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r268683 - in stable/10: sys/cam/ctl usr.sbin/ctladm usr.sbin/ctld
Message-ID:  <201407151706.s6FH6B1F083817@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Tue Jul 15 17:06:10 2014
New Revision: 268683
URL: http://svnweb.freebsd.org/changeset/base/268683

Log:
  MFC r268293:
  Burry devid port method, which was a gross hack.
  
  Instead make ports provide wanted port and target IDs, and LUNs provide
  wanted LUN IDs.  After that core Device ID VPD code only had to link all
  of them together and add relative port and port group numbers.
  
  LUN ID for iSCSI LUNs no longer created by CTL, but by ctld, and passed
  to CTL as "scsiname" LUN option.  This makes LUNs to report the same set
  of IDs, independently from the port through which it is accessed, as
  required by SCSI specifications.

Modified:
  stable/10/sys/cam/ctl/ctl.c
  stable/10/sys/cam/ctl/ctl_frontend.c
  stable/10/sys/cam/ctl/ctl_frontend.h
  stable/10/sys/cam/ctl/ctl_frontend_cam_sim.c
  stable/10/sys/cam/ctl/ctl_frontend_iscsi.c
  stable/10/sys/cam/ctl/ctl_private.h
  stable/10/sys/cam/ctl/scsi_ctl.c
  stable/10/usr.sbin/ctladm/ctladm.8
  stable/10/usr.sbin/ctld/kernel.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/cam/ctl/ctl.c
==============================================================================
--- stable/10/sys/cam/ctl/ctl.c	Tue Jul 15 17:05:11 2014	(r268682)
+++ stable/10/sys/cam/ctl/ctl.c	Tue Jul 15 17:06:10 2014	(r268683)
@@ -4295,7 +4295,11 @@ ctl_alloc_lun(struct ctl_softc *ctl_soft
 {
 	struct ctl_lun *nlun, *lun;
 	struct ctl_port *port;
+	struct scsi_vpd_id_descriptor *desc;
+	struct scsi_vpd_id_t10 *t10id;
+	const char *scsiname, *vendor;
 	int lun_number, i, lun_malloced;
+	int devidlen, idlen1, idlen2, len;
 
 	if (be_lun == NULL)
 		return (EINVAL);
@@ -4327,6 +4331,43 @@ ctl_alloc_lun(struct ctl_softc *ctl_soft
 	if (lun_malloced)
 		lun->flags = CTL_LUN_MALLOCED;
 
+	/* Generate LUN ID. */
+	devidlen = max(CTL_DEVID_MIN_LEN,
+	    strnlen(be_lun->device_id, CTL_DEVID_LEN));
+	idlen1 = sizeof(*t10id) + devidlen;
+	len = sizeof(struct scsi_vpd_id_descriptor) + idlen1;
+	scsiname = ctl_get_opt(&be_lun->options, "scsiname");
+	if (scsiname != NULL) {
+		idlen2 = roundup2(strlen(scsiname) + 1, 4);
+		len += sizeof(struct scsi_vpd_id_descriptor) + idlen2;
+	}
+	lun->lun_devid = malloc(sizeof(struct ctl_devid) + len,
+	    M_CTL, M_WAITOK | M_ZERO);
+	lun->lun_devid->len = len;
+	desc = (struct scsi_vpd_id_descriptor *)lun->lun_devid->data;
+	desc->proto_codeset = SVPD_ID_CODESET_ASCII;
+	desc->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_LUN | SVPD_ID_TYPE_T10;
+	desc->length = idlen1;
+	t10id = (struct scsi_vpd_id_t10 *)&desc->identifier[0];
+	memset(t10id->vendor, ' ', sizeof(t10id->vendor));
+	if ((vendor = ctl_get_opt(&be_lun->options, "vendor")) == NULL) {
+		strncpy((char *)t10id->vendor, CTL_VENDOR, sizeof(t10id->vendor));
+	} else {
+		strncpy(t10id->vendor, vendor,
+		    min(sizeof(t10id->vendor), strlen(vendor)));
+	}
+	strncpy((char *)t10id->vendor_spec_id,
+	    (char *)be_lun->device_id, devidlen);
+	if (scsiname != NULL) {
+		desc = (struct scsi_vpd_id_descriptor *)(&desc->identifier[0] +
+		    desc->length);
+		desc->proto_codeset = SVPD_ID_CODESET_UTF8;
+		desc->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_LUN |
+		    SVPD_ID_TYPE_SCSI_NAME;
+		desc->length = idlen2;
+		strlcpy(desc->identifier, scsiname, idlen2);
+	}
+
 	mtx_lock(&ctl_softc->ctl_lock);
 	/*
 	 * See if the caller requested a particular LUN number.  If so, see
@@ -4548,6 +4589,7 @@ ctl_free_lun(struct ctl_lun *lun)
 	lun->be_lun->lun_shutdown(lun->be_lun->be_lun);
 
 	mtx_destroy(&lun->lun_lock);
+	free(lun->lun_devid, M_CTL);
 	if (lun->flags & CTL_LUN_MALLOCED)
 		free(lun, M_CTL);
 
@@ -9626,39 +9668,29 @@ static int
 ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len)
 {
 	struct scsi_vpd_device_id *devid_ptr;
-	struct scsi_vpd_id_descriptor *desc, *desc1;
-	struct scsi_vpd_id_descriptor *desc2, *desc3; /* for types 4h and 5h */
-	struct scsi_vpd_id_t10 *t10id;
+	struct scsi_vpd_id_descriptor *desc;
 	struct ctl_softc *ctl_softc;
 	struct ctl_lun *lun;
 	struct ctl_port *port;
-	char *val;
-	int data_len, devid_len;
+	int data_len;
+	uint8_t proto;
 
 	ctl_softc = control_softc;
 
 	port = ctl_softc->ctl_ports[ctl_port_idx(ctsio->io_hdr.nexus.targ_port)];
-
-	if (port->devid != NULL)
-		return ((port->devid)(ctsio, alloc_len));
-
 	lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
 
-	if (lun == NULL) {
-		devid_len = CTL_DEVID_MIN_LEN;
-	} else {
-		devid_len = max(CTL_DEVID_MIN_LEN,
-		    strnlen(lun->be_lun->device_id, CTL_DEVID_LEN));
-	}
-
 	data_len = sizeof(struct scsi_vpd_device_id) +
-		sizeof(struct scsi_vpd_id_descriptor) +
-		sizeof(struct scsi_vpd_id_t10) + devid_len +
-		sizeof(struct scsi_vpd_id_descriptor) + CTL_WWPN_LEN +
-		sizeof(struct scsi_vpd_id_descriptor) +
+	    sizeof(struct scsi_vpd_id_descriptor) +
 		sizeof(struct scsi_vpd_id_rel_trgt_port_id) +
-		sizeof(struct scsi_vpd_id_descriptor) +
+	    sizeof(struct scsi_vpd_id_descriptor) +
 		sizeof(struct scsi_vpd_id_trgt_port_grp_id);
+	if (lun && lun->lun_devid)
+		data_len += lun->lun_devid->len;
+	if (port->port_devid)
+		data_len += port->port_devid->len;
+	if (port->target_devid)
+		data_len += port->target_devid->len;
 
 	ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
 	devid_ptr = (struct scsi_vpd_device_id *)ctsio->kern_data_ptr;
@@ -9677,15 +9709,6 @@ ctl_inquiry_evpd_devid(struct ctl_scsiio
 	ctsio->kern_rel_offset = 0;
 	ctsio->kern_sg_entries = 0;
 
-	desc = (struct scsi_vpd_id_descriptor *)devid_ptr->desc_list;
-	t10id = (struct scsi_vpd_id_t10 *)&desc->identifier[0];
-	desc1 = (struct scsi_vpd_id_descriptor *)(&desc->identifier[0] +
-		sizeof(struct scsi_vpd_id_t10) + devid_len);
-	desc2 = (struct scsi_vpd_id_descriptor *)(&desc1->identifier[0] +
-	          CTL_WWPN_LEN);
-	desc3 = (struct scsi_vpd_id_descriptor *)(&desc2->identifier[0] +
-	         sizeof(struct scsi_vpd_id_rel_trgt_port_id));
-
 	/*
 	 * The control device is always connected.  The disk device, on the
 	 * other hand, may not be online all the time.
@@ -9695,112 +9718,69 @@ ctl_inquiry_evpd_devid(struct ctl_scsiio
 				     lun->be_lun->lun_type;
 	else
 		devid_ptr->device = (SID_QUAL_LU_OFFLINE << 5) | T_DIRECT;
-
 	devid_ptr->page_code = SVPD_DEVICE_ID;
-
 	scsi_ulto2b(data_len - 4, devid_ptr->length);
 
-	/*
-	 * For Fibre channel,
-	 */
 	if (port->port_type == CTL_PORT_FC)
-	{
-		desc->proto_codeset = (SCSI_PROTO_FC << 4) |
-				      SVPD_ID_CODESET_ASCII;
-        	desc1->proto_codeset = (SCSI_PROTO_FC << 4) |
-		              SVPD_ID_CODESET_BINARY;
-	}
+		proto = SCSI_PROTO_FC << 4;
+	else if (port->port_type == CTL_PORT_ISCSI)
+		proto = SCSI_PROTO_ISCSI << 4;
 	else
-	{
-		desc->proto_codeset = (SCSI_PROTO_SPI << 4) |
-				      SVPD_ID_CODESET_ASCII;
-        	desc1->proto_codeset = (SCSI_PROTO_SPI << 4) |
-		              SVPD_ID_CODESET_BINARY;
-	}
-	desc2->proto_codeset = desc3->proto_codeset = desc1->proto_codeset;
+		proto = SCSI_PROTO_SPI << 4;
+	desc = (struct scsi_vpd_id_descriptor *)devid_ptr->desc_list;
 
 	/*
 	 * We're using a LUN association here.  i.e., this device ID is a
 	 * per-LUN identifier.
 	 */
-	desc->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_LUN | SVPD_ID_TYPE_T10;
-	desc->length = sizeof(*t10id) + devid_len;
-	if (lun == NULL || (val = ctl_get_opt(&lun->be_lun->options,
-	    "vendor")) == NULL) {
-		strncpy((char *)t10id->vendor, CTL_VENDOR, sizeof(t10id->vendor));
-	} else {
-		memset(t10id->vendor, ' ', sizeof(t10id->vendor));
-		strncpy(t10id->vendor, val,
-		    min(sizeof(t10id->vendor), strlen(val)));
+	if (lun && lun->lun_devid) {
+		memcpy(desc, lun->lun_devid->data, lun->lun_devid->len);
+		desc = (struct scsi_vpd_id_descriptor *)((uint8_t *)desc +
+		    lun->lun_devid->len);
 	}
 
 	/*
-	 * desc1 is for the WWPN which is a port asscociation.
+	 * This is for the WWPN which is a port association.
 	 */
-	desc1->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_PORT | SVPD_ID_TYPE_NAA;
-	desc1->length = CTL_WWPN_LEN;
-	/* XXX Call Reggie's get_WWNN func here then add port # to the end */
-	/* For testing just create the WWPN */
-#if 0
-	ddb_GetWWNN((char *)desc1->identifier);
-
-	/* NOTE: if the port is 0 or 8 we don't want to subtract 1 */
-	/* This is so Copancontrol will return something sane */
-	if (ctsio->io_hdr.nexus.targ_port!=0 &&
-	    ctsio->io_hdr.nexus.targ_port!=8)
-		desc1->identifier[7] += ctsio->io_hdr.nexus.targ_port-1;
-	else
-		desc1->identifier[7] += ctsio->io_hdr.nexus.targ_port;
-#endif
-
-	be64enc(desc1->identifier, port->wwpn);
+	if (port->port_devid) {
+		memcpy(desc, port->port_devid->data, port->port_devid->len);
+		desc = (struct scsi_vpd_id_descriptor *)((uint8_t *)desc +
+		    port->port_devid->len);
+	}
 
 	/*
-	 * desc2 is for the Relative Target Port(type 4h) identifier
+	 * This is for the Relative Target Port(type 4h) identifier
 	 */
-	desc2->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_PORT
-	                 | SVPD_ID_TYPE_RELTARG;
-	desc2->length = 4;
-//#if 0
-	/* NOTE: if the port is 0 or 8 we don't want to subtract 1 */
-	/* This is so Copancontrol will return something sane */
-	if (ctsio->io_hdr.nexus.targ_port!=0 &&
-	    ctsio->io_hdr.nexus.targ_port!=8)
-		desc2->identifier[3] = ctsio->io_hdr.nexus.targ_port - 1;
-	else
-	        desc2->identifier[3] = ctsio->io_hdr.nexus.targ_port;
-//#endif
+	desc->proto_codeset = proto | SVPD_ID_CODESET_BINARY;
+	desc->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_PORT |
+	    SVPD_ID_TYPE_RELTARG;
+	desc->length = 4;
+	scsi_ulto2b(ctsio->io_hdr.nexus.targ_port, &desc->identifier[2]);
+	desc = (struct scsi_vpd_id_descriptor *)(&desc->identifier[0] +
+	    sizeof(struct scsi_vpd_id_rel_trgt_port_id));
 
 	/*
-	 * desc3 is for the Target Port Group(type 5h) identifier
+	 * This is for the Target Port Group(type 5h) identifier
 	 */
-	desc3->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_PORT
-	                 | SVPD_ID_TYPE_TPORTGRP;
-	desc3->length = 4;
+	desc->proto_codeset = proto | SVPD_ID_CODESET_BINARY;
+	desc->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_PORT |
+	    SVPD_ID_TYPE_TPORTGRP;
+	desc->length = 4;
 	if (ctsio->io_hdr.nexus.targ_port < CTL_MAX_PORTS || ctl_is_single)
-		desc3->identifier[3] = 1;
+		scsi_ulto2b(1, &desc->identifier[2]);
 	else
-		desc3->identifier[3] = 2;
+		scsi_ulto2b(2, &desc->identifier[2]);
+	desc = (struct scsi_vpd_id_descriptor *)(&desc->identifier[0] +
+	    sizeof(struct scsi_vpd_id_trgt_port_grp_id));
 
 	/*
-	 * If we've actually got a backend, copy the device id from the
-	 * per-LUN data.  Otherwise, set it to all spaces.
+	 * This is for the Target identifier
 	 */
-	if (lun != NULL) {
-		/*
-		 * Copy the backend's LUN ID.
-		 */
-		strncpy((char *)t10id->vendor_spec_id,
-			(char *)lun->be_lun->device_id, devid_len);
-	} else {
-		/*
-		 * No backend, set this to spaces.
-		 */
-		memset(t10id->vendor_spec_id, 0x20, devid_len);
+	if (port->target_devid) {
+		memcpy(desc, port->target_devid->data, port->target_devid->len);
 	}
 
 	ctsio->scsi_status = SCSI_STATUS_OK;
-
 	ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
 	ctsio->be_move_done = ctl_config_move_done;
 	ctl_datamove((union ctl_io *)ctsio);

Modified: stable/10/sys/cam/ctl/ctl_frontend.c
==============================================================================
--- stable/10/sys/cam/ctl/ctl_frontend.c	Tue Jul 15 17:05:11 2014	(r268682)
+++ stable/10/sys/cam/ctl/ctl_frontend.c	Tue Jul 15 17:06:10 2014	(r268683)
@@ -219,6 +219,11 @@ ctl_port_deregister(struct ctl_port *por
 	ctl_pool_free(pool);
 	ctl_free_opts(&port->options);
 
+	free(port->port_devid, M_CTL);
+	port->port_devid = NULL;
+	free(port->target_devid, M_CTL);
+	port->target_devid = NULL;
+
 bailout:
 	return (retval);
 }
@@ -227,11 +232,49 @@ void
 ctl_port_set_wwns(struct ctl_port *port, int wwnn_valid, uint64_t wwnn,
 		      int wwpn_valid, uint64_t wwpn)
 {
-	if (wwnn_valid)
+	struct scsi_vpd_id_descriptor *desc;
+	int len, proto;
+
+	if (port->port_type == CTL_PORT_FC)
+		proto = SCSI_PROTO_FC << 4;
+	else if (port->port_type == CTL_PORT_ISCSI)
+		proto = SCSI_PROTO_ISCSI << 4;
+	else
+		proto = SCSI_PROTO_SPI << 4;
+
+	if (wwnn_valid) {
 		port->wwnn = wwnn;
 
-	if (wwpn_valid)
+		free(port->target_devid, M_CTL);
+
+		len = sizeof(struct scsi_vpd_device_id) + CTL_WWPN_LEN;
+		port->target_devid = malloc(sizeof(struct ctl_devid) + len,
+		    M_CTL, M_WAITOK | M_ZERO);
+		port->target_devid->len = len;
+		desc = (struct scsi_vpd_id_descriptor *)port->target_devid->data;
+		desc->proto_codeset = proto | SVPD_ID_CODESET_BINARY;
+		desc->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_TARGET |
+		    SVPD_ID_TYPE_NAA;
+		desc->length = CTL_WWPN_LEN;
+		scsi_u64to8b(port->wwnn, desc->identifier);
+	}
+
+	if (wwpn_valid) {
 		port->wwpn = wwpn;
+
+		free(port->port_devid, M_CTL);
+
+		len = sizeof(struct scsi_vpd_device_id) + CTL_WWPN_LEN;
+		port->port_devid = malloc(sizeof(struct ctl_devid) + len,
+		    M_CTL, M_WAITOK | M_ZERO);
+		port->port_devid->len = len;
+		desc = (struct scsi_vpd_id_descriptor *)port->port_devid->data;
+		desc->proto_codeset = proto | SVPD_ID_CODESET_BINARY;
+		desc->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_PORT |
+		    SVPD_ID_TYPE_NAA;
+		desc->length = CTL_WWPN_LEN;
+		scsi_u64to8b(port->wwpn, desc->identifier);
+	}
 }
 
 void

Modified: stable/10/sys/cam/ctl/ctl_frontend.h
==============================================================================
--- stable/10/sys/cam/ctl/ctl_frontend.h	Tue Jul 15 17:05:11 2014	(r268682)
+++ stable/10/sys/cam/ctl/ctl_frontend.h	Tue Jul 15 17:06:10 2014	(r268683)
@@ -53,7 +53,6 @@ typedef int (*targ_func_t)(void *arg, st
 typedef	int (*lun_func_t)(void *arg, struct ctl_id targ_id, int lun_id);
 typedef int (*fe_ioctl_t)(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
 			  struct thread *td);
-typedef int (*fe_devid_t)(struct ctl_scsiio *ctsio, int alloc_len);
 
 #define CTL_FRONTEND_DECLARE(name, driver) \
 	static int name ## _modevent(module_t mod, int type, void *data) \
@@ -218,7 +217,6 @@ struct ctl_port {
 	void		*onoff_arg;		/* passed to CTL */
 	lun_func_t	lun_enable;		/* passed to CTL */
 	lun_func_t	lun_disable;		/* passed to CTL */
-	fe_devid_t	devid;			/* passed to CTL */
 	void		*targ_lun_arg;		/* passed to CTL */
 	void		(*fe_datamove)(union ctl_io *io); /* passed to CTL */
 	void		(*fe_done)(union ctl_io *io); /* passed to CTL */
@@ -231,6 +229,8 @@ struct ctl_port {
 	uint64_t	wwpn;			/* set by CTL before online */
 	ctl_port_status	status;			/* used by CTL */
 	ctl_options_t	options;		/* passed to CTL */
+	struct ctl_devid *port_devid;		/* passed to CTL */
+	struct ctl_devid *target_devid;		/* passed to CTL */
 	STAILQ_ENTRY(ctl_port) fe_links;	/* used by CTL */
 	STAILQ_ENTRY(ctl_port) links;		/* used by CTL */
 };

Modified: stable/10/sys/cam/ctl/ctl_frontend_cam_sim.c
==============================================================================
--- stable/10/sys/cam/ctl/ctl_frontend_cam_sim.c	Tue Jul 15 17:05:11 2014	(r268682)
+++ stable/10/sys/cam/ctl/ctl_frontend_cam_sim.c	Tue Jul 15 17:06:10 2014	(r268683)
@@ -193,8 +193,7 @@ cfcs_init(void)
 			/* Company ID */ 0x5000000000000000ULL |
 			/* NL-Port */    0x0300;
 		softc->wwpn = softc->wwnn + port->targ_port + 1;
-		port->wwnn = softc->wwnn;
-		port->wwpn = softc->wwpn;
+		ctl_port_set_wwns(port, true, softc->wwnn, true, softc->wwpn);
 	} else {
 		softc->wwnn = port->wwnn;
 		softc->wwpn = port->wwpn;

Modified: stable/10/sys/cam/ctl/ctl_frontend_iscsi.c
==============================================================================
--- stable/10/sys/cam/ctl/ctl_frontend_iscsi.c	Tue Jul 15 17:05:11 2014	(r268682)
+++ stable/10/sys/cam/ctl/ctl_frontend_iscsi.c	Tue Jul 15 17:06:10 2014	(r268683)
@@ -155,7 +155,6 @@ static int	cfiscsi_lun_disable(void *arg
 		    struct ctl_id target_id, int lun_id);
 static int	cfiscsi_ioctl(struct cdev *dev,
 		    u_long cmd, caddr_t addr, int flag, struct thread *td);
-static int	cfiscsi_devid(struct ctl_scsiio *ctsio, int alloc_len);
 static void	cfiscsi_datamove(union ctl_io *io);
 static void	cfiscsi_done(union ctl_io *io);
 static uint32_t	cfiscsi_map_lun(void *arg, uint32_t lun);
@@ -1952,8 +1951,9 @@ cfiscsi_ioctl_port_create(struct ctl_req
 	struct cfiscsi_target *ct;
 	struct ctl_port *port;
 	const char *target, *alias, *tag;
+	struct scsi_vpd_id_descriptor *desc;
 	ctl_options_t opts;
-	int retval;
+	int retval, len, idlen;
 
 	ctl_init_opts(&opts, req->num_args, req->kern_args);
 	target = ctl_get_opt(&opts, "cfiscsi_target");
@@ -1998,7 +1998,6 @@ cfiscsi_ioctl_port_create(struct ctl_req
 	port->lun_enable = cfiscsi_lun_enable;
 	port->lun_disable = cfiscsi_lun_disable;
 	port->targ_lun_arg = ct;
-	port->devid = cfiscsi_devid;
 	port->fe_datamove = cfiscsi_datamove;
 	port->fe_done = cfiscsi_done;
 
@@ -2010,10 +2009,41 @@ cfiscsi_ioctl_port_create(struct ctl_req
 	port->options = opts;
 	STAILQ_INIT(&opts);
 
+	/* Generate Port ID. */
+	idlen = strlen(target) + strlen(",t,0x0001") + 1;
+	idlen = roundup2(idlen, 4);
+	len = sizeof(struct scsi_vpd_device_id) + idlen;
+	port->port_devid = malloc(sizeof(struct ctl_devid) + len,
+	    M_CTL, M_WAITOK | M_ZERO);
+	port->port_devid->len = len;
+	desc = (struct scsi_vpd_id_descriptor *)port->port_devid->data;
+	desc->proto_codeset = (SCSI_PROTO_ISCSI << 4) | SVPD_ID_CODESET_UTF8;
+	desc->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_PORT |
+	    SVPD_ID_TYPE_SCSI_NAME;
+	desc->length = idlen;
+	snprintf(desc->identifier, idlen, "%s,t,0x%4.4x",
+	    target, port->virtual_port);
+
+	/* Generate Target ID. */
+	idlen = strlen(target) + 1;
+	idlen = roundup2(idlen, 4);
+	len = sizeof(struct scsi_vpd_device_id) + idlen;
+	port->target_devid = malloc(sizeof(struct ctl_devid) + len,
+	    M_CTL, M_WAITOK | M_ZERO);
+	port->target_devid->len = len;
+	desc = (struct scsi_vpd_id_descriptor *)port->target_devid->data;
+	desc->proto_codeset = (SCSI_PROTO_ISCSI << 4) | SVPD_ID_CODESET_UTF8;
+	desc->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_TARGET |
+	    SVPD_ID_TYPE_SCSI_NAME;
+	desc->length = idlen;
+	strlcpy(desc->identifier, target, idlen);
+
 	retval = ctl_port_register(port, /*master_SC*/ 1);
 	if (retval != 0) {
 		ctl_free_opts(&port->options);
 		cfiscsi_target_release(ct);
+		free(port->port_devid, M_CFISCSI);
+		free(port->target_devid, M_CFISCSI);
 		req->status = CTL_LUN_ERROR;
 		snprintf(req->error_str, sizeof(req->error_str),
 		    "ctl_frontend_register() failed with error %d", retval);
@@ -2140,206 +2170,6 @@ cfiscsi_ioctl(struct cdev *dev,
 	return (0);
 }
 
-static int
-cfiscsi_devid(struct ctl_scsiio *ctsio, int alloc_len)
-{
-	struct cfiscsi_session *cs;
-	struct scsi_vpd_device_id *devid_ptr;
-	struct scsi_vpd_id_descriptor *desc, *desc1, *desc2, *desc3, *desc4;
-	struct scsi_vpd_id_descriptor *desc5;
-	struct scsi_vpd_id_t10 *t10id;
-	struct ctl_lun *lun;
-	const struct icl_pdu *request;
-	int i, ret;
-	char *val;
-	size_t data_len, devid_len, wwnn_len, wwpn_len, lun_name_len;
-
-	lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
-	request = ctsio->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr;
-	cs = PDU_SESSION(request);
-
-	wwpn_len = strlen(cs->cs_target->ct_name);
-	wwpn_len += strlen(",t,0x0001");
-	wwpn_len += 1; /* '\0' */
-	if ((wwpn_len % 4) != 0)
-		wwpn_len += (4 - (wwpn_len % 4));
-
-	wwnn_len = strlen(cs->cs_target->ct_name);
-	wwnn_len += 1; /* '\0' */
-	if ((wwnn_len % 4) != 0)
-		wwnn_len += (4 - (wwnn_len % 4));
-
-	if (lun == NULL) {
-		devid_len = CTL_DEVID_MIN_LEN;
-		lun_name_len = 0;
-	} else {
-		devid_len = max(CTL_DEVID_MIN_LEN,
-		    strnlen(lun->be_lun->device_id, CTL_DEVID_LEN));
-		lun_name_len = strlen(cs->cs_target->ct_name);
-		lun_name_len += strlen(",lun,XXXXXXXX");
-		lun_name_len += 1; /* '\0' */
-		if ((lun_name_len % 4) != 0)
-			lun_name_len += (4 - (lun_name_len % 4));
-	}
-
-	data_len = sizeof(struct scsi_vpd_device_id) +
-		sizeof(struct scsi_vpd_id_descriptor) +
-		sizeof(struct scsi_vpd_id_t10) + devid_len +
-		sizeof(struct scsi_vpd_id_descriptor) + lun_name_len +
-		sizeof(struct scsi_vpd_id_descriptor) + wwnn_len +
-		sizeof(struct scsi_vpd_id_descriptor) + wwpn_len +
-		sizeof(struct scsi_vpd_id_descriptor) +
-		sizeof(struct scsi_vpd_id_rel_trgt_port_id) +
-		sizeof(struct scsi_vpd_id_descriptor) +
-		sizeof(struct scsi_vpd_id_trgt_port_grp_id);
-
-	ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
-	devid_ptr = (struct scsi_vpd_device_id *)ctsio->kern_data_ptr;
-	ctsio->kern_sg_entries = 0;
-
-	if (data_len < alloc_len) {
-		ctsio->residual = alloc_len - data_len;
-		ctsio->kern_data_len = data_len;
-		ctsio->kern_total_len = data_len;
-	} else {
-		ctsio->residual = 0;
-		ctsio->kern_data_len = alloc_len;
-		ctsio->kern_total_len = alloc_len;
-	}
-	ctsio->kern_data_resid = 0;
-	ctsio->kern_rel_offset = 0;
-	ctsio->kern_sg_entries = 0;
-
-	desc = (struct scsi_vpd_id_descriptor *)devid_ptr->desc_list;
-	t10id = (struct scsi_vpd_id_t10 *)&desc->identifier[0];
-	desc1 = (struct scsi_vpd_id_descriptor *)(&desc->identifier[0] +
-	    sizeof(struct scsi_vpd_id_t10) + devid_len);
-	desc2 = (struct scsi_vpd_id_descriptor *)(&desc1->identifier[0] +
-	    lun_name_len);
-	desc3 = (struct scsi_vpd_id_descriptor *)(&desc2->identifier[0] +
-	    wwnn_len);
-	desc4 = (struct scsi_vpd_id_descriptor *)(&desc3->identifier[0] +
-	    wwpn_len);
-	desc5 = (struct scsi_vpd_id_descriptor *)(&desc4->identifier[0] +
-	    sizeof(struct scsi_vpd_id_rel_trgt_port_id));
-
-	if (lun != NULL)
-		devid_ptr->device = (SID_QUAL_LU_CONNECTED << 5) |
-		    lun->be_lun->lun_type;
-	else
-		devid_ptr->device = (SID_QUAL_LU_OFFLINE << 5) | T_DIRECT;
-
-	devid_ptr->page_code = SVPD_DEVICE_ID;
-
-	scsi_ulto2b(data_len - 4, devid_ptr->length);
-
-	/*
-	 * We're using a LUN association here.  i.e., this device ID is a
-	 * per-LUN identifier.
-	 */
-	desc->proto_codeset = (SCSI_PROTO_ISCSI << 4) | SVPD_ID_CODESET_ASCII;
-	desc->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_LUN | SVPD_ID_TYPE_T10;
-	desc->length = sizeof(*t10id) + devid_len;
-	if (lun == NULL || (val = ctl_get_opt(&lun->be_lun->options,
-	    "vendor")) == NULL) {
-		strncpy((char *)t10id->vendor, CTL_VENDOR, sizeof(t10id->vendor));
-	} else {
-		memset(t10id->vendor, ' ', sizeof(t10id->vendor));
-		strncpy(t10id->vendor, val,
-		    min(sizeof(t10id->vendor), strlen(val)));
-	}
-
-	/*
-	 * If we've actually got a backend, copy the device id from the
-	 * per-LUN data.  Otherwise, set it to all spaces.
-	 */
-	if (lun != NULL) {
-		/*
-		 * Copy the backend's LUN ID.
-		 */
-		strncpy((char *)t10id->vendor_spec_id,
-		    (char *)lun->be_lun->device_id, devid_len);
-	} else {
-		/*
-		 * No backend, set this to spaces.
-		 */
-		memset(t10id->vendor_spec_id, 0x20, devid_len);
-	}
-
-	/*
-	 * desc1 is for the unique LUN name.
-	 *
-	 * XXX: According to SPC-3, LUN must report the same ID through
-	 *      all the ports.  The code below, however, reports the
-	 *      ID only via iSCSI.
-	 */
-	desc1->proto_codeset = (SCSI_PROTO_ISCSI << 4) | SVPD_ID_CODESET_UTF8;
-	desc1->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_LUN |
-		SVPD_ID_TYPE_SCSI_NAME;
-	desc1->length = lun_name_len;
-	if (lun != NULL) {
-		/*
-		 * Find the per-target LUN number.
-		 */
-		for (i = 0; i < CTL_MAX_LUNS; i++) {
-			if (cs->cs_target->ct_luns[i] == lun->lun)
-				break;
-		}
-		KASSERT(i < CTL_MAX_LUNS,
-		    ("lun %jd not found", (uintmax_t)lun->lun));
-		ret = snprintf(desc1->identifier, lun_name_len, "%s,lun,%d",
-		    cs->cs_target->ct_name, i);
-		KASSERT(ret > 0 && ret <= lun_name_len, ("bad snprintf"));
-	} else {
-		KASSERT(lun_name_len == 0, ("no lun, but lun_name_len != 0"));
-	}
-
-	/*
-	 * desc2 is for the Target Name.
-	 */
-	desc2->proto_codeset = (SCSI_PROTO_ISCSI << 4) | SVPD_ID_CODESET_UTF8;
-	desc2->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_TARGET |
-	    SVPD_ID_TYPE_SCSI_NAME;
-	desc2->length = wwnn_len;
-	snprintf(desc2->identifier, wwnn_len, "%s", cs->cs_target->ct_name);
-
-	/*
-	 * desc3 is for the WWPN which is a port asscociation.
-	 */
-	desc3->proto_codeset = (SCSI_PROTO_ISCSI << 4) | SVPD_ID_CODESET_UTF8;
-	desc3->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_PORT |
-	    SVPD_ID_TYPE_SCSI_NAME;
-	desc3->length = wwpn_len;
-	snprintf(desc3->identifier, wwpn_len, "%s,t,0x%4.4x",
-	    cs->cs_target->ct_name, cs->cs_portal_group_tag);
-
-	/*
-	 * desc3 is for the Relative Target Port(type 4h) identifier
-	 */
-	desc4->proto_codeset = (SCSI_PROTO_ISCSI << 4) | SVPD_ID_CODESET_BINARY;
-	desc4->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_PORT |
-	    SVPD_ID_TYPE_RELTARG;
-	desc4->length = 4;
-	desc4->identifier[3] = 1;
-
-	/*
-	 * desc4 is for the Target Port Group(type 5h) identifier
-	 */
-	desc5->proto_codeset = (SCSI_PROTO_ISCSI << 4) | SVPD_ID_CODESET_BINARY;
-	desc5->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_PORT |
-	    SVPD_ID_TYPE_TPORTGRP;
-	desc5->length = 4;
-	desc5->identifier[3] = 1;
-
-	ctsio->scsi_status = SCSI_STATUS_OK;
-
-	ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
-	ctsio->be_move_done = ctl_config_move_done;
-	ctl_datamove((union ctl_io *)ctsio);
-
-	return (CTL_RETVAL_COMPLETE);
-}
-
 static void
 cfiscsi_target_hold(struct cfiscsi_target *ct)
 {

Modified: stable/10/sys/cam/ctl/ctl_private.h
==============================================================================
--- stable/10/sys/cam/ctl/ctl_private.h	Tue Jul 15 17:05:11 2014	(r268682)
+++ stable/10/sys/cam/ctl/ctl_private.h	Tue Jul 15 17:06:10 2014	(r268683)
@@ -367,6 +367,11 @@ struct ctl_per_res_info {
 #define CTL_PR_ALL_REGISTRANTS  0xFFFF
 #define CTL_PR_NO_RESERVATION   0xFFF0
 
+struct ctl_devid {
+	int		len;
+	uint8_t		data[];
+};
+
 /*
  * For report target port groups.
  */
@@ -402,6 +407,7 @@ struct ctl_lun {
 	uint16_t        		pr_res_idx;
 	uint8_t				res_type;
 	uint8_t				write_buffer[524288];
+	struct ctl_devid		*lun_devid;
 };
 
 typedef enum {

Modified: stable/10/sys/cam/ctl/scsi_ctl.c
==============================================================================
--- stable/10/sys/cam/ctl/scsi_ctl.c	Tue Jul 15 17:05:11 2014	(r268682)
+++ stable/10/sys/cam/ctl/scsi_ctl.c	Tue Jul 15 17:06:10 2014	(r268683)
@@ -1732,10 +1732,9 @@ ctlfe_onoffline(void *arg, int online)
 			 * using with the frontend code so it's reported
 			 * accurately.
 			 */
-			bus_softc->port.wwnn = 
-				ccb->knob.xport_specific.fc.wwnn;
-			bus_softc->port.wwpn = 
-				ccb->knob.xport_specific.fc.wwpn;
+			ctl_port_set_wwns(&bus_softc->port,
+			    true, ccb->knob.xport_specific.fc.wwnn,
+			    true, ccb->knob.xport_specific.fc.wwpn);
 			set_wwnn = 1;
 #else /* RANDOM_WWNN */
 			/*
@@ -1751,10 +1750,9 @@ ctlfe_onoffline(void *arg, int online)
 					bus_softc->port.wwpn;
 				set_wwnn = 1;
 			} else {
-				bus_softc->port.wwnn =
-					ccb->knob.xport_specific.fc.wwnn;
-				bus_softc->port.wwpn =
-					ccb->knob.xport_specific.fc.wwpn;
+				ctl_port_set_wwns(&bus_softc->port,
+				    true, ccb->knob.xport_specific.fc.wwnn,
+				    true, ccb->knob.xport_specific.fc.wwpn);
 			}
 #endif /* RANDOM_WWNN */
 

Modified: stable/10/usr.sbin/ctladm/ctladm.8
==============================================================================
--- stable/10/usr.sbin/ctladm/ctladm.8	Tue Jul 15 17:05:11 2014	(r268682)
+++ stable/10/usr.sbin/ctladm/ctladm.8	Tue Jul 15 17:06:10 2014	(r268683)
@@ -945,6 +945,8 @@ Specifies LUN vendor string up to 8 char
 Specifies LUN product string up to 16 chars.
 .It Va revision
 Specifies LUN revision string up to 4 chars.
+.It Va scsiname
+Specifies LUN SCSI name string.
 .It Va unmap
 Set to "on", enables UNMAP support for the LUN.
 .El

Modified: stable/10/usr.sbin/ctld/kernel.c
==============================================================================
--- stable/10/usr.sbin/ctld/kernel.c	Tue Jul 15 17:05:11 2014	(r268682)
+++ stable/10/usr.sbin/ctld/kernel.c	Tue Jul 15 17:06:10 2014	(r268683)
@@ -113,7 +113,6 @@ struct cctl_lun {
 	char *serial_number;
 	char *device_id;
 	char *cfiscsi_target;
-	char *cfiscsi_target_alias;
 	int cfiscsi_lun;
 	STAILQ_HEAD(,cctl_lun_nv) attr_list;
 	STAILQ_ENTRY(cctl_lun) links;
@@ -230,9 +229,6 @@ cctl_end_element(void *user_data, const 
 	} else if (strcmp(name, "cfiscsi_target") == 0) {
 		cur_lun->cfiscsi_target = str;
 		str = NULL;
-	} else if (strcmp(name, "cfiscsi_target_alias") == 0) {
-		cur_lun->cfiscsi_target_alias = str;
-		str = NULL;
 	} else if (strcmp(name, "cfiscsi_lun") == 0) {
 		cur_lun->cfiscsi_lun = strtoul(str, NULL, 0);
 	} else if (strcmp(name, "lun") == 0) {
@@ -640,17 +636,6 @@ kernel_lun_add(struct lun *lun)
 		assert(lo != NULL);
 	}
 
-	if (lun->l_target->t_alias != NULL) {
-		lo = lun_option_find(lun, "cfiscsi_target_alias");
-		if (lo != NULL) {
-			lun_option_set(lo, lun->l_target->t_alias);
-		} else {
-			lo = lun_option_new(lun, "cfiscsi_target_alias",
-			    lun->l_target->t_alias);
-			assert(lo != NULL);
-		}
-	}
-
 	asprintf(&tmp, "%d", lun->l_lun);
 	if (tmp == NULL)
 		log_errx(1, "asprintf");
@@ -664,6 +649,19 @@ kernel_lun_add(struct lun *lun)
 		assert(lo != NULL);
 	}
 
+	asprintf(&tmp, "%s,lun,%d", lun->l_target->t_name, lun->l_lun);
+	if (tmp == NULL)
+		log_errx(1, "asprintf");
+	lo = lun_option_find(lun, "scsiname");
+	if (lo != NULL) {
+		lun_option_set(lo, tmp);
+		free(tmp);
+	} else {
+		lo = lun_option_new(lun, "scsiname", tmp);
+		free(tmp);
+		assert(lo != NULL);
+	}
+
 	num_options = 0;
 	TAILQ_FOREACH(lo, &lun->l_options, lo_next)
 		num_options++;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201407151706.s6FH6B1F083817>