diff options
author | mav <mav@FreeBSD.org> | 2015-02-19 14:31:16 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2015-02-19 14:31:16 +0000 |
commit | aa6a7df89f1b4850d6005220f912240b8daeece7 (patch) | |
tree | 282042eb15012260f41a76a3f6a645a80bd3d224 /usr.sbin/ctladm | |
parent | 31fb601bdcf989b8cbedd19f0fb14b8e56eb253c (diff) | |
download | FreeBSD-src-aa6a7df89f1b4850d6005220f912240b8daeece7.zip FreeBSD-src-aa6a7df89f1b4850d6005220f912240b8daeece7.tar.gz |
MFC r278037: 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.
Relnotes: yes
Sponsored by: iXsystems, Inc.
Diffstat (limited to 'usr.sbin/ctladm')
-rw-r--r-- | usr.sbin/ctladm/ctladm.8 | 37 | ||||
-rw-r--r-- | usr.sbin/ctladm/ctladm.c | 78 |
2 files changed, 108 insertions, 7 deletions
diff --git a/usr.sbin/ctladm/ctladm.8 b/usr.sbin/ctladm/ctladm.8 index a22a61c..b0e7154 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); |