From 3b583b79679e496cacb99dc8379917a79be1914e Mon Sep 17 00:00:00 2001 From: dougb Date: Wed, 21 Dec 2005 07:11:35 +0000 Subject: [PATCH] MFC the inclusion of scripts from the local_startup directories into the base rcorder, and related changes. --- UPDATING | 10 ++++ etc/defaults/rc.conf | 5 ++ etc/rc | 46 ++++++++++++++--- etc/rc.d/Makefile | 2 +- etc/rc.d/devfs | 2 +- etc/rc.d/dumpon | 1 - etc/rc.d/initrandom | 1 - etc/rc.d/localpkg | 37 ++------------ etc/rc.d/rcconf.sh | 12 ----- etc/rc.d/resolv | 1 - etc/rc.shutdown | 8 ++- etc/rc.subr | 42 +++++++++++++++- share/man/man5/rc.conf.5 | 27 ++++++++++ share/man/man8/diskless.8 | 14 +++++- share/man/man8/rc.8 | 101 ++++++++++++++++---------------------- sys/sys/param.h | 2 +- 16 files changed, 192 insertions(+), 119 deletions(-) delete mode 100644 etc/rc.d/rcconf.sh diff --git a/UPDATING b/UPDATING index 2508d7b56e18..a9d335775c6c 100644 --- a/UPDATING +++ b/UPDATING @@ -8,6 +8,16 @@ Items affecting the ports and packages system can be found in /usr/ports/UPDATING. Please read that file before running portupgrade. +20051220: + Scripts in the local_startup directories (as defined in + /etc/defaults/rc.conf) that have the new rc.d semantics will + now be run as part of the base system rcorder. If there are + errors or problems with one of these local scripts, it could + cause boot problems. If you encounter such problems, boot in + single user mode, remove that script from the */rc.d directory. + Please report the problem to the port's maintainer, and the + freebsd-ports@freebsd.org mailing list. + 20051101: FreeBSD 6.0-RELEASE diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index 7f851ef0e306..ddfa971cb07f 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -24,6 +24,11 @@ rc_debug="NO" # Set to YES to enable debugging output from rc.d rc_info="NO" # Enables display of informational messages at boot. rcshutdown_timeout="30" # Seconds to wait before terminating rc.shutdown +early_late_divider="mountcritlocal" # Script that separates early/late + # stages of the boot process. Make sure you know + # the ramifications if you change this. + # See rc.conf(5) for more details. + swapfile="NO" # Set to name of swapfile if aux swapfile desired. apm_enable="NO" # Set to YES to enable APM BIOS functions (or NO). apmd_enable="NO" # Run apmd to handle APM event from userland. diff --git a/etc/rc b/etc/rc index bc2e6f906cff..ea7d502f01dc 100644 --- a/etc/rc +++ b/etc/rc @@ -50,12 +50,6 @@ HOME=/ PATH=/sbin:/bin:/usr/sbin:/usr/bin export HOME PATH -. /etc/rc.subr - -# Note: the system configuration files are loaded as part of -# the RCNG system (rc.d/rcconf.sh). Do not load them here as it may -# interfere with diskless booting. -# if [ "$1" = autoboot ]; then autoboot=yes _boot="faststart" @@ -70,12 +64,52 @@ if [ ${dlv:=0} -ne 0 -o -f /etc/diskless ]; then sh /etc/rc.initdiskless fi +# Run these after determining whether we are booting diskless in order +# to minimize the number of files that are needed on a diskless system, +# and to make the configuration file variables available to rc itself. +# +. /etc/rc.subr +echo "Loading configuration files." +load_rc_config 'XXX' + skip="-s nostart" [ `/sbin/sysctl -n security.jail.jailed` -eq 1 ] && skip="$skip -s nojail" + +# Do a first pass to get everything up to $early_late_divider so that +# we can do a second pass that includes $local_startup directories +# files=`rcorder ${skip} /etc/rc.d/* 2>/dev/null` for _rc_elem in ${files}; do run_rc_script ${_rc_elem} ${_boot} + + case "$_rc_elem" in + */${early_late_divider}) break ;; + esac +done + +unset files local_rc + +# Now that disks are mounted, for each dir in $local_startup +# search for init scripts that use the new rc.d semantics. +# +case ${local_startup} in +[Nn][Oo] | '') ;; +*) find_local_scripts_new ;; +esac + +files=`rcorder ${skip} /etc/rc.d/* ${local_rc} 2>/dev/null` +_skip_early=1 +for _rc_elem in ${files}; do + case "$_skip_early" in + 1) case "$_rc_elem" in + */${early_late_divider}) _skip_early=0 ;; + esac + continue + ;; + esac + + run_rc_script ${_rc_elem} ${_boot} done echo '' diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile index 71523befd629..92d1d7fff018 100755 --- a/etc/rc.d/Makefile +++ b/etc/rc.d/Makefile @@ -29,7 +29,7 @@ FILES= DAEMON LOGIN NETWORKING SERVERS \ pccard pcvt pf pflog pfsync \ powerd power_profile ppp-user pppoed pwcheck \ quota \ - ramdisk ramdisk-own random rarpd rcconf.sh resolv root \ + ramdisk ramdisk-own random rarpd resolv root \ route6d routed routing rpcbind rtadvd rwho \ savecore sdpd securelevel sendmail \ serial sppp swap1 \ diff --git a/etc/rc.d/devfs b/etc/rc.d/devfs index d74e988e4efd..e7a607112449 100644 --- a/etc/rc.d/devfs +++ b/etc/rc.d/devfs @@ -4,7 +4,7 @@ # # PROVIDE: devfs -# REQUIRE: rcconf mountcritremote +# REQUIRE: mountcritremote # BEFORE: SERVERS securelevel # KEYWORD: nojail diff --git a/etc/rc.d/dumpon b/etc/rc.d/dumpon index 7697eab20400..cc049ec89a00 100644 --- a/etc/rc.d/dumpon +++ b/etc/rc.d/dumpon @@ -4,7 +4,6 @@ # # PROVIDE: dumpon -# REQUIRE: rcconf # BEFORE: disks savecore initrandom # KEYWORD: nojail diff --git a/etc/rc.d/initrandom b/etc/rc.d/initrandom index 2c8dc525f98d..a336cb85ef30 100644 --- a/etc/rc.d/initrandom +++ b/etc/rc.d/initrandom @@ -4,7 +4,6 @@ # # PROVIDE: initrandom -# REQUIRE: rcconf # BEFORE: disks # KEYWORD: nojail diff --git a/etc/rc.d/localpkg b/etc/rc.d/localpkg index c4ade879024b..0eba5239fa1c 100644 --- a/etc/rc.d/localpkg +++ b/etc/rc.d/localpkg @@ -23,29 +23,16 @@ pkg_start() ;; *) echo -n 'Local package initialization:' - slist="" - if [ -z "${script_name_sep}" ]; then - script_name_sep=" " - fi - for dir in ${local_startup}; do - if [ -d "${dir}" ]; then - for script in ${dir}/*.sh; do - slist="${slist}${script_name_sep}${script}" - done - fi - done - script_save_sep="$IFS" - IFS="${script_name_sep}" - for script in ${slist}; do + find_local_scripts_old + for script in ${zlist} ${slist}; do if [ -x "${script}" ]; then (set -T trap 'exit 1' 2 ${script} start) elif [ -f "${script}" -o -L "${script}" ]; then - echo -n " (skipping ${script##*/}, not executable)" + echo -n " (skipping ${script}, not executable)" fi done - IFS="${script_save_sep}" echo '.' ;; esac @@ -53,33 +40,19 @@ pkg_start() pkg_stop() { - # For each dir in $local_startup, search for init scripts matching *.sh case ${local_startup} in [Nn][Oo] | '') ;; *) echo -n 'Shutting down daemon processes:' - slist="" - if [ -z "${script_name_sep}" ]; then - script_name_sep=" " - fi - for dir in ${local_startup}; do - if [ -d "${dir}" ]; then - for script in ${dir}/*.sh; do - slist="${slist}${script_name_sep}${script}" - done - fi - done - script_save_sep="$IFS" - IFS="${script_name_sep}" - for script in `reverse_list ${slist}`; do + find_local_scripts_old + for script in `reverse_list ${slist} ${zlist}`; do if [ -x "${script}" ]; then (set -T trap 'exit 1' 2 ${script} stop) fi done - IFS="${script_save_sep}" echo '.' ;; esac diff --git a/etc/rc.d/rcconf.sh b/etc/rc.d/rcconf.sh deleted file mode 100644 index fdcd95b29958..000000000000 --- a/etc/rc.d/rcconf.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -# -# $FreeBSD$ -# - -# PROVIDE: rcconf -# BEFORE: disks initrandom - -. /etc/rc.subr - -echo "Loading configuration files." -load_rc_config 'XXX' diff --git a/etc/rc.d/resolv b/etc/rc.d/resolv index d2d637119dd0..08e775f0ee5d 100644 --- a/etc/rc.d/resolv +++ b/etc/rc.d/resolv @@ -28,7 +28,6 @@ # # PROVIDE: resolv -# REQUIRE: rcconf # KEYWORD: nojail . /etc/rc.subr diff --git a/etc/rc.shutdown b/etc/rc.shutdown index 075881f3d4f4..ebe79d74132b 100644 --- a/etc/rc.shutdown +++ b/etc/rc.shutdown @@ -82,7 +82,13 @@ fi # rcorder_opts="-k shutdown" [ `/sbin/sysctl -n security.jail.jailed` -eq 1 ] && rcorder_opts="$rcorder_opts -s nojail" -files=`rcorder ${rcorder_opts} /etc/rc.d/* 2>/dev/null` + +case ${local_startup} in +[Nn][Oo] | '') ;; +*) find_local_scripts_new ;; +esac + +files=`rcorder ${rcorder_opts} /etc/rc.d/* ${local_rc} 2>/dev/null` for _rc_elem in `reverse_list $files`; do debug "run_rc_script $_rc_elem faststop" diff --git a/etc/rc.subr b/etc/rc.subr index beddb1628eed..7c77cc801f7d 100644 --- a/etc/rc.subr +++ b/etc/rc.subr @@ -832,10 +832,10 @@ run_rc_script() eval unset ${_arg}_cmd ${_arg}_precmd ${_arg}_postcmd case "$_file" in - *.sh) # run in current shell + /etc/rc.d/*.sh) # run in current shell set $_arg; . $_file ;; - *[~#]|*.OLD|*.orig|*,v) # scratch file; skip + *[~#]|*.OLD|*.bak|*.orig|*,v) # scratch file; skip warn "Ignoring scratch file $_file" ;; *) # run in subshell @@ -1355,4 +1355,42 @@ geli_make_list() echo ${devices2} } +# Find scripts in local_startup directories that use the old syntax +# +find_local_scripts_old () { + zlist='' + slist='' + for dir in ${local_startup}; do + if [ -d "${dir}" ]; then + for file in ${dir}/[0-9]*.sh; do + grep '^# PROVIDE:' $file >/dev/null 2>&1 && + continue + zlist="$zlist $file" + done + for file in ${dir}/[^0-9]*.sh; do + grep '^# PROVIDE:' $file >/dev/null 2>&1 && + continue + slist="$slist $file" + done + fi + done +} + +find_local_scripts_new () { + local_rc='' + for dir in ${local_startup}; do + if [ -d "${dir}" ]; then + for file in `grep -l '^# PROVIDE:' ${dir}/* 2>/dev/null`; do + case "$file" in + *.sample) ;; + *) if [ -x "$file" ]; then + local_rc="${local_rc} ${file}" + fi + ;; + esac + done + fi + done +} + fi diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5 index 6575ed798735..cb4ad13c9ac5 100644 --- a/share/man/man5/rc.conf.5 +++ b/share/man/man5/rc.conf.5 @@ -90,6 +90,33 @@ disable informational messages from the rc scripts. Informational messages are displayed when a condition that is not serious enough to warrant a warning or an error occurs. +.It Va early_late_divider +.Pq Vt str +The name of the script that should be used as the +delimiter between the +.Dq early +and +.Dq late +stages of the boot process. +The early stage should contain all the services needed to +get the disks (local or remote) mounted so that the late +stage can include scripts contained in the directories +listed in the +.Va local_startup +variable (see below). +Thus, the two likely candidates for this value are +mountcritlocal for the typical system, +and mountcritremote if the system needs remote file +systems mounted to get access to the +.Va local_startup +directories; for example when +.Pa /usr/local +is NFS mounted. +Extreme care should be taken when changing this value, +and before changing it one should ensure that there are +adequate provisions to recover from a failed boot +(such as physical contact with the machine, +or reliable remote console access). .It Va swapfile .Pq Vt str If set to diff --git a/share/man/man8/diskless.8 b/share/man/man8/diskless.8 index 01b53d5df3e2..da302fdb668c 100644 --- a/share/man/man8/diskless.8 +++ b/share/man/man8/diskless.8 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 28, 2004 +.Dd December 10, 2005 .Dt DISKLESS 8 .Os .Sh NAME @@ -248,6 +248,18 @@ scripts provide a mechanism through which you can override various files in .Pa /etc (as well as other subdirectories of root). +.Pp +One difference that you should pay particular attention to is +the value of +.Va local_startup +in +.Pa /etc/defaults/rc.conf . +A typical value for a +.Nm +boot is +.Va mountcritremote , +however your needs may be different. +.Pp The scripts provide four overriding directories situated in .Pa /conf/base , diff --git a/share/man/man8/rc.8 b/share/man/man8/rc.8 index 5a6419dce945..a5b19e6d870e 100644 --- a/share/man/man8/rc.8 +++ b/share/man/man8/rc.8 @@ -35,7 +35,7 @@ .\" @(#)rc.8 8.2 (Berkeley) 12/11/93 .\" $FreeBSD$ .\" -.Dd November 4, 2002 +.Dd December 19, 2005 .Dt RC 8 .Os .Sh NAME @@ -94,12 +94,6 @@ executed at boot time and shutdown time. .Ss Operation of Nm .Bl -enum .It -Source -.Pa /etc/rc.subr -to load various -.Xr rc.subr 8 -shell functions to use. -.It If autobooting, set .Va autoboot Ns = Ns Li yes and enable a flag @@ -114,17 +108,35 @@ speedup will not occur when .Nm is started up after exiting the single-user shell. .It +Determine whether the system is booting diskless, +and if so run the +.Pa /etc/rc.initdiskless +script. +.It +Source +.Pa /etc/rc.subr +to load various +.Xr rc.subr 8 +shell functions to use. +.It +Load the configuration files. +.It +Determine if booting in a jail, +and add +.Dq nojail +to the list of KEYWORDS to skip in +.Xr rcorder 8 . +.It Invoke .Xr rcorder 8 to order the files in .Pa /etc/rc.d/ that do not have a .Dq Li nostart -keyword (refer to +KEYWORD (refer to .Xr rcorder 8 Ns 's .Fl s -flag), -and assign the result to a variable. +flag). .It Call each script in turn using .Fn run_rc_script @@ -138,6 +150,18 @@ and sources the script in a subshell. If the script has a .Pa .sh suffix then it is sourced directly into the current shell. +Stop processing when the script that is the value of the +.Va $early_late_divider +has been run. +.It +Re-run +.Xr rcorder 8 , +this time including the scripts in the +.Va $local_startup +directories. +Ignore everything up to the +.Va $early_late_divider , +then start executing the scripts as described above. .El .Ss Operation of Nm rc.shutdown .Bl -enum @@ -148,13 +172,18 @@ to load various .Xr rc.subr 8 shell functions to use. .It +Load the configuration files. +.It Invoke .Xr rcorder 8 to order the files in .Pa /etc/rc.d/ +and the +.Va $local_startup +directories that have a .Dq Li shutdown -keyword (refer to +KEYWORD (refer to .Xr rcorder 8 Ns 's .Fl k flag), @@ -188,13 +217,9 @@ In order of startup, these are: .Bl -tag -width ".Pa NETWORKING" .It Pa NETWORKING Ensure basic network services are running, including general -network configuration -.Pq Pa network1 , network2 , network3 . +network configuration. .It Pa SERVERS -Ensure basic services (such as -.Pa NETWORKING , ppp-user , syslogd , -and -.Pa isdnd ) +Ensure basic services exist for services that start early (such as .Pa named ) , because they are required by @@ -406,24 +431,6 @@ The script is used to set any special configurations for serial devices. .Pp The -.Pa /etc/rc.d/network* -scripts are used to start the network. -The network is started in several passes. -The first pass, -.Pa /etc/rc.d/network1 , -sets the hostname and domainname and configures the network -interfaces. -The -.Pa /etc/rc.d/network2 -script starts routing and sets routing options. -The -.Pa /etc/rc.d/network3 -script sets additional networking options. -Finally, the -.Pa /etc/rc.d/network_ipv6 -script configures IPv6 interfaces and options. -.Pp -The .Nm rc.firewall script is used to configure rules for the kernel based firewall service. @@ -496,7 +503,6 @@ Most scripts require little more than the following. # PROVIDE: foo # REQUIRE: bar_service_required_to_precede_foo -# BEFORE: baz_service_requiring_foo_to_precede_it \&. /etc/rc.subr @@ -537,29 +543,6 @@ load_rc_config $name run_rc_command "$1" .Ed .Pp -The following is a simple, hypothetical example of an old-style -.Pa /usr/local/etc/rc.d/ -script, -which would start a daemon at boot time, -and kill it at shutdown time. -.Bd -literal -offset indent -#!/bin/sh - -# -# initialization/shutdown script for foobar package - -case "$1" in -start) - /usr/local/sbin/foo -d && echo -n ' foo' - ;; -stop) - kill `cat /var/run/foo.pid` && echo -n ' foo' - ;; -*) - echo "unknown option: $1 - should be 'start' or 'stop'" >&2 - ;; -esac -.Ed -.Pp As all processes are killed by .Xr init 8 at shutdown, the explicit diff --git a/sys/sys/param.h b/sys/sys/param.h index d466d43c5ca3..7a6e7c53fa87 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -57,7 +57,7 @@ * is created, otherwise 1. */ #undef __FreeBSD_version -#define __FreeBSD_version 600100 /* Master, propagated to newvers */ +#define __FreeBSD_version 600101 /* Master, propagated to newvers */ #ifndef LOCORE #include