svn commit: r272978 - in head: sys/cam/ctl usr.sbin/ctladm

Alexander Motin mav at FreeBSD.org
Sun Oct 12 06:55:35 UTC 2014


Author: mav
Date: Sun Oct 12 06:55:34 2014
New Revision: 272978
URL: https://svnweb.freebsd.org/changeset/base/272978

Log:
  Improve and document `ctladm portlist` subcommand.
  
  Make this subcommand less FC-specific, reporting target and port addresses
  in more generic way.  Also make it report list of connected initiators in
  unified way, working for both FC and iSCSI, and potentially others.
  
  MFC after:	1 week

Modified:
  head/sys/cam/ctl/ctl.c
  head/usr.sbin/ctladm/ctladm.8
  head/usr.sbin/ctladm/ctladm.c

Modified: head/sys/cam/ctl/ctl.c
==============================================================================
--- head/sys/cam/ctl/ctl.c	Sun Oct 12 06:14:50 2014	(r272977)
+++ head/sys/cam/ctl/ctl.c	Sun Oct 12 06:55:34 2014	(r272978)
@@ -2237,6 +2237,43 @@ ctl_sbuf_printf_esc(struct sbuf *sb, cha
 	return (retval);
 }
 
+static void
+ctl_id_sbuf(struct ctl_devid *id, struct sbuf *sb)
+{
+	struct scsi_vpd_id_descriptor *desc;
+	int i;
+
+	if (id == NULL || id->len < 4)
+		return;
+	desc = (struct scsi_vpd_id_descriptor *)id->data;
+	switch (desc->id_type & SVPD_ID_TYPE_MASK) {
+	case SVPD_ID_TYPE_T10:
+		sbuf_printf(sb, "t10.");
+		break;
+	case SVPD_ID_TYPE_EUI64:
+		sbuf_printf(sb, "eui.");
+		break;
+	case SVPD_ID_TYPE_NAA:
+		sbuf_printf(sb, "naa.");
+		break;
+	case SVPD_ID_TYPE_SCSI_NAME:
+		break;
+	}
+	switch (desc->proto_codeset & SVPD_ID_CODESET_MASK) {
+	case SVPD_ID_CODESET_BINARY:
+		for (i = 0; i < desc->length; i++)
+			sbuf_printf(sb, "%02x", desc->identifier[i]);
+		break;
+	case SVPD_ID_CODESET_ASCII:
+		sbuf_printf(sb, "%.*s", (int)desc->length,
+		    (char *)desc->identifier);
+		break;
+	case SVPD_ID_CODESET_UTF8:
+		sbuf_printf(sb, "%s", (char *)desc->identifier);
+		break;
+	}
+}
+
 static int
 ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
 	  struct thread *td)
@@ -3288,6 +3325,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, 
 		struct ctl_port *port;
 		struct ctl_lun_list *list;
 		struct ctl_option *opt;
+		int j;
 
 		list = (struct ctl_lun_list *)addr;
 
@@ -3344,15 +3382,17 @@ ctl_ioctl(struct cdev *dev, u_long cmd, 
 			if (retval != 0)
 				break;
 
-			retval = sbuf_printf(sb, "\t<wwnn>%#jx</wwnn>\n",
-			    (uintmax_t)port->wwnn);
-			if (retval != 0)
-				break;
+			if (port->target_devid != NULL) {
+				sbuf_printf(sb, "\t<target>");
+				ctl_id_sbuf(port->target_devid, sb);
+				sbuf_printf(sb, "</target>\n");
+			}
 
-			retval = sbuf_printf(sb, "\t<wwpn>%#jx</wwpn>\n",
-			    (uintmax_t)port->wwpn);
-			if (retval != 0)
-				break;
+			if (port->port_devid != NULL) {
+				sbuf_printf(sb, "\t<port>");
+				ctl_id_sbuf(port->port_devid, sb);
+				sbuf_printf(sb, "</port>\n");
+			}
 
 			if (port->port_info != NULL) {
 				retval = port->port_info(port->onoff_arg, sb);
@@ -3366,6 +3406,26 @@ ctl_ioctl(struct cdev *dev, u_long cmd, 
 					break;
 			}
 
+			for (j = 0; j < CTL_MAX_INIT_PER_PORT; j++) {
+				if (port->wwpn_iid[j].in_use == 0 ||
+				    (port->wwpn_iid[j].wwpn == 0 &&
+				     port->wwpn_iid[j].name == NULL))
+					continue;
+
+				if (port->wwpn_iid[j].name != NULL)
+					retval = sbuf_printf(sb,
+					    "\t<initiator>%u %s</initiator>\n",
+					    j, port->wwpn_iid[j].name);
+				else
+					retval = sbuf_printf(sb,
+					    "\t<initiator>%u naa.%08jx</initiator>\n",
+					    j, port->wwpn_iid[j].wwpn);
+				if (retval != 0)
+					break;
+			}
+			if (retval != 0)
+				break;
+
 			retval = sbuf_printf(sb, "</targ_port>\n");
 			if (retval != 0)
 				break;

Modified: head/usr.sbin/ctladm/ctladm.8
==============================================================================
--- head/usr.sbin/ctladm/ctladm.8	Sun Oct 12 06:14:50 2014	(r272977)
+++ head/usr.sbin/ctladm/ctladm.8	Sun Oct 12 06:55:34 2014	(r272978)
@@ -34,7 +34,7 @@
 .\" $Id: //depot/users/kenm/FreeBSD-test2/usr.sbin/ctladm/ctladm.8#3 $
 .\" $FreeBSD$
 .\"
-.Dd October 8, 2014
+.Dd October 12, 2014
 .Dt CTLADM 8
 .Os
 .Sh NAME
@@ -193,6 +193,14 @@
 .Op Fl q
 .Op Fl x
 .Nm
+.Ic portlist
+.Op Fl f Ar frontend
+.Op Fl i
+.Op Fl p Ar targ_port
+.Op Fl q
+.Op Fl v
+.Op Fl x
+.Nm
 .Ic dumpooa
 .Nm
 .Ic dumpstructs
@@ -768,6 +776,22 @@ As a general rule, the WWPN must be diff
 .It Fl x
 Output the port list in XML format.
 .El
+.It Ic portlist
+List CTL frontend ports.
+.Bl -tag -width 12n
+.It Fl f Ar frontend
+Specify the frontend type.
+.It Fl i
+Report target and connected initiators addresses
+.It Fl p Ar targ_port
+Specify the frontend port number.
+.It Fl q
+Omit the header in the port list output.
+.It Fl v
+Enable verbose output (report all port options).
+.It Fl x
+Output the port list in XML format.
+.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 Oct 12 06:14:50 2014	(r272977)
+++ head/usr.sbin/ctladm/ctladm.c	Sun Oct 12 06:55:34 2014	(r272978)
@@ -191,7 +191,7 @@ static struct ctladm_opts option_table[]
 	{"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:vx"},
+	{"portlist", CTLADM_CMD_PORTLIST, CTLADM_ARG_NONE, "f:ip: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},
@@ -4100,7 +4100,8 @@ struct cctl_port {
 	char *frontend_type;
 	char *name;
 	int pp, vp;
-	char *wwnn, *wwpn;
+	char *target, *port;
+	STAILQ_HEAD(,cctl_lun_nv) init_list;
 	STAILQ_HEAD(,cctl_lun_nv) attr_list;
 	STAILQ_ENTRY(cctl_port) links;
 };
@@ -4144,6 +4145,7 @@ cctl_start_pelement(void *user_data, con
 		portlist->num_ports++;
 		portlist->cur_port = cur_port;
 
+		STAILQ_INIT(&cur_port->init_list);
 		STAILQ_INIT(&cur_port->attr_list);
 		STAILQ_INSERT_TAIL(&portlist->port_list, cur_port, links);
 
@@ -4205,11 +4207,11 @@ cctl_end_pelement(void *user_data, const
 		cur_port->pp = strtoull(str, NULL, 0);
 	} else if (strcmp(name, "virtual_port") == 0) {
 		cur_port->vp = strtoull(str, NULL, 0);
-	} else if (strcmp(name, "wwnn") == 0) {
-		cur_port->wwnn = str;
+	} else if (strcmp(name, "target") == 0) {
+		cur_port->target = str;
 		str = NULL;
-	} else if (strcmp(name, "wwpn") == 0) {
-		cur_port->wwpn = str;
+	} else if (strcmp(name, "port") == 0) {
+		cur_port->port = str;
 		str = NULL;
 	} else if (strcmp(name, "targ_port") == 0) {
 		portlist->cur_port = NULL;
@@ -4230,7 +4232,10 @@ cctl_end_pelement(void *user_data, const
 
 		nv->value = str;
 		str = NULL;
-		STAILQ_INSERT_TAIL(&cur_port->attr_list, nv, links);
+		if (strcmp(name, "initiator") == 0)
+			STAILQ_INSERT_TAIL(&cur_port->init_list, nv, links);
+		else
+			STAILQ_INSERT_TAIL(&cur_port->attr_list, nv, links);
 	}
 
 	free(str);
@@ -4258,7 +4263,8 @@ cctl_portlist(int fd, int argc, char **a
 	int dump_xml = 0;
 	int retval, c;
 	char *frontend = NULL;
-	int verbose = 0;
+	uint64_t portarg = UINT64_MAX;
+	int verbose = 0, init = 0, quiet = 0;
 
 	retval = 0;
 	port_len = 4096;
@@ -4271,6 +4277,15 @@ cctl_portlist(int fd, int argc, char **a
 		case 'f':
 			frontend = strdup(optarg);
 			break;
+		case 'i':
+			init++;
+			break;
+		case 'p':
+			portarg = strtoll(optarg, NULL, 0);
+			break;
+		case 'q':
+			quiet++;
+			break;
 		case 'v':
 			verbose++;
 			break;
@@ -4327,8 +4342,8 @@ retry:
 		goto bailout;
 	}
 
-	printf("Port Online Frontend %-12s pp vp %-18s %-18s\n",
-	    "Name", "WWNN", "WWPN");
+	if (quiet == 0)
+		printf("Port Online Frontend Name     pp vp\n");
 	STAILQ_FOREACH(port, &portlist.port_list, links) {
 		struct cctl_lun_nv *nv;
 
@@ -4336,16 +4351,26 @@ retry:
 		 && (strcmp(port->frontend_type, frontend) != 0))
 			continue;
 
-		printf("%-4ju %-6s %-8s %-12s %-2d %-2d %-18s %-18s\n",
+		if ((portarg != UINT64_MAX) && (portarg != port->port_id))
+			continue;
+
+		printf("%-4ju %-6s %-8s %-8s %-2d %-2d %s\n",
 		    (uintmax_t)port->port_id, port->online,
 		    port->frontend_type, port->name, port->pp, port->vp,
-		    port->wwnn, port->wwpn);
+		    port->port ? port->port : "");
 
-		if (verbose == 0)
-			continue;
+		if (init || verbose) {
+			if (port->target)
+				printf("  Target: %s\n", port->target);
+			STAILQ_FOREACH(nv, &port->init_list, links) {
+				printf("  Initiator: %s\n", nv->value);
+			}
+		}
 
-		STAILQ_FOREACH(nv, &port->attr_list, links) {
-			printf("      %s=%s\n", nv->name, nv->value);
+		if (verbose) {
+			STAILQ_FOREACH(nv, &port->attr_list, links) {
+				printf("      %s=%s\n", nv->name, nv->value);
+			}
 		}
 	}
 bailout:
@@ -4401,7 +4426,7 @@ usage(int error)
 "                            [-s len fmt [args]] [-c] [-d delete_id]\n"
 "         ctladm port        <-l | -o <on|off> | [-w wwnn][-W wwpn]>\n"
 "                            [-p targ_port] [-t port_type] [-q] [-x]\n"
-"         ctladm portlist    [-f frontend] [-v] [-x]\n"
+"         ctladm portlist    [-f frontend] [-i] [-p targ_port] [-q] [-v] [-x]\n"
 "         ctladm islist      [-v | -x]\n"
 "         ctladm islogout    <-a | -c connection-id | -i name | -p portal>\n"
 "         ctladm isterminate <-a | -c connection-id | -i name | -p portal>\n"
@@ -4487,6 +4512,13 @@ usage(int error)
 "-p targ_port             : specify target port number\n"
 "-q                       : omit header in list output\n"
 "-x                       : output port list in XML format\n"
+"portlist options:\n"
+"-f fronetnd              : specify frontend type\n"
+"-i                       : report target and initiators addresses\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"
 "bbrread options:\n"
 "-l lba                   : starting LBA\n"
 "-d datalen               : length, in bytes, to read\n",


More information about the svn-src-all mailing list