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.cc251
1 files changed, 110 insertions, 141 deletions
diff --git a/usr.sbin/ctld/kernel.cc b/usr.sbin/ctld/kernel.cc
index 39bbb4290e84..6b17ce60ac69 100644
--- a/usr.sbin/ctld/kernel.cc
+++ b/usr.sbin/ctld/kernel.cc
@@ -75,8 +75,6 @@
#define NVLIST_BUFSIZE 1024
-extern bool proxy_mode;
-
int ctl_fd = 0;
void
@@ -108,7 +106,7 @@ kernel_init(void)
/*
* Backend LUN information.
*/
-using attr_list = std::list<std::pair<std::string, std::string>>;
+using attr_list_t = std::list<std::pair<std::string, std::string>>;
struct cctl_lun {
uint64_t lun_id;
@@ -119,7 +117,7 @@ struct cctl_lun {
std::string serial_number;
std::string device_id;
std::string ctld_name;
- attr_list attr_list;
+ attr_list_t attr_list;
};
struct cctl_port {
@@ -128,11 +126,14 @@ struct cctl_port {
std::string port_name;
int pp;
int vp;
+ uint16_t portid;
int cfiscsi_state;
std::string cfiscsi_target;
+ std::string nqn;
uint16_t cfiscsi_portal_group_tag;
std::string ctld_portal_group_name;
- attr_list attr_list;
+ std::string ctld_transport_group_name;
+ attr_list_t attr_list;
};
struct cctl_devlist_data {
@@ -324,6 +325,14 @@ cctl_end_pelement(void *user_data, const char *name)
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 = 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) {
@@ -432,6 +441,93 @@ retry_port:
return (true);
}
+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;
+ }
+
+ 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.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);
+ }
+}
+
+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;
+ }
+ }
+
+ 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->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)
{
@@ -455,51 +551,13 @@ conf_new_from_kernel(struct kports &kports)
name += "/" + std::to_string(port.vp);
}
- 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");
- continue;
- }
- }
- continue;
- }
- if (port.cfiscsi_state != 1) {
- log_debugx("CTL port %ju is not active (%d); ignoring",
- (uintmax_t)port.port_id, port.cfiscsi_state);
- continue;
- }
-
- const char *t_name = port.cfiscsi_target.c_str();
- struct target *targ = conf->find_target(t_name);
- if (targ == NULL) {
- targ = conf->add_target(t_name);
- if (targ == NULL) {
- log_warnx("Failed to add target \"%s\"",
- t_name);
- continue;
- }
- }
-
- if (port.ctld_portal_group_name.empty())
- continue;
- const char *pg_name = port.ctld_portal_group_name.c_str();
- struct portal_group *pg = conf->find_portal_group(pg_name);
- if (pg == NULL) {
- pg = conf->add_portal_group(pg_name);
- if (pg == NULL) {
- log_warnx("Failed to add portal_group \"%s\"",
- pg_name);
- continue;
- }
- }
- 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);
- continue;
+ 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);
}
}
@@ -705,65 +763,7 @@ lun::kernel_remove() const
return (true);
}
-void
-ctld_connection::kernel_handoff()
-{
- struct portal_group *pg = conn_portal->portal_group();
- struct ctl_iscsi req;
-
- bzero(&req, sizeof(req));
-
- req.type = CTL_ISCSI_HANDOFF;
- strlcpy(req.data.handoff.initiator_name, conn_initiator_name.c_str(),
- sizeof(req.data.handoff.initiator_name));
- strlcpy(req.data.handoff.initiator_addr, conn_initiator_addr.c_str(),
- sizeof(req.data.handoff.initiator_addr));
- if (!conn_initiator_alias.empty()) {
- strlcpy(req.data.handoff.initiator_alias,
- conn_initiator_alias.c_str(),
- sizeof(req.data.handoff.initiator_alias));
- }
- memcpy(req.data.handoff.initiator_isid, conn_initiator_isid,
- sizeof(req.data.handoff.initiator_isid));
- strlcpy(req.data.handoff.target_name, conn_target->name(),
- sizeof(req.data.handoff.target_name));
- strlcpy(req.data.handoff.offload, pg->offload(),
- sizeof(req.data.handoff.offload));
-#ifdef ICL_KERNEL_PROXY
- if (proxy_mode)
- req.data.handoff.connection_id = conn.conn_socket;
- else
- req.data.handoff.socket = conn.conn_socket;
-#else
- req.data.handoff.socket = conn.conn_socket;
-#endif
- req.data.handoff.portal_group_tag = pg->tag();
- if (conn.conn_header_digest == CONN_DIGEST_CRC32C)
- req.data.handoff.header_digest = CTL_ISCSI_DIGEST_CRC32C;
- if (conn.conn_data_digest == CONN_DIGEST_CRC32C)
- req.data.handoff.data_digest = CTL_ISCSI_DIGEST_CRC32C;
- req.data.handoff.cmdsn = conn.conn_cmdsn;
- req.data.handoff.statsn = conn.conn_statsn;
- req.data.handoff.max_recv_data_segment_length =
- conn.conn_max_recv_data_segment_length;
- req.data.handoff.max_send_data_segment_length =
- conn.conn_max_send_data_segment_length;
- req.data.handoff.max_burst_length = conn.conn_max_burst_length;
- req.data.handoff.first_burst_length = conn.conn_first_burst_length;
- req.data.handoff.immediate_data = conn.conn_immediate_data;
-
- if (ioctl(ctl_fd, CTL_ISCSI, &req) == -1) {
- log_err(1, "error issuing CTL_ISCSI ioctl; "
- "dropping connection");
- }
-
- if (req.status != CTL_ISCSI_OK) {
- log_errx(1, "error returned from CTL iSCSI handoff request: "
- "%s; dropping connection", req.error_str);
- }
-}
-
-static bool
+bool
ctl_create_port(const char *driver, const nvlist_t *nvl, uint32_t *ctl_port)
{
struct ctl_req req;
@@ -812,26 +812,6 @@ ctl_create_port(const char *driver, const nvlist_t *nvl, uint32_t *ctl_port)
}
bool
-portal_group_port::kernel_create_port()
-{
- struct portal_group *pg = p_portal_group;
- struct target *targ = p_target;
-
- freebsd::nvlist_up nvl = pg->options();
- nvlist_add_string(nvl.get(), "cfiscsi_target", targ->name());
- nvlist_add_string(nvl.get(), "ctld_portal_group_name", pg->name());
- nvlist_add_stringf(nvl.get(), "cfiscsi_portal_group_tag", "%u",
- pg->tag());
-
- if (targ->has_alias()) {
- nvlist_add_string(nvl.get(), "cfiscsi_target_alias",
- targ->alias());
- }
-
- return (ctl_create_port("iscsi", nvl.get(), &p_ctl_port));
-}
-
-bool
ioctl_port::kernel_create_port()
{
freebsd::nvlist_up nvl(nvlist_create(0));
@@ -971,17 +951,6 @@ ctl_remove_port(const char *driver, nvlist_t *nvl)
}
bool
-portal_group_port::kernel_remove_port()
-{
- freebsd::nvlist_up nvl(nvlist_create(0));
- nvlist_add_string(nvl.get(), "cfiscsi_target", p_target->name());
- nvlist_add_stringf(nvl.get(), "cfiscsi_portal_group_tag", "%u",
- p_portal_group->tag());
-
- return (ctl_remove_port("iscsi", nvl.get()));
-}
-
-bool
ioctl_port::kernel_remove_port()
{
freebsd::nvlist_up nvl(nvlist_create(0));
@@ -1141,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)