source: bootscripts/lfs/lib/services/init-functions@ 701d877e

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 701d877e was 701d877e, checked in by DJ Lucas <dj@…>, 12 years ago

Revert previous change to init-functions and set defaults for interactive prompt in rc

git-svn-id: http://svn.linuxfromscratch.org/LFS/trunk/BOOK@9675 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
70BOOTLOG=/run/var/bootlog
71KILLDELAY=3
72
73# Set any user specified environment variables e.g. HEADLESS
74[ -r /etc/sysconfig/rc.site ] && . /etc/sysconfig/rc.site
75
76################################################################################
77# start_daemon() #
78# Usage: start_daemon [-f] [-n nicelevel] [-p pidfile] pathname [args...] #
79# #
80# Purpose: This runs the specified program as a daemon #
81# #
82# Inputs: -f: (force) run the program even if it is already running. #
83# -n nicelevel: specify a nice level. See 'man nice(1)'. #
84# -p pidfile: use the specified file to determine PIDs. #
85# pathname: the complete path to the specified program #
86# args: additional arguments passed to the program (pathname) #
87# #
88# Return values (as defined by LSB exit codes): #
89# 0 - program is running or service is OK #
90# 1 - generic or unspecified error #
91# 2 - invalid or excessive argument(s) #
92# 5 - program is not installed #
93################################################################################
94start_daemon()
95{
96 local force=""
97 local nice="0"
98 local pidfile=""
99 local pidlist=""
100 local retval=""
101
102 # Process arguments
103 while true
104 do
105 case "${1}" in
106
107 -f)
108 force="1"
109 shift 1
110 ;;
111
112 -n)
113 nice="${2}"
114 shift 2
115 ;;
116
117 -p)
118 pidfile="${2}"
119 shift 2
120 ;;
121
122 -*)
123 return 2
124 ;;
125
126 *)
127 program="${1}"
128 break
129 ;;
130 esac
131 done
132
133 # Check for a valid program
134 if [ ! -e "${program}" ]; then return 5; fi
135
136 # Execute
137 if [ -z "${force}" ]; then
138 if [ -z "${pidfile}" ]; then
139 # Determine the pid by discovery
140 pidlist=`pidofproc "${1}"`
141 retval="${?}"
142 else
143 # The PID file contains the needed PIDs
144 # Note that by LSB requirement, the path must be given to pidofproc,
145 # however, it is not used by the current implementation or standard.
146 pidlist=`pidofproc -p "${pidfile}" "${1}"`
147 retval="${?}"
148 fi
149
150 # Return a value ONLY
151 # It is the init script's (or distribution's functions) responsibilty
152 # to log messages!
153 case "${retval}" in
154
155 0)
156 # Program is already running correctly, this is a
157 # succesful start.
158 return 0
159 ;;
160
161 1)
162 # Program is not running, but an invalid pid file exists
163 # remove the pid file and continue
164 rm -f "${pidfile}"
165 ;;
166
167 3)
168 # Program is not running and no pidfile exists
169 # do nothing here, let start_deamon continue.
170 ;;
171
172 *)
173 # Others as returned by status values shall not be interpreted
174 # and returned as an unspecified error.
175 return 1
176 ;;
177 esac
178 fi
179
180 # Do the start!
181 nice -n "${nice}" "${@}"
182}
183
184################################################################################
185# killproc() #
186# Usage: killproc [-p pidfile] pathname [signal] #
187# #
188# Purpose: Send control signals to running processes #
189# #
190# Inputs: -p pidfile, uses the specified pidfile #
191# pathname, pathname to the specified program #
192# signal, send this signal to pathname #
193# #
194# Return values (as defined by LSB exit codes): #
195# 0 - program (pathname) has stopped/is already stopped or a #
196# running program has been sent specified signal and stopped #
197# successfully #
198# 1 - generic or unspecified error #
199# 2 - invalid or excessive argument(s) #
200# 5 - program is not installed #
201# 7 - program is not running and a signal was supplied #
202################################################################################
203killproc()
204{
205 local pidfile
206 local program
207 local prefix
208 local progname
209 local signal="-TERM"
210 local fallback="-KILL"
211 local nosig
212 local pidlist
213 local retval
214 local pid
215 local delay="30"
216 local piddead
217 local dtime
218
219 # Process arguments
220 while true; do
221 case "${1}" in
222 -p)
223 pidfile="${2}"
224 shift 2
225 ;;
226
227 *)
228 program="${1}"
229 if [ -n "${2}" ]; then
230 signal="${2}"
231 fallback=""
232 else
233 nosig=1
234 fi
235
236 # Error on additional arguments
237 if [ -n "${3}" ]; then
238 return 2
239 else
240 break
241 fi
242 ;;
243 esac
244 done
245
246 # Check for a valid program
247 if [ ! -e "${program}" ]; then return 5; fi
248
249 # Check for a valid signal
250 check_signal "${signal}"
251 if [ "${?}" -ne "0" ]; then return 2; fi
252
253 # Get a list of pids
254 if [ -z "${pidfile}" ]; then
255 # determine the pid by discovery
256 pidlist=`pidofproc "${1}"`
257 retval="${?}"
258 else
259 # The PID file contains the needed PIDs
260 # Note that by LSB requirement, the path must be given to pidofproc,
261 # however, it is not used by the current implementation or standard.
262 pidlist=`pidofproc -p "${pidfile}" "${1}"`
263 retval="${?}"
264 fi
265
266 # Return a value ONLY
267 # It is the init script's (or distribution's functions) responsibilty
268 # to log messages!
269 case "${retval}" in
270
271 0)
272 # Program is running correctly
273 # Do nothing here, let killproc continue.
274 ;;
275
276 1)
277 # Program is not running, but an invalid pid file exists
278 # Remove the pid file.
279 rm -f "${pidfile}"
280
281 # This is only a success if no signal was passed.
282 if [ -n "${nosig}" ]; then
283 return 0
284 else
285 return 7
286 fi
287 ;;
288
289 3)
290 # Program is not running and no pidfile exists
291 # This is only a success if no signal was passed.
292 if [ -n "${nosig}" ]; then
293 return 0
294 else
295 return 7
296 fi
297 ;;
298
299 *)
300 # Others as returned by status values shall not be interpreted
301 # and returned as an unspecified error.
302 return 1
303 ;;
304 esac
305
306 # Perform different actions for exit signals and control signals
307 check_sig_type "${signal}"
308
309 if [ "${?}" -eq "0" ]; then # Signal is used to terminate the program
310
311 # Account for empty pidlist (pid file still exists and no
312 # signal was given)
313 if [ "${pidlist}" != "" ]; then
314
315 # Kill the list of pids
316 for pid in ${pidlist}; do
317
318 kill -0 "${pid}" 2> /dev/null
319
320 if [ "${?}" -ne "0" ]; then
321 # Process is dead, continue to next and assume all is well
322 continue
323 else
324 kill "${signal}" "${pid}" 2> /dev/null
325
326 # Wait up to ${delay}/10 seconds to for "${pid}" to
327 # terminate in 10ths of a second
328
329 while [ "${delay}" -ne "0" ]; do
330 kill -0 "${pid}" 2> /dev/null || piddead="1"
331 if [ "${piddead}" = "1" ]; then break; fi
332 sleep 0.1
333 delay="$(( ${delay} - 1 ))"
334 done
335
336 # If a fallback is set, and program is still running, then
337 # use the fallback
338 if [ -n "${fallback}" -a "${piddead}" != "1" ]; then
339 kill "${fallback}" "${pid}" 2> /dev/null
340 sleep 1
341 # Check again, and fail if still running
342 kill -0 "${pid}" 2> /dev/null && return 1
343 else
344 # just check one last time and if still alive, fail
345 sleep 1
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 it's job, and evaluate kills 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="${pids}${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: [-p pidfle] statusproc {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 [ -z "${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 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 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 echo -e "${WARNING}${1} is not running" \
534 "but ${pidfile} exists.${NORMAL}"
535 else
536 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 echo -n -e "${BMPREFIX}${@}"
570 echo -e "${CURS_ZERO}${SUCCESS_PREFIX}${SET_COL}${BRACKET}[${SUCCESS} OK ${BRACKET}]${NORMAL}"
571
572 # Strip non-printable characters from log file
573 local logmessage=`echo "${@}" | sed 's/\\\033[^a-zA-Z]*.//g'`
574
575 timespec
576 echo -e "${STAMP} ${logmessage} OK" >> ${BOOTLOG}
577
578 return 0
579}
580
581log_success_msg2()
582{
583 echo -n -e "${BMPREFIX}${@}"
584 echo -e "${CURS_ZERO}${SUCCESS_PREFIX}${SET_COL}${BRACKET}[${SUCCESS} OK ${BRACKET}]${NORMAL}"
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 echo -n -e "${BMPREFIX}${@}"
605 echo -e "${CURS_ZERO}${FAILURE_PREFIX}${SET_COL}${BRACKET}[${FAILURE} FAIL ${BRACKET}]${NORMAL}"
606
607 # Strip non-printable characters from log file
608
609 timespec
610 local logmessage=`echo "${@}" | sed 's/\\\033[^a-zA-Z]*.//g'`
611 echo -e "${STAMP} ${logmessage} FAIL" >> ${BOOTLOG}
612
613 return 0
614}
615
616log_failure_msg2()
617{
618 echo -n -e "${BMPREFIX}${@}"
619 echo -e "${CURS_ZERO}${FAILURE_PREFIX}${SET_COL}${BRACKET}[${FAILURE} FAIL ${BRACKET}]${NORMAL}"
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 echo -n -e "${BMPREFIX}${@}"
638 echo -e "${CURS_ZERO}${WARNING_PREFIX}${SET_COL}${BRACKET}[${WARNING} WARN ${BRACKET}]${NORMAL}"
639
640 # Strip non-printable characters from log file
641 local logmessage=`echo "${@}" | sed 's/\\\033[^a-zA-Z]*.//g'`
642 timespec
643 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 echo -n -e "${BMPREFIX}${@}"
660
661 # Strip non-printable characters from log file
662 local logmessage=`echo "${@}" | sed 's/\\\033[^a-zA-Z]*.//g'`
663 timespec
664 echo -n -e "${STAMP} ${logmessage}" >> ${BOOTLOG}
665
666 return 0
667}
668
669log_info_msg2()
670{
671 echo -n -e "${@}"
672
673 # Strip non-printable characters from log file
674 local logmessage=`echo "${@}" | sed 's/\\\033[^a-zA-Z]*.//g'`
675 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# End /lib/lsb/init-functions
Note: See TracBrowser for help on using the repository browser.