blob: fdb8ac76e3e4a6a102092dbd40b7ba3cf4e93fc0 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
|
#! /bin/sh
#
# rc
#
# Starts/stops services on runlevel changes.
#
# Optimization: A start script is not run when the service was already
# configured to run in the previous runlevel. A stop script is not run
# when the the service was already configured not to run in the previous
# runlevel.
#
# Authors:
# Miquel van Smoorenburg <miquels@cistron.nl>
# Bruce Perens <Bruce@Pixar.com>
PATH=/sbin:/usr/sbin:/bin:/usr/bin
export PATH
# Un-comment the following for interactive debugging. Do not un-comment
# this for debugging a real boot process as no scripts will be executed.
# debug=echo
# Specify method used to enable concurrent init.d scripts.
# Valid options are 'none' and 'makefile'. Obsolete options
# used earlier are 'shell' and 'startpar'. The obsolete options
# are aliases for 'makefile' since 2010-05-14. The default since
# the same date is 'makefile', as the init.d scripts in Debian now
# include dependency information and are ordered using this
# information. See insserv for information on dependency based
# boot sequencing.
CONCURRENCY=makefile
# Make sure the name survive changing the argument list
scriptname="$0"
umask 022
on_exit() {
echo "error: '$scriptname' exited outside the expected code flow."
}
trap on_exit EXIT # Enable emergency handler
# Ignore CTRL-C only in this shell, so we can interrupt subprocesses.
trap ":" INT QUIT TSTP
# Set onlcr to avoid staircase effect.
stty onlcr 0>&1
# Functions for splash progress bars
if [ -e /lib/init/splash-functions-base ] ; then
. /lib/init/splash-functions-base
else
# Quiet down script if old initscripts version without /lib/init/splash-functions-base is used.
splash_progress() { return 1; }
splash_stop() { return 1; }
fi
# Now find out what the current and what the previous runlevel are.
runlevel=$RUNLEVEL
# Get first argument. Set new runlevel to this argument.
[ "$1" != "" ] && runlevel=$1
if [ "$runlevel" = "" ]
then
echo "Usage: $scriptname <runlevel>" >&2
exit 1
fi
previous=$PREVLEVEL
[ "$previous" = "" ] && previous=N
export runlevel previous
if [ -f /etc/default/rcS ] ; then
. /etc/default/rcS
fi
export VERBOSE
if [ -f /lib/lsb/init-functions ] ; then
. /lib/lsb/init-functions
else
log_action_msg() { echo $@; }
log_failure_msg() { echo $@; }
log_warning_msg() { echo $@; }
fi
#
# Stub to do progress bar ticks (for splash programs) on startup
#
startup_progress() {
# Avoid divide by zero if anyone moved xdm/kdm/gdm first in a runlevel.
if [ 0 -eq "$num_steps" ] ; then return; fi
step=$(($step + $step_change))
progress=$(($step * $progress_size / $num_steps + $first_step))
$debug splash_progress "$progress" || true
}
#
# Check if we are able to use make like booting. It require the
# insserv package to be enabled. Boot concurrency also requires
# startpar to be installed.
#
if [ "none" != "$CONCURRENCY" ] ; then
test -s /etc/init.d/.depend.boot || CONCURRENCY="none"
test -s /etc/init.d/.depend.start || CONCURRENCY="none"
test -s /etc/init.d/.depend.stop || CONCURRENCY="none"
if test -e /etc/init.d/.legacy-bootordering ; then
CONCURRENCY="none"
fi
startpar -v > /dev/null 2>&1 || CONCURRENCY="none"
fi
#
# Start script or program.
#
case "$CONCURRENCY" in
makefile|startpar|shell) # startpar and shell are obsolete
CONCURRENCY=makefile
log_action_msg "Using makefile-style concurrent boot in runlevel $runlevel"
# The splash API is not handled with this CONCURRENCY mode.
# It need to be implented in startpar. Until that is done
# stop the splash screen before starting services, to avoid
# usplash and X to confuse each other during boot.
startup() {
if [ start = "$1" ] || [ boot = "$1" ]
then
$debug splash_stop || true
fi
eval "$(startpar -p 4 -t 20 -T 3 -M $1 -P $previous -R $runlevel)"
if [ -n "$failed_service" ]
then
log_failure_msg "startpar: service(s) returned failure: $failed_service"
fi
if [ -n "$skipped_service" ]
then
log_warning_msg "startpar: service(s) skipped: $skipped_service"
fi
unset failed_service skipped_service
}
;;
none|*)
startup() {
action=$1
shift
scripts="$@"
for script in $scripts ; do
$debug "$script" $action
startup_progress
done
}
;;
esac
# Check if the splash screen should be stopped before the given
# script.
is_splash_stop_scripts() {
scriptname=$1
case "$scriptname" in
# killprocs is used in runlevel 1
gdm|xdm|kdm|ltsp-client|ltsp-client-core|reboot|halt|killprocs)
return 0
;;
esac
return 1
}
# Is there an rc directory for this new runlevel?
if [ -d /etc/rc$runlevel.d ]
then
# Find out where in the progress bar the initramfs got to.
PROGRESS_STATE=0
if [ -f /dev/.initramfs/progress_state ]; then
. /dev/.initramfs/progress_state
fi
# Split the remaining portion of the progress bar into thirds
progress_size=$(((100 - $PROGRESS_STATE) / 3))
case "$runlevel" in
0|6)
ACTION=stop
# Count down from 0 to -100 and use the entire bar
first_step=0
progress_size=100
step_change=-1
;;
S)
ACTION=start
# Begin where the initramfs left off and use 2/3
# of the remaining space
first_step=$PROGRESS_STATE
progress_size=$(($progress_size * 2))
step_change=1
;;
*)
ACTION=start
# Begin where rcS left off and use the final 1/3 of
# the space (by leaving progress_size unchanged)
first_step=$(($progress_size * 2 + $PROGRESS_STATE))
step_change=1
;;
esac
# Count the number of scripts we need to run
# (for progress bars)
num_steps=0
for s in /etc/rc$runlevel.d/[SK]*; do
if is_splash_stop_scripts "${s##/etc/rc$runlevel.d/S??}" ; then
break
fi
num_steps=$(($num_steps + 1))
done
step=0
# First, run the KILL scripts.
if [ makefile = "$CONCURRENCY" ]
then
if [ "$ACTION" = "start" ] && [ "$previous" != N ]
then
startup stop
fi
elif [ "$previous" != N ]
then
# Run all scripts with the same level in parallel
CURLEVEL=""
for s in /etc/rc$runlevel.d/K*
do
# Extract order value from symlink
level=${s#/etc/rc$runlevel.d/K}
level=${level%%[a-zA-Z]*}
if [ "$level" = "$CURLEVEL" ]
then
continue
fi
CURLEVEL=$level
SCRIPTS=""
for i in /etc/rc$runlevel.d/K$level*
do
# Check if the script is there.
[ ! -f $i ] && continue
#
# Find stop script in previous runlevel but
# no start script there.
#
suffix=${i#/etc/rc$runlevel.d/K[0-9][0-9]}
previous_stop=/etc/rc$previous.d/K[0-9][0-9]$suffix
previous_start=/etc/rc$previous.d/S[0-9][0-9]$suffix
#
# If there is a stop script in the previous level
# and _no_ start script there, we don't
# have to re-stop the service.
#
[ -f $previous_stop ] && [ ! -f $previous_start ] && continue
# Stop the service.
SCRIPTS="$SCRIPTS $i"
if is_splash_stop_scripts "$suffix" ; then
$debug splash_stop || true
fi
done
startup stop $SCRIPTS
done
fi
if [ makefile = "$CONCURRENCY" ]
then
if [ S = "$runlevel" ]
then
startup boot
else
startup $ACTION
fi
else
# Now run the START scripts for this runlevel.
# Run all scripts with the same level in parallel
CURLEVEL=""
for s in /etc/rc$runlevel.d/S*
do
# Extract order value from symlink
level=${s#/etc/rc$runlevel.d/S}
level=${level%%[a-zA-Z]*}
if [ "$level" = "$CURLEVEL" ]
then
continue
fi
CURLEVEL=$level
SCRIPTS=""
for i in /etc/rc$runlevel.d/S$level*
do
[ ! -f $i ] && continue
suffix=${i#/etc/rc$runlevel.d/S[0-9][0-9]}
if [ "$previous" != N ]
then
#
# Find start script in previous runlevel and
# stop script in this runlevel.
#
stop=/etc/rc$runlevel.d/K[0-9][0-9]$suffix
previous_start=/etc/rc$previous.d/S[0-9][0-9]$suffix
#
# If there is a start script in the previous level
# and _no_ stop script in this level, we don't
# have to re-start the service.
#
if [ start = "$ACTION" ] ; then
[ -f $previous_start ] && [ ! -f $stop ] && continue
else
# Workaround for the special
# handling of runlevels 0 and 6.
previous_stop=/etc/rc$previous.d/K[0-9][0-9]$suffix
#
# If there is a stop script in the previous level
# and _no_ start script there, we don't
# have to re-stop the service.
#
[ -f $previous_stop ] && [ ! -f $previous_start ] && continue
fi
fi
SCRIPTS="$SCRIPTS $i"
if is_splash_stop_scripts "$suffix" ; then
$debug splash_stop || true
fi
done
startup $ACTION $SCRIPTS
done
fi
fi
trap - EXIT # Disable emergency handler
exit 0
|