git: 2bb9180bb5d0 - main - ctld: Convert struct target to a C++ class
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 04 Aug 2025 19:47:01 UTC
The branch main has been updated by jhb:
URL: https://cgit.FreeBSD.org/src/commit/?id=2bb9180bb5d0054bf79529d6a1cb56b61a94629a
commit 2bb9180bb5d0054bf79529d6a1cb56b61a94629a
Author: John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2025-08-04 19:38:07 +0000
Commit: John Baldwin <jhb@FreeBSD.org>
CommitDate: 2025-08-04 19:38:07 +0000
ctld: Convert struct target to a C++ class
- Use std::string for string members.
- Use std::array for the array of LUN pointers indexed by LUN id.
- Move meat of the target_* functions from conf.cc into class methods.
Sponsored by: Chelsio Communications
Pull Request: https://github.com/freebsd/freebsd-src/pull/1794
---
usr.sbin/ctld/conf.cc | 165 ++----------------
usr.sbin/ctld/ctld.cc | 406 ++++++++++++++++++++++++++++++++-------------
usr.sbin/ctld/ctld.hh | 55 +++++-
usr.sbin/ctld/discovery.cc | 16 +-
usr.sbin/ctld/kernel.cc | 28 ++--
usr.sbin/ctld/login.cc | 22 +--
6 files changed, 384 insertions(+), 308 deletions(-)
diff --git a/usr.sbin/ctld/conf.cc b/usr.sbin/ctld/conf.cc
index 8913cccd5889..81451009067c 100644
--- a/usr.sbin/ctld/conf.cc
+++ b/usr.sbin/ctld/conf.cc
@@ -341,217 +341,78 @@ target_finish(void)
target = NULL;
}
-static bool
-target_use_private_auth(const char *keyword)
-{
- if (target->t_auth_group != nullptr) {
- if (!target->t_private_auth) {
- log_warnx("cannot use both auth-group and "
- "%s for target \"%s\"", keyword, target->t_name);
- return (false);
- }
- } else {
- target->t_auth_group = auth_group_new(target);
- if (target->t_auth_group == nullptr)
- return (false);
- target->t_private_auth = true;
- }
- return (true);
-}
-
bool
target_add_chap(const char *user, const char *secret)
{
- if (!target_use_private_auth("chap"))
- return (false);
- return (target->t_auth_group->add_chap(user, secret));
+ return (target->add_chap(user, secret));
}
bool
target_add_chap_mutual(const char *user, const char *secret,
const char *user2, const char *secret2)
{
- if (!target_use_private_auth("chap-mutual"))
- return (false);
- return (target->t_auth_group->add_chap_mutual(user, secret, user2,
- secret2));
+ return (target->add_chap_mutual(user, secret, user2, secret2));
}
bool
target_add_initiator_name(const char *name)
{
- if (!target_use_private_auth("initiator-name"))
- return (false);
- return (target->t_auth_group->add_initiator_name(name));
+ return (target->add_initiator_name(name));
}
bool
target_add_initiator_portal(const char *addr)
{
- if (!target_use_private_auth("initiator-portal"))
- return (false);
- return (target->t_auth_group->add_initiator_portal(addr));
+ return (target->add_initiator_portal(addr));
}
bool
target_add_lun(u_int id, const char *name)
{
- struct lun *t_lun;
-
- if (id >= MAX_LUNS) {
- log_warnx("LUN %u too big for target \"%s\"", id,
- target->t_name);
- return (false);
- }
-
- if (target->t_luns[id] != NULL) {
- log_warnx("duplicate LUN %u for target \"%s\"", id,
- target->t_name);
- return (false);
- }
-
- t_lun = lun_find(conf, name);
- if (t_lun == NULL) {
- log_warnx("unknown LUN named %s used for target \"%s\"",
- name, target->t_name);
- return (false);
- }
-
- target->t_luns[id] = t_lun;
- return (true);
+ return (target->add_lun(id, name));
}
bool
target_add_portal_group(const char *pg_name, const char *ag_name)
{
- struct portal_group *pg;
- auth_group_sp ag;
-
- pg = portal_group_find(conf, pg_name);
- if (pg == NULL) {
- log_warnx("unknown portal-group \"%s\" for target \"%s\"",
- pg_name, target->t_name);
- return (false);
- }
-
- if (ag_name != NULL) {
- ag = auth_group_find(conf, ag_name);
- if (ag == NULL) {
- log_warnx("unknown auth-group \"%s\" for target \"%s\"",
- ag_name, target->t_name);
- return (false);
- }
- }
-
- if (!port_new(conf, target, pg, std::move(ag))) {
- log_warnx("can't link portal-group \"%s\" to target \"%s\"",
- pg_name, target->t_name);
- return (false);
- }
- return (true);
+ return (target->add_portal_group(pg_name, ag_name));
}
bool
target_set_alias(const char *alias)
{
- if (target->t_alias != NULL) {
- log_warnx("alias for target \"%s\" specified more than once",
- target->t_name);
- return (false);
- }
- target->t_alias = checked_strdup(alias);
- return (true);
+ return (target->set_alias(alias));
}
bool
target_set_auth_group(const char *name)
{
- if (target->t_auth_group != nullptr) {
- if (target->t_private_auth)
- log_warnx("cannot use both auth-group and explicit "
- "authorisations for target \"%s\"", target->t_name);
- else
- log_warnx("auth-group for target \"%s\" "
- "specified more than once", target->t_name);
- return (false);
- }
- target->t_auth_group = auth_group_find(conf, name);
- if (target->t_auth_group == nullptr) {
- log_warnx("unknown auth-group \"%s\" for target \"%s\"", name,
- target->t_name);
- return (false);
- }
- return (true);
+ return (target->set_auth_group(name));
}
bool
target_set_auth_type(const char *type)
{
- if (!target_use_private_auth("auth-type"))
- return (false);
- return (target->t_auth_group->set_type(type));
+ return (target->set_auth_type(type));
}
bool
target_set_physical_port(const char *pport)
{
- if (target->t_pport != NULL) {
- log_warnx("cannot set multiple physical ports for target "
- "\"%s\"", target->t_name);
- return (false);
- }
- target->t_pport = checked_strdup(pport);
- return (true);
+ return (target->set_physical_port(pport));
}
bool
target_set_redirection(const char *addr)
{
-
- if (target->t_redirection != NULL) {
- log_warnx("cannot set redirection to \"%s\" for "
- "target \"%s\"; already defined",
- addr, target->t_name);
- return (false);
- }
-
- target->t_redirection = checked_strdup(addr);
-
- return (true);
+ return (target->set_redirection(addr));
}
bool
target_start_lun(u_int id)
{
- struct lun *new_lun;
- char *name;
-
- if (id >= MAX_LUNS) {
- log_warnx("LUN %u too big for target \"%s\"", id,
- target->t_name);
- return (false);
- }
-
- if (target->t_luns[id] != NULL) {
- log_warnx("duplicate LUN %u for target \"%s\"", id,
- target->t_name);
- return (false);
- }
-
- if (asprintf(&name, "%s,lun,%u", target->t_name, id) <= 0)
- log_err(1, "asprintf");
-
- new_lun = lun_new(conf, name);
- if (new_lun == NULL)
- return (false);
-
- new_lun->set_scsiname(name);
- free(name);
-
- target->t_luns[id] = new_lun;
-
- lun = new_lun;
- return (true);
+ lun = target->start_lun(id);
+ return (lun != nullptr);
}
bool
diff --git a/usr.sbin/ctld/ctld.cc b/usr.sbin/ctld/ctld.cc
index 1dbc6988b9d1..2aaba32ed101 100644
--- a/usr.sbin/ctld/ctld.cc
+++ b/usr.sbin/ctld/ctld.cc
@@ -51,6 +51,7 @@
#include <unistd.h>
#include <cam/scsi/scsi_all.h>
+#include <algorithm>
#include <libutil++.hh>
#include "conf.h"
@@ -101,7 +102,6 @@ conf_new(void)
struct conf *conf;
conf = new struct conf();
- TAILQ_INIT(&conf->conf_targets);
conf->conf_isns_period = 900;
conf->conf_isns_timeout = 5;
@@ -115,12 +115,8 @@ conf_new(void)
void
conf_delete(struct conf *conf)
{
- struct target *targ, *tmp;
-
assert(conf->conf_pidfh == NULL);
- TAILQ_FOREACH_SAFE(targ, &conf->conf_targets, t_next, tmp)
- target_delete(targ);
free(conf->conf_pidfile_path);
delete conf;
}
@@ -410,13 +406,6 @@ auth_group_new(struct conf *conf, const char *name)
return (pair.first->second.get());
}
-auth_group_sp
-auth_group_new(struct target *target)
-{
- return (std::make_shared<auth_group>(freebsd::stringf("target \"%s\"",
- target->t_name)));
-}
-
auth_group_sp
auth_group_find(const struct conf *conf, const char *name)
{
@@ -516,13 +505,13 @@ parse_addr_port(const char *address, const char *def_port)
void
portal_group::add_port(struct portal_group_port *port)
{
- pg_ports.emplace(port->target()->t_name, port);
+ pg_ports.emplace(port->target()->name(), port);
}
void
portal_group::remove_port(struct portal_group_port *port)
{
- auto it = pg_ports.find(port->target()->t_name);
+ auto it = pg_ports.find(port->target()->name());
pg_ports.erase(it);
}
@@ -821,11 +810,10 @@ isns::send_request(int s, struct isns_req req)
static struct isns_req
isns_register_request(struct conf *conf, const char *hostname)
{
- struct target *target;
const struct portal_group *pg;
isns_req req(ISNS_FUNC_DEVATTRREG, ISNS_FLAG_CLIENT, "register");
- req.add_str(32, TAILQ_FIRST(&conf->conf_targets)->t_name);
+ req.add_str(32, conf->conf_first_target->name());
req.add_delim();
req.add_str(1, hostname);
req.add_32(2, 2); /* 2 -- iSCSI */
@@ -840,12 +828,14 @@ isns_register_request(struct conf *conf, const char *hostname)
req.add_port(17, portal->ai());
}
}
- TAILQ_FOREACH(target, &conf->conf_targets, t_next) {
- req.add_str(32, target->t_name);
+ for (const auto &kv : conf->conf_targets) {
+ const struct target *target = kv.second.get();
+
+ req.add_str(32, target->name());
req.add_32(33, 1); /* 1 -- Target*/
- if (target->t_alias != NULL)
- req.add_str(34, target->t_alias);
- for (const port *port : target->t_ports) {
+ if (target->has_alias())
+ req.add_str(34, target->alias());
+ for (const port *port : target->ports()) {
pg = port->portal_group();
if (pg == nullptr)
continue;
@@ -863,7 +853,7 @@ static struct isns_req
isns_check_request(struct conf *conf, const char *hostname)
{
isns_req req(ISNS_FUNC_DEVATTRQRY, ISNS_FLAG_CLIENT, "check");
- req.add_str(32, TAILQ_FIRST(&conf->conf_targets)->t_name);
+ req.add_str(32, conf->conf_first_target->name());
req.add_str(1, hostname);
req.add_delim();
req.add(2, 0, NULL);
@@ -874,7 +864,7 @@ static struct isns_req
isns_deregister_request(struct conf *conf, const char *hostname)
{
isns_req req(ISNS_FUNC_DEVDEREG, ISNS_FLAG_CLIENT, "deregister");
- req.add_str(32, TAILQ_FIRST(&conf->conf_targets)->t_name);
+ req.add_str(32, conf->conf_first_target->name());
req.add_delim();
req.add_str(1, hostname);
return (req);
@@ -887,8 +877,7 @@ isns_register_targets(struct conf *conf, struct isns *isns,
int error;
char hostname[256];
- if (TAILQ_EMPTY(&conf->conf_targets) ||
- conf->conf_portal_groups.empty())
+ if (conf->conf_targets.empty() || conf->conf_portal_groups.empty())
return;
set_timeout(conf->conf_isns_timeout, false);
freebsd::fd_up s = isns->connect();
@@ -900,7 +889,7 @@ isns_register_targets(struct conf *conf, struct isns *isns,
if (error != 0)
log_err(1, "gethostname");
- if (oldconf == NULL || TAILQ_EMPTY(&oldconf->conf_targets))
+ if (oldconf == nullptr || oldconf->conf_first_target == nullptr)
oldconf = conf;
isns->send_request(s, isns_deregister_request(oldconf, hostname));
isns->send_request(s, isns_register_request(conf, hostname));
@@ -914,8 +903,7 @@ isns_check(struct conf *conf, struct isns *isns)
int error;
char hostname[256];
- if (TAILQ_EMPTY(&conf->conf_targets) ||
- conf->conf_portal_groups.empty())
+ if (conf->conf_targets.empty() || conf->conf_portal_groups.empty())
return;
set_timeout(conf->conf_isns_timeout, false);
freebsd::fd_up s = isns->connect();
@@ -941,8 +929,7 @@ isns_deregister_targets(struct conf *conf, struct isns *isns)
int error;
char hostname[256];
- if (TAILQ_EMPTY(&conf->conf_targets) ||
- conf->conf_portal_groups.empty())
+ if (conf->conf_targets.empty() || conf->conf_portal_groups.empty())
return;
set_timeout(conf->conf_isns_timeout, false);
freebsd::fd_up s = isns->connect();
@@ -987,13 +974,13 @@ kports::find_port(std::string_view name)
port::port(struct target *target) :
p_target(target)
{
- target->t_ports.push_back(this);
+ target->add_port(this);
}
void
port::clear_references()
{
- p_target->t_ports.remove(this);
+ p_target->remove_port(this);
}
portal_group_port::portal_group_port(struct target *target,
@@ -1029,7 +1016,7 @@ port_new(struct conf *conf, struct target *target, struct portal_group *pg,
auth_group_sp ag)
{
std::string name = freebsd::stringf("%s-%s", pg->name(),
- target->t_name);
+ target->name());
const auto &pair = conf->conf_ports.try_emplace(name,
std::make_unique<portal_group_port>(target, pg, ag));
if (!pair.second) {
@@ -1045,7 +1032,7 @@ port_new(struct conf *conf, struct target *target, struct portal_group *pg,
uint32_t ctl_port)
{
std::string name = freebsd::stringf("%s-%s", pg->name(),
- target->t_name);
+ target->name());
const auto &pair = conf->conf_ports.try_emplace(name,
std::make_unique<portal_group_port>(target, pg, ctl_port));
if (!pair.second) {
@@ -1060,7 +1047,7 @@ static bool
port_new_pp(struct conf *conf, struct target *target, struct pport *pp)
{
std::string name = freebsd::stringf("%s-%s", pp->name(),
- target->t_name);
+ target->name());
const auto &pair = conf->conf_ports.try_emplace(name,
std::make_unique<kernel_port>(target, pp));
if (!pair.second) {
@@ -1084,7 +1071,7 @@ port_new_ioctl(struct conf *conf, struct kports &kports, struct target *target,
if (pport != NULL)
return (port_new_pp(conf, target, pport));
- std::string name = pname + "-" + target->t_name;
+ std::string name = pname + "-" + target->name();
const auto &pair = conf->conf_ports.try_emplace(name,
std::make_unique<ioctl_port>(target, pp, vp));
if (!pair.second) {
@@ -1107,55 +1094,280 @@ portal_group::find_port(std::string_view target) const
struct target *
target_new(struct conf *conf, const char *name)
{
- struct target *targ;
- int i, len;
+ if (!valid_iscsi_name(name, log_warnx))
+ return (nullptr);
+
+ /*
+ * RFC 3722 requires us to normalize the name to lowercase.
+ */
+ std::string t_name(name);
+ for (char &c : t_name)
+ c = tolower(c);
- targ = target_find(conf, name);
- if (targ != NULL) {
+ auto const &pair = conf->conf_targets.try_emplace(t_name,
+ std::make_unique<target>(conf, t_name));
+ if (!pair.second) {
log_warnx("duplicated target \"%s\"", name);
return (NULL);
}
- if (valid_iscsi_name(name, log_warnx) == false) {
- return (NULL);
+
+ if (conf->conf_first_target == nullptr)
+ conf->conf_first_target = pair.first->second.get();
+ return (pair.first->second.get());
+}
+
+struct target *
+target_find(struct conf *conf, const char *name)
+{
+ auto it = conf->conf_targets.find(name);
+ if (it == conf->conf_targets.end())
+ return (nullptr);
+ return (it->second.get());
+}
+
+bool
+target::use_private_auth(const char *keyword)
+{
+ if (t_private_auth)
+ return (true);
+
+ if (t_auth_group != nullptr) {
+ log_warnx("cannot use both auth-group and %s for target \"%s\"",
+ keyword, name());
+ return (false);
}
- targ = new target();
- targ->t_name = checked_strdup(name);
- /*
- * RFC 3722 requires us to normalize the name to lowercase.
- */
- len = strlen(name);
- for (i = 0; i < len; i++)
- targ->t_name[i] = tolower(targ->t_name[i]);
+ std::string label = freebsd::stringf("target \"%s\"", name());
+ t_auth_group = std::make_shared<struct auth_group>(label);
+ t_private_auth = true;
+ return (true);
+}
+
+bool
+target::add_chap(const char *user, const char *secret)
+{
+ if (!use_private_auth("chap"))
+ return (false);
+ return (t_auth_group->add_chap(user, secret));
+}
+
+bool
+target::add_chap_mutual(const char *user, const char *secret,
+ const char *user2, const char *secret2)
+{
+ if (!use_private_auth("chap-mutual"))
+ return (false);
+ return (t_auth_group->add_chap_mutual(user, secret, user2, secret2));
+}
+
+bool
+target::add_initiator_name(std::string_view name)
+{
+ if (!use_private_auth("initiator-name"))
+ return (false);
+ return (t_auth_group->add_initiator_name(name));
+}
+
+bool
+target::add_initiator_portal(const char *addr)
+{
+ if (!use_private_auth("initiator-portal"))
+ return (false);
+ return (t_auth_group->add_initiator_portal(addr));
+}
+
+bool
+target::add_lun(u_int id, const char *lun_name)
+{
+ struct lun *t_lun;
+
+ if (id >= MAX_LUNS) {
+ log_warnx("LUN %u too big for target \"%s\"", id, name());
+ return (false);
+ }
+
+ if (t_luns[id] != NULL) {
+ log_warnx("duplicate LUN %u for target \"%s\"", id, name());
+ return (false);
+ }
+
+ t_lun = lun_find(t_conf, lun_name);
+ if (t_lun == NULL) {
+ log_warnx("unknown LUN named %s used for target \"%s\"",
+ lun_name, name());
+ return (false);
+ }
+
+ t_luns[id] = t_lun;
+ return (true);
+}
+
+bool
+target::add_portal_group(const char *pg_name, const char *ag_name)
+{
+ struct portal_group *pg;
+ auth_group_sp ag;
+
+ pg = portal_group_find(t_conf, pg_name);
+ if (pg == NULL) {
+ log_warnx("unknown portal-group \"%s\" for target \"%s\"",
+ pg_name, name());
+ return (false);
+ }
+
+ if (ag_name != NULL) {
+ ag = auth_group_find(t_conf, ag_name);
+ if (ag == NULL) {
+ log_warnx("unknown auth-group \"%s\" for target \"%s\"",
+ ag_name, name());
+ return (false);
+ }
+ }
+
+ if (!port_new(t_conf, this, pg, std::move(ag))) {
+ log_warnx("can't link portal-group \"%s\" to target \"%s\"",
+ pg_name, name());
+ return (false);
+ }
+ return (true);
+}
+
+bool
+target::set_alias(std::string_view alias)
+{
+ if (has_alias()) {
+ log_warnx("alias for target \"%s\" specified more than once",
+ name());
+ return (false);
+ }
+ t_alias = alias;
+ return (true);
+}
+
+bool
+target::set_auth_group(const char *ag_name)
+{
+ if (t_auth_group != nullptr) {
+ if (t_private_auth)
+ log_warnx("cannot use both auth-group and explicit "
+ "authorisations for target \"%s\"", name());
+ else
+ log_warnx("auth-group for target \"%s\" "
+ "specified more than once", name());
+ return (false);
+ }
+ t_auth_group = auth_group_find(t_conf, ag_name);
+ if (t_auth_group == nullptr) {
+ log_warnx("unknown auth-group \"%s\" for target \"%s\"",
+ ag_name, name());
+ return (false);
+ }
+ return (true);
+}
+
+bool
+target::set_auth_type(const char *type)
+{
+ if (!use_private_auth("auth-type"))
+ return (false);
+ return (t_auth_group->set_type(type));
+}
+
+bool
+target::set_physical_port(std::string_view pport)
+{
+ if (!t_pport.empty()) {
+ log_warnx("cannot set multiple physical ports for target "
+ "\"%s\"", name());
+ return (false);
+ }
+ t_pport = pport;
+ return (true);
+}
+
+bool
+target::set_redirection(const char *addr)
+{
+ if (!t_redirection.empty()) {
+ log_warnx("cannot set redirection to \"%s\" for "
+ "target \"%s\"; already defined",
+ addr, name());
+ return (false);
+ }
- targ->t_conf = conf;
- TAILQ_INSERT_TAIL(&conf->conf_targets, targ, t_next);
+ t_redirection = addr;
+ return (true);
+}
+
+struct lun *
+target::start_lun(u_int id)
+{
+ struct lun *new_lun;
- return (targ);
+ if (id >= MAX_LUNS) {
+ log_warnx("LUN %u too big for target \"%s\"", id,
+ name());
+ return (nullptr);
+ }
+
+ if (t_luns[id] != NULL) {
+ log_warnx("duplicate LUN %u for target \"%s\"", id,
+ name());
+ return (nullptr);
+ }
+
+ std::string lun_name = freebsd::stringf("%s,lun,%u", name(), id);
+ new_lun = lun_new(t_conf, lun_name.c_str());
+ if (new_lun == nullptr)
+ return (nullptr);
+
+ new_lun->set_scsiname(lun_name.c_str());
+
+ t_luns[id] = new_lun;
+
+ return (new_lun);
}
void
-target_delete(struct target *targ)
+target::add_port(struct port *port)
{
- TAILQ_REMOVE(&targ->t_conf->conf_targets, targ, t_next);
+ t_ports.push_back(port);
+}
- free(targ->t_pport);
- free(targ->t_name);
- free(targ->t_redirection);
- delete targ;
+void
+target::remove_port(struct port *port)
+{
+ t_ports.remove(port);
}
-struct target *
-target_find(struct conf *conf, const char *name)
+void
+target::remove_lun(struct lun *lun)
{
- struct target *targ;
+ /* XXX: clang is not able to deduce the type without the cast. */
+ std::replace(t_luns.begin(), t_luns.end(), lun,
+ static_cast<struct lun *>(nullptr));
+}
- TAILQ_FOREACH(targ, &conf->conf_targets, t_next) {
- if (strcasecmp(targ->t_name, name) == 0)
- return (targ);
+void
+target::verify()
+{
+ if (t_auth_group == nullptr) {
+ t_auth_group = auth_group_find(t_conf, "default");
+ assert(t_auth_group != nullptr);
+ }
+ if (t_ports.empty()) {
+ struct portal_group *pg = portal_group_find(t_conf, "default");
+ assert(pg != NULL);
+ port_new(t_conf, this, pg, nullptr);
}
- return (NULL);
+ bool found = std::any_of(t_luns.begin(), t_luns.end(),
+ [](struct lun *lun) { return (lun != nullptr); });
+ if (!found && t_redirection.empty())
+ log_warnx("no LUNs defined for target \"%s\"", name());
+ if (found && !t_redirection.empty())
+ log_debugx("target \"%s\" contains luns, but configured "
+ "for redirection", name());
}
lun::lun(struct conf *conf, std::string_view name)
@@ -1178,15 +1390,8 @@ lun_new(struct conf *conf, const char *name)
static void
conf_delete_target_luns(struct conf *conf, struct lun *lun)
{
- struct target *targ;
- int i;
-
- TAILQ_FOREACH(targ, &conf->conf_targets, t_next) {
- for (i = 0; i < MAX_LUNS; i++) {
- if (targ->t_luns[i] == lun)
- targ->t_luns[i] = NULL;
- }
- }
+ for (const auto &kv : conf->conf_targets)
+ kv.second->remove_lun(lun);
}
struct lun *
@@ -1518,11 +1723,6 @@ lun::verify()
bool
conf_verify(struct conf *conf)
{
- struct portal_group *pg;
- struct target *targ;
- bool found;
- int i;
-
if (conf->conf_pidfile_path == NULL)
conf->conf_pidfile_path = checked_strdup(DEFAULT_PIDFILE);
@@ -1546,31 +1746,8 @@ conf_verify(struct conf *conf)
}
}
- TAILQ_FOREACH(targ, &conf->conf_targets, t_next) {
- if (targ->t_auth_group == NULL) {
- targ->t_auth_group = auth_group_find(conf,
- "default");
- assert(targ->t_auth_group != NULL);
- }
- if (targ->t_ports.empty()) {
- pg = portal_group_find(conf, "default");
- assert(pg != NULL);
- port_new(conf, targ, pg, nullptr);
- }
- found = false;
- for (i = 0; i < MAX_LUNS; i++) {
- if (targ->t_luns[i] != NULL)
- found = true;
- }
- if (!found && targ->t_redirection == NULL) {
- log_warnx("no LUNs defined for target \"%s\"",
- targ->t_name);
- }
- if (found && targ->t_redirection != NULL) {
- log_debugx("target \"%s\" contains luns, "
- " but configured for redirection",
- targ->t_name);
- }
+ for (auto &kv : conf->conf_targets) {
+ kv.second->verify();
}
for (auto &kv : conf->conf_portal_groups) {
kv.second->verify(conf);
@@ -2361,40 +2538,41 @@ conf_new_from_file(const char *path, bool ucl)
static bool
new_pports_from_conf(struct conf *conf, struct kports &kports)
{
- struct target *targ;
struct pport *pp;
int ret, i_pp, i_vp;
- TAILQ_FOREACH(targ, &conf->conf_targets, t_next) {
- if (!targ->t_pport)
+ for (auto &kv : conf->conf_targets) {
+ struct target *targ = kv.second.get();
+
+ if (!targ->has_pport())
continue;
- ret = sscanf(targ->t_pport, "ioctl/%d/%d", &i_pp, &i_vp);
+ ret = sscanf(targ->pport(), "ioctl/%d/%d", &i_pp, &i_vp);
if (ret > 0) {
if (!port_new_ioctl(conf, kports, targ, i_pp, i_vp)) {
log_warnx("can't create new ioctl port "
- "for target \"%s\"", targ->t_name);
+ "for target \"%s\"", targ->name());
return (false);
}
continue;
}
- pp = kports.find_port(targ->t_pport);
+ pp = kports.find_port(targ->pport());
if (pp == NULL) {
log_warnx("unknown port \"%s\" for target \"%s\"",
- targ->t_pport, targ->t_name);
+ targ->pport(), targ->name());
return (false);
}
if (pp->linked()) {
log_warnx("can't link port \"%s\" to target \"%s\", "
"port already linked to some target",
- targ->t_pport, targ->t_name);
+ targ->pport(), targ->name());
return (false);
}
if (!port_new_pp(conf, targ, pp)) {
log_warnx("can't link port \"%s\" to target \"%s\"",
- targ->t_pport, targ->t_name);
+ targ->pport(), targ->name());
return (false);
}
}
diff --git a/usr.sbin/ctld/ctld.hh b/usr.sbin/ctld/ctld.hh
index 7fb0ed7a8bea..a242a3282b31 100644
--- a/usr.sbin/ctld/ctld.hh
+++ b/usr.sbin/ctld/ctld.hh
@@ -41,6 +41,7 @@
#include <libiscsiutil.h>
#include <libutil.h>
+#include <array>
#include <list>
#include <memory>
#include <string>
@@ -347,16 +348,53 @@ private:
};
struct target {
- TAILQ_ENTRY(target) t_next;
+ target(struct conf *conf, std::string_view name) :
+ t_conf(conf), t_name(name) {}
+
+ bool has_alias() const { return !t_alias.empty(); }
+ bool has_pport() const { return !t_pport.empty(); }
+ bool has_redirection() const { return !t_redirection.empty(); }
+ const char *alias() const { return t_alias.c_str(); }
+ const char *name() const { return t_name.c_str(); }
+ const char *pport() const { return t_pport.c_str(); }
+ bool private_auth() const { return t_private_auth; }
+ const char *redirection() const { return t_redirection.c_str(); }
+
+ struct auth_group *auth_group() const { return t_auth_group.get(); }
+ const std::list<port *> &ports() const { return t_ports; }
+ const struct lun *lun(int idx) const { return t_luns[idx]; }
+
+ bool add_chap(const char *user, const char *secret);
+ bool add_chap_mutual(const char *user, const char *secret,
+ const char *user2, const char *secret2);
+ bool add_initiator_name(std::string_view name);
+ bool add_initiator_portal(const char *addr);
+ bool add_lun(u_int id, const char *lun_name);
+ bool add_portal_group(const char *pg_name, const char *ag_name);
+ bool set_alias(std::string_view alias);
+ bool set_auth_group(const char *ag_name);
+ bool set_auth_type(const char *type);
+ bool set_physical_port(std::string_view pport);
+ bool set_redirection(const char *addr);
+ struct lun *start_lun(u_int id);
+
+ void add_port(struct port *port);
+ void remove_lun(struct lun *lun);
+ void remove_port(struct port *port);
+ void verify();
+
+private:
+ bool use_private_auth(const char *keyword);
+
struct conf *t_conf;
- struct lun *t_luns[MAX_LUNS] = {};
+ std::array<struct lun *, MAX_LUNS> t_luns;
auth_group_sp t_auth_group;
std::list<port *> t_ports;
- char *t_name;
- char *t_alias;
- char *t_redirection;
+ std::string t_name;
+ std::string t_alias;
+ std::string t_redirection;
/* Name of this target's physical port, if any, i.e. "isp0" */
- char *t_pport;
+ std::string t_pport;
bool t_private_auth;
};
@@ -379,11 +417,12 @@ struct conf {
char *conf_pidfile_path = nullptr;
std::unordered_map<std::string, std::unique_ptr<lun>> conf_luns;
- TAILQ_HEAD(, target) conf_targets;
+ std::unordered_map<std::string, std::unique_ptr<target>> conf_targets;
std::unordered_map<std::string, auth_group_sp> conf_auth_groups;
std::unordered_map<std::string, std::unique_ptr<port>> conf_ports;
std::unordered_map<std::string, portal_group_up> conf_portal_groups;
std::unordered_map<std::string, isns> conf_isns;
+ struct target *conf_first_target = nullptr;
int conf_isns_period;
int conf_isns_timeout;
int conf_debug;
@@ -466,7 +505,6 @@ void conf_start(struct conf *new_conf);
bool conf_verify(struct conf *conf);
struct auth_group *auth_group_new(struct conf *conf, const char *name);
-auth_group_sp auth_group_new(struct target *target);
*** 233 LINES SKIPPED ***