The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=2bb9180bb5d0054bf79529d6a1cb56b61a94629a
commit 2bb9180bb5d0054bf79529d6a1cb56b61a94629a Author: John Baldwin <j...@freebsd.org> AuthorDate: 2025-08-04 19:38:07 +0000 Commit: John Baldwin <j...@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 ***