ctld: Refactor ioctl port handling
- Normalize ioctl port names when the port name is first added to the configuration. This can catch potential duplicate port names sooner and helps with other parts of this change. - When recognizing existing ioctl ports, always expand the name to include the physical and virtual port numbers. This permits binding ioctl/0/0 or ioctl/1/0 to a target, for example. - When adding physical ports to a target, first check for an existing kernel port to reuse. This handles both ioctl and non-ioctl ports and removes the need for the conf::add_port method for ioctl ports to check in kports. - If an existing kport isn't found when adding physical ports, check to see if the port name is an ioctl port. If so, call conf::add_port to add an ioctl port. This add_port method overload is now simpler as it always creates a new port. NB: The kernel_port class handles CTL ports that already existed before ctld started including existing ioctl ports, whereas the ioctl_port class handles ioctl ports that are created and completely managed by ctld. This was true before this change but is perhaps more obvious after this change. Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D57092
This commit is contained in:
+49
-31
@@ -1180,16 +1180,8 @@ conf::add_port(struct target *target, struct pport *pp)
|
||||
}
|
||||
|
||||
bool
|
||||
conf::add_port(struct kports &kports, struct target *target, int pp, int vp)
|
||||
conf::add_port(struct target *target, const std::string &pname, int pp, int vp)
|
||||
{
|
||||
struct pport *pport;
|
||||
|
||||
std::string pname = freebsd::stringf("ioctl/%d/%d", pp, vp);
|
||||
|
||||
pport = kports.find_port(pname);
|
||||
if (pport != NULL)
|
||||
return (add_port(target, pport));
|
||||
|
||||
std::string name = pname + "-" + target->name();
|
||||
const auto &pair = conf_ports.try_emplace(name,
|
||||
std::make_unique<ioctl_port>(target, pp, vp));
|
||||
@@ -1387,6 +1379,19 @@ target::set_auth_type(const char *type)
|
||||
bool
|
||||
target::add_physical_port(std::string_view pport)
|
||||
{
|
||||
/* Normalize ioctl port names. */
|
||||
std::string pname;
|
||||
if (pport.compare(0, strlen("ioctl/"), "ioctl/") == 0) {
|
||||
int ret, pp, vp;
|
||||
|
||||
pname = std::string(pport);
|
||||
ret = sscanf(pname.c_str(), "ioctl/%d/%d", &pp, &vp);
|
||||
if (ret == 2) {
|
||||
pname = freebsd::stringf("ioctl/%d/%d", pp, vp);
|
||||
pport = pname;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &s : t_pports) {
|
||||
if (s == pport) {
|
||||
log_warnx("duplicate physical port \"%s\" for target "
|
||||
@@ -2643,35 +2648,48 @@ conf::add_pports(struct kports &kports)
|
||||
struct target *targ = kv.second.get();
|
||||
|
||||
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());
|
||||
/*
|
||||
* If this port is already present in the
|
||||
* kernel, reuse the existing port.
|
||||
*/
|
||||
pp = kports.find_port(pport);
|
||||
if (pp != nullptr) {
|
||||
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);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
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);
|
||||
/*
|
||||
* If this port is an ioctl port, create a new
|
||||
* port.
|
||||
*/
|
||||
ret = sscanf(pport.c_str(), "ioctl/%d/%d", &i_pp,
|
||||
&i_vp);
|
||||
if (ret == 2) {
|
||||
if (!add_port(targ, pport, i_pp, i_vp)) {
|
||||
log_warnx("can't create new port %s "
|
||||
"for %s", pport.c_str(),
|
||||
targ->label());
|
||||
return (false);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
log_warnx("unknown port \"%s\" for %s",
|
||||
pport.c_str(), targ->label());
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
return (true);
|
||||
|
||||
@@ -487,7 +487,7 @@ struct conf {
|
||||
bool add_port(struct target *target, struct portal_group *pg,
|
||||
uint32_t ctl_port);
|
||||
bool add_port(struct target *target, struct pport *pp);
|
||||
bool add_port(struct kports &kports, struct target *target, int pp,
|
||||
bool add_port(struct target *target, const std::string &pname, int pp,
|
||||
int vp);
|
||||
bool add_pports(struct kports &kports);
|
||||
|
||||
|
||||
@@ -549,7 +549,10 @@ conf_new_from_kernel(struct kports &kports)
|
||||
continue;
|
||||
|
||||
std::string name = port.port_name;
|
||||
if (port.pp != 0 || port.vp != 0) {
|
||||
if (port.port_frontend == "ioctl")
|
||||
name += "/" + std::to_string(port.pp) + "/" +
|
||||
std::to_string(port.vp);
|
||||
else if (port.pp != 0 || port.vp != 0) {
|
||||
name += "/" + std::to_string(port.pp);
|
||||
if (port.vp != 0)
|
||||
name += "/" + std::to_string(port.vp);
|
||||
|
||||
Reference in New Issue
Block a user