rc.shutdown revision 98189
1#!/bin/sh
2#
3# Copyright (c) 1997  Ollivier Robert
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
27# $FreeBSD: head/etc/rc.shutdown 98189 2002-06-13 22:30:02Z gordon $
28#
29
30# Site-specific closing actions for daemons run by init on shutdown,
31# or before going single-user from multi-user.
32# Output and errors are directed to console by init, and the
33# console is the controlling terminal.
34
35stty status '^T'
36
37# Set shell to ignore SIGINT (2), but not children;
38# shell catches SIGQUIT (3) and returns to single user after fsck.
39trap : 2
40trap : 3	# shouldn't be needed
41
42HOME=/
43PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin
44export HOME PATH
45
46# If there is a global system configuration file, suck it in.
47# XXX - It's only purpose is to catch rc_ng="YES".
48#
49if [ -r /etc/defaults/rc.conf ]; then
50	. /etc/defaults/rc.conf
51	source_rc_confs
52elif [ -r /etc/rc.conf ]; then
53	. /etc/rc.conf
54fi
55
56case ${rc_ng} in
57[Yy][Ee][Ss])
58	. /etc/rc.subr
59
60	load_rc_config 'XXX'
61
62	# If requested, start a watchdog timer in the background which
63	# will terminate rc.shutdown if rc.shutdown doesn't complete
64	# within the specified time.
65	#
66	_rcshutdown_watchdog=
67	if [ -n "$rcshutdown_timeout" ]; then
68		debug "Initiating watchdog timer."
69		sleep $rcshutdown_timeout && ( 
70			_msg="$rcshutdown_timeout second watchdog" \
71			    " timeout expired. Shutdown terminated."
72			logger -t rc.shutdown "$_msg"
73			echo "$_msg"
74			date
75			kill -KILL $$ >/dev/null 2>&1
76		) &
77		_rcshutdown_watchdog=$!
78	fi
79
80	# Determine the shutdown order of the /etc/rc.d scripts,
81	# and perform the operation
82	# XXX - rcorder(8) with multiple -k switches works as a logical OR,
83	#       so, we can't do this: rcorder -k shutdown -k FreeBSD.
84	#
85	files=`eval grep -l \'^# KEYWORD:.*FreeBSD\' \`rcorder -k shutdown /etc/rc.d/*\``
86
87	for _rc_elem in `reverse_list $files`; do
88		debug "run_rc_script $_rc_elem stop"
89		run_rc_script $_rc_elem stop
90	done
91
92	# Terminate the background watchdog timer (if it is running)
93	#
94	if [ -n "$_rcshutdown_watchdog" ]; then
95		kill -TERM $_rcshutdown_watchdog >/dev/null 2>&1
96	fi
97
98	echo '.'
99	exit 0
100	;;
101*)
102	# fall-through to the old rc scripts
103	;;
104esac
105
106# reverse_list list
107#	print the list in reverse order
108#
109reverse_list()
110{
111	_revlist=
112	for _revfile in $*; do
113		_revlist="$_revfile${script_name_sep}$_revlist"
114	done
115	echo $_revlist
116}
117
118# Write some entropy so the rebooting /dev/random can reseed
119#
120case ${entropy_file} in
121[Nn][Oo] | '')
122	;;
123*)
124	echo -n 'Writing entropy file:'
125	rm -f ${entropy_file}
126	oumask=`umask`
127	umask 077
128	if touch ${entropy_file} ; then
129		entropy_file_confirmed="${entropy_file}"
130	else
131		# Try this as a reasonable alternative for read-only
132		# roots, diskless workstations, etc.
133		rm -f /var/db/entropy
134		if touch /var/db/entropy ; then
135			entropy_file_confirmed=/var/db/entropy
136		fi
137	fi
138	case ${entropy_file_confirmed} in
139	'')
140		echo ' ERROR - entropy file write failed'
141		;;
142	*)
143		dd if=/dev/random of=${entropy_file_confirmed} \
144		   bs=4096 count=1 2> /dev/null
145		echo '.'
146		;;
147	esac
148	umask ${oumask}
149	;;
150esac
151
152# Check if /var/db/mounttab is clean.
153case $1 in
154reboot)
155	if [ -f /var/db/mounttab ]; then
156		rpc.umntall
157	fi
158	;;
159esac
160
161echo -n 'Shutting down daemon processes:'
162
163# for each valid dir in $local_startup, search for init scripts matching *.sh
164case ${local_startup} in
165[Nn][Oo] | '')
166	;;
167*)
168	slist=""
169	if [ -z "${script_name_sep}" ]; then
170		script_name_sep=" "
171	fi
172	for dir in ${local_startup}; do
173		if [ -d "${dir}" ]; then
174			for script in ${dir}/*.sh; do
175				slist="${slist}${script_name_sep}${script}"
176			done
177		fi
178	done
179	script_save_sep="$IFS"
180	IFS="${script_name_sep}"
181	for script in `reverse_list ${slist}`; do
182		if [ -x "${script}" ]; then
183			(set -T
184			trap 'exit 1' 2
185			${script} stop)
186		fi
187	done
188	IFS="${script_save_sep}"
189	echo '.'
190	;;
191esac
192
193# Insert other shutdown procedures here
194
195# Saving firewall state tables should be done last
196echo -n 'Saving firewall state tables:'
197
198# Save IP-filter state tables
199case ${ipfs_enable} in
200[Yy][Ee][Ss])
201	echo -n ' ipfs'
202	${ipfs_program:-/sbin/ipfs} -W ${ipfs_flags}
203	;;
204esac
205
206echo '.'
207exit 0
208