diff options
author | mav <mav@FreeBSD.org> | 2015-10-05 08:52:37 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2015-10-05 08:52:37 +0000 |
commit | 3f61db5756a866fb4ec6b09cacd0ccbce7410361 (patch) | |
tree | d369d267fc93dd2f4f997f191e4630af47e29402 /usr.sbin | |
parent | c060972cd4ad911e494f964ecbd92d6c4ffd0f10 (diff) | |
download | FreeBSD-src-3f61db5756a866fb4ec6b09cacd0ccbce7410361.zip FreeBSD-src-3f61db5756a866fb4ec6b09cacd0ccbce7410361.tar.gz |
MFC r287500: Allow LUN options modification via CTL_LUNREQ_MODIFY.
Not all changes take effect, but that is a different question.
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/ctladm/ctladm.8 | 9 | ||||
-rw-r--r-- | usr.sbin/ctladm/ctladm.c | 83 | ||||
-rw-r--r-- | usr.sbin/ctld/ctld.c | 18 | ||||
-rw-r--r-- | usr.sbin/ctld/ctld.h | 2 | ||||
-rw-r--r-- | usr.sbin/ctld/kernel.c | 29 |
5 files changed, 123 insertions, 18 deletions
diff --git a/usr.sbin/ctladm/ctladm.8 b/usr.sbin/ctladm/ctladm.8 index 545676f..11b953c 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 May 22, 2015 +.Dd September 6, 2015 .Dt CTLADM 8 .Os .Sh NAME @@ -166,6 +166,7 @@ .Ic modify .Aq Fl b Ar backend .Aq Fl l Ar lun_id +.Op Fl o Ar name=value .Aq Fl s Ar size_bytes .Nm .Ic devlist @@ -859,6 +860,12 @@ and .Dq block . .It Fl l Ar lun_id Specify the LUN number to remove. +.It Fl o Ar name=value +Specify a backend-specific name/value pair. +Multiple +.Fl o +arguments may be specified. +Refer to the backend documentation for arguments that may be used. .It Fl s Ar size_bytes Specify the size of the LUN in bytes. For the diff --git a/usr.sbin/ctladm/ctladm.c b/usr.sbin/ctladm/ctladm.c index 4f66b30..71fd5f3 100644 --- a/usr.sbin/ctladm/ctladm.c +++ b/usr.sbin/ctladm/ctladm.c @@ -183,7 +183,7 @@ static struct ctladm_opts option_table[] = { {"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:"}, + {"modify", CTLADM_CMD_MODIFY, CTLADM_ARG_NONE, "b:l:o:s:"}, {"port", CTLADM_CMD_PORT, CTLADM_ARG_NONE, "lo:p:qt:w:W:x"}, {"portlist", CTLADM_CMD_PORTLIST, CTLADM_ARG_NONE, "f:ilp:qvx"}, {"prin", CTLADM_CMD_PRES_IN, CTLADM_ARG_NEED_TL, "a:"}, @@ -3169,8 +3169,11 @@ cctl_modify_lun(int fd, int argc, char **argv, char *combinedopt) uint32_t lun_id = 0; int lun_id_set = 0, lun_size_set = 0; char *backend_name = NULL; + STAILQ_HEAD(, cctl_req_option) option_list; + int num_options = 0; int retval = 0, c; + STAILQ_INIT(&option_list); while ((c = getopt(argc, argv, combinedopt)) != -1) { switch (c) { case 'b': @@ -3180,6 +3183,43 @@ cctl_modify_lun(int fd, int argc, char **argv, char *combinedopt) lun_id = strtoul(optarg, NULL, 0); lun_id_set = 1; break; + case 'o': { + struct cctl_req_option *option; + char *tmpstr; + char *name, *value; + + tmpstr = strdup(optarg); + name = strsep(&tmpstr, "="); + if (name == NULL) { + warnx("%s: option -o takes \"name=value\"" + "argument", __func__); + retval = 1; + goto bailout; + } + value = strsep(&tmpstr, "="); + if (value == NULL) { + warnx("%s: option -o takes \"name=value\"" + "argument", __func__); + retval = 1; + goto bailout; + } + option = malloc(sizeof(*option)); + if (option == NULL) { + warn("%s: error allocating %zd bytes", + __func__, sizeof(*option)); + retval = 1; + goto bailout; + } + option->name = strdup(name); + option->namelen = strlen(name) + 1; + option->value = strdup(value); + option->vallen = strlen(value) + 1; + free(tmpstr); + + STAILQ_INSERT_TAIL(&option_list, option, links); + num_options++; + break; + } case 's': if (strcasecmp(optarg, "auto") != 0) { retval = expand_number(optarg, &lun_size); @@ -3203,8 +3243,9 @@ cctl_modify_lun(int fd, int argc, char **argv, char *combinedopt) if (lun_id_set == 0) errx(1, "%s: LUN id (-l) must be specified", __func__); - if (lun_size_set == 0) - errx(1, "%s: size (-s) must be specified", __func__); + if (lun_size_set == 0 && num_options == 0) + errx(1, "%s: size (-s) or options (-o) must be specified", + __func__); bzero(&req, sizeof(req)); @@ -3214,6 +3255,42 @@ cctl_modify_lun(int fd, int argc, char **argv, char *combinedopt) req.reqdata.modify.lun_id = lun_id; req.reqdata.modify.lun_size_bytes = lun_size; + req.num_be_args = num_options; + if (num_options > 0) { + struct cctl_req_option *option, *next_option; + int i; + + req.be_args = malloc(num_options * sizeof(*req.be_args)); + if (req.be_args == NULL) { + warn("%s: error allocating %zd bytes", __func__, + num_options * sizeof(*req.be_args)); + retval = 1; + goto bailout; + } + + for (i = 0, option = STAILQ_FIRST(&option_list); + i < num_options; i++, option = next_option) { + next_option = STAILQ_NEXT(option, links); + + req.be_args[i].namelen = option->namelen; + req.be_args[i].name = strdup(option->name); + req.be_args[i].vallen = option->vallen; + req.be_args[i].value = strdup(option->value); + /* + * XXX KDM do we want a way to specify a writeable + * flag of some sort? Do we want a way to specify + * binary data? + */ + req.be_args[i].flags = CTL_BEARG_ASCII | CTL_BEARG_RD; + + STAILQ_REMOVE(&option_list, option, cctl_req_option, + links); + free(option->name); + free(option->value); + free(option); + } + } + if (ioctl(fd, CTL_LUN_REQ, &req) == -1) { warn("%s: error issuing CTL_LUN_REQ ioctl", __func__); retval = 1; diff --git a/usr.sbin/ctld/ctld.c b/usr.sbin/ctld/ctld.c index dc33224..85f1133 100644 --- a/usr.sbin/ctld/ctld.c +++ b/usr.sbin/ctld/ctld.c @@ -1944,18 +1944,14 @@ conf_apply(struct conf *oldconf, struct conf *newconf) TAILQ_FOREACH_SAFE(newlun, &newconf->conf_luns, l_next, tmplun) { oldlun = lun_find(oldconf, newlun->l_name); if (oldlun != NULL) { - if (newlun->l_size != oldlun->l_size || - newlun->l_size == 0) { - log_debugx("resizing lun \"%s\", CTL lun %d", + log_debugx("modifying lun \"%s\", CTL lun %d", + newlun->l_name, newlun->l_ctl_lun); + error = kernel_lun_modify(newlun); + if (error != 0) { + log_warnx("failed to " + "modify lun \"%s\", CTL lun %d", newlun->l_name, newlun->l_ctl_lun); - error = kernel_lun_resize(newlun); - if (error != 0) { - log_warnx("failed to " - "resize lun \"%s\", CTL lun %d", - newlun->l_name, - newlun->l_ctl_lun); - cumulated_error++; - } + cumulated_error++; } continue; } diff --git a/usr.sbin/ctld/ctld.h b/usr.sbin/ctld/ctld.h index ab6186b..a4e260b 100644 --- a/usr.sbin/ctld/ctld.h +++ b/usr.sbin/ctld/ctld.h @@ -387,7 +387,7 @@ void lun_option_set(struct lun_option *clo, void kernel_init(void); int kernel_lun_add(struct lun *lun); -int kernel_lun_resize(struct lun *lun); +int kernel_lun_modify(struct lun *lun); int kernel_lun_remove(struct lun *lun); void kernel_handoff(struct connection *conn); int kernel_port_add(struct port *port); diff --git a/usr.sbin/ctld/kernel.c b/usr.sbin/ctld/kernel.c index 3c714ea..914d027 100644 --- a/usr.sbin/ctld/kernel.c +++ b/usr.sbin/ctld/kernel.c @@ -743,9 +743,11 @@ kernel_lun_add(struct lun *lun) } int -kernel_lun_resize(struct lun *lun) +kernel_lun_modify(struct lun *lun) { + struct lun_option *lo; struct ctl_lun_req req; + int error, i, num_options; bzero(&req, sizeof(req)); @@ -755,7 +757,30 @@ kernel_lun_resize(struct lun *lun) req.reqdata.modify.lun_id = lun->l_ctl_lun; req.reqdata.modify.lun_size_bytes = lun->l_size; - if (ioctl(ctl_fd, CTL_LUN_REQ, &req) == -1) { + num_options = 0; + TAILQ_FOREACH(lo, &lun->l_options, lo_next) + num_options++; + + req.num_be_args = num_options; + if (num_options > 0) { + req.be_args = malloc(num_options * sizeof(*req.be_args)); + if (req.be_args == NULL) { + log_warn("error allocating %zd bytes", + num_options * sizeof(*req.be_args)); + return (1); + } + + i = 0; + TAILQ_FOREACH(lo, &lun->l_options, lo_next) { + str_arg(&req.be_args[i], lo->lo_name, lo->lo_value); + i++; + } + assert(i == num_options); + } + + error = ioctl(ctl_fd, CTL_LUN_REQ, &req); + free(req.be_args); + if (error != 0) { log_warn("error issuing CTL_LUN_REQ ioctl"); return (1); } |