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

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.6 7.7 7.8 7.9 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 eec8fcb was eec8fcb, checked in by Bruce Dubbs <bdubbs@…>, 10 years ago

Add acl and attr packages
Minor grammar fixes
Update standards compliance statments
Put e2fsprogs executables in /bin

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

  • Property mode set to 100644
File size: 28.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## 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 # successful 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 fi
348 fi
349 done
350 fi
351
352 # Check for and remove stale PID files.
353 if [ -z "${pidfile}" ]; then
354 # Find the basename of $program
355 prefix=`echo "${program}" | sed 's/[^/]*$//'`
356 progname=`echo "${program}" | sed "s@${prefix}@@"`
357
358 if [ -e "/var/run/${progname}.pid" ]; then
359 rm -f "/var/run/${progname}.pid" 2> /dev/null
360 fi
361 else
362 if [ -e "${pidfile}" ]; then rm -f "${pidfile}" 2> /dev/null; fi
363 fi
364
365 # For signals that do not expect a program to exit, simply
366 # let kill do its job, and evaluate kill's return for value
367
368 else # check_sig_type - signal is not used to terminate program
369 for pid in ${pidlist}; do
370 kill "${signal}" "${pid}"
371 if [ "${?}" -ne "0" ]; then return 1; fi
372 done
373 fi
374}
375
376################################################################################
377# pidofproc() #
378# Usage: pidofproc [-p pidfile] pathname #
379# #
380# Purpose: This function returns one or more pid(s) for a particular daemon #
381# #
382# Inputs: -p pidfile, use the specified pidfile instead of pidof #
383# pathname, path to the specified program #
384# #
385# Return values (as defined by LSB status codes): #
386# 0 - Success (PIDs to stdout) #
387# 1 - Program is dead, PID file still exists (remaining PIDs output) #
388# 3 - Program is not running (no output) #
389################################################################################
390pidofproc()
391{
392 local pidfile
393 local program
394 local prefix
395 local progname
396 local pidlist
397 local lpids
398 local exitstatus="0"
399
400 # Process arguments
401 while true; do
402 case "${1}" in
403
404 -p)
405 pidfile="${2}"
406 shift 2
407 ;;
408
409 *)
410 program="${1}"
411 if [ -n "${2}" ]; then
412 # Too many arguments
413 # Since this is status, return unknown
414 return 4
415 else
416 break
417 fi
418 ;;
419 esac
420 done
421
422 # If a PID file is not specified, try and find one.
423 if [ -z "${pidfile}" ]; then
424 # Get the program's basename
425 prefix=`echo "${program}" | sed 's/[^/]*$//'`
426
427 if [ -z "${prefix}" ]; then
428 progname="${program}"
429 else
430 progname=`echo "${program}" | sed "s@${prefix}@@"`
431 fi
432
433 # If a PID file exists with that name, assume that is it.
434 if [ -e "/var/run/${progname}.pid" ]; then
435 pidfile="/var/run/${progname}.pid"
436 fi
437 fi
438
439 # If a PID file is set and exists, use it.
440 if [ -n "${pidfile}" -a -e "${pidfile}" ]; then
441
442 # Use the value in the first line of the pidfile
443 pidlist=`/bin/head -n1 "${pidfile}"`
444 # This can optionally be written as 'sed 1q' to repalce 'head -n1'
445 # should LFS move /bin/head to /usr/bin/head
446 else
447 # Use pidof
448 pidlist=`pidof "${program}"`
449 fi
450
451 # Figure out if all listed PIDs are running.
452 for pid in ${pidlist}; do
453 kill -0 ${pid} 2> /dev/null
454
455 if [ "${?}" -eq "0" ]; then
456 lpids="${lpids}${pid} "
457 else
458 exitstatus="1"
459 fi
460 done
461
462 if [ -z "${lpids}" -a ! -f "${pidfile}" ]; then
463 return 3
464 else
465 echo "${lpids}"
466 return "${exitstatus}"
467 fi
468}
469
470################################################################################
471# statusproc() #
472# Usage: statusproc [-p pidfile] pathname #
473# #
474# Purpose: This function prints the status of a particular daemon to stdout #
475# #
476# Inputs: -p pidfile, use the specified pidfile instead of pidof #
477# pathname, path to the specified program #
478# #
479# Return values: #
480# 0 - Status printed #
481# 1 - Input error. The daemon to check was not specified. #
482################################################################################
483statusproc()
484{
485 local pidfile
486 local pidlist
487
488 if [ "${#}" = "0" ]; then
489 echo "Usage: statusproc [-p pidfle] {program}"
490 exit 1
491 fi
492
493 # Process arguments
494 while true; do
495 case "${1}" in
496
497 -p)
498 pidfile="${2}"
499 shift 2
500 ;;
501
502 *)
503 if [ -n "${2}" ]; then
504 echo "Too many arguments"
505 return 1
506 else
507 break
508 fi
509 ;;
510 esac
511 done
512
513 if [ -n "${pidfile}" ]; then
514 pidlist=`pidofproc -p "${pidfile}" $@`
515 else
516 pidlist=`pidofproc $@`
517 fi
518
519 # Trim trailing blanks
520 pidlist=`echo "${pidlist}" | sed -r 's/ +$//'`
521
522 base="${1##*/}"
523
524 if [ -n "${pidlist}" ]; then
525 /bin/echo -e "${INFO}${base} is running with Process" \
526 "ID(s) ${pidlist}.${NORMAL}"
527 else
528 if [ -n "${base}" -a -e "/var/run/${base}.pid" ]; then
529 /bin/echo -e "${WARNING}${1} is not running but" \
530 "/var/run/${base}.pid exists.${NORMAL}"
531 else
532 if [ -n "${pidfile}" -a -e "${pidfile}" ]; then
533 /bin/echo -e "${WARNING}${1} is not running" \
534 "but ${pidfile} exists.${NORMAL}"
535 else
536 /bin/echo -e "${INFO}${1} is not running.${NORMAL}"
537 fi
538 fi
539 fi
540}
541
542################################################################################
543# timespec() #
544# #
545# Purpose: An internal utility function to format a timestamp #
546# a boot log file. Sets the STAMP variable. #
547# #
548# Return value: Not used #
549################################################################################
550timespec()
551{
552 STAMP="$(echo `date +"%b %d %T %:z"` `hostname`) "
553 return 0
554}
555
556################################################################################
557# log_success_msg() #
558# Usage: log_success_msg ["message"] #
559# #
560# Purpose: Print a successful status message to the screen and #
561# a boot log file. #
562# #
563# Inputs: $@ - Message #
564# #
565# Return values: Not used #
566################################################################################
567log_success_msg()
568{
569 /bin/echo -n -e "${BMPREFIX}${@}"
570 /bin/echo -e "${CURS_ZERO}${SUCCESS_PREFIX}${SET_COL}${SUCCESS_SUFFIX}"
571
572 # Strip non-printable characters from log file
573 logmessage=`echo "${@}" | sed 's/\\\033[^a-zA-Z]*.//g'`
574
575 timespec
576 /bin/echo -e "${STAMP} ${logmessage} OK" >> ${BOOTLOG}
577
578 return 0
579}
580
581log_success_msg2()
582{
583 /bin/echo -n -e "${BMPREFIX}${@}"
584 /bin/echo -e "${CURS_ZERO}${SUCCESS_PREFIX}${SET_COL}${SUCCESS_SUFFIX}"
585
586 echo " OK" >> ${BOOTLOG}
587
588 return 0
589}
590
591################################################################################
592# log_failure_msg() #
593# Usage: log_failure_msg ["message"] #
594# #
595# Purpose: Print a failure status message to the screen and #
596# a boot log file. #
597# #
598# Inputs: $@ - Message #
599# #
600# Return values: Not used #
601################################################################################
602log_failure_msg()
603{
604 /bin/echo -n -e "${BMPREFIX}${@}"
605 /bin/echo -e "${CURS_ZERO}${FAILURE_PREFIX}${SET_COL}${FAILURE_SUFFIX}"
606
607 # Strip non-printable characters from log file
608
609 timespec
610 logmessage=`echo "${@}" | sed 's/\\\033[^a-zA-Z]*.//g'`
611 /bin/echo -e "${STAMP} ${logmessage} FAIL" >> ${BOOTLOG}
612
613 return 0
614}
615
616log_failure_msg2()
617{
618 /bin/echo -n -e "${BMPREFIX}${@}"
619 /bin/echo -e "${CURS_ZERO}${FAILURE_PREFIX}${SET_COL}${FAILURE_SUFFIX}"
620
621 echo "FAIL" >> ${BOOTLOG}
622
623 return 0
624}
625
626################################################################################
627# log_warning_msg() #
628# Usage: log_warning_msg ["message"] #
629# #
630# Purpose: Print a warning status message to the screen and #
631# a boot log file. #
632# #
633# Return values: Not used #
634################################################################################
635log_warning_msg()
636{
637 /bin/echo -n -e "${BMPREFIX}${@}"
638 /bin/echo -e "${CURS_ZERO}${WARNING_PREFIX}${SET_COL}${WARNING_SUFFIX}"
639
640 # Strip non-printable characters from log file
641 logmessage=`echo "${@}" | sed 's/\\\033[^a-zA-Z]*.//g'`
642 timespec
643 /bin/echo -e "${STAMP} ${logmessage} WARN" >> ${BOOTLOG}
644
645 return 0
646}
647
648################################################################################
649# log_info_msg() #
650# Usage: log_info_msg message #
651# #
652# Purpose: Print an information message to the screen and #
653# a boot log file. Does not print a trailing newline character. #
654# #
655# Return values: Not used #
656################################################################################
657log_info_msg()
658{
659 /bin/echo -n -e "${BMPREFIX}${@}"
660
661 # Strip non-printable characters from log file
662 logmessage=`echo "${@}" | sed 's/\\\033[^a-zA-Z]*.//g'`
663 timespec
664 /bin/echo -n -e "${STAMP} ${logmessage}" >> ${BOOTLOG}
665
666 return 0
667}
668
669log_info_msg2()
670{
671 /bin/echo -n -e "${@}"
672
673 # Strip non-printable characters from log file
674 logmessage=`echo "${@}" | sed 's/\\\033[^a-zA-Z]*.//g'`
675 /bin/echo -n -e "${logmessage}" >> ${BOOTLOG}
676
677 return 0
678}
679
680################################################################################
681# evaluate_retval() #
682# Usage: Evaluate a return value and print success or failyure as appropriate #
683# #
684# Purpose: Convenience function to terminate an info message #
685# #
686# Return values: Not used #
687################################################################################
688evaluate_retval()
689{
690 local error_value="${?}"
691
692 if [ ${error_value} = 0 ]; then
693 log_success_msg2
694 else
695 log_failure_msg2
696 fi
697}
698
699################################################################################
700# check_signal() #
701# Usage: check_signal [ -{signal} | {signal} ] #
702# #
703# Purpose: Check for a valid signal. This is not defined by any LSB draft, #
704# however, it is required to check the signals to determine if the #
705# signals chosen are invalid arguments to the other functions. #
706# #
707# Inputs: Accepts a single string value in the form or -{signal} or {signal} #
708# #
709# Return values: #
710# 0 - Success (signal is valid #
711# 1 - Signal is not valid #
712################################################################################
713check_signal()
714{
715 local valsig
716
717 # Add error handling for invalid signals
718 valsig="-ALRM -HUP -INT -KILL -PIPE -POLL -PROF -TERM -USR1 -USR2"
719 valsig="${valsig} -VTALRM -STKFLT -PWR -WINCH -CHLD -URG -TSTP -TTIN"
720 valsig="${valsig} -TTOU -STOP -CONT -ABRT -FPE -ILL -QUIT -SEGV -TRAP"
721 valsig="${valsig} -SYS -EMT -BUS -XCPU -XFSZ -0 -1 -2 -3 -4 -5 -6 -8 -9"
722 valsig="${valsig} -11 -13 -14 -15"
723
724 echo "${valsig}" | grep -- " ${1} " > /dev/null
725
726 if [ "${?}" -eq "0" ]; then
727 return 0
728 else
729 return 1
730 fi
731}
732
733################################################################################
734# check_sig_type() #
735# Usage: check_signal [ -{signal} | {signal} ] #
736# #
737# Purpose: Check if signal is a program termination signal or a control signal #
738# This is not defined by any LSB draft, however, it is required to #
739# check the signals to determine if they are intended to end a #
740# program or simply to control it. #
741# #
742# Inputs: Accepts a single string value in the form or -{signal} or {signal} #
743# #
744# Return values: #
745# 0 - Signal is used for program termination #
746# 1 - Signal is used for program control #
747################################################################################
748check_sig_type()
749{
750 local valsig
751
752 # The list of termination signals (limited to generally used items)
753 valsig="-ALRM -INT -KILL -TERM -PWR -STOP -ABRT -QUIT -2 -3 -6 -9 -14 -15"
754
755 echo "${valsig}" | grep -- " ${1} " > /dev/null
756
757 if [ "${?}" -eq "0" ]; then
758 return 0
759 else
760 return 1
761 fi
762}
763
764################################################################################
765# wait_for_user() #
766# #
767# Purpose: Wait for the user to respond if not a headless system #
768# #
769################################################################################
770wait_for_user()
771{
772 # Wait for the user by default
773 [ "${HEADLESS=0}" = "0" ] && read ENTER
774 return 0
775}
776
777################################################################################
778# is_true() #
779# #
780# Purpose: Utility to test if a variable is true | yes | 1 #
781# #
782################################################################################
783is_true()
784{
785 [ "$1" = "1" ] || [ "$1" = "yes" ] || [ "$1" = "true" ] || [ "$1" = "y" ] ||
786 [ "$1" = "t" ]
787}
788
789# End /lib/lsb/init-functions
Note: See TracBrowser for help on using the repository browser.