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

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.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 bd899fb was bd899fb, checked in by Bruce Dubbs <bdubbs@…>, 12 years ago

Update scripts to support BLFS bridge devices.
Cosmetic cleanups

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

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