The branch stable/15 has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=8071cdf83451f112ce17da3f429c8ae86699d7e5
commit 8071cdf83451f112ce17da3f429c8ae86699d7e5 Author: John Baldwin <[email protected]> AuthorDate: 2026-04-20 17:19:25 +0000 Commit: John Baldwin <[email protected]> CommitDate: 2026-06-23 16:05:37 +0000 ctld: Support multiple physical ports in a target PR: 293076 Reported by: Ken J. Thomson <[email protected]> Reviewed by: asomers Fixes: 969876fcee57 ("ctld: parse config file independently of getting kernel info") Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D55767 (cherry picked from commit 7bb2b3801554a58039ed9d1fd05b65ce24c6c661) --- usr.sbin/ctld/conf.cc | 4 +-- usr.sbin/ctld/conf.h | 2 +- usr.sbin/ctld/ctld.cc | 72 ++++++++++++++++++++++++----------------------- usr.sbin/ctld/ctld.hh | 11 ++++---- usr.sbin/ctld/parse.y | 2 +- usr.sbin/ctld/uclparse.cc | 2 +- 6 files changed, 47 insertions(+), 46 deletions(-) diff --git a/usr.sbin/ctld/conf.cc b/usr.sbin/ctld/conf.cc index 56a149a58a25..a2c00525826b 100644 --- a/usr.sbin/ctld/conf.cc +++ b/usr.sbin/ctld/conf.cc @@ -404,9 +404,9 @@ target_set_auth_type(const char *type) } bool -target_set_physical_port(const char *pport) +target_add_physical_port(const char *pport) { - return (target->set_physical_port(pport)); + return (target->add_physical_port(pport)); } bool diff --git a/usr.sbin/ctld/conf.h b/usr.sbin/ctld/conf.h index 642c8f234d30..7eaee4f9871c 100644 --- a/usr.sbin/ctld/conf.h +++ b/usr.sbin/ctld/conf.h @@ -83,11 +83,11 @@ bool target_add_chap_mutual(const char *user, const char *secret, bool target_add_initiator_name(const char *name); bool target_add_initiator_portal(const char *addr); bool target_add_lun(u_int id, const char *name); +bool target_add_physical_port(const char *pport); bool target_add_portal_group(const char *pg_name, const char *ag_name); bool target_set_alias(const char *alias); bool target_set_auth_group(const char *name); bool target_set_auth_type(const char *type); -bool target_set_physical_port(const char *pport); bool target_set_redirection(const char *addr); bool target_start_lun(u_int id); diff --git a/usr.sbin/ctld/ctld.cc b/usr.sbin/ctld/ctld.cc index 336aedd68aab..2dda88f97b73 100644 --- a/usr.sbin/ctld/ctld.cc +++ b/usr.sbin/ctld/ctld.cc @@ -1097,9 +1097,9 @@ kports::has_port(std::string_view name) } struct pport * -kports::find_port(std::string_view name) +kports::find_port(const std::string &name) { - auto it = pports.find(std::string(name)); + auto it = pports.find(name); if (it == pports.end()) return (nullptr); return (&it->second); @@ -1398,14 +1398,16 @@ target::set_auth_type(const char *type) } bool -target::set_physical_port(std::string_view pport) +target::add_physical_port(std::string_view pport) { - if (!t_pport.empty()) { - log_warnx("cannot set multiple physical ports for target " - "\"%s\"", name()); - return (false); + for (const auto &s : t_pports) { + if (s == pport) { + log_warnx("duplicate physical port \"%s\" for target " + "\"%s\"", s.c_str(), name()); + return (false); + } } - t_pport = pport; + t_pports.emplace_back(pport); return (true); } @@ -2634,36 +2636,36 @@ conf::add_pports(struct kports &kports) for (auto &kv : conf_targets) { struct target *targ = kv.second.get(); - if (!targ->has_pport()) - continue; + for (const auto &pport : targ->pports()) { + ret = sscanf(pport.c_str(), "ioctl/%d/%d", &i_pp, + &i_vp); + if (ret > 0) { + if (!add_port(kports, targ, i_pp, i_vp)) { + log_warnx("can't create new ioctl port " + "for %s", targ->label()); + return (false); + } - ret = sscanf(targ->pport(), "ioctl/%d/%d", &i_pp, &i_vp); - if (ret > 0) { - if (!add_port(kports, targ, i_pp, i_vp)) { - log_warnx("can't create new ioctl port " - "for %s", targ->label()); - return (false); + continue; } - continue; - } - - pp = kports.find_port(targ->pport()); - if (pp == NULL) { - log_warnx("unknown port \"%s\" for %s", - targ->pport(), targ->label()); - return (false); - } - if (pp->linked()) { - log_warnx("can't link port \"%s\" to %s, " - "port already linked to some target", - targ->pport(), targ->label()); - return (false); - } - if (!add_port(targ, pp)) { - log_warnx("can't link port \"%s\" to %s", - targ->pport(), targ->label()); - return (false); + pp = kports.find_port(pport); + if (pp == NULL) { + log_warnx("unknown port \"%s\" for %s", + pport.c_str(), targ->label()); + return (false); + } + if (pp->linked()) { + log_warnx("can't link port \"%s\" to %s, " + "port already linked to some target", + pport.c_str(), targ->label()); + return (false); + } + if (!add_port(targ, pp)) { + log_warnx("can't link port \"%s\" to %s", + pport.c_str(), targ->label()); + return (false); + } } } return (true); diff --git a/usr.sbin/ctld/ctld.hh b/usr.sbin/ctld/ctld.hh index 2e1ee7869ceb..a88ef7eac96e 100644 --- a/usr.sbin/ctld/ctld.hh +++ b/usr.sbin/ctld/ctld.hh @@ -383,17 +383,16 @@ struct target { virtual ~target() = default; 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 *label() const { return t_label.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 std::list<std::string> &pports() const { return t_pports; } const struct lun *lun(int idx) const { return t_luns[idx]; } bool add_chap(const char *user, const char *secret); @@ -405,12 +404,12 @@ struct target { virtual bool add_initiator_portal(const char *) { return false; } virtual bool add_lun(u_int, const char *) { return false; } virtual bool add_namespace(u_int, const char *) { return false; } + bool add_physical_port(std::string_view pport); virtual bool add_portal_group(const char *pg_name, const char *ag_name) = 0; 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); virtual struct lun *start_lun(u_int) { return nullptr; } virtual struct lun *start_namespace(u_int) { return nullptr; } @@ -435,8 +434,8 @@ protected: std::string t_label; std::string t_alias; std::string t_redirection; - /* Name of this target's physical port, if any, i.e. "isp0" */ - std::string t_pport; + /* Names of this target's physical ports, e.g. "isp0" */ + std::list<std::string> t_pports; bool t_private_auth = false; }; @@ -584,7 +583,7 @@ private: struct kports { bool add_port(std::string &name, uint32_t ctl_port); bool has_port(std::string_view name); - struct pport *find_port(std::string_view name); + struct pport *find_port(const std::string &name); private: std::unordered_map<std::string, struct pport> pports; diff --git a/usr.sbin/ctld/parse.y b/usr.sbin/ctld/parse.y index 5725c16b459a..05171d3aa159 100644 --- a/usr.sbin/ctld/parse.y +++ b/usr.sbin/ctld/parse.y @@ -774,7 +774,7 @@ target_port: PORT STR { bool ok; - ok = target_set_physical_port($2); + ok = target_add_physical_port($2); free($2); if (!ok) return (1); diff --git a/usr.sbin/ctld/uclparse.cc b/usr.sbin/ctld/uclparse.cc index 8a62636ffec6..0c6b2af8d741 100644 --- a/usr.sbin/ctld/uclparse.cc +++ b/usr.sbin/ctld/uclparse.cc @@ -1255,7 +1255,7 @@ uclparse_target(const char *name, const ucl::Ucl &top) return false; } - if (!target_set_physical_port(obj.string_value().c_str())) + if (!target_add_physical_port(obj.string_value().c_str())) return false; }
