Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 May 2026 21:00:33 +0000
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: caef3c50ac06 - main - ctld: Refactor ioctl port handling
Message-ID:  <6a175b71.23698.7ab2b30a@gitrepo.freebsd.org>

index | next in thread | raw e-mail

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);


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a175b71.23698.7ab2b30a>