aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/ctld/kernel.cc
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/ctld/kernel.cc')
-rw-r--r--usr.sbin/ctld/kernel.cc980
1 files changed, 422 insertions, 558 deletions
diff --git a/usr.sbin/ctld/kernel.cc b/usr.sbin/ctld/kernel.cc
index 0cd0eaff6c6f..b214cd4e8c29 100644
--- a/usr.sbin/ctld/kernel.cc
+++ b/usr.sbin/ctld/kernel.cc
@@ -46,7 +46,6 @@
#include <sys/module.h>
#include <sys/queue.h>
#include <sys/sbuf.h>
-#include <sys/nv.h>
#include <sys/stat.h>
#include <assert.h>
#include <bsdxml.h>
@@ -68,7 +67,7 @@
#include <cam/ctl/ctl_util.h>
#include <cam/ctl/ctl_scsi_all.h>
-#include "ctld.h"
+#include "ctld.hh"
#ifdef ICL_KERNEL_PROXY
#include <netdb.h>
@@ -76,8 +75,6 @@
#define NVLIST_BUFSIZE 1024
-extern bool proxy_mode;
-
int ctl_fd = 0;
void
@@ -109,42 +106,43 @@ kernel_init(void)
/*
* Backend LUN information.
*/
+using attr_list = std::list<std::pair<std::string, std::string>>;
+
struct cctl_lun {
uint64_t lun_id;
- char *backend_type;
+ std::string backend_type;
uint8_t device_type;
uint64_t size_blocks;
uint32_t blocksize;
- char *serial_number;
- char *device_id;
- char *ctld_name;
- nvlist_t *attr_list;
- STAILQ_ENTRY(cctl_lun) links;
+ std::string serial_number;
+ std::string device_id;
+ std::string ctld_name;
+ attr_list attr_list;
};
struct cctl_port {
uint32_t port_id;
- char *port_frontend;
- char *port_name;
+ std::string port_frontend;
+ std::string port_name;
int pp;
int vp;
+ uint16_t portid;
int cfiscsi_state;
- char *cfiscsi_target;
+ std::string cfiscsi_target;
+ std::string nqn;
uint16_t cfiscsi_portal_group_tag;
- char *ctld_portal_group_name;
- nvlist_t *attr_list;
- STAILQ_ENTRY(cctl_port) links;
+ std::string ctld_portal_group_name;
+ std::string ctld_transport_group_name;
+ attr_list attr_list;
};
struct cctl_devlist_data {
- int num_luns;
- STAILQ_HEAD(,cctl_lun) lun_list;
- struct cctl_lun *cur_lun;
- int num_ports;
- STAILQ_HEAD(,cctl_port) port_list;
- struct cctl_port *cur_port;
- int level;
- struct sbuf *cur_sb[32];
+ std::list<cctl_lun> lun_list;
+ struct cctl_lun *cur_lun = nullptr;
+ std::list<cctl_port> port_list;
+ struct cctl_port *cur_port = nullptr;
+ u_int level = 0;
+ struct sbuf *cur_sb[32] = {};
};
static void
@@ -157,9 +155,8 @@ cctl_start_element(void *user_data, const char *name, const char **attr)
devlist = (struct cctl_devlist_data *)user_data;
cur_lun = devlist->cur_lun;
devlist->level++;
- if ((u_int)devlist->level >= (sizeof(devlist->cur_sb) /
- sizeof(devlist->cur_sb[0])))
- log_errx(1, "%s: too many nesting levels, %zd max", __func__,
+ if (devlist->level >= nitems(devlist->cur_sb))
+ log_errx(1, "%s: too many nesting levels, %zu max", __func__,
nitems(devlist->cur_sb));
devlist->cur_sb[devlist->level] = sbuf_new_auto();
@@ -171,17 +168,11 @@ cctl_start_element(void *user_data, const char *name, const char **attr)
log_errx(1, "%s: improper lun element nesting",
__func__);
- cur_lun = reinterpret_cast<struct cctl_lun *>(calloc(1, sizeof(*cur_lun)));
- if (cur_lun == NULL)
- log_err(1, "%s: cannot allocate %zd bytes", __func__,
- sizeof(*cur_lun));
+ devlist->lun_list.emplace_back();
+ cur_lun = &devlist->lun_list.back();
- devlist->num_luns++;
devlist->cur_lun = cur_lun;
- cur_lun->attr_list = nvlist_create(0);
- STAILQ_INSERT_TAIL(&devlist->lun_list, cur_lun, links);
-
for (i = 0; attr[i] != NULL; i += 2) {
if (strcmp(attr[i], "id") == 0) {
cur_lun->lun_id = strtoull(attr[i+1], NULL, 0);
@@ -198,8 +189,7 @@ cctl_end_element(void *user_data, const char *name)
{
struct cctl_devlist_data *devlist;
struct cctl_lun *cur_lun;
- char *str;
- int error;
+ std::string str;
devlist = (struct cctl_devlist_data *)user_data;
cur_lun = devlist->cur_lun;
@@ -213,55 +203,39 @@ cctl_end_element(void *user_data, const char *name)
devlist->level, name);
sbuf_finish(devlist->cur_sb[devlist->level]);
- str = checked_strdup(sbuf_data(devlist->cur_sb[devlist->level]));
-
- if (strlen(str) == 0) {
- free(str);
- str = NULL;
- }
+ str = sbuf_data(devlist->cur_sb[devlist->level]);
sbuf_delete(devlist->cur_sb[devlist->level]);
devlist->cur_sb[devlist->level] = NULL;
devlist->level--;
if (strcmp(name, "backend_type") == 0) {
- cur_lun->backend_type = str;
- str = NULL;
+ cur_lun->backend_type = std::move(str);
} else if (strcmp(name, "lun_type") == 0) {
- if (str == NULL)
+ if (str.empty())
log_errx(1, "%s: %s missing its argument", __func__, name);
- cur_lun->device_type = strtoull(str, NULL, 0);
+ cur_lun->device_type = strtoull(str.c_str(), NULL, 0);
} else if (strcmp(name, "size") == 0) {
- if (str == NULL)
+ if (str.empty())
log_errx(1, "%s: %s missing its argument", __func__, name);
- cur_lun->size_blocks = strtoull(str, NULL, 0);
+ cur_lun->size_blocks = strtoull(str.c_str(), NULL, 0);
} else if (strcmp(name, "blocksize") == 0) {
- if (str == NULL)
+ if (str.empty())
log_errx(1, "%s: %s missing its argument", __func__, name);
- cur_lun->blocksize = strtoul(str, NULL, 0);
+ cur_lun->blocksize = strtoul(str.c_str(), NULL, 0);
} else if (strcmp(name, "serial_number") == 0) {
- cur_lun->serial_number = str;
- str = NULL;
+ cur_lun->serial_number = std::move(str);
} else if (strcmp(name, "device_id") == 0) {
- cur_lun->device_id = str;
- str = NULL;
+ cur_lun->device_id = std::move(str);
} else if (strcmp(name, "ctld_name") == 0) {
- cur_lun->ctld_name = str;
- str = NULL;
+ cur_lun->ctld_name = std::move(str);
} else if (strcmp(name, "lun") == 0) {
devlist->cur_lun = NULL;
} else if (strcmp(name, "ctllunlist") == 0) {
/* Nothing. */
} else {
- nvlist_move_string(cur_lun->attr_list, name, str);
- error = nvlist_error(cur_lun->attr_list);
- if (error != 0)
- log_errc(1, error, "%s: failed to add nv pair for %s",
- __func__, name);
- str = NULL;
+ cur_lun->attr_list.emplace_back(name, std::move(str));
}
-
- free(str);
}
static void
@@ -274,9 +248,8 @@ cctl_start_pelement(void *user_data, const char *name, const char **attr)
devlist = (struct cctl_devlist_data *)user_data;
cur_port = devlist->cur_port;
devlist->level++;
- if ((u_int)devlist->level >= (sizeof(devlist->cur_sb) /
- sizeof(devlist->cur_sb[0])))
- log_errx(1, "%s: too many nesting levels, %zd max", __func__,
+ if (devlist->level >= nitems(devlist->cur_sb))
+ log_errx(1, "%s: too many nesting levels, %zu max", __func__,
nitems(devlist->cur_sb));
devlist->cur_sb[devlist->level] = sbuf_new_auto();
@@ -288,17 +261,10 @@ cctl_start_pelement(void *user_data, const char *name, const char **attr)
log_errx(1, "%s: improper port element nesting (%s)",
__func__, name);
- cur_port = reinterpret_cast<struct cctl_port *>(calloc(1, sizeof(*cur_port)));
- if (cur_port == NULL)
- log_err(1, "%s: cannot allocate %zd bytes", __func__,
- sizeof(*cur_port));
-
- devlist->num_ports++;
+ devlist->port_list.emplace_back();
+ cur_port = &devlist->port_list.back();
devlist->cur_port = cur_port;
- cur_port->attr_list = nvlist_create(0);
- STAILQ_INSERT_TAIL(&devlist->port_list, cur_port, links);
-
for (i = 0; attr[i] != NULL; i += 2) {
if (strcmp(attr[i], "id") == 0) {
cur_port->port_id = strtoul(attr[i+1], NULL, 0);
@@ -315,8 +281,7 @@ cctl_end_pelement(void *user_data, const char *name)
{
struct cctl_devlist_data *devlist;
struct cctl_port *cur_port;
- char *str;
- int error;
+ std::string str;
devlist = (struct cctl_devlist_data *)user_data;
cur_port = devlist->cur_port;
@@ -330,59 +295,51 @@ cctl_end_pelement(void *user_data, const char *name)
devlist->level, name);
sbuf_finish(devlist->cur_sb[devlist->level]);
- str = checked_strdup(sbuf_data(devlist->cur_sb[devlist->level]));
-
- if (strlen(str) == 0) {
- free(str);
- str = NULL;
- }
+ str = sbuf_data(devlist->cur_sb[devlist->level]);
sbuf_delete(devlist->cur_sb[devlist->level]);
devlist->cur_sb[devlist->level] = NULL;
devlist->level--;
if (strcmp(name, "frontend_type") == 0) {
- cur_port->port_frontend = str;
- str = NULL;
+ cur_port->port_frontend = std::move(str);
} else if (strcmp(name, "port_name") == 0) {
- cur_port->port_name = str;
- str = NULL;
+ cur_port->port_name = std::move(str);
} else if (strcmp(name, "physical_port") == 0) {
- if (str == NULL)
+ if (str.empty())
log_errx(1, "%s: %s missing its argument", __func__, name);
- cur_port->pp = strtoul(str, NULL, 0);
+ cur_port->pp = strtoul(str.c_str(), NULL, 0);
} else if (strcmp(name, "virtual_port") == 0) {
- if (str == NULL)
+ if (str.empty())
log_errx(1, "%s: %s missing its argument", __func__, name);
- cur_port->vp = strtoul(str, NULL, 0);
+ cur_port->vp = strtoul(str.c_str(), NULL, 0);
} else if (strcmp(name, "cfiscsi_target") == 0) {
- cur_port->cfiscsi_target = str;
- str = NULL;
+ cur_port->cfiscsi_target = std::move(str);
} else if (strcmp(name, "cfiscsi_state") == 0) {
- if (str == NULL)
+ if (str.empty())
log_errx(1, "%s: %s missing its argument", __func__, name);
- cur_port->cfiscsi_state = strtoul(str, NULL, 0);
+ cur_port->cfiscsi_state = strtoul(str.c_str(), NULL, 0);
} else if (strcmp(name, "cfiscsi_portal_group_tag") == 0) {
- if (str == NULL)
+ if (str.empty())
log_errx(1, "%s: %s missing its argument", __func__, name);
- cur_port->cfiscsi_portal_group_tag = strtoul(str, NULL, 0);
+ cur_port->cfiscsi_portal_group_tag = strtoul(str.c_str(), NULL, 0);
} else if (strcmp(name, "ctld_portal_group_name") == 0) {
- cur_port->ctld_portal_group_name = str;
- str = NULL;
+ cur_port->ctld_portal_group_name = std::move(str);
+ } else if (strcmp(name, "ctld_transport_group_name") == 0) {
+ cur_port->ctld_transport_group_name = std::move(str);
+ } else if (strcmp(name, "nqn") == 0) {
+ cur_port->nqn = std::move(str);
+ } else if (strcmp(name, "portid") == 0) {
+ if (str.empty())
+ log_errx(1, "%s: %s missing its argument", __func__, name);
+ cur_port->portid = strtoul(str.c_str(), NULL, 0);
} else if (strcmp(name, "targ_port") == 0) {
devlist->cur_port = NULL;
} else if (strcmp(name, "ctlportlist") == 0) {
/* Nothing. */
} else {
- nvlist_move_string(cur_port->attr_list, name, str);
- error = nvlist_error(cur_port->attr_list);
- if (error != 0)
- log_errc(1, error, "%s: failed to add nv pair for %s",
- __func__, name);
- str = NULL;
+ cur_port->attr_list.emplace_back(name, std::move(str));
}
-
- free(str);
}
static void
@@ -395,329 +352,307 @@ cctl_char_handler(void *user_data, const XML_Char *str, int len)
sbuf_bcat(devlist->cur_sb[devlist->level], str, len);
}
-struct conf *
-conf_new_from_kernel(struct kports *kports)
+static bool
+parse_kernel_config(struct cctl_devlist_data &devlist)
{
- struct conf *conf = NULL;
- struct target *targ;
- struct portal_group *pg;
- struct pport *pp;
- struct port *cp;
- struct lun *cl;
struct ctl_lun_list list;
- struct cctl_devlist_data devlist;
- struct cctl_lun *lun;
- struct cctl_port *port;
XML_Parser parser;
- const char *key;
- char *str, *name;
- void *cookie;
- int error, len, retval;
-
- bzero(&devlist, sizeof(devlist));
- STAILQ_INIT(&devlist.lun_list);
- STAILQ_INIT(&devlist.port_list);
+ int retval;
- log_debugx("obtaining previously configured CTL luns from the kernel");
-
- str = NULL;
- len = 4096;
+ std::vector<char> buf(4096);
retry:
- str = reinterpret_cast<char *>(realloc(str, len));
- if (str == NULL)
- log_err(1, "realloc");
-
bzero(&list, sizeof(list));
- list.alloc_len = len;
+ list.alloc_len = buf.size();
list.status = CTL_LUN_LIST_NONE;
- list.lun_xml = str;
+ list.lun_xml = buf.data();
if (ioctl(ctl_fd, CTL_LUN_LIST, &list) == -1) {
log_warn("error issuing CTL_LUN_LIST ioctl");
- free(str);
- return (NULL);
+ return (false);
}
if (list.status == CTL_LUN_LIST_ERROR) {
log_warnx("error returned from CTL_LUN_LIST ioctl: %s",
list.error_str);
- free(str);
- return (NULL);
+ return (false);
}
if (list.status == CTL_LUN_LIST_NEED_MORE_SPACE) {
- len = len << 1;
+ buf.resize(buf.size() << 1);
goto retry;
}
parser = XML_ParserCreate(NULL);
if (parser == NULL) {
log_warnx("unable to create XML parser");
- free(str);
- return (NULL);
+ return (false);
}
XML_SetUserData(parser, &devlist);
XML_SetElementHandler(parser, cctl_start_element, cctl_end_element);
XML_SetCharacterDataHandler(parser, cctl_char_handler);
- retval = XML_Parse(parser, str, strlen(str), 1);
+ retval = XML_Parse(parser, buf.data(), strlen(buf.data()), 1);
XML_ParserFree(parser);
- free(str);
if (retval != 1) {
log_warnx("XML_Parse failed");
- return (NULL);
+ return (false);
}
- str = NULL;
- len = 4096;
retry_port:
- str = reinterpret_cast<char *>(realloc(str, len));
- if (str == NULL)
- log_err(1, "realloc");
-
bzero(&list, sizeof(list));
- list.alloc_len = len;
+ list.alloc_len = buf.size();
list.status = CTL_LUN_LIST_NONE;
- list.lun_xml = str;
+ list.lun_xml = buf.data();
if (ioctl(ctl_fd, CTL_PORT_LIST, &list) == -1) {
log_warn("error issuing CTL_PORT_LIST ioctl");
- free(str);
- return (NULL);
+ return (false);
}
if (list.status == CTL_LUN_LIST_ERROR) {
log_warnx("error returned from CTL_PORT_LIST ioctl: %s",
list.error_str);
- free(str);
- return (NULL);
+ return (false);
}
if (list.status == CTL_LUN_LIST_NEED_MORE_SPACE) {
- len = len << 1;
+ buf.resize(buf.size() << 1);
goto retry_port;
}
parser = XML_ParserCreate(NULL);
if (parser == NULL) {
log_warnx("unable to create XML parser");
- free(str);
- return (NULL);
+ return (false);
}
XML_SetUserData(parser, &devlist);
XML_SetElementHandler(parser, cctl_start_pelement, cctl_end_pelement);
XML_SetCharacterDataHandler(parser, cctl_char_handler);
- retval = XML_Parse(parser, str, strlen(str), 1);
+ retval = XML_Parse(parser, buf.data(), strlen(buf.data()), 1);
XML_ParserFree(parser);
- free(str);
if (retval != 1) {
log_warnx("XML_Parse failed");
- return (NULL);
+ return (false);
}
- conf = conf_new();
+ return (true);
+}
- name = NULL;
- STAILQ_FOREACH(port, &devlist.port_list, links) {
- if (strcmp(port->port_frontend, "ha") == 0)
- continue;
- free(name);
- if (port->pp == 0 && port->vp == 0) {
- name = checked_strdup(port->port_name);
- } else if (port->vp == 0) {
- retval = asprintf(&name, "%s/%d",
- port->port_name, port->pp);
- if (retval <= 0)
- log_err(1, "asprintf");
- } else {
- retval = asprintf(&name, "%s/%d/%d",
- port->port_name, port->pp, port->vp);
- if (retval <= 0)
- log_err(1, "asprintf");
+void
+add_iscsi_port(struct kports &kports, struct conf *conf,
+ const struct cctl_port &port, std::string &name)
+{
+ if (port.cfiscsi_target.empty()) {
+ log_debugx("CTL port %u \"%s\" wasn't managed by ctld; ",
+ port.port_id, name.c_str());
+ if (!kports.has_port(name)) {
+ if (!kports.add_port(name, port.port_id)) {
+ log_warnx("kports::add_port failed");
+ return;
+ }
}
+ return;
+ }
+ if (port.cfiscsi_state != 1) {
+ log_debugx("CTL port %ju is not active (%d); ignoring",
+ (uintmax_t)port.port_id, port.cfiscsi_state);
+ return;
+ }
- if (port->cfiscsi_target == NULL) {
- log_debugx("CTL port %u \"%s\" wasn't managed by ctld; ",
- port->port_id, name);
- pp = pport_find(kports, name);
- if (pp == NULL) {
- pp = pport_new(kports, name, port->port_id);
- if (pp == NULL) {
- log_warnx("pport_new failed");
- continue;
- }
- }
- continue;
+ const char *t_name = port.cfiscsi_target.c_str();
+ struct target *targ = conf->find_target(t_name);
+ if (targ == nullptr) {
+ targ = conf->add_target(t_name);
+ if (targ == nullptr) {
+ log_warnx("Failed to add target \"%s\"", t_name);
+ return;
}
- if (port->cfiscsi_state != 1) {
- log_debugx("CTL port %ju is not active (%d); ignoring",
- (uintmax_t)port->port_id, port->cfiscsi_state);
- continue;
+ }
+
+ if (port.ctld_portal_group_name.empty())
+ return;
+
+ const char *pg_name = port.ctld_portal_group_name.c_str();
+ struct portal_group *pg = conf->find_portal_group(pg_name);
+ if (pg == nullptr) {
+ pg = conf->add_portal_group(pg_name);
+ if (pg == nullptr) {
+ log_warnx("Failed to add portal-group \"%s\"", pg_name);
+ return;
}
+ }
+ pg->set_tag(port.cfiscsi_portal_group_tag);
+ if (!conf->add_port(targ, pg, port.port_id)) {
+ log_warnx("Failed to add port for target \"%s\" and portal-group \"%s\"",
+ t_name, pg_name);
+ }
+}
- targ = target_find(conf, port->cfiscsi_target);
- if (targ == NULL) {
- targ = target_new(conf, port->cfiscsi_target);
- if (targ == NULL) {
- log_warnx("target_new failed");
- continue;
- }
+void
+add_nvmf_port(struct conf *conf, const struct cctl_port &port,
+ std::string &name)
+{
+ if (port.nqn.empty() || port.ctld_transport_group_name.empty()) {
+ log_debugx("CTL port %u \"%s\" wasn't managed by ctld; ",
+ port.port_id, name.c_str());
+ return;
+ }
+
+ const char *nqn = port.nqn.c_str();
+ struct target *targ = conf->find_controller(nqn);
+ if (targ == nullptr) {
+ targ = conf->add_controller(nqn);
+ if (targ == nullptr) {
+ log_warnx("Failed to add controller \"%s\"", nqn);
+ return;
}
+ }
- if (port->ctld_portal_group_name == NULL)
- continue;
- pg = portal_group_find(conf, port->ctld_portal_group_name);
- if (pg == NULL) {
- pg = portal_group_new(conf, port->ctld_portal_group_name);
- if (pg == NULL) {
- log_warnx("portal_group_new failed");
- continue;
- }
+ const char *tg_name = port.ctld_transport_group_name.c_str();
+ struct portal_group *pg = conf->find_transport_group(tg_name);
+ if (pg == nullptr) {
+ pg = conf->add_transport_group(tg_name);
+ if (pg == nullptr) {
+ log_warnx("Failed to add transport-group \"%s\"",
+ tg_name);
+ return;
}
- pg->pg_tag = port->cfiscsi_portal_group_tag;
- cp = port_new(conf, targ, pg);
- if (cp == NULL) {
- log_warnx("port_new failed");
+ }
+ pg->set_tag(port.portid);
+ if (!conf->add_port(targ, pg, port.port_id)) {
+ log_warnx("Failed to add port for controller \"%s\" and transport-group \"%s\"",
+ nqn, tg_name);
+ }
+}
+
+conf_up
+conf_new_from_kernel(struct kports &kports)
+{
+ struct cctl_devlist_data devlist;
+
+ log_debugx("obtaining previously configured CTL luns from the kernel");
+
+ if (!parse_kernel_config(devlist))
+ return {};
+
+ conf_up conf = std::make_unique<struct conf>();
+
+ for (const auto &port : devlist.port_list) {
+ if (port.port_frontend == "ha")
continue;
+
+ std::string name = port.port_name;
+ if (port.pp != 0) {
+ name += "/" + std::to_string(port.pp);
+ if (port.vp != 0)
+ name += "/" + std::to_string(port.vp);
+ }
+
+ if (port.port_frontend == "iscsi") {
+ add_iscsi_port(kports, conf.get(), port, name);
+ } else if (port.port_frontend == "nvmf") {
+ add_nvmf_port(conf.get(), port, name);
+ } else {
+ /* XXX: Treat all unknown ports as iSCSI? */
+ add_iscsi_port(kports, conf.get(), port, name);
}
- cp->p_ctl_port = port->port_id;
- }
- while ((port = STAILQ_FIRST(&devlist.port_list))) {
- STAILQ_REMOVE_HEAD(&devlist.port_list, links);
- free(port->port_frontend);
- free(port->port_name);
- free(port->cfiscsi_target);
- free(port->ctld_portal_group_name);
- nvlist_destroy(port->attr_list);
- free(port);
}
- free(name);
- STAILQ_FOREACH(lun, &devlist.lun_list, links) {
- if (lun->ctld_name == NULL) {
+ for (const auto &lun : devlist.lun_list) {
+ if (lun.ctld_name.empty()) {
log_debugx("CTL lun %ju wasn't managed by ctld; "
- "ignoring", (uintmax_t)lun->lun_id);
+ "ignoring", (uintmax_t)lun.lun_id);
continue;
}
- cl = lun_find(conf, lun->ctld_name);
+ const char *l_name = lun.ctld_name.c_str();
+ struct lun *cl = conf->find_lun(l_name);
if (cl != NULL) {
log_warnx("found CTL lun %ju \"%s\", "
"also backed by CTL lun %d; ignoring",
- (uintmax_t)lun->lun_id, lun->ctld_name,
- cl->l_ctl_lun);
+ (uintmax_t)lun.lun_id, l_name,
+ cl->ctl_lun());
continue;
}
log_debugx("found CTL lun %ju \"%s\"",
- (uintmax_t)lun->lun_id, lun->ctld_name);
+ (uintmax_t)lun.lun_id, l_name);
- cl = lun_new(conf, lun->ctld_name);
+ cl = conf->add_lun(l_name);
if (cl == NULL) {
log_warnx("lun_new failed");
continue;
}
- cl->l_backend = lun->backend_type;
- lun->backend_type = NULL;
- cl->l_device_type = lun->device_type;
- cl->l_blocksize = lun->blocksize;
- cl->l_device_id = lun->device_id;
- lun->device_id = NULL;
- cl->l_serial = lun->serial_number;
- lun->serial_number = NULL;
- cl->l_size = lun->size_blocks * cl->l_blocksize;
- cl->l_ctl_lun = lun->lun_id;
-
- cookie = NULL;
- while ((key = nvlist_next(lun->attr_list, NULL, &cookie)) !=
- NULL) {
- if (strcmp(key, "file") == 0 ||
- strcmp(key, "dev") == 0) {
- cl->l_path = checked_strdup(
- cnvlist_get_string(cookie));
+ cl->set_backend(lun.backend_type.c_str());
+ cl->set_device_type(lun.device_type);
+ cl->set_blocksize(lun.blocksize);
+ cl->set_device_id(lun.device_id.c_str());
+ cl->set_serial(lun.serial_number.c_str());
+ cl->set_size(lun.size_blocks * lun.blocksize);
+ cl->set_ctl_lun(lun.lun_id);
+
+ for (const auto &pair : lun.attr_list) {
+ const char *key = pair.first.c_str();
+ const char *value = pair.second.c_str();
+ if (pair.first == "file" || pair.first == "dev") {
+ cl->set_path(value);
continue;
}
- nvlist_add_string(cl->l_options, key,
- cnvlist_get_string(cookie));
- error = nvlist_error(cl->l_options);
- if (error != 0)
- log_warnc(error, "unable to add CTL lun option "
+ if (!cl->add_option(key, value))
+ log_warnx("unable to add CTL lun option "
"%s for CTL lun %ju \"%s\"",
- key, (uintmax_t)lun->lun_id,
- cl->l_name);
+ key, (uintmax_t)lun.lun_id,
+ cl->name());
}
}
- while ((lun = STAILQ_FIRST(&devlist.lun_list))) {
- STAILQ_REMOVE_HEAD(&devlist.lun_list, links);
- nvlist_destroy(lun->attr_list);
- free(lun);
- }
return (conf);
}
-static void
-nvlist_replace_string(nvlist_t *nvl, const char *name, const char *value)
-{
- if (nvlist_exists_string(nvl, name))
- nvlist_free_string(nvl, name);
- nvlist_add_string(nvl, name, value);
-}
-
-int
-kernel_lun_add(struct lun *lun)
+bool
+lun::kernel_add()
{
struct ctl_lun_req req;
int error;
bzero(&req, sizeof(req));
- strlcpy(req.backend, lun->l_backend, sizeof(req.backend));
+ strlcpy(req.backend, l_backend.c_str(), sizeof(req.backend));
req.reqtype = CTL_LUNREQ_CREATE;
- req.reqdata.create.blocksize_bytes = lun->l_blocksize;
+ req.reqdata.create.blocksize_bytes = l_blocksize;
- if (lun->l_size != 0)
- req.reqdata.create.lun_size_bytes = lun->l_size;
+ if (l_size != 0)
+ req.reqdata.create.lun_size_bytes = l_size;
- if (lun->l_ctl_lun >= 0) {
- req.reqdata.create.req_lun_id = lun->l_ctl_lun;
+ if (l_ctl_lun >= 0) {
+ req.reqdata.create.req_lun_id = l_ctl_lun;
req.reqdata.create.flags |= CTL_LUN_FLAG_ID_REQ;
}
req.reqdata.create.flags |= CTL_LUN_FLAG_DEV_TYPE;
- req.reqdata.create.device_type = lun->l_device_type;
+ req.reqdata.create.device_type = l_device_type;
- if (lun->l_serial != NULL) {
- strncpy((char *)req.reqdata.create.serial_num, lun->l_serial,
+ if (!l_serial.empty()) {
+ strncpy((char *)req.reqdata.create.serial_num, l_serial.c_str(),
sizeof(req.reqdata.create.serial_num));
req.reqdata.create.flags |= CTL_LUN_FLAG_SERIAL_NUM;
}
- if (lun->l_device_id != NULL) {
- strncpy((char *)req.reqdata.create.device_id, lun->l_device_id,
- sizeof(req.reqdata.create.device_id));
+ if (!l_device_id.empty()) {
+ strncpy((char *)req.reqdata.create.device_id,
+ l_device_id.c_str(), sizeof(req.reqdata.create.device_id));
req.reqdata.create.flags |= CTL_LUN_FLAG_DEVID;
}
- if (lun->l_path != NULL)
- nvlist_replace_string(lun->l_options, "file", lun->l_path);
-
- nvlist_replace_string(lun->l_options, "ctld_name", lun->l_name);
-
- if (!nvlist_exists_string(lun->l_options, "scsiname") &&
- lun->l_scsiname != NULL)
- nvlist_add_string(lun->l_options, "scsiname", lun->l_scsiname);
-
- if (!nvlist_empty(lun->l_options)) {
- req.args = nvlist_pack(lun->l_options, &req.args_len);
- if (req.args == NULL) {
- log_warn("error packing nvlist");
- return (1);
- }
+ freebsd::nvlist_up nvl = options();
+ req.args = nvlist_pack(nvl.get(), &req.args_len);
+ if (req.args == NULL) {
+ log_warn("error packing nvlist");
+ return (false);
}
error = ioctl(ctl_fd, CTL_LUN_REQ, &req);
@@ -725,13 +660,13 @@ kernel_lun_add(struct lun *lun)
if (error != 0) {
log_warn("error issuing CTL_LUN_REQ ioctl");
- return (1);
+ return (false);
}
switch (req.status) {
case CTL_LUN_ERROR:
log_warnx("LUN creation error: %s", req.error_str);
- return (1);
+ return (false);
case CTL_LUN_WARNING:
log_warnx("LUN creation warning: %s", req.error_str);
break;
@@ -740,42 +675,32 @@ kernel_lun_add(struct lun *lun)
default:
log_warnx("unknown LUN creation status: %d",
req.status);
- return (1);
+ return (false);
}
- lun->l_ctl_lun = req.reqdata.create.req_lun_id;
- return (0);
+ l_ctl_lun = req.reqdata.create.req_lun_id;
+ return (true);
}
-int
-kernel_lun_modify(struct lun *lun)
+bool
+lun::kernel_modify() const
{
struct ctl_lun_req req;
int error;
bzero(&req, sizeof(req));
- strlcpy(req.backend, lun->l_backend, sizeof(req.backend));
+ strlcpy(req.backend, l_backend.c_str(), sizeof(req.backend));
req.reqtype = CTL_LUNREQ_MODIFY;
- req.reqdata.modify.lun_id = lun->l_ctl_lun;
- req.reqdata.modify.lun_size_bytes = lun->l_size;
-
- if (lun->l_path != NULL)
- nvlist_replace_string(lun->l_options, "file", lun->l_path);
-
- nvlist_replace_string(lun->l_options, "ctld_name", lun->l_name);
+ req.reqdata.modify.lun_id = l_ctl_lun;
+ req.reqdata.modify.lun_size_bytes = l_size;
- if (!nvlist_exists_string(lun->l_options, "scsiname") &&
- lun->l_scsiname != NULL)
- nvlist_add_string(lun->l_options, "scsiname", lun->l_scsiname);
-
- if (!nvlist_empty(lun->l_options)) {
- req.args = nvlist_pack(lun->l_options, &req.args_len);
- if (req.args == NULL) {
- log_warn("error packing nvlist");
- return (1);
- }
+ freebsd::nvlist_up nvl = options();
+ req.args = nvlist_pack(nvl.get(), &req.args_len);
+ if (req.args == NULL) {
+ log_warn("error packing nvlist");
+ return (false);
}
error = ioctl(ctl_fd, CTL_LUN_REQ, &req);
@@ -783,13 +708,13 @@ kernel_lun_modify(struct lun *lun)
if (error != 0) {
log_warn("error issuing CTL_LUN_REQ ioctl");
- return (1);
+ return (false);
}
switch (req.status) {
case CTL_LUN_ERROR:
log_warnx("LUN modification error: %s", req.error_str);
- return (1);
+ return (false);
case CTL_LUN_WARNING:
log_warnx("LUN modification warning: %s", req.error_str);
break;
@@ -798,33 +723,33 @@ kernel_lun_modify(struct lun *lun)
default:
log_warnx("unknown LUN modification status: %d",
req.status);
- return (1);
+ return (false);
}
- return (0);
+ return (true);
}
-int
-kernel_lun_remove(struct lun *lun)
+bool
+lun::kernel_remove() const
{
struct ctl_lun_req req;
bzero(&req, sizeof(req));
- strlcpy(req.backend, lun->l_backend, sizeof(req.backend));
+ strlcpy(req.backend, l_backend.c_str(), sizeof(req.backend));
req.reqtype = CTL_LUNREQ_RM;
- req.reqdata.rm.lun_id = lun->l_ctl_lun;
+ req.reqdata.rm.lun_id = l_ctl_lun;
if (ioctl(ctl_fd, CTL_LUN_REQ, &req) == -1) {
log_warn("error issuing CTL_LUN_REQ ioctl");
- return (1);
+ return (false);
}
switch (req.status) {
case CTL_LUN_ERROR:
log_warnx("LUN removal error: %s", req.error_str);
- return (1);
+ return (false);
case CTL_LUN_WARNING:
log_warnx("LUN removal warning: %s", req.error_str);
break;
@@ -832,167 +757,104 @@ kernel_lun_remove(struct lun *lun)
break;
default:
log_warnx("unknown LUN removal status: %d", req.status);
- return (1);
+ return (false);
}
- return (0);
+ return (true);
}
-void
-kernel_handoff(struct ctld_connection *conn)
+bool
+ctl_create_port(const char *driver, const nvlist_t *nvl, uint32_t *ctl_port)
{
- struct ctl_iscsi req;
+ struct ctl_req req;
+ char result_buf[NVLIST_BUFSIZE];
+ int error;
bzero(&req, sizeof(req));
+ req.reqtype = CTL_REQ_CREATE;
- req.type = CTL_ISCSI_HANDOFF;
- strlcpy(req.data.handoff.initiator_name,
- conn->conn_initiator_name, sizeof(req.data.handoff.initiator_name));
- strlcpy(req.data.handoff.initiator_addr,
- conn->conn_initiator_addr, sizeof(req.data.handoff.initiator_addr));
- if (conn->conn_initiator_alias != NULL) {
- strlcpy(req.data.handoff.initiator_alias,
- conn->conn_initiator_alias, sizeof(req.data.handoff.initiator_alias));
+ strlcpy(req.driver, driver, sizeof(req.driver));
+ req.args = nvlist_pack(nvl, &req.args_len);
+ if (req.args == NULL) {
+ log_warn("error packing nvlist");
+ return (false);
}
- memcpy(req.data.handoff.initiator_isid, conn->conn_initiator_isid,
- sizeof(req.data.handoff.initiator_isid));
- strlcpy(req.data.handoff.target_name,
- conn->conn_target->t_name, sizeof(req.data.handoff.target_name));
- if (conn->conn_portal->p_portal_group->pg_offload != NULL) {
- strlcpy(req.data.handoff.offload,
- conn->conn_portal->p_portal_group->pg_offload,
- sizeof(req.data.handoff.offload));
+
+ req.result = result_buf;
+ req.result_len = sizeof(result_buf);
+ error = ioctl(ctl_fd, CTL_PORT_REQ, &req);
+ free(req.args);
+
+ if (error != 0) {
+ log_warn("error issuing CTL_PORT_REQ ioctl");
+ return (false);
+ }
+ if (req.status == CTL_LUN_ERROR) {
+ log_warnx("error returned from port creation request: %s",
+ req.error_str);
+ return (false);
+ }
+ if (req.status != CTL_LUN_OK) {
+ log_warnx("unknown port creation request status %d",
+ req.status);
+ return (false);
}
-#ifdef ICL_KERNEL_PROXY
- if (proxy_mode)
- req.data.handoff.connection_id = conn->conn.conn_socket;
- else
- req.data.handoff.socket = conn->conn.conn_socket;
-#else
- req.data.handoff.socket = conn->conn.conn_socket;
-#endif
- req.data.handoff.portal_group_tag =
- conn->conn_portal->p_portal_group->pg_tag;
- if (conn->conn.conn_header_digest == CONN_DIGEST_CRC32C)
- req.data.handoff.header_digest = CTL_ISCSI_DIGEST_CRC32C;
- if (conn->conn.conn_data_digest == CONN_DIGEST_CRC32C)
- req.data.handoff.data_digest = CTL_ISCSI_DIGEST_CRC32C;
- req.data.handoff.cmdsn = conn->conn.conn_cmdsn;
- req.data.handoff.statsn = conn->conn.conn_statsn;
- req.data.handoff.max_recv_data_segment_length =
- conn->conn.conn_max_recv_data_segment_length;
- req.data.handoff.max_send_data_segment_length =
- conn->conn.conn_max_send_data_segment_length;
- req.data.handoff.max_burst_length = conn->conn.conn_max_burst_length;
- req.data.handoff.first_burst_length =
- conn->conn.conn_first_burst_length;
- req.data.handoff.immediate_data = conn->conn.conn_immediate_data;
- if (ioctl(ctl_fd, CTL_ISCSI, &req) == -1) {
- log_err(1, "error issuing CTL_ISCSI ioctl; "
- "dropping connection");
+ freebsd::nvlist_up result_nvl(nvlist_unpack(result_buf, req.result_len,
+ 0));
+ if (result_nvl == NULL) {
+ log_warnx("error unpacking result nvlist");
+ return (false);
}
- if (req.status != CTL_ISCSI_OK) {
- log_errx(1, "error returned from CTL iSCSI handoff request: "
- "%s; dropping connection", req.error_str);
+ *ctl_port = nvlist_get_number(result_nvl.get(), "port_id");
+ return (true);
+}
+
+bool
+ioctl_port::kernel_create_port()
+{
+ freebsd::nvlist_up nvl(nvlist_create(0));
+ nvlist_add_stringf(nvl.get(), "pp", "%d", p_ioctl_pp);
+ nvlist_add_stringf(nvl.get(), "vp", "%d", p_ioctl_vp);
+
+ return (ctl_create_port("ioctl", nvl.get(), &p_ctl_port));
+}
+
+bool
+kernel_port::kernel_create_port()
+{
+ struct ctl_port_entry entry;
+ struct target *targ = p_target;
+
+ p_ctl_port = p_pport->ctl_port();
+
+ if (strncmp(targ->name(), "naa.", 4) == 0 &&
+ strlen(targ->name()) == 20) {
+ bzero(&entry, sizeof(entry));
+ entry.port_type = CTL_PORT_NONE;
+ entry.targ_port = p_ctl_port;
+ entry.flags |= CTL_PORT_WWNN_VALID;
+ entry.wwnn = strtoull(targ->name() + 4, NULL, 16);
+ if (ioctl(ctl_fd, CTL_SET_PORT_WWNS, &entry) == -1)
+ log_warn("CTL_SET_PORT_WWNS ioctl failed");
}
+ return (true);
}
-int
-kernel_port_add(struct port *port)
+bool
+port::kernel_add()
{
struct ctl_port_entry entry;
- struct ctl_req req;
struct ctl_lun_map lm;
- struct target *targ = port->p_target;
- struct portal_group *pg = port->p_portal_group;
- char result_buf[NVLIST_BUFSIZE];
+ struct target *targ = p_target;
int error, i;
- /* Create iSCSI port. */
- if (port->p_portal_group || port->p_ioctl_port) {
- bzero(&req, sizeof(req));
- req.reqtype = CTL_REQ_CREATE;
-
- if (port->p_portal_group) {
- strlcpy(req.driver, "iscsi", sizeof(req.driver));
- req.args_nvl = nvlist_clone(pg->pg_options);
- nvlist_add_string(req.args_nvl, "cfiscsi_target",
- targ->t_name);
- nvlist_add_string(req.args_nvl,
- "ctld_portal_group_name", pg->pg_name);
- nvlist_add_stringf(req.args_nvl,
- "cfiscsi_portal_group_tag", "%u", pg->pg_tag);
-
- if (targ->t_alias) {
- nvlist_add_string(req.args_nvl,
- "cfiscsi_target_alias", targ->t_alias);
- }
- }
-
- if (port->p_ioctl_port) {
- strlcpy(req.driver, "ioctl", sizeof(req.driver));
- req.args_nvl = nvlist_create(0);
- nvlist_add_stringf(req.args_nvl, "pp", "%d",
- port->p_ioctl_pp);
- nvlist_add_stringf(req.args_nvl, "vp", "%d",
- port->p_ioctl_vp);
- }
-
- req.args = nvlist_pack(req.args_nvl, &req.args_len);
- if (req.args == NULL) {
- nvlist_destroy(req.args_nvl);
- log_warn("error packing nvlist");
- return (1);
- }
-
- req.result = result_buf;
- req.result_len = sizeof(result_buf);
- error = ioctl(ctl_fd, CTL_PORT_REQ, &req);
- free(req.args);
- nvlist_destroy(req.args_nvl);
-
- if (error != 0) {
- log_warn("error issuing CTL_PORT_REQ ioctl");
- return (1);
- }
- if (req.status == CTL_LUN_ERROR) {
- log_warnx("error returned from port creation request: %s",
- req.error_str);
- return (1);
- }
- if (req.status != CTL_LUN_OK) {
- log_warnx("unknown port creation request status %d",
- req.status);
- return (1);
- }
-
- req.result_nvl = nvlist_unpack(result_buf, req.result_len, 0);
- if (req.result_nvl == NULL) {
- log_warnx("error unpacking result nvlist");
- return (1);
- }
-
- port->p_ctl_port = nvlist_get_number(req.result_nvl, "port_id");
- nvlist_destroy(req.result_nvl);
- } else if (port->p_pport) {
- port->p_ctl_port = port->p_pport->pp_ctl_port;
-
- if (strncmp(targ->t_name, "naa.", 4) == 0 &&
- strlen(targ->t_name) == 20) {
- bzero(&entry, sizeof(entry));
- entry.port_type = CTL_PORT_NONE;
- entry.targ_port = port->p_ctl_port;
- entry.flags |= CTL_PORT_WWNN_VALID;
- entry.wwnn = strtoull(targ->t_name + 4, NULL, 16);
- if (ioctl(ctl_fd, CTL_SET_PORT_WWNS, &entry) == -1)
- log_warn("CTL_SET_PORT_WWNS ioctl failed");
- }
- }
+ if (!kernel_create_port())
+ return (false);
/* Explicitly enable mapping to block any access except allowed. */
- lm.port = port->p_ctl_port;
+ lm.port = p_ctl_port;
lm.plun = UINT32_MAX;
lm.lun = 0;
error = ioctl(ctl_fd, CTL_LUN_MAP, &lm);
@@ -1001,11 +863,11 @@ kernel_port_add(struct port *port)
/* Map configured LUNs */
for (i = 0; i < MAX_LUNS; i++) {
- if (targ->t_luns[i] == NULL)
+ if (targ->lun(i) == nullptr)
continue;
- lm.port = port->p_ctl_port;
+ lm.port = p_ctl_port;
lm.plun = i;
- lm.lun = targ->t_luns[i]->l_ctl_lun;
+ lm.lun = targ->lun(i)->ctl_lun();
error = ioctl(ctl_fd, CTL_LUN_MAP, &lm);
if (error != 0)
log_warn("CTL_LUN_MAP ioctl failed");
@@ -1013,120 +875,122 @@ kernel_port_add(struct port *port)
/* Enable port */
bzero(&entry, sizeof(entry));
- entry.targ_port = port->p_ctl_port;
+ entry.targ_port = p_ctl_port;
error = ioctl(ctl_fd, CTL_ENABLE_PORT, &entry);
if (error != 0) {
log_warn("CTL_ENABLE_PORT ioctl failed");
- return (-1);
+ return (false);
}
- return (0);
+ return (true);
}
-int
-kernel_port_update(struct port *port, struct port *oport)
+bool
+port::kernel_update(const struct port *oport)
{
struct ctl_lun_map lm;
- struct target *targ = port->p_target;
+ struct target *targ = p_target;
struct target *otarg = oport->p_target;
int error, i;
uint32_t olun;
+ p_ctl_port = oport->p_ctl_port;
+
/* Map configured LUNs and unmap others */
for (i = 0; i < MAX_LUNS; i++) {
- lm.port = port->p_ctl_port;
+ lm.port = p_ctl_port;
lm.plun = i;
- if (targ->t_luns[i] == NULL)
+ if (targ->lun(i) == nullptr)
lm.lun = UINT32_MAX;
else
- lm.lun = targ->t_luns[i]->l_ctl_lun;
- if (otarg->t_luns[i] == NULL)
+ lm.lun = targ->lun(i)->ctl_lun();
+ if (otarg->lun(i) == nullptr)
olun = UINT32_MAX;
else
- olun = otarg->t_luns[i]->l_ctl_lun;
+ olun = otarg->lun(i)->ctl_lun();
if (lm.lun == olun)
continue;
error = ioctl(ctl_fd, CTL_LUN_MAP, &lm);
if (error != 0)
log_warn("CTL_LUN_MAP ioctl failed");
}
- return (0);
+ return (true);
}
-int
-kernel_port_remove(struct port *port)
+bool
+ctl_remove_port(const char *driver, nvlist_t *nvl)
{
- struct ctl_port_entry entry;
- struct ctl_lun_map lm;
struct ctl_req req;
- struct target *targ = port->p_target;
- struct portal_group *pg = port->p_portal_group;
int error;
- /* Disable port */
- bzero(&entry, sizeof(entry));
- entry.targ_port = port->p_ctl_port;
- error = ioctl(ctl_fd, CTL_DISABLE_PORT, &entry);
+ strlcpy(req.driver, driver, sizeof(req.driver));
+ req.reqtype = CTL_REQ_REMOVE;
+ req.args = nvlist_pack(nvl, &req.args_len);
+ if (req.args == NULL) {
+ log_warn("error packing nvlist");
+ return (false);
+ }
+
+ error = ioctl(ctl_fd, CTL_PORT_REQ, &req);
+ free(req.args);
+
if (error != 0) {
- log_warn("CTL_DISABLE_PORT ioctl failed");
- return (-1);
+ log_warn("error issuing CTL_PORT_REQ ioctl");
+ return (false);
+ }
+ if (req.status == CTL_LUN_ERROR) {
+ log_warnx("error returned from port removal request: %s",
+ req.error_str);
+ return (false);
}
+ if (req.status != CTL_LUN_OK) {
+ log_warnx("unknown port removal request status %d", req.status);
+ return (false);
+ }
+ return (true);
+}
- /* Remove iSCSI or ioctl port. */
- if (port->p_portal_group || port->p_ioctl_port) {
- bzero(&req, sizeof(req));
- strlcpy(req.driver, port->p_ioctl_port ? "ioctl" : "iscsi",
- sizeof(req.driver));
- req.reqtype = CTL_REQ_REMOVE;
- req.args_nvl = nvlist_create(0);
- if (req.args_nvl == NULL)
- log_err(1, "nvlist_create");
-
- if (port->p_ioctl_port)
- nvlist_add_stringf(req.args_nvl, "port_id", "%d",
- port->p_ctl_port);
- else {
- nvlist_add_string(req.args_nvl, "cfiscsi_target",
- targ->t_name);
- nvlist_add_stringf(req.args_nvl,
- "cfiscsi_portal_group_tag", "%u", pg->pg_tag);
- }
+bool
+ioctl_port::kernel_remove_port()
+{
+ freebsd::nvlist_up nvl(nvlist_create(0));
+ nvlist_add_stringf(nvl.get(), "port_id", "%d", p_ctl_port);
- req.args = nvlist_pack(req.args_nvl, &req.args_len);
- if (req.args == NULL) {
- nvlist_destroy(req.args_nvl);
- log_warn("error packing nvlist");
- return (1);
- }
+ return (ctl_remove_port("ioctl", nvl.get()));
+}
- error = ioctl(ctl_fd, CTL_PORT_REQ, &req);
- free(req.args);
- nvlist_destroy(req.args_nvl);
+bool
+kernel_port::kernel_remove_port()
+{
+ struct ctl_lun_map lm;
+ int error;
- if (error != 0) {
- log_warn("error issuing CTL_PORT_REQ ioctl");
- return (1);
- }
- if (req.status == CTL_LUN_ERROR) {
- log_warnx("error returned from port removal request: %s",
- req.error_str);
- return (1);
- }
- if (req.status != CTL_LUN_OK) {
- log_warnx("unknown port removal request status %d",
- req.status);
- return (1);
- }
- } else {
- /* Disable LUN mapping. */
- lm.port = port->p_ctl_port;
- lm.plun = UINT32_MAX;
- lm.lun = UINT32_MAX;
- error = ioctl(ctl_fd, CTL_LUN_MAP, &lm);
- if (error != 0)
- log_warn("CTL_LUN_MAP ioctl failed");
+ /* Disable LUN mapping. */
+ lm.port = p_ctl_port;
+ lm.plun = UINT32_MAX;
+ lm.lun = UINT32_MAX;
+ error = ioctl(ctl_fd, CTL_LUN_MAP, &lm);
+ if (error != 0)
+ log_warn("CTL_LUN_MAP ioctl failed");
+ return (true);
+}
+
+bool
+port::kernel_remove()
+{
+ struct ctl_port_entry entry;
+ int error;
+
+ /* Disable port */
+ bzero(&entry, sizeof(entry));
+ entry.targ_port = p_ctl_port;
+ error = ioctl(ctl_fd, CTL_DISABLE_PORT, &entry);
+ if (error != 0) {
+ log_warn("CTL_DISABLE_PORT ioctl failed");
+ return (false);
}
- return (0);
+
+ return (kernel_remove_port());
}
#ifdef ICL_KERNEL_PROXY
@@ -1246,7 +1110,7 @@ void
kernel_capsicate(void)
{
cap_rights_t rights;
- const unsigned long cmds[] = { CTL_ISCSI };
+ const unsigned long cmds[] = { CTL_ISCSI, CTL_NVMF };
cap_rights_init(&rights, CAP_IOCTL);
if (caph_rights_limit(ctl_fd, &rights) < 0)