summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ctladm
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2015-02-01 21:50:28 +0000
committermav <mav@FreeBSD.org>2015-02-01 21:50:28 +0000
commit8adb86862b914637b98b57e7708b6d2171e108e1 (patch)
tree73947d5774a365e2dbdf24d9296d66ac4cb8e566 /usr.sbin/ctladm
parent034497915685715efafad305dcd278c391b06ee4 (diff)
downloadFreeBSD-src-8adb86862b914637b98b57e7708b6d2171e108e1.zip
FreeBSD-src-8adb86862b914637b98b57e7708b6d2171e108e1.tar.gz
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.
Diffstat (limited to 'usr.sbin/ctladm')
-rw-r--r--usr.sbin/ctladm/ctladm.837
-rw-r--r--usr.sbin/ctladm/ctladm.c78
2 files changed, 108 insertions, 7 deletions
diff --git a/usr.sbin/ctladm/ctladm.8 b/usr.sbin/ctladm/ctladm.8
index 2a5123a..14710c2 100644
--- a/usr.sbin/ctladm/ctladm.8
+++ b/usr.sbin/ctladm/ctladm.8
@@ -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 options).
.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
diff --git a/usr.sbin/ctladm/ctladm.c b/usr.sbin/ctladm/ctladm.c
index 9f72c83..3351e3c 100644
--- a/usr.sbin/ctladm/ctladm.c
+++ b/usr.sbin/ctladm/ctladm.c
@@ -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, const char *name, const char **attr)
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 char *name)
} 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 char *name)
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 char *name)
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 **argv, char *combinedopt)
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 **argv, char *combinedopt)
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);
OpenPOWER on IntegriCloud