git: 7d88b0e3dbe4 - stable/14 - rc.subr: remove the dependency on bsdconfig
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 01 Jun 2025 09:22:25 UTC
The branch stable/14 has been updated by ivy:
URL: https://cgit.FreeBSD.org/src/commit/?id=7d88b0e3dbe46da939bd9f95164b2d332e9fd53d
commit 7d88b0e3dbe46da939bd9f95164b2d332e9fd53d
Author: Lexi Winter <ivy@FreeBSD.org>
AuthorDate: 2025-05-14 14:33:36 +0000
Commit: Lexi Winter <ivy@FreeBSD.org>
CommitDate: 2025-06-01 09:14:52 +0000
rc.subr: remove the dependency on bsdconfig
rc.subr uses sysrc(8) for the 'enable' and 'disable' commands, which
means the entire rc(8) stack depends on bsdconfig. Instead, provide a
minimal amount of rc.conf-editing functionality in rc.subr and use it to
implement these commands.
Reviewed by: des, bapt
Approved by: des (mentor)
Differential Revision: https://reviews.freebsd.org/D50325
(cherry picked from commit f6328f052518d56c01f10e14cd9ef1f2675c01a4)
---
libexec/rc/rc.subr | 102 ++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 86 insertions(+), 16 deletions(-)
diff --git a/libexec/rc/rc.subr b/libexec/rc/rc.subr
index 5140f2a1addc..c6bc6d1a1395 100644
--- a/libexec/rc/rc.subr
+++ b/libexec/rc/rc.subr
@@ -53,6 +53,9 @@ PS="/bin/ps -ww"
JID=0
CPUSET="/bin/cpuset"
+# Cache the services that we loaded with load_rc_config.
+_loaded_services=""
+
# rc_service provides the path to the service script that we are executing.
# This is not being set here in an execution context, necessarily, so it's
# really just a reasonable guess, and it will get overwritten later if
@@ -1102,28 +1105,17 @@ run_rc_command()
;;
enable)
- _out=$(/usr/sbin/sysrc -vs "$name" "$rcvar=YES") &&
- echo "$name enabled in ${_out%%:*}"
+ _out=$(write_rcvar "$rcvar" "YES") &&
+ echo "$name enabled in $_out"
;;
disable)
- _out=$(/usr/sbin/sysrc -vs "$name" "$rcvar=NO") &&
- echo "$name disabled in ${_out%%:*}"
+ _out=$(write_rcvar "$rcvar" "NO") &&
+ echo "$name disabled in $_out"
;;
delete)
- _files=
- for _file in $(/usr/sbin/sysrc -lEs "$name"); do
- _out=$(/usr/sbin/sysrc -Fif $_file "$rcvar") && _files="$_files $_file"
- done
- /usr/sbin/sysrc -x "$rcvar" && echo "$rcvar deleted in ${_files# }"
- # delete file in rc.conf.d if desired and empty.
- checkyesno service_delete_empty || _files=
- for _file in $_files; do
- [ "$_file" = "${_file#*/rc.conf.d/}" ] && continue
- [ $(/usr/bin/stat -f%z $_file) -gt 0 ] && continue
- /bin/rm "$_file" && echo "Empty file $_file removed"
- done
+ delete_rcvar "$rcvar"
;;
status)
@@ -1540,6 +1532,7 @@ load_rc_config()
# If a service name was specified, attempt to load
# service-specific configuration
if [ -n "$_name" ] ; then
+ _loaded_services="${_loaded_services} ${_name}"
for _d in /etc ${local_startup}; do
_d=${_d%/rc.d}
if [ -f ${_d}/rc.conf.d/"$_name" ]; then
@@ -2293,6 +2286,83 @@ _echoonce()
esac
}
+# _find_rcvar var
+# Find the rc.conf file (other than /etc/defaults/rc.conf) that sets $var.
+_find_rcvar()
+{
+ local _var _dir _files
+
+ [ -n "$1" ] || return 1
+ _var="$1"; shift
+
+ _files="/etc/rc.conf"
+ for _dir in /etc ${local_startup}; do
+ for _name in $_loaded_services; do
+ _files="${_dir%/rc.d}/rc.conf.d/${_name} ${_files}"
+ done
+ done
+
+ /usr/bin/grep 2>/dev/null -rl "^${_var}=" $_files | /usr/bin/head -1
+}
+
+# write_rcvar var value
+# Add or replace the rc var $var with the value $value.
+# Look for a current setting of $var in /etc/rc.conf or /etc/rc.conf.d/$name,
+# and if found, modify it there; otherwise, append to /etc/rc.conf.
+write_rcvar()
+{
+ local _var _value _file _dir
+
+ [ -n "$1" ] || return 1
+ _var="$1"; shift
+ [ -n "$1" ] || return 1
+ _value="$1"; shift
+
+ _file="$(_find_rcvar "$_var")"
+ if [ -n "$_file" ]; then
+ local _=$'\01'
+ /usr/bin/sed -i '' "s${_}^${_var}=.*${_}${_var}=\"$_value\"${_}" "$_file"
+ echo $_file
+ return
+ fi
+
+ for _dir in /etc ${local_startup}; do
+ _file="${_dir%/rc.d}/rc.conf.d/${name}"
+ if [ -f "$_file" ]; then
+ echo "${_var}=\"${_value}\"" >>"$_file"
+ echo "$_file"
+ return
+ fi
+ done
+
+ echo "${_var}=\"${_value}\"" >>/etc/rc.conf
+ echo "/etc/rc.conf"
+}
+
+# delete_rcvar var
+# Remove the rc var $var.
+# Look for a current setting of $var in /etc/rc.conf or /etc/rc.conf.d/$name,
+# and if found, remove it. If service_delete_empty is enabled, and the
+# resulting file is empty, also delete the file.
+delete_rcvar()
+{
+ local _var _files
+
+ [ -n "$1" ] || return 1
+ _var="$1"; shift
+
+ _file="$(_find_rcvar "$_var")"
+ if [ -n "$_file" ]; then
+ /usr/bin/sed -i '' "/^${_var}=/d" "$_file"
+ echo "$_var deleted in $_file"
+
+ if checkyesno service_delete_empty && [ ! -s "$_file" ]; then
+ /bin/rm -f "$_file"
+ echo "Empty file $_file removed"
+ fi
+ fi
+}
+
# If the loader env variable rc.debug is set, turn on debugging. rc.conf will
# still override this, but /etc/defaults/rc.conf can't unconditionally set this
# since it would undo what we've done here.