Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 1 Feb 2015 21:50:28 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r278037 - in head: sys/cam/ctl usr.sbin/ctladm usr.sbin/ctld
Message-ID:  <201502012150.t11LoSfT024581@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Sun Feb  1 21:50:28 2015
New Revision: 278037
URL: https://svnweb.freebsd.org/changeset/base/278037

Log:
  CTL LUN mapping rewrite.
  
  Replace iSCSI-specific LUN mapping mechanism with new one, working for any
  ports.  By default all ports are created without LUN mapping, exposing all
  CTL LUNs as before.  But, if needed, LUN mapping can be manually set on
  per-port basis via ctladm.  For its iSCSI ports ctld does it via ioctl(2).
  The next step will be to teach ctld to work with FibreChannel ports also.
  
  Respecting additional flexibility of the new mechanism, ctl.conf now allows
  alternative syntax for LUN definition.  LUNs can now be defined in global
  context, and then referenced from targets by unique name, as needed.  It
  allows same LUN to be exposed several times via multiple targets.
  
  While there, increase limit for LUNs per target in ctld from 256 to 1024.
  Some initiators do not support LUNs above 255, but that is not our problem.
  
  Discussed with:	trasz
  MFC after:	2 weeks
  Relnotes:	yes
  Sponsored by:	iXsystems, Inc.

Modified:
  head/sys/cam/ctl/ctl.c
  head/sys/cam/ctl/ctl_frontend.c
  head/sys/cam/ctl/ctl_frontend.h
  head/sys/cam/ctl/ctl_frontend_iscsi.c
  head/sys/cam/ctl/ctl_frontend_iscsi.h
  head/sys/cam/ctl/ctl_ioctl.h
  head/sys/cam/ctl/ctl_private.h
  head/sys/cam/ctl/ctl_tpc_local.c
  head/usr.sbin/ctladm/ctladm.8
  head/usr.sbin/ctladm/ctladm.c
  head/usr.sbin/ctld/ctl.conf.5
  head/usr.sbin/ctld/ctld.c
  head/usr.sbin/ctld/ctld.h
  head/usr.sbin/ctld/kernel.c
  head/usr.sbin/ctld/parse.y

Modified: head/sys/cam/ctl/ctl.c
==============================================================================
--- head/sys/cam/ctl/ctl.c	Sun Feb  1 20:16:18 2015	(r278036)
+++ head/sys/cam/ctl/ctl.c	Sun Feb  1 21:50:28 2015	(r278037)
@@ -398,12 +398,11 @@ static int ctl_ioctl_fill_ooa(struct ctl
 			      struct ctl_ooa_entry *kern_entries);
 static int ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
 		     struct thread *td);
-static uint32_t ctl_map_lun(struct ctl_softc *softc, int port_num, uint32_t lun);
-static uint32_t ctl_map_lun_back(struct ctl_softc *softc, int port_num, uint32_t lun);
 static int ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *lun,
 			 struct ctl_be_lun *be_lun, struct ctl_id target_id);
 static int ctl_free_lun(struct ctl_lun *lun);
 static void ctl_create_lun(struct ctl_be_lun *be_lun);
+static struct ctl_port * ctl_io_port(struct ctl_io_hdr *io_hdr);
 /**
 static void ctl_failover_change_pages(struct ctl_softc *softc,
 				      struct ctl_scsiio *ctsio, int master);
@@ -3411,6 +3410,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, 
 		struct ctl_lun_list *list;
 		struct ctl_option *opt;
 		int j;
+		uint32_t plun;
 
 		list = (struct ctl_lun_list *)addr;
 
@@ -3491,6 +3491,18 @@ ctl_ioctl(struct cdev *dev, u_long cmd, 
 					break;
 			}
 
+			if (port->lun_map != NULL) {
+				sbuf_printf(sb, "\t<lun_map>on</lun_map>\n");
+				for (j = 0; j < CTL_MAX_LUNS; j++) {
+					plun = ctl_lun_map_from_port(port, j);
+					if (plun >= CTL_MAX_LUNS)
+						continue;
+					sbuf_printf(sb,
+					    "\t<lun id=\"%u\">%u</lun>\n",
+					    j, plun);
+				}
+			}
+
 			for (j = 0; j < CTL_MAX_INIT_PER_PORT; j++) {
 				if (port->wwpn_iid[j].in_use == 0 ||
 				    (port->wwpn_iid[j].wwpn == 0 &&
@@ -3538,6 +3550,38 @@ ctl_ioctl(struct cdev *dev, u_long cmd, 
 		sbuf_delete(sb);
 		break;
 	}
+	case CTL_LUN_MAP: {
+		struct ctl_lun_map *lm  = (struct ctl_lun_map *)addr;
+		struct ctl_port *port;
+
+		mtx_lock(&softc->ctl_lock);
+		if (lm->port >= CTL_MAX_PORTS ||
+		    (port = softc->ctl_ports[lm->port]) == NULL) {
+			mtx_unlock(&softc->ctl_lock);
+			return (ENXIO);
+		}
+		if (lm->plun < CTL_MAX_LUNS) {
+			if (lm->lun == UINT32_MAX)
+				retval = ctl_lun_map_unset(port, lm->plun);
+			else if (lm->lun < CTL_MAX_LUNS &&
+			    softc->ctl_luns[lm->lun] != NULL)
+				retval = ctl_lun_map_set(port, lm->plun, lm->lun);
+			else {
+				mtx_unlock(&softc->ctl_lock);
+				return (ENXIO);
+			}
+		} else if (lm->plun == UINT32_MAX) {
+			if (lm->lun == UINT32_MAX)
+				retval = ctl_lun_map_deinit(port);
+			else
+				retval = ctl_lun_map_init(port);
+		} else {
+			mtx_unlock(&softc->ctl_lock);
+			return (ENXIO);
+		}
+		mtx_unlock(&softc->ctl_lock);
+		break;
+	}
 	default: {
 		/* XXX KDM should we fix this? */
 #if 0
@@ -3602,35 +3646,106 @@ ctl_port_idx(int port_num)
 		return(port_num - CTL_MAX_PORTS);
 }
 
-static uint32_t
-ctl_map_lun(struct ctl_softc *softc, int port_num, uint32_t lun_id)
+int
+ctl_lun_map_init(struct ctl_port *port)
+{
+	uint32_t i;
+
+	if (port->lun_map == NULL)
+		port->lun_map = malloc(sizeof(uint32_t) * CTL_MAX_LUNS,
+		    M_CTL, M_NOWAIT);
+	if (port->lun_map == NULL)
+		return (ENOMEM);
+	for (i = 0; i < CTL_MAX_LUNS; i++)
+		port->lun_map[i] = UINT32_MAX;
+	return (0);
+}
+
+int
+ctl_lun_map_deinit(struct ctl_port *port)
+{
+
+	if (port->lun_map == NULL)
+		return (0);
+	free(port->lun_map, M_CTL);
+	port->lun_map = NULL;
+	return (0);
+}
+
+int
+ctl_lun_map_set(struct ctl_port *port, uint32_t plun, uint32_t glun)
+{
+	int status;
+
+	if (port->lun_map == NULL) {
+		status = ctl_lun_map_init(port);
+		if (status != 0)
+			return (status);
+	}
+	port->lun_map[plun] = glun;
+	return (0);
+}
+
+int
+ctl_lun_map_unset(struct ctl_port *port, uint32_t plun)
+{
+
+	if (port->lun_map == NULL)
+		return (0);
+	port->lun_map[plun] = UINT32_MAX;
+	return (0);
+}
+
+int
+ctl_lun_map_unsetg(struct ctl_port *port, uint32_t glun)
+{
+	int i;
+
+	if (port->lun_map == NULL)
+		return (0);
+	for (i = 0; i < CTL_MAX_LUNS; i++) {
+		if (port->lun_map[i] == glun)
+			port->lun_map[i] = UINT32_MAX;
+	}
+	return (0);
+}
+
+uint32_t
+ctl_lun_map_from_port(struct ctl_port *port, uint32_t lun_id)
 {
-	struct ctl_port *port;
 
-	port = softc->ctl_ports[ctl_port_idx(port_num)];
 	if (port == NULL)
 		return (UINT32_MAX);
-	if (port->lun_map == NULL)
+	if (port->lun_map == NULL || lun_id >= CTL_MAX_LUNS)
 		return (lun_id);
-	return (port->lun_map(port->targ_lun_arg, lun_id));
+	return (port->lun_map[lun_id]);
 }
 
-static uint32_t
-ctl_map_lun_back(struct ctl_softc *softc, int port_num, uint32_t lun_id)
+uint32_t
+ctl_lun_map_to_port(struct ctl_port *port, uint32_t lun_id)
 {
-	struct ctl_port *port;
 	uint32_t i;
 
-	port = softc->ctl_ports[ctl_port_idx(port_num)];
+	if (port == NULL)
+		return (UINT32_MAX);
 	if (port->lun_map == NULL)
 		return (lun_id);
 	for (i = 0; i < CTL_MAX_LUNS; i++) {
-		if (port->lun_map(port->targ_lun_arg, i) == lun_id)
+		if (port->lun_map[i] == lun_id)
 			return (i);
 	}
 	return (UINT32_MAX);
 }
 
+static struct ctl_port *
+ctl_io_port(struct ctl_io_hdr *io_hdr)
+{
+	int port_num;
+
+	port_num = io_hdr->nexus.targ_port;
+	return (control_softc->ctl_ports[ctl_port_idx(port_num)]);
+}
+
 /*
  * Note:  This only works for bitmask sizes that are at least 32 bits, and
  * that are a power of 2.
@@ -4676,9 +4791,7 @@ static int
 ctl_free_lun(struct ctl_lun *lun)
 {
 	struct ctl_softc *softc;
-#if 0
 	struct ctl_port *port;
-#endif
 	struct ctl_lun *nlun;
 	int i;
 
@@ -4686,6 +4799,9 @@ ctl_free_lun(struct ctl_lun *lun)
 
 	mtx_assert(&softc->ctl_lock, MA_OWNED);
 
+	STAILQ_FOREACH(port, &softc->port_list, links)
+		ctl_lun_map_unsetg(port, lun->lun);
+
 	STAILQ_REMOVE(&softc->lun_list, lun, ctl_lun, links);
 
 	ctl_clear_mask(softc->ctl_lun_mask, lun->lun);
@@ -7343,8 +7459,7 @@ ctl_report_tagret_port_groups(struct ctl
 	STAILQ_FOREACH(port, &softc->port_list, links) {
 		if ((port->status & CTL_PORT_STATUS_ONLINE) == 0)
 			continue;
-		if (ctl_map_lun_back(softc, port->targ_port, lun->lun) >=
-		    CTL_MAX_LUNS)
+		if (ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
 			continue;
 		num_target_ports++;
 	}
@@ -7417,8 +7532,7 @@ ctl_report_tagret_port_groups(struct ctl
 		STAILQ_FOREACH(port, &softc->port_list, links) {
 			if ((port->status & CTL_PORT_STATUS_ONLINE) == 0)
 				continue;
-			if (ctl_map_lun_back(softc, port->targ_port, lun->lun)
-			    >= CTL_MAX_LUNS)
+			if (ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
 				continue;
 			p = port->targ_port % CTL_MAX_PORTS + g * CTL_MAX_PORTS;
 			scsi_ulto2b(p, tpg_desc->descriptors[pc].
@@ -9260,6 +9374,7 @@ ctl_report_luns(struct ctl_scsiio *ctsio
 	struct scsi_report_luns *cdb;
 	struct scsi_report_luns_data *lun_data;
 	struct ctl_lun *lun, *request_lun;
+	struct ctl_port *port;
 	int num_luns, retval;
 	uint32_t alloc_len, lun_datalen;
 	int num_filled, well_known;
@@ -9316,6 +9431,7 @@ ctl_report_luns(struct ctl_scsiio *ctsio
 
 	request_lun = (struct ctl_lun *)
 		ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
+	port = ctl_io_port(&ctsio->io_hdr);
 
 	lun_datalen = sizeof(*lun_data) +
 		(num_luns * sizeof(struct scsi_report_luns_lundata));
@@ -9328,8 +9444,7 @@ ctl_report_luns(struct ctl_scsiio *ctsio
 
 	mtx_lock(&softc->ctl_lock);
 	for (targ_lun_id = 0, num_filled = 0; targ_lun_id < CTL_MAX_LUNS && num_filled < num_luns; targ_lun_id++) {
-		lun_id = ctl_map_lun(softc, ctsio->io_hdr.nexus.targ_port,
-		    targ_lun_id);
+		lun_id = ctl_lun_map_from_port(port, targ_lun_id);
 		if (lun_id >= CTL_MAX_LUNS)
 			continue;
 		lun = softc->ctl_luns[lun_id];
@@ -10014,8 +10129,7 @@ ctl_inquiry_evpd_scsi_ports(struct ctl_s
 		if ((port->status & CTL_PORT_STATUS_ONLINE) == 0)
 			continue;
 		if (lun != NULL &&
-		    ctl_map_lun_back(softc, port->targ_port, lun->lun) >=
-		    CTL_MAX_LUNS)
+		    ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
 			continue;
 		num_target_ports++;
 		if (port->init_devid)
@@ -10068,8 +10182,7 @@ ctl_inquiry_evpd_scsi_ports(struct ctl_s
 			if ((port->status & CTL_PORT_STATUS_ONLINE) == 0)
 				continue;
 			if (lun != NULL &&
-			    ctl_map_lun_back(softc, port->targ_port, lun->lun)
-			    >= CTL_MAX_LUNS)
+			    ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
 				continue;
 			p = port->targ_port % CTL_MAX_PORTS + g * CTL_MAX_PORTS;
 			scsi_ulto2b(p, pd->relative_port_id);
@@ -13745,6 +13858,7 @@ int
 ctl_queue_sense(union ctl_io *io)
 {
 	struct ctl_lun *lun;
+	struct ctl_port *port;
 	struct ctl_softc *softc;
 	uint32_t initidx, targ_lun;
 
@@ -13765,8 +13879,8 @@ ctl_queue_sense(union ctl_io *io)
 	 * If we don't have a LUN for this, just toss the sense
 	 * information.
 	 */
-	targ_lun = io->io_hdr.nexus.targ_lun;
-	targ_lun = ctl_map_lun(softc, io->io_hdr.nexus.targ_port, targ_lun);
+	port = ctl_io_port(&ctsio->io_hdr);
+	targ_lun = ctl_lun_map_from_port(port, io->io_hdr.nexus.targ_lun);
 	if ((targ_lun < CTL_MAX_LUNS)
 	 && (softc->ctl_luns[targ_lun] != NULL))
 		lun = softc->ctl_luns[targ_lun];
@@ -13806,6 +13920,7 @@ bailout:
 int
 ctl_queue(union ctl_io *io)
 {
+	struct ctl_port *port;
 
 	CTL_DEBUG_PRINT(("ctl_queue cdb[0]=%02X\n", io->scsiio.cdb[0]));
 
@@ -13815,9 +13930,9 @@ ctl_queue(union ctl_io *io)
 #endif /* CTL_TIME_IO */
 
 	/* Map FE-specific LUN ID into global one. */
+	port = ctl_io_port(&io->io_hdr);
 	io->io_hdr.nexus.targ_mapped_lun =
-	    ctl_map_lun(control_softc, io->io_hdr.nexus.targ_port,
-	     io->io_hdr.nexus.targ_lun);
+	    ctl_lun_map_from_port(port, io->io_hdr.nexus.targ_lun);
 
 	switch (io->io_hdr.io_type) {
 	case CTL_IO_SCSI:

Modified: head/sys/cam/ctl/ctl_frontend.c
==============================================================================
--- head/sys/cam/ctl/ctl_frontend.c	Sun Feb  1 20:16:18 2015	(r278036)
+++ head/sys/cam/ctl/ctl_frontend.c	Sun Feb  1 21:50:28 2015	(r278037)
@@ -234,6 +234,7 @@ ctl_port_deregister(struct ctl_port *por
 	ctl_pool_free(pool);
 	ctl_free_opts(&port->options);
 
+	ctl_lun_map_deinit(port);
 	free(port->port_devid, M_CTL);
 	port->port_devid = NULL;
 	free(port->target_devid, M_CTL);

Modified: head/sys/cam/ctl/ctl_frontend.h
==============================================================================
--- head/sys/cam/ctl/ctl_frontend.h	Sun Feb  1 20:16:18 2015	(r278036)
+++ head/sys/cam/ctl/ctl_frontend.h	Sun Feb  1 21:50:28 2015	(r278037)
@@ -51,7 +51,6 @@ typedef void (*fe_shutdown_t)(void);
 typedef void (*port_func_t)(void *onoff_arg);
 typedef int (*port_info_func_t)(void *onoff_arg, struct sbuf *sb);
 typedef	int (*lun_func_t)(void *arg, struct ctl_id targ_id, int lun_id);
-typedef	uint32_t (*lun_map_func_t)(void *arg, uint32_t lun_id);
 typedef int (*fe_ioctl_t)(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
 			  struct thread *td);
 
@@ -226,7 +225,7 @@ 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 */
-	lun_map_func_t	lun_map;		/* passed to CTL */
+	uint32_t	*lun_map;		/* 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 */

Modified: head/sys/cam/ctl/ctl_frontend_iscsi.c
==============================================================================
--- head/sys/cam/ctl/ctl_frontend_iscsi.c	Sun Feb  1 20:16:18 2015	(r278036)
+++ head/sys/cam/ctl/ctl_frontend_iscsi.c	Sun Feb  1 21:50:28 2015	(r278037)
@@ -151,7 +151,6 @@ static int	cfiscsi_lun_enable(void *arg,
 		    struct ctl_id target_id, int lun_id);
 static int	cfiscsi_lun_disable(void *arg,
 		    struct ctl_id target_id, int lun_id);
-static uint32_t	cfiscsi_lun_map(void *arg, uint32_t lun);
 static int	cfiscsi_ioctl(struct cdev *dev,
 		    u_long cmd, caddr_t addr, int flag, struct thread *td);
 static void	cfiscsi_datamove(union ctl_io *io);
@@ -2031,7 +2030,6 @@ cfiscsi_ioctl_port_create(struct ctl_req
 	port->onoff_arg = ct;
 	port->lun_enable = cfiscsi_lun_enable;
 	port->lun_disable = cfiscsi_lun_disable;
-	port->lun_map = cfiscsi_lun_map;
 	port->targ_lun_arg = ct;
 	port->fe_datamove = cfiscsi_datamove;
 	port->fe_done = cfiscsi_done;
@@ -2081,7 +2079,7 @@ cfiscsi_ioctl_port_create(struct ctl_req
 		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);
+		    "ctl_port_register() failed with error %d", retval);
 		return;
 	}
 done:
@@ -2259,7 +2257,6 @@ cfiscsi_target_find_or_create(struct cfi
     const char *alias)
 {
 	struct cfiscsi_target *ct, *newct;
-	int i;
 
 	if (name[0] == '\0' || strlen(name) >= CTL_ISCSI_NAME_LEN)
 		return (NULL);
@@ -2277,9 +2274,6 @@ cfiscsi_target_find_or_create(struct cfi
 		return (ct);
 	}
 
-	for (i = 0; i < CTL_MAX_LUNS; i++)
-		newct->ct_luns[i] = UINT32_MAX;
-
 	strlcpy(newct->ct_name, name, sizeof(newct->ct_name));
 	if (alias != NULL)
 		strlcpy(newct->ct_alias, alias, sizeof(newct->ct_alias));
@@ -2294,108 +2288,17 @@ cfiscsi_target_find_or_create(struct cfi
 	return (newct);
 }
 
-/*
- * Takes LUN from the target space and returns LUN from the CTL space.
- */
-static uint32_t
-cfiscsi_lun_map(void *arg, uint32_t lun)
-{
-	struct cfiscsi_target *ct = arg;
-
-	if (lun >= CTL_MAX_LUNS) {
-		CFISCSI_DEBUG("requested lun number %d is higher "
-		    "than maximum %d", lun, CTL_MAX_LUNS - 1);
-		return (UINT32_MAX);
-	}
-	return (ct->ct_luns[lun]);
-}
-
-static int
-cfiscsi_target_set_lun(struct cfiscsi_target *ct,
-    unsigned long lun_id, unsigned long ctl_lun_id)
-{
-
-	if (lun_id >= CTL_MAX_LUNS) {
-		CFISCSI_WARN("requested lun number %ld is higher "
-		    "than maximum %d", lun_id, CTL_MAX_LUNS - 1);
-		return (-1);
-	}
-
-	if (ct->ct_luns[lun_id] < CTL_MAX_LUNS) {
-		/*
-		 * CTL calls cfiscsi_lun_enable() twice for each LUN - once
-		 * when the LUN is created, and a second time just before
-		 * the port is brought online; don't emit warnings
-		 * for that case.
-		 */
-		if (ct->ct_luns[lun_id] == ctl_lun_id)
-			return (0);
-		CFISCSI_WARN("lun %ld already allocated", lun_id);
-		return (-1);
-	}
-
-#if 0
-	CFISCSI_DEBUG("adding mapping for lun %ld, target %s "
-	    "to ctl lun %ld", lun_id, ct->ct_name, ctl_lun_id);
-#endif
-
-	ct->ct_luns[lun_id] = ctl_lun_id;
-
-	return (0);
-}
-
 static int
 cfiscsi_lun_enable(void *arg, struct ctl_id target_id, int lun_id)
 {
-	struct cfiscsi_softc *softc;
-	struct cfiscsi_target *ct;
-	const char *target = NULL;
-	const char *lun = NULL;
-	unsigned long tmp;
-
-	ct = (struct cfiscsi_target *)arg;
-	softc = ct->ct_softc;
-
-	target = ctl_get_opt(&control_softc->ctl_luns[lun_id]->be_lun->options,
-	    "cfiscsi_target");
-	lun = ctl_get_opt(&control_softc->ctl_luns[lun_id]->be_lun->options,
-	    "cfiscsi_lun");
-
-	if (target == NULL && lun == NULL)
-		return (0);
-
-	if (target == NULL || lun == NULL) {
-		CFISCSI_WARN("lun added with cfiscsi_target, but without "
-		    "cfiscsi_lun, or the other way around; ignoring");
-		return (0);
-	}
-
-	if (strcmp(target, ct->ct_name) != 0)
-		return (0);
 
-	tmp = strtoul(lun, NULL, 10);
-	cfiscsi_target_set_lun(ct, tmp, lun_id);
 	return (0);
 }
 
 static int
 cfiscsi_lun_disable(void *arg, struct ctl_id target_id, int lun_id)
 {
-	struct cfiscsi_softc *softc;
-	struct cfiscsi_target *ct;
-	int i;
-
-	ct = (struct cfiscsi_target *)arg;
-	softc = ct->ct_softc;
 
-	mtx_lock(&softc->lock);
-	for (i = 0; i < CTL_MAX_LUNS; i++) {
-		if (ct->ct_luns[i] != lun_id)
-			continue;
-		ct->ct_luns[i] = UINT32_MAX;
-		break;
-	}
-	mtx_unlock(&softc->lock);
 	return (0);
 }
 

Modified: head/sys/cam/ctl/ctl_frontend_iscsi.h
==============================================================================
--- head/sys/cam/ctl/ctl_frontend_iscsi.h	Sun Feb  1 20:16:18 2015	(r278036)
+++ head/sys/cam/ctl/ctl_frontend_iscsi.h	Sun Feb  1 21:50:28 2015	(r278037)
@@ -38,7 +38,6 @@
 
 struct cfiscsi_target {
 	TAILQ_ENTRY(cfiscsi_target)	ct_next;
-	uint32_t			ct_luns[CTL_MAX_LUNS];
 	struct cfiscsi_softc		*ct_softc;
 	volatile u_int			ct_refcount;
 	char				ct_name[CTL_ISCSI_NAME_LEN];

Modified: head/sys/cam/ctl/ctl_ioctl.h
==============================================================================
--- head/sys/cam/ctl/ctl_ioctl.h	Sun Feb  1 20:16:18 2015	(r278036)
+++ head/sys/cam/ctl/ctl_ioctl.h	Sun Feb  1 21:50:28 2015	(r278037)
@@ -805,6 +805,12 @@ struct ctl_iscsi {
 						/* passed to userland */
 };
 
+struct ctl_lun_map {
+	uint32_t		port;
+	uint32_t		plun;
+	uint32_t		lun;
+};
+
 #define	CTL_IO			_IOWR(CTL_MINOR, 0x00, union ctl_io)
 #define	CTL_ENABLE_PORT		_IOW(CTL_MINOR, 0x04, struct ctl_port_entry)
 #define	CTL_DISABLE_PORT	_IOW(CTL_MINOR, 0x05, struct ctl_port_entry)
@@ -832,6 +838,7 @@ struct ctl_iscsi {
 #define	CTL_ISCSI		_IOWR(CTL_MINOR, 0x25, struct ctl_iscsi)
 #define	CTL_PORT_REQ		_IOWR(CTL_MINOR, 0x26, struct ctl_req)
 #define	CTL_PORT_LIST		_IOWR(CTL_MINOR, 0x27, struct ctl_lun_list)
+#define	CTL_LUN_MAP		_IOW(CTL_MINOR, 0x28, struct ctl_lun_map)
 
 #endif /* _CTL_IOCTL_H_ */
 

Modified: head/sys/cam/ctl/ctl_private.h
==============================================================================
--- head/sys/cam/ctl/ctl_private.h	Sun Feb  1 20:16:18 2015	(r278036)
+++ head/sys/cam/ctl/ctl_private.h	Sun Feb  1 21:50:28 2015	(r278037)
@@ -492,6 +492,13 @@ extern const struct ctl_cmd_entry ctl_cm
 uint32_t ctl_get_initindex(struct ctl_nexus *nexus);
 uint32_t ctl_get_resindex(struct ctl_nexus *nexus);
 uint32_t ctl_port_idx(int port_num);
+int ctl_lun_map_init(struct ctl_port *port);
+int ctl_lun_map_deinit(struct ctl_port *port);
+int ctl_lun_map_set(struct ctl_port *port, uint32_t plun, uint32_t glun);
+int ctl_lun_map_unset(struct ctl_port *port, uint32_t plun);
+int ctl_lun_map_unsetg(struct ctl_port *port, uint32_t glun);
+uint32_t ctl_lun_map_from_port(struct ctl_port *port, uint32_t plun);
+uint32_t ctl_lun_map_to_port(struct ctl_port *port, uint32_t glun);
 int ctl_pool_create(struct ctl_softc *ctl_softc, const char *pool_name,
 		    uint32_t total_ctl_io, void **npool);
 void ctl_pool_free(struct ctl_io_pool *pool);

Modified: head/sys/cam/ctl/ctl_tpc_local.c
==============================================================================
--- head/sys/cam/ctl/ctl_tpc_local.c	Sun Feb  1 20:16:18 2015	(r278036)
+++ head/sys/cam/ctl/ctl_tpc_local.c	Sun Feb  1 21:50:28 2015	(r278037)
@@ -314,48 +314,30 @@ tpcl_resolve(struct ctl_softc *softc, in
 	struct scsi_ec_cscd_id *cscdid;
 	struct ctl_port *port;
 	struct ctl_lun *lun;
-	uint64_t lunid = UINT64_MAX, l;
-	int i;
+	uint64_t lunid = UINT64_MAX;
 
 	if (cscd->type_code != EC_CSCD_ID)
 		return (lunid);
 
 	cscdid = (struct scsi_ec_cscd_id *)cscd;
 	mtx_lock(&softc->ctl_lock);
-	if (init_port >= 0) {
+	if (init_port >= 0)
 		port = softc->ctl_ports[ctl_port_idx(init_port)];
-		if (port == NULL || port->lun_map == NULL)
-			init_port = -1;
-	}
-	if (init_port < 0) {
-		STAILQ_FOREACH(lun, &softc->lun_list, links) {
-			if (lun->lun_devid == NULL)
-				continue;
-			if (scsi_devid_match(lun->lun_devid->data,
-			    lun->lun_devid->len, &cscdid->codeset,
-			    cscdid->length + 4) == 0) {
-				lunid = lun->lun;
-				if (ss && lun->be_lun)
-					*ss = lun->be_lun->blocksize;
-				break;
-			}
-		}
-	} else {
-		for (i = 0; i < CTL_MAX_LUNS; i++) {
-			l = port->lun_map(port->targ_lun_arg, i);
-			if (l >= CTL_MAX_LUNS)
-				continue;
-			lun = softc->ctl_luns[l];
-			if (lun == NULL || lun->lun_devid == NULL)
-				continue;
-			if (scsi_devid_match(lun->lun_devid->data,
-			    lun->lun_devid->len, &cscdid->codeset,
-			    cscdid->length + 4) == 0) {
-				lunid = lun->lun;
-				if (ss && lun->be_lun)
-					*ss = lun->be_lun->blocksize;
-				break;
-			}
+	else
+		port = NULL;
+	STAILQ_FOREACH(lun, &softc->lun_list, links) {
+		if (port != NULL &&
+		    ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
+			continue;
+		if (lun->lun_devid == NULL)
+			continue;
+		if (scsi_devid_match(lun->lun_devid->data,
+		    lun->lun_devid->len, &cscdid->codeset,
+		    cscdid->length + 4) == 0) {
+			lunid = lun->lun;
+			if (ss && lun->be_lun)
+				*ss = lun->be_lun->blocksize;
+			break;
 		}
 	}
 	mtx_unlock(&softc->ctl_lock);

Modified: head/usr.sbin/ctladm/ctladm.8
==============================================================================
--- head/usr.sbin/ctladm/ctladm.8	Sun Feb  1 20:16:18 2015	(r278036)
+++ head/usr.sbin/ctladm/ctladm.8	Sun Feb  1 21:50:28 2015	(r278037)
@@ -34,7 +34,7 @@
 .\" $Id: //depot/users/kenm/FreeBSD-test2/usr.sbin/ctladm/ctladm.8#3 $
 .\" $FreeBSD$
 .\"
-.Dd December 17, 2014
+.Dd February 1, 2015
 .Dt CTLADM 8
 .Os
 .Sh NAME
@@ -196,11 +196,17 @@
 .Ic portlist
 .Op Fl f Ar frontend
 .Op Fl i
+.Op Fl l
 .Op Fl p Ar targ_port
 .Op Fl q
 .Op Fl v
 .Op Fl x
 .Nm
+.Ic lunmap
+.Aq Fl p Ar targ_port
+.Op Fl l Ar pLUN
+.Op Fl L Ar cLUN
+.Nm
 .Ic dumpooa
 .Nm
 .Ic dumpstructs
@@ -782,7 +788,9 @@ List CTL frontend ports.
 .It Fl f Ar frontend
 Specify the frontend type.
 .It Fl i
-Report target and connected initiators addresses
+Report target and connected initiators addresses.
+.It Fl l
+Report LUN mapping.
 .It Fl p Ar targ_port
 Specify the frontend port number.
 .It Fl q
@@ -792,6 +800,31 @@ Enable verbose output (report all port o
 .It Fl x
 Output the port list in XML format.
 .El
+.It Ic lunmap
+Change LUN mapping for specified port.
+If both
+.Ar pLUN
+and
+.Ar cLUN
+are specified -- LUN will be mapped.
+If
+.Ar pLUN
+is specified, but
+.Ar cLUN
+is not -- LUN will be unmapped.
+If neither
+.Ar pLUN
+nor
+.Ar cLUN
+are specified -- LUN mapping will be disabled, exposing all CTL LUNs.
+.Bl -tag -width 12n
+.It Fl p Ar targ_port
+Specify the frontend port number.
+.It Fl l Ar pLUN
+LUN number visible by specified port.
+.It Fl L Ar cLUN
+CTL LUN number.
+.El
 .It Ic dumpooa
 Dump the OOA (Order Of Arrival) queue for each LUN registered with CTL.
 .It Ic dumpstructs

Modified: head/usr.sbin/ctladm/ctladm.c
==============================================================================
--- head/usr.sbin/ctladm/ctladm.c	Sun Feb  1 20:16:18 2015	(r278036)
+++ head/usr.sbin/ctladm/ctladm.c	Sun Feb  1 21:50:28 2015	(r278037)
@@ -121,7 +121,8 @@ typedef enum {
 	CTLADM_CMD_MODIFY,
 	CTLADM_CMD_ISLIST,
 	CTLADM_CMD_ISLOGOUT,
-	CTLADM_CMD_ISTERMINATE
+	CTLADM_CMD_ISTERMINATE,
+	CTLADM_CMD_LUNMAP
 } ctladm_cmdfunction;
 
 typedef enum {
@@ -188,10 +189,11 @@ static struct ctladm_opts option_table[]
 	{"islogout", CTLADM_CMD_ISLOGOUT, CTLADM_ARG_NONE, "ac:i:p:"},
 	{"isterminate", CTLADM_CMD_ISTERMINATE, CTLADM_ARG_NONE, "ac:i:p:"},
 	{"lunlist", CTLADM_CMD_LUNLIST, CTLADM_ARG_NONE, NULL},
+	{"lunmap", CTLADM_CMD_LUNMAP, CTLADM_ARG_NONE, "p:l:L:"},
 	{"modesense", CTLADM_CMD_MODESENSE, CTLADM_ARG_NEED_TL, "P:S:dlm:c:"},
 	{"modify", CTLADM_CMD_MODIFY, CTLADM_ARG_NONE, "b:l:s:"},
 	{"port", CTLADM_CMD_PORT, CTLADM_ARG_NONE, "lo:p:qt:w:W:x"},
-	{"portlist", CTLADM_CMD_PORTLIST, CTLADM_ARG_NONE, "f:ip:qvx"},
+	{"portlist", CTLADM_CMD_PORTLIST, CTLADM_ARG_NONE, "f:ilp:qvx"},
 	{"prin", CTLADM_CMD_PRES_IN, CTLADM_ARG_NEED_TL, "a:"},
 	{"prout", CTLADM_CMD_PRES_OUT, CTLADM_ARG_NEED_TL, "a:k:r:s:"},
 	{"read", CTLADM_CMD_READ, CTLADM_ARG_NEED_TL, rw_opts},
@@ -4106,8 +4108,9 @@ struct cctl_port {
 	char *frontend_type;
 	char *name;
 	int pp, vp;
-	char *target, *port;
+	char *target, *port, *lun_map;
 	STAILQ_HEAD(,cctl_lun_nv) init_list;
+	STAILQ_HEAD(,cctl_lun_nv) lun_list;
 	STAILQ_HEAD(,cctl_lun_nv) attr_list;
 	STAILQ_ENTRY(cctl_port) links;
 };
@@ -4161,6 +4164,7 @@ cctl_start_pelement(void *user_data, con
 		portlist->cur_port = cur_port;
 
 		STAILQ_INIT(&cur_port->init_list);
+		STAILQ_INIT(&cur_port->lun_list);
 		STAILQ_INIT(&cur_port->attr_list);
 		cur_port->port_id = portlist->cur_id;
 		STAILQ_INSERT_TAIL(&portlist->port_list, cur_port, links);
@@ -4220,6 +4224,9 @@ cctl_end_pelement(void *user_data, const
 	} else if (strcmp(name, "port") == 0) {
 		cur_port->port = str;
 		str = NULL;
+	} else if (strcmp(name, "lun_map") == 0) {
+		cur_port->lun_map = str;
+		str = NULL;
 	} else if (strcmp(name, "targ_port") == 0) {
 		portlist->cur_port = NULL;
 	} else if (strcmp(name, "ctlportlist") == 0) {
@@ -4232,7 +4239,8 @@ cctl_end_pelement(void *user_data, const
 			err(1, "%s: can't allocate %zd bytes for nv pair",
 			    __func__, sizeof(*nv));
 
-		if (strcmp(name, "initiator") == 0)
+		if (strcmp(name, "initiator") == 0 ||
+		    strcmp(name, "lun") == 0)
 			asprintf(&nv->name, "%ju", portlist->cur_id);
 		else
 			nv->name = strdup(name);
@@ -4244,6 +4252,8 @@ cctl_end_pelement(void *user_data, const
 		str = NULL;
 		if (strcmp(name, "initiator") == 0)
 			STAILQ_INSERT_TAIL(&cur_port->init_list, nv, links);
+		else if (strcmp(name, "lun") == 0)
+			STAILQ_INSERT_TAIL(&cur_port->lun_list, nv, links);
 		else
 			STAILQ_INSERT_TAIL(&cur_port->attr_list, nv, links);
 	}
@@ -4274,7 +4284,7 @@ cctl_portlist(int fd, int argc, char **a
 	int retval, c;
 	char *frontend = NULL;
 	uint64_t portarg = UINT64_MAX;
-	int verbose = 0, init = 0, quiet = 0;
+	int verbose = 0, init = 0, lun = 0, quiet = 0;
 
 	retval = 0;
 	port_len = 4096;
@@ -4290,6 +4300,9 @@ cctl_portlist(int fd, int argc, char **a
 		case 'i':
 			init++;
 			break;
+		case 'l':
+			lun++;
+			break;
 		case 'p':
 			portarg = strtoll(optarg, NULL, 0);
 			break;
@@ -4381,6 +4394,17 @@ retry:
 			}
 		}
 
+		if (lun || verbose) {
+			if (port->lun_map) {
+				STAILQ_FOREACH(nv, &port->lun_list, links)
+					printf("  LUN %s: %s\n",
+					    nv->name, nv->value);
+				if (STAILQ_EMPTY(&port->lun_list))
+					printf("  No LUNs mapped\n");
+			} else
+				printf("  All LUNs mapped\n");
+		}
+
 		if (verbose) {
 			STAILQ_FOREACH(nv, &port->attr_list, links) {
 				printf("      %s=%s\n", nv->name, nv->value);
@@ -4393,6 +4417,41 @@ bailout:
 	return (retval);
 }
 
+static int
+cctl_lunmap(int fd, int argc, char **argv, char *combinedopt)
+{
+	struct ctl_lun_map lm;
+	int retval = 0, c;
+
+	retval = 0;
+	lm.port = UINT32_MAX;
+	lm.plun = UINT32_MAX;
+	lm.lun = UINT32_MAX;
+
+	while ((c = getopt(argc, argv, combinedopt)) != -1) {
+		switch (c) {
+		case 'p':
+			lm.port = strtoll(optarg, NULL, 0);
+			break;
+		case 'l':
+			lm.plun = strtoll(optarg, NULL, 0);
+			break;
+		case 'L':
+			lm.lun = strtoll(optarg, NULL, 0);
+			break;
+		default:
+			break;
+		}
+	}
+
+	if (ioctl(fd, CTL_LUN_MAP, &lm) == -1) {
+		warn("%s: error issuing CTL_LUN_MAP ioctl", __func__);
+		retval = 1;
+	}
+
+	return (retval);
+}
+
 void
 usage(int error)
 {
@@ -4430,6 +4489,7 @@ usage(int error)
 "         ctladm hardstop\n"
 "         ctladm hardstart\n"
 "         ctladm lunlist\n"
+"         ctladm lunmap      -p targ_port [-l pLUN] [-L cLUN]\n"
 "         ctladm bbrread     [dev_id] <-l lba> <-d datalen>\n"
 "         ctladm delay       [dev_id] <-l datamove|done> [-T oneshot|cont]\n"
 "                            [-t secs]\n"
@@ -4529,10 +4589,15 @@ usage(int error)
 "portlist options:\n"
 "-f fronetnd              : specify frontend type\n"
 "-i                       : report target and initiators addresses\n"
+"-l                       : report LUN mapping\n"
 "-p targ_port             : specify target port number\n"
 "-q                       : omit header in list output\n"
 "-v                       : verbose output (report all port options)\n"
 "-x                       : output port list in XML format\n"
+"lunmap options:\n"
+"-p targ_port             : specify target port number\n"
+"-L pLUN                  : specify port-visible LUN\n"
+"-L cLUN                  : specify CTL LUN\n"
 "bbrread options:\n"
 "-l lba                   : starting LBA\n"
 "-d datalen               : length, in bytes, to read\n",
@@ -4760,6 +4825,9 @@ main(int argc, char **argv)
 	case CTLADM_CMD_PORTLIST:
 		retval = cctl_portlist(fd, argc, argv, combinedopt);
 		break;
+	case CTLADM_CMD_LUNMAP:
+		retval = cctl_lunmap(fd, argc, argv, combinedopt);
+		break;
 	case CTLADM_CMD_READCAPACITY:
 		retval = cctl_read_capacity(fd, target, lun, initid, retries,
 					    argc, argv, combinedopt);

Modified: head/usr.sbin/ctld/ctl.conf.5
==============================================================================
--- head/usr.sbin/ctld/ctl.conf.5	Sun Feb  1 20:16:18 2015	(r278036)
+++ head/usr.sbin/ctld/ctl.conf.5	Sun Feb  1 21:50:28 2015	(r278037)
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd November 24, 2014
+.Dd February 1, 2015
 .Dt CTL.CONF 5
 .Os
 .Sh NAME
@@ -60,9 +60,14 @@ file is:
 .Dl ...
 }
 
+.No lun Ar name No {
+.Dl path Ar path
+}
+
 .No target Ar name {
 .Dl auth-group Ar name
 .Dl portal-group Ar name
+.Dl lun Ar number Ar name
 .Dl lun Ar number No {
 .Dl 	path Ar path
 .Dl }
@@ -95,6 +100,10 @@ Create a
 configuration context,
 defining a new portal-group,
 which can then be assigned to any number of targets.
+.It Ic lun Ar name
+Create a
+.Sy lun
+configuration context, defining a LUN to be exported by some target(s).
 .It Ic target Ar name
 Create a
 .Sy target
@@ -312,6 +321,10 @@ IPv4 or IPv6 address to redirect initiat
 When configured, all initiators attempting to connect to this target
 will get redirected using "Target moved temporarily" login response.
 Redirection happens after successful authentication.
+.It Ic lun Ar number Ar name
+Export previously defined
+.Sy lun
+by the parent target.
 .It Ic lun Ar number
 Create a
 .Sy lun
@@ -387,21 +400,21 @@ target iqn.2012-06.com.example:target0 {
 	}
 }
 
+lun example_1 {
+	path /dev/zvol/tank/example_1
+}
+
 target iqn.2012-06.com.example:target1 {
 	chap chapuser chapsecret
-	lun 0 {
-		path /dev/zvol/tank/example_1
-	}
+	lun 0 example_1
 }
 
 target iqn.2012-06.com.example:target2 {
 	auth-group ag0
 	portal-group pg0
-	lun 0 {
-		path /dev/zvol/tank/example2_0
-	}
+	lun 0 example_1
 	lun 1 {
-		path /dev/zvol/tank/example2_1
+		path /dev/zvol/tank/example_2
 		option foo bar
 	}
 }

Modified: head/usr.sbin/ctld/ctld.c
==============================================================================
--- head/usr.sbin/ctld/ctld.c	Sun Feb  1 20:16:18 2015	(r278036)
+++ head/usr.sbin/ctld/ctld.c	Sun Feb  1 21:50:28 2015	(r278037)
@@ -87,6 +87,7 @@ conf_new(void)
 	conf = calloc(1, sizeof(*conf));
 	if (conf == NULL)
 		log_err(1, "calloc");
+	TAILQ_INIT(&conf->conf_luns);
 	TAILQ_INIT(&conf->conf_targets);
 	TAILQ_INIT(&conf->conf_auth_groups);
 	TAILQ_INIT(&conf->conf_portal_groups);
@@ -104,6 +105,7 @@ conf_new(void)
 void
 conf_delete(struct conf *conf)
 {
+	struct lun *lun, *ltmp;
 	struct target *targ, *tmp;
 	struct auth_group *ag, *cagtmp;
 	struct portal_group *pg, *cpgtmp;
@@ -111,6 +113,8 @@ conf_delete(struct conf *conf)
 
 	assert(conf->conf_pidfh == NULL);
 
+	TAILQ_FOREACH_SAFE(lun, &conf->conf_luns, l_next, ltmp)
+		lun_delete(lun);
 	TAILQ_FOREACH_SAFE(targ, &conf->conf_targets, t_next, tmp)
 		target_delete(targ);
 	TAILQ_FOREACH_SAFE(ag, &conf->conf_auth_groups, ag_next, cagtmp)
@@ -1146,7 +1150,6 @@ target_new(struct conf *conf, const char
 	for (i = 0; i < len; i++)
 		targ->t_name[i] = tolower(targ->t_name[i]);
 
-	TAILQ_INIT(&targ->t_luns);
 	targ->t_conf = conf;
 	TAILQ_INSERT_TAIL(&conf->conf_targets, targ, t_next);
 
@@ -1156,12 +1159,9 @@ target_new(struct conf *conf, const char
 void
 target_delete(struct target *targ)
 {
-	struct lun *lun, *tmp;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



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