The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=f1c5de5fab9d5cada11935418db11e19ebff7e34
commit f1c5de5fab9d5cada11935418db11e19ebff7e34 Author: John Baldwin <[email protected]> AuthorDate: 2026-05-18 19:48:09 +0000 Commit: John Baldwin <[email protected]> CommitDate: 2026-05-18 19:49:35 +0000 ctld: Add a dedicated conf method for shutting down Currently the main loop creates an empty config and applies it to force a shutdown of all of the existing configuration. While this is functional and does avoid duplicating some code, it is also a bit clunky and requires a special hack in the pidfile path handling in the conf::apply method. Instead, use a dedicated conf::shutdown method which tears down the CTL ports and LUNs and closes the sockets. Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D56532 --- usr.sbin/ctld/ctld.cc | 56 ++++++++++++++++++++++++++++++++++++--------------- usr.sbin/ctld/ctld.hh | 1 + 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/usr.sbin/ctld/ctld.cc b/usr.sbin/ctld/ctld.cc index 627ecf8bba93..24b02a936670 100644 --- a/usr.sbin/ctld/ctld.cc +++ b/usr.sbin/ctld/ctld.cc @@ -1976,11 +1976,9 @@ conf::apply(struct conf *oldconf) /* * Rename the pidfile if the pathname changes. On startup, * oldconf created via conf_new_from_kernel will not contain a - * valid pidfile_path. On shutdown, the temporary newconf - * will not contain a valid pidfile_path. + * valid pidfile_path. */ - if (!oldconf->conf_pidfile_path.empty() && - !conf_pidfile_path.empty()) { + if (!oldconf->conf_pidfile_path.empty()) { if (oldconf->conf_pidfile_path != conf_pidfile_path) { /* pidfile has changed. rename it */ log_debugx("moving pidfile to %s", @@ -2210,6 +2208,41 @@ conf::apply(struct conf *oldconf) return (cumulated_error); } +void +conf::shutdown() +{ + /* Deregister from iSNS servers. */ + for (auto &kv : conf_isns) + isns_deregister_targets(&kv.second); + + /* Remove all ports. */ + for (const auto &kv : conf_ports) { + const std::string &name = kv.first; + port *port = kv.second.get(); + + if (port->is_dummy()) + continue; + log_debugx("removing port \"%s\"", name.c_str()); + if (!port->kernel_remove()) + log_warnx("failed to remove port %s", name.c_str()); + } + + /* Remove all LUNs. */ + for (const auto &kv : conf_luns) { + struct lun *lun = kv.second.get(); + + if (!lun->kernel_remove()) + log_warnx("failed to remove lun \"%s\", CTL lun %d", + lun->name(), lun->ctl_lun()); + } + + /* Close sockets on all portal groups. */ + for (auto &kv : conf_portal_groups) + kv.second->close_sockets(); + for (auto &kv : conf_transport_groups) + kv.second->close_sockets(); +} + bool timed_out(void) { @@ -2767,21 +2800,12 @@ main(int argc, char **argv) oldconf.reset(); } } else if (sigterm_received) { - log_debugx("exiting on signal; " - "reloading empty configuration"); + log_debugx("exiting on signal"); - log_debugx("removing CTL iSCSI ports " + log_debugx("removing CTL iSCSI and NVMeoF ports " "and terminating all connections"); - oldconf = std::move(newconf); - newconf = std::make_unique<conf>(); - if (debug > 0) - newconf->set_debug(debug); - error = newconf->apply(oldconf.get()); - if (error != 0) - log_warnx("failed to apply configuration"); - oldconf.reset(); - + newconf->shutdown(); log_warnx("exiting on signal"); return (0); } else { diff --git a/usr.sbin/ctld/ctld.hh b/usr.sbin/ctld/ctld.hh index d3b08dc12603..7ae033804157 100644 --- a/usr.sbin/ctld/ctld.hh +++ b/usr.sbin/ctld/ctld.hh @@ -513,6 +513,7 @@ struct conf { int apply(struct conf *oldconf); void delete_target_luns(struct lun *lun); bool reuse_portal_group_socket(struct portal &newp); + void shutdown(); bool verify(); private:
