source: bootscripts/lfs/lib/services/init-functions@ f874424

10.0 10.0-rc1 10.1 10.1-rc1 11.0 11.0-rc1 11.0-rc2 11.0-rc3 11.1 11.1-rc1 11.2 11.2-rc1 11.3 11.3-rc1 12.0 12.0-rc1 12.1 12.1-rc1 7.0 7.1 7.2 7.3 7.4 7.5 7.5-systemd 7.6 7.6-systemd 7.7 7.7-systemd 7.8 7.8-systemd 7.9 7.9-systemd 8.0 8.1 8.2 8.3 8.4 9.0 9.1 arm bdubbs/gcc13 ml-11.0 multilib renodr/libudev-from-systemd s6-init trunk xry111/arm64 xry111/arm64-12.0 xry111/clfs-ng xry111/lfs-next xry111/loongarch xry111/loongarch-12.0 xry111/loongarch-12.1 xry111/mips64el xry111/pip3 xry111/rust-wip-20221008 xry111/update-glibc
Last change on this file since f874424 was f874424, checked in by Bruce Dubbs <bdubbs@…>, 13 years ago

Rename /etc/sysconfig/init_params to /etc/sysconfig/rc.site.
Move network services to /lib/services.
Move init-functions to /lib/lsb.
Make /lib/lsb a symlink to /lib/services.
Create convenience symlink /etc/init.d->/etc/rc.d/init.d
Add help and man pages to ifup/ifdown.

Append /run/var/bootlog to /var/log/boot.log at the end of
the boot sequence.

Add capability to step through the boot scripts at boot time.

Optionally allow environment variables in sysconfig directory's
console, network, and clock files to be placed in rc.site.

Add an optional FASTBOOT parameter to set /fastboot when rebooting.

Remove a minor warning message from udev that is triggered
by the udev_retry boot script.

Add SKIPTMPCLEAN as an optional parameter to skip cleaning /tmp at boot time.

Add a page to Chapter 7 documenting rc.site.

git-svn-id: http://svn.linuxfromscratch.org/LFS/trunk/BOOK@9597 4aa44e1e-78dd-0310-a6d2-fbcd4c07a689

  • Property mode set to 100644
File size: 24.6 KB
Line 
1#!/bin/sh
2########################################################################
3#
4# Begin /lib/lsb/init-funtions
5#
6# Description : Run Level Control Functions
7#
8# Authors : Gerard Beekmans - gerard@linuxfromscratch.org
9# : DJ Lucas - dj@linuxfromscratch.org
10# Update : Bruce Dubbs - bdubbs@linuxfromscratch.org
11#
12# Version : LFS 7.0
13#
14# Notes : With code based on Matthias Benkmann's simpleinit-msb
15# http://winterdrache.de/linux/newboot/index.html
16#
17# The file should be located in /lib/lsb
18#
19########################################################################
20
21# Set any needed environment variables e.g. HEADLESS
22[ -r /etc/sysconfig/rc.site ] && . /etc/sysconfig/rc.site
23
24## Environmental setup
25# Setup default values for environment
26umask 022
27export PATH="/bin:/usr/bin:/sbin:/usr/sbin"
28
29## Screen Dimensions
30# Find current screen size
31if [ -z "${COLUMNS}" ]; then
32 COLUMNS=$(stty size)
33 COLUMNS=${COLUMNS##* }
34fi
35
36# When using remote connections, such as a serial port, stty size returns 0
37if [ "${COLUMNS}" = "0" ]; then
38 COLUMNS=80
39fi
40
41## Measurements for positioning result messages
42COL=$((${COLUMNS} - 8))
43WCOL=$((${COL} - 2))
44
45## Set Cursor Position Commands, used via echo
46SET_COL="\\033[${COL}G" # at the $COL char
47SET_WCOL="\\033[${WCOL}G" # at the $WCOL char
48CURS_UP="\\033[1A\\033[0G" # Up one line, at the 0'th char
49
50## Set color commands, used via echo
51# Please consult `man console_codes for more information
52# under the "ECMA-48 Set Graphics Rendition" section
53#
54# Warning: when switching from a 8bit to a 9bit font,
55# the linux console will reinterpret the bold (1;) to
56# the top 256 glyphs of the 9bit font. This does
57# not affect framebuffer consoles
58
59NORMAL="\\033[0;39m" # Standard console grey
60SUCCESS="\\033[1;32m" # Success is green
61WARNING="\\033[1;33m" # Warnings are yellow
62FAILURE="\\033[1;31m" # Failures are red
63INFO="\\033[1;36m" # Information is light cyan
64BRACKET="\\033[1;34m" # Brackets are blue
65
66BOOTLOG=/run/var/bootlog
67KILLDELAY=3
68
69
70
71################################################################################
72# start_daemon() #
73# Usage: start_daemon [-f] [-n nicelevel] [-p pidfile] pathname [args...] #
74# #
75# Purpose: This runs the specified program as a daemon #
76# #
77# Inputs: -f: (force) run the program even if it is already running. #
78# -n nicelevel: specify a nice level. See 'man nice(1)'. #
79# -p pidfile: use the specified file to determine PIDs. #
80# pathname: the complete path to the specified program #
81# args: additional arguments passed to the program (pathname) #
82# #
83# Return values (as defined by LSB exit codes): #
84# 0 - program is running or service is OK #
85# 1 - generic or unspecified error #
86# 2 - invalid or excessive argument(s) #
87# 5 - program is not installed #
88################################################################################
89start_daemon()
90{
91 local force=""
92 local nice="0"
93 local pidfile=""
94 local pidlist=""
95 local retval=""
96
97 # Process arguments
98 while true
99 do
100 case "${1}" in
101
102 -f)
103 force="1"
104 shift 1
105 ;;
106
107 -n)
108 nice="${2}"
109 shift 2
110 ;;
111
112 -p)
113 pidfile="${2}"
114 shift 2
115 ;;
116
117 -*)
118 return 2
119 ;;
120
121 *)
122 program="${1}"
123 break
124 ;;
125 esac
126 done
127
128 # Check for a valid program
129 if [ ! -e "${program}" ]; then return 5; fi
130
131 # Execute
132 if [ -z "${force}" ]; then
133 if [ -z "${pidfile}" ]; then
134 # Determine the pid by discovery
135 pidlist=`pidofproc "${1}"`
136 retval="${?}"
137 else
138 # The PID file contains the needed PIDs
139 # Note that by LSB requirement, the path must be given to pidofproc,
140 # however, it is not used by the current implementation or standard.
141 pidlist=`pidofproc -p "${pidfile}" "${1}"`
142 retval="${?}"
143 fi
144
145 # Return a value ONLY
146 # It is the init script's (or distribution's functions) responsibilty
147 # to log messages!
148 case "${retval}" in
149
150 0)
151 # Program is already running correctly, this is a
152 # succesful start.
153 return 0
154 ;;
155
156 1)
157 # Program is not running, but an invalid pid file exists
158 # remove the pid file and continue
159 rm -f "${pidfile}"
160 ;;
161
162 3)
163 # Program is not running and no pidfile exists
164 # do nothing here, let start_deamon continue.
165 ;;
166
167 *)
168 # Others as returned by status values shall not be interpreted
169 # and returned as an unspecified error.
170 return 1
171 ;;
172 esac
173 fi
174
175 # Do the start!
176
177 nice -n "${nice}" "${@}"
178}
179
180################################################################################
181# killproc() #
182# Usage: killproc [-p pidfile] pathname [signal] #
183# #
184# Purpose: Send control signals to running processes #
185# #
186# Inputs: -p pidfile, uses the specified pidfile #
187# pathname, pathname to the specified program #
188# signal, send this signal to pathname #
189# #
190# Return values (as defined by LSB exit codes): #
191# 0 - program (pathname) has stopped/is already stopped or a #
192# running program has been sent specified signal and stopped #
193# successfully #
194# 1 - generic or unspecified error #
195# 2 - invalid or excessive argument(s) #
196# 5 - program is not installed #
197# 7 - program is not running and a signal was supplied #
198################################################################################
199killproc()
200{
201 local pidfile
202 local program
203 local prefix
204 local progname
205 local signal="-TERM"
206 local fallback="-KILL"
207 local nosig
208 local pidlist
209 local retval
210 local pid
211 local delay="30"
212 local piddead
213 local dtime
214
215 # Process arguments
216 while true; do
217 case "${1}" in
218 -p)
219 pidfile="${2}"
220 shift 2
221 ;;
222
223 *)
224 program="${1}"
225 if [ -n "${2}" ]; then
226 signal="${2}"
227 fallback=""
228 else
229 nosig=1
230 fi
231
232 # Error on additional arguments
233 if [ -n "${3}" ]; then
234 return 2
235 else
236 break
237 fi
238 ;;
239 esac
240 done
241
242 # Check for a valid program
243 if [ ! -e "${program}" ]; then return 5; fi
244
245 # Check for a valid signal
246 check_signal "${signal}"
247 if [ "${?}" -ne "0" ]; then return 2; fi
248
249 # Get a list of pids
250 if [ -z "${pidfile}" ]; then
251 # determine the pid by discovery
252 pidlist=`pidofproc "${1}"`
253 retval="${?}"
254 else
255 # The PID file contains the needed PIDs
256 # Note that by LSB requirement, the path must be given to pidofproc,
257 # however, it is not used by the current implementation or standard.
258 pidlist=`pidofproc -p "${pidfile}" "${1}"`
259 retval="${?}"
260 fi
261
262 # Return a value ONLY
263 # It is the init script's (or distribution's functions) responsibilty
264 # to log messages!
265 case "${retval}" in
266
267 0)
268 # Program is running correctly
269 # Do nothing here, let killproc continue.
270 ;;
271
272 1)
273 # Program is not running, but an invalid pid file exists
274 # Remove the pid file.
275 rm -f "${pidfile}"
276
277 # This is only a success if no signal was passed.
278 if [ -n "${nosig}" ]; then
279 return 0
280 else
281 return 7
282 fi
283 ;;
284
285 3)
286 # Program is not running and no pidfile exists
287 # This is only a success if no signal was passed.
288 if [ -n "${nosig}" ]; then
289 return 0
290 else
291 return 7
292 fi
293 ;;
294
295 *)
296 # Others as returned by status values shall not be interpreted
297 # and returned as an unspecified error.
298 return 1
299 ;;
300 esac
301
302 # Perform different actions for exit signals and control signals
303 check_sig_type "${signal}"
304
305 if [ "${?}" -eq "0" ]; then # Signal is used to terminate the program
306
307 # Account for empty pidlist (pid file still exists and no
308 # signal was given)
309 if [ "${pidlist}" != "" ]; then
310
311 # Kill the list of pids
312 for pid in ${pidlist}; do
313
314 kill -0 "${pid}" 2> /dev/null
315
316 if [ "${?}" -ne "0" ]; then
317 # Process is dead, continue to next and assume all is well
318 continue
319 else
320 kill "${signal}" "${pid}" 2> /dev/null
321
322 # Wait up to ${delay}/10 seconds to for "${pid}" to
323 # terminate in 10ths of a second
324
325 while [ "${delay}" -ne "0" ]; do
326 kill -0 "${pid}" 2> /dev/null || piddead="1"
327 if [ "${piddead}" = "1" ]; then break; fi
328 sleep 0.1
329 delay="$(( ${delay} - 1 ))"
330 done
331
332 # If a fallback is set, and program is still running, then
333 # use the fallback
334 if [ -n "${fallback}" -a "${piddead}" != "1" ]; then
335 kill "${fallback}" "${pid}" 2> /dev/null
336 sleep 1
337 # Check again, and fail if still running
338 kill -0 "${pid}" 2> /dev/null && return 1
339 else
340 # just check one last time and if still alive, fail
341 sleep 1
342 kill -0 "${pid}" 2> /dev/null && return 1
343 fi
344 fi
345 done
346 fi
347
348 # Check for and remove stale PID files.
349 if [ -z "${pidfile}" ]; then
350 # Find the basename of $program
351 prefix=`echo "${program}" | sed 's/[^/]*$//'`
352 progname=`echo "${program}" | sed "s@${prefix}@@"`
353
354 if [ -e "/var/run/${progname}.pid" ]; then
355 rm -f "/var/run/${progname}.pid" 2> /dev/null
356 fi
357 else
358 if [ -e "${pidfile}" ]; then rm -f "${pidfile}" 2> /dev/null; fi
359 fi
360
361 # For signals that do not expect a program to exit, simply
362 # let kill do it's job, and evaluate kills return for value
363
364 else # check_sig_type - signal is not used to terminate program
365 for pid in ${pidlist}; do
366 kill "${signal}" "${pid}"
367 if [ "${?}" -ne "0" ]; then return 1; fi
368 done
369 fi
370}
371
372################################################################################
373# pidofproc() #
374# Usage: pidofproc [-p pidfile] pathname #
375# #
376# Purpose: This function returns one or more pid(s) for a particular daemon #
377# #
378# Inputs: -p pidfile, use the specified pidfile instead of pidof #
379# pathname, path to the specified program #
380# #
381# Return values (as defined by LSB status codes): #
382# 0 - Success (PIDs to stdout) #
383# 1 - Program is dead, PID file still exists (remaining PIDs output) #
384# 3 - Program is not running (no output) #
385################################################################################
386pidofproc()
387{
388 local pidfile
389 local program
390 local prefix
391 local progname
392 local pidlist
393 local lpids
394 local exitstatus="0"
395
396 # Process arguments
397 while true; do
398 case "${1}" in
399
400 -p)
401 pidfile="${2}"
402 shift 2
403 ;;
404
405 *)
406 program="${1}"
407 if [ -n "${2}" ]; then
408 # Too many arguments
409 # Since this is status, return unknown
410 return 4
411 else
412 break
413 fi
414 ;;
415 esac
416 done
417
418 # If a PID file is not specified, try and find one.
419 if [ -z "${pidfile}" ]; then
420 # Get the program's basename
421 prefix=`echo "${program}" | sed 's/[^/]*$//'`
422 progname=`echo "${program}" | sed "s@${prefix}@@"`
423
424 # If a PID file exists with that name, assume that is it.
425 if [ -e "/var/run/${progname}.pid" ]; then
426 pidfile="/var/run/${progname}.pid"
427 fi
428 fi
429
430 # If a PID file is set and exists, use it.
431 if [ -n "${pidfile}" -a -e "${pidfile}" ]; then
432
433 # Use the value in the first line of the pidfile
434 pidlist=`/bin/head -n1 "${pidfile}"`
435 # This can optionally be written as 'sed 1q' to repalce 'head -n1'
436 # should LFS move /bin/head to /usr/bin/head
437 else
438 # Use pidof
439 pidlist=`pidof "${program}"`
440 fi
441
442 # Figure out if all listed PIDs are running.
443 for pid in ${pidlist}; do
444 kill -0 ${pid} 2> /dev/null
445
446 if [ "${?}" -eq "0" ]; then
447 lpids="${pids}${pid} "
448 else
449 exitstatus="1"
450 fi
451 done
452
453 if [ -z "${lpids}" -a ! -f "${pidfile}" ]; then
454 return 3
455 else
456 echo "${lpids}"
457 return "${exitstatus}"
458 fi
459}
460
461################################################################################
462# timespec() #
463# #
464# Purpose: An internal utility function to format a timestamp #
465# a boot log file. Sets the STAMP variable. #
466# #
467# Return value: Not used #
468################################################################################
469timespec()
470{
471 STAMP="$(echo `date +"%b %d %T %:z"` `hostname`) "
472 return 0
473}
474
475################################################################################
476# log_success_msg() #
477# Usage: log_success_msg ["message"] #
478# #
479# Purpose: Print a successful status message to the screen and #
480# a boot log file. #
481# #
482# Inputs: $@ - Message #
483# #
484# Return values: Not used #
485################################################################################
486log_success_msg()
487{
488 echo -n -e "${@}"
489 echo -e "${SET_COL}${BRACKET}[${SUCCESS} OK ${BRACKET}]${NORMAL}"
490
491 timespec
492 echo -e "${STAMP} ${@} OK" >> ${BOOTLOG}
493 return 0
494}
495
496log_success_msg2()
497{
498 echo -n -e "${@}"
499 echo -e "${SET_COL}${BRACKET}[${SUCCESS} OK ${BRACKET}]${NORMAL}"
500
501 echo " OK" >> ${BOOTLOG}
502 return 0
503}
504
505################################################################################
506# log_failure_msg() #
507# Usage: log_failure_msg ["message"] #
508# #
509# Purpose: Print a failure status message to the screen and #
510# a boot log file. #
511# #
512# Inputs: $@ - Message #
513# #
514# Return values: Not used #
515################################################################################
516log_failure_msg()
517{
518 echo -n -e "${@}"
519 echo -e "${SET_COL}${BRACKET}[${FAILURE} FAIL ${BRACKET}]${NORMAL}"
520
521 timespec
522 echo -e "${STAMP} ${@} FAIL" >> ${BOOTLOG}
523 return 0
524}
525
526log_failure_msg2()
527{
528 echo -n -e "${@}"
529 echo -e "${SET_COL}${BRACKET}[${FAILURE} FAIL ${BRACKET}]${NORMAL}"
530
531 echo "FAIL" >> ${BOOTLOG}
532 return 0
533}
534
535################################################################################
536# log_warning_msg() #
537# Usage: log_warning_msg ["message"] #
538# #
539# Purpose: Print a warning status message to the screen and #
540# a boot log file. #
541# #
542# Return values: Not used #
543################################################################################
544log_warning_msg()
545{
546 echo -n -e "${@}"
547 echo -e "${SET_COL}${BRACKET}[${WARNING} WARN ${BRACKET}]${NORMAL}"
548
549 timespec
550 echo -e "${STAMP} ${@} WARN" >> ${BOOTLOG}
551 return 0
552}
553
554################################################################################
555# log_info_msg() #
556# Usage: log_info_msg message #
557# #
558# Purpose: Print an information message to the screen and #
559# a boot log file. Does not print a trailing newline character. #
560# #
561# Return values: Not used #
562################################################################################
563log_info_msg()
564{
565 echo -n -e "${@}"
566
567 timespec
568 echo -n -e "${STAMP} ${@}" >> ${BOOTLOG}
569 return 0
570}
571
572log_info_msg2()
573{
574 echo -n -e "${@}"
575
576 echo -n -e "${@}" >> ${BOOTLOG}
577 return 0
578}
579
580################################################################################
581# evaluate_retval() #
582# Usage: Evaluate a return value and print success or failyure as appropriate #
583# #
584# Purpose: Convenience function to terminate an info message #
585# #
586# Return values: Not used #
587################################################################################
588evaluate_retval()
589{
590 local error_value="${?}"
591
592 if [ ${error_value} = 0 ]; then
593 log_success_msg2
594 else
595 log_failure_msg2
596 fi
597}
598
599################################################################################
600# check_signal() #
601# Usage: check_signal [ -{signal} | {signal} ] #
602# #
603# Purpose: Check for a valid signal. This is not defined by any LSB draft, #
604# however, it is required to check the signals to determine if the #
605# signals chosen are invalid arguments to the other functions. #
606# #
607# Inputs: Accepts a single string value in the form or -{signal} or {signal} #
608# #
609# Return values: #
610# 0 - Success (signal is valid #
611# 1 - Signal is not valid #
612################################################################################
613check_signal()
614{
615 local valsig
616
617 # Add error handling for invalid signals
618 valsig="-ALRM -HUP -INT -KILL -PIPE -POLL -PROF -TERM -USR1 -USR2"
619 valsig="${valsig} -VTALRM -STKFLT -PWR -WINCH -CHLD -URG -TSTP -TTIN"
620 valsig="${valsig} -TTOU -STOP -CONT -ABRT -FPE -ILL -QUIT -SEGV -TRAP"
621 valsig="${valsig} -SYS -EMT -BUS -XCPU -XFSZ -0 -1 -2 -3 -4 -5 -6 -8 -9"
622 valsig="${valsig} -11 -13 -14 -15"
623
624 echo "${valsig}" | grep -- " ${1} " > /dev/null
625
626 if [ "${?}" -eq "0" ]; then
627 return 0
628 else
629 return 1
630 fi
631}
632
633################################################################################
634# check_sig_type() #
635# Usage: check_signal [ -{signal} | {signal} ] #
636# #
637# Purpose: Check if signal is a program termination signal or a control signal #
638# This is not defined by any LSB draft, however, it is required to #
639# check the signals to determine if they are intended to end a #
640# program or simply to control it. #
641# #
642# Inputs: Accepts a single string value in the form or -{signal} or {signal} #
643# #
644# Return values: #
645# 0 - Signal is used for program termination #
646# 1 - Signal is used for program control #
647################################################################################
648check_sig_type()
649{
650 local valsig
651
652 # The list of termination signals (limited to generally used items)
653 valsig="-ALRM -INT -KILL -TERM -PWR -STOP -ABRT -QUIT -2 -3 -6 -9 -14 -15"
654
655 echo "${valsig}" | grep -- " ${1} " > /dev/null
656
657 if [ "${?}" -eq "0" ]; then
658 return 0
659 else
660 return 1
661 fi
662}
663
664################################################################################
665# wait_for_user() #
666# #
667# Purpose: Wait for the user to respond if not a headless system #
668# #
669################################################################################
670wait_for_user()
671{
672 # Wait for the user by default
673 [ "${HEADLESS=0}" = "0" ] && read ENTER
674 return 0
675}
676
677# End /lib/lsb/init-functions
Note: See TracBrowser for help on using the repository browser.