git: caef3c50ac06 - main - ctld: Refactor ioctl port handling
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 27 May 2026 21:00:33 UTC
The branch main has been updated by jhb:
URL: https://cgit.FreeBSD.org/src/commit/?id=caef3c50ac067ca751ba4950f310821a521ebf57
commit caef3c50ac067ca751ba4950f310821a521ebf57
Author: John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2026-05-27 20:57:23 +0000
Commit: John Baldwin <jhb@FreeBSD.org>
CommitDate: 2026-05-27 20:57:23 +0000
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
---
usr.sbin/ctld/ctld.cc | 80 ++++++++++++++++++++++++++++++-------------------
usr.sbin/ctld/ctld.hh | 2 +-
usr.sbin/ctld/kernel.cc | 5 +++-
3 files changed, 54 insertions(+), 33 deletions(-)
diff --git a/usr.sbin/ctld/ctld.cc b/usr.sbin/ctld/ctld.cc
index 9bdf15976911..8b99bde14911 100644
--- a/usr.sbin/ctld/ctld.cc
+++ b/usr.sbin/ctld/ctld.cc
@@ -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);
diff --git a/usr.sbin/ctld/ctld.hh b/usr.sbin/ctld/ctld.hh
index 7ae033804157..8d63de06dd80 100644
--- a/usr.sbin/ctld/ctld.hh
+++ b/usr.sbin/ctld/ctld.hh
@@ -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);
diff --git a/usr.sbin/ctld/kernel.cc b/usr.sbin/ctld/kernel.cc
index 59a339e1c96b..8c5c447f3e80 100644
--- a/usr.sbin/ctld/kernel.cc
+++ b/usr.sbin/ctld/kernel.cc
@@ -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);