ctld: Support multiple physical ports in a target
PR: 293076
Reported by: Ken J. Thomson <thomsonk@yandex.com>
Reviewed by: asomers
Fixes: 969876fcee ("ctld: parse config file independently of getting kernel info")
Sponsored by: Chelsio Communications
Differential Revision: https://reviews.freebsd.org/D55767
This commit is contained in:
@@ -404,9 +404,9 @@ target_set_auth_type(const char *type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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
|
bool
|
||||||
|
|||||||
@@ -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_name(const char *name);
|
||||||
bool target_add_initiator_portal(const char *addr);
|
bool target_add_initiator_portal(const char *addr);
|
||||||
bool target_add_lun(u_int id, const char *name);
|
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_add_portal_group(const char *pg_name, const char *ag_name);
|
||||||
bool target_set_alias(const char *alias);
|
bool target_set_alias(const char *alias);
|
||||||
bool target_set_auth_group(const char *name);
|
bool target_set_auth_group(const char *name);
|
||||||
bool target_set_auth_type(const char *type);
|
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_set_redirection(const char *addr);
|
||||||
bool target_start_lun(u_int id);
|
bool target_start_lun(u_int id);
|
||||||
|
|
||||||
|
|||||||
+37
-35
@@ -1082,9 +1082,9 @@ kports::has_port(std::string_view name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct pport *
|
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())
|
if (it == pports.end())
|
||||||
return (nullptr);
|
return (nullptr);
|
||||||
return (&it->second);
|
return (&it->second);
|
||||||
@@ -1383,14 +1383,16 @@ target::set_auth_type(const char *type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
target::set_physical_port(std::string_view pport)
|
target::add_physical_port(std::string_view pport)
|
||||||
{
|
{
|
||||||
if (!t_pport.empty()) {
|
for (const auto &s : t_pports) {
|
||||||
log_warnx("cannot set multiple physical ports for target "
|
if (s == pport) {
|
||||||
"\"%s\"", name());
|
log_warnx("duplicate physical port \"%s\" for target "
|
||||||
return (false);
|
"\"%s\"", s.c_str(), name());
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
t_pport = pport;
|
t_pports.emplace_back(pport);
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2619,36 +2621,36 @@ conf::add_pports(struct kports &kports)
|
|||||||
for (auto &kv : conf_targets) {
|
for (auto &kv : conf_targets) {
|
||||||
struct target *targ = kv.second.get();
|
struct target *targ = kv.second.get();
|
||||||
|
|
||||||
if (!targ->has_pport())
|
for (const auto &pport : targ->pports()) {
|
||||||
continue;
|
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);
|
continue;
|
||||||
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;
|
pp = kports.find_port(pport);
|
||||||
}
|
if (pp == NULL) {
|
||||||
|
log_warnx("unknown port \"%s\" for %s",
|
||||||
pp = kports.find_port(targ->pport());
|
pport.c_str(), targ->label());
|
||||||
if (pp == NULL) {
|
return (false);
|
||||||
log_warnx("unknown port \"%s\" for %s",
|
}
|
||||||
targ->pport(), targ->label());
|
if (pp->linked()) {
|
||||||
return (false);
|
log_warnx("can't link port \"%s\" to %s, "
|
||||||
}
|
"port already linked to some target",
|
||||||
if (pp->linked()) {
|
pport.c_str(), targ->label());
|
||||||
log_warnx("can't link port \"%s\" to %s, "
|
return (false);
|
||||||
"port already linked to some target",
|
}
|
||||||
targ->pport(), targ->label());
|
if (!add_port(targ, pp)) {
|
||||||
return (false);
|
log_warnx("can't link port \"%s\" to %s",
|
||||||
}
|
pport.c_str(), targ->label());
|
||||||
if (!add_port(targ, pp)) {
|
return (false);
|
||||||
log_warnx("can't link port \"%s\" to %s",
|
}
|
||||||
targ->pport(), targ->label());
|
|
||||||
return (false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (true);
|
return (true);
|
||||||
|
|||||||
@@ -381,17 +381,16 @@ struct target {
|
|||||||
virtual ~target() = default;
|
virtual ~target() = default;
|
||||||
|
|
||||||
bool has_alias() const { return !t_alias.empty(); }
|
bool has_alias() const { return !t_alias.empty(); }
|
||||||
bool has_pport() const { return !t_pport.empty(); }
|
|
||||||
bool has_redirection() const { return !t_redirection.empty(); }
|
bool has_redirection() const { return !t_redirection.empty(); }
|
||||||
const char *alias() const { return t_alias.c_str(); }
|
const char *alias() const { return t_alias.c_str(); }
|
||||||
const char *name() const { return t_name.c_str(); }
|
const char *name() const { return t_name.c_str(); }
|
||||||
const char *label() const { return t_label.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; }
|
bool private_auth() const { return t_private_auth; }
|
||||||
const char *redirection() const { return t_redirection.c_str(); }
|
const char *redirection() const { return t_redirection.c_str(); }
|
||||||
|
|
||||||
struct auth_group *auth_group() const { return t_auth_group.get(); }
|
struct auth_group *auth_group() const { return t_auth_group.get(); }
|
||||||
const std::list<port *> &ports() const { return t_ports; }
|
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]; }
|
const struct lun *lun(int idx) const { return t_luns[idx]; }
|
||||||
|
|
||||||
bool add_chap(const char *user, const char *secret);
|
bool add_chap(const char *user, const char *secret);
|
||||||
@@ -403,12 +402,12 @@ struct target {
|
|||||||
virtual bool add_initiator_portal(const char *) { return false; }
|
virtual bool add_initiator_portal(const char *) { return false; }
|
||||||
virtual bool add_lun(u_int, const char *) { return false; }
|
virtual bool add_lun(u_int, const char *) { return false; }
|
||||||
virtual bool add_namespace(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,
|
virtual bool add_portal_group(const char *pg_name,
|
||||||
const char *ag_name) = 0;
|
const char *ag_name) = 0;
|
||||||
bool set_alias(std::string_view alias);
|
bool set_alias(std::string_view alias);
|
||||||
bool set_auth_group(const char *ag_name);
|
bool set_auth_group(const char *ag_name);
|
||||||
bool set_auth_type(const char *type);
|
bool set_auth_type(const char *type);
|
||||||
bool set_physical_port(std::string_view pport);
|
|
||||||
bool set_redirection(const char *addr);
|
bool set_redirection(const char *addr);
|
||||||
virtual struct lun *start_lun(u_int) { return nullptr; }
|
virtual struct lun *start_lun(u_int) { return nullptr; }
|
||||||
virtual struct lun *start_namespace(u_int) { return nullptr; }
|
virtual struct lun *start_namespace(u_int) { return nullptr; }
|
||||||
@@ -433,8 +432,8 @@ protected:
|
|||||||
std::string t_label;
|
std::string t_label;
|
||||||
std::string t_alias;
|
std::string t_alias;
|
||||||
std::string t_redirection;
|
std::string t_redirection;
|
||||||
/* Name of this target's physical port, if any, i.e. "isp0" */
|
/* Names of this target's physical ports, e.g. "isp0" */
|
||||||
std::string t_pport;
|
std::list<std::string> t_pports;
|
||||||
bool t_private_auth = false;
|
bool t_private_auth = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -582,7 +581,7 @@ private:
|
|||||||
struct kports {
|
struct kports {
|
||||||
bool add_port(std::string &name, uint32_t ctl_port);
|
bool add_port(std::string &name, uint32_t ctl_port);
|
||||||
bool has_port(std::string_view name);
|
bool has_port(std::string_view name);
|
||||||
struct pport *find_port(std::string_view name);
|
struct pport *find_port(const std::string &name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<std::string, struct pport> pports;
|
std::unordered_map<std::string, struct pport> pports;
|
||||||
|
|||||||
@@ -774,7 +774,7 @@ target_port: PORT STR
|
|||||||
{
|
{
|
||||||
bool ok;
|
bool ok;
|
||||||
|
|
||||||
ok = target_set_physical_port($2);
|
ok = target_add_physical_port($2);
|
||||||
free($2);
|
free($2);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return (1);
|
return (1);
|
||||||
|
|||||||
@@ -1255,7 +1255,7 @@ uclparse_target(const char *name, const ucl::Ucl &top)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!target_set_physical_port(obj.string_value().c_str()))
|
if (!target_add_physical_port(obj.string_value().c_str()))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user