source: bootscripts/lfs/init.d/functions@ 04ad582

clfs-1.2 clfs-2.1 clfs-3.0.0-systemd clfs-3.0.0-sysvinit systemd sysvinit
Last change on this file since 04ad582 was 8953f24, checked in by Jim Gifford <clfs@…>, 18 years ago

Readded Bootlog to bootscripts

  • Property mode set to 100644
File size: 16.0 KB
Line 
1#!/bin/sh
2########################################################################
3# Begin $rc_base/init.d/functions
4#
5# Description : Run Level Control Functions
6#
7# Authors : Gerard Beekmans - gerard@linuxfromscratch.org
8#
9# Version : 00.00
10#
11# Notes : With code based on Matthias Benkmann's simpleinit-msb
12# http://winterdrache.de/linux/newboot/index.html
13#
14########################################################################
15
16if [ -e /etc/sysconfig/lcd ]; then
17 if [ -e /dev/lcd ]; then
18 source /etc/sysconfig/lcd
19 fi
20fi
21
22if [ -e /etc/sysconfig/bootscripts ]; then
23 source /etc/sysconfig/bootscripts
24fi
25
26## Environmental setup
27# Setup default values for environment
28umask 022
29export PATH="/bin:/usr/bin:/sbin:/usr/sbin"
30
31# Signal sent to running processes to refresh their configuration
32RELOADSIG="HUP"
33
34# Number of seconds between STOPSIG and FALLBACK when stopping processes
35KILLDELAY="3"
36
37## Screen Dimensions
38# Find current screen size
39if [ -z "${COLUMNS}" ]; then
40 COLUMNS=$(stty size)
41 COLUMNS=${COLUMNS##* }
42fi
43
44# When using remote connections, such as a serial port, stty size returns 0
45if [ "${COLUMNS}" = "0" ]; then
46 COLUMNS=80
47fi
48
49## Measurements for positioning result messages
50COL=$((${COLUMNS} - 8))
51WCOL=$((${COL} - 2))
52
53## Set Cursor Position Commands, used via echo -e
54SET_COL="\\033[${COL}G" # at the $COL char
55SET_WCOL="\\033[${WCOL}G" # at the $WCOL char
56CURS_UP="\\033[1A\\033[0G" # Up one line, at the 0'th char
57
58## Set color commands, used via echo -e
59# Please consult `man console_codes for more information
60# under the "ECMA-48 Set Graphics Rendition" section
61#
62# Warning: when switching from a 8bit to a 9bit font,
63# the linux console will reinterpret the bold (1;) to
64# the top 256 glyphs of the 9bit font. This does
65# not affect framebuffer consoles
66NORMAL="\\033[0;39m" # Standard console grey
67SUCCESS="\\033[1;32m" # Success is green
68WARNING="\\033[1;33m" # Warnings are yellow
69FAILURE="\\033[1;31m" # Failures are red
70INFO="\\033[1;36m" # Information is light cyan
71BRACKET="\\033[1;34m" # Brackets are blue
72
73STRING_LENGTH="0" # the length of the current message
74
75#*******************************************************************************
76# Function - boot_mesg()
77#
78# Purpose: Sending information from bootup scripts to the console
79#
80# Inputs: $1 is the message
81# $2 is the colorcode for the console
82#
83# Outputs: Standard Output
84#
85# Dependencies: - sed for parsing strings.
86# - grep for counting string length.
87#
88# Todo:
89#*******************************************************************************
90boot_mesg()
91{
92 local ECHOPARM=""
93
94 if [ "$LCD_PROG" ]; then
95 LCD_OUT1="${1:0:$LCD_CHAR}"
96 $LCD_PROG "$LCD_OUT1" > /dev/null 2>&1
97 fi
98
99 while true
100 do
101 case "${1}" in
102 -n)
103 ECHOPARM=" -n "
104 shift 1
105 ;;
106 -*)
107 echo "Unknown Option: ${1}"
108 return 1
109 ;;
110 *)
111 break
112 ;;
113 esac
114 done
115
116 ## Figure out the length of what is to be printed to be used
117 ## for warning messges.
118 STRING_LENGTH="`echo "${1}" | sed \
119 -e 's,.,.,g' -e 'l 1' | grep -c \$`"
120
121 # Print the message to the screen
122 echo ${ECHOPARM} -e "${2}${1}"
123
124}
125
126boot_mesg_flush()
127{
128 # Reset STRING_LENGTH for next message
129 STRING_LENGTH="0"
130 if [ "$LOGGING" ]; then
131 boot_log "${BOOTMESG}${@}"
132 fi
133}
134
135boot_log()
136{
137 if [ "$LOGGING" ]; then
138 /bin/logger -p local2.info -t bootlog "${@}"
139 else
140 return 0
141 fi
142}
143
144echo_ok()
145{
146 echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${SUCCESS} OK ${BRACKET}]"
147 echo -e "${NORMAL}"
148 boot_mesg_flush "[ OK ]"
149 if [ "$LCD_PROG" ]; then
150 if [ "$LCD_LINES" = "2" ]; then
151 LCD_OUT2="[ OK ]"
152 $LCD_PROG "$LCD_OUT1" "$LCD_OUT2" > /dev/null 2>&1
153 else
154 LCD_OUT2="${LCD_OUT1:0:12} OK"
155 $LCD_PROG "$LCD_OUT2" > /dev/null 2>&1
156 fi
157 fi
158}
159
160echo_failure()
161{
162 echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${FAILURE} FAIL ${BRACKET}]"
163 echo -e "${NORMAL}"
164 boot_mesg_flush "[ FAIL ]"
165 if [ "$LCD_PROG" ]; then
166 if [ "$LCD_LINES" = "2" ]; then
167 LCD_OUT2="[ FAIL ]"
168 $LCD_PROG "$LCD_OUT1" "$LCD_OUT2" > /dev/null 2>&1
169 else
170 LCD_OUT2="${LCD_OUT1:0:10} FAIL"
171 $LCD_PROG "$LCD_OUT2" > /dev/null 2>&1
172 fi
173 fi
174}
175
176echo_warning()
177{
178 echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${WARNING} WARN ${BRACKET}]"
179 echo -e "${NORMAL}"
180 if [ "$LCD_PROG" ]; then
181 if [ "$LCD_LINES" = "2" ]; then
182 LCD_OUT2="[ WARN ]"
183 $LCD_PROG "$LCD_OUT1" "$LCD_OUT2" > /dev/null 2>&1
184 else
185 LCD_OUT2="${LCD_OUT1:0:10} WARN"
186 $LCD_PROG "$LCD_OUT2" > /dev/null 2>&1
187 fi
188 fi
189 boot_mesg_flush "[ WARN ]"
190}
191
192print_error_msg()
193{
194 echo_failure
195 # $i is inherited by the rc script
196 boot_log "\n\n${i} failed and exited with a return value of ${error_value}."
197 boot_mesg_flush
198 boot_mesg -n "FAILURE:\n\nYou should not be reading this error message.\n\n" ${FAILURE}
199 boot_mesg -n " It means that an unforeseen error took"
200 boot_mesg -n " place in ${i}, which exited with a return value of"
201 boot_mesg " ${error_value}.\n"
202 boot_mesg_flush
203 boot_mesg -n "If you're able to track this"
204 boot_mesg -n " error down to a bug in one of the files provided by"
205 boot_mesg -n " the CLFS book, please be so kind to inform us at"
206 boot_mesg " clfs-dev@cross-lfs.org.\n"
207 boot_mesg_flush
208 if [ "$INTERACTIVE" ]; then
209 boot_mesg -n "Press Enter to continue..." ${INFO}
210 boot_mesg "" ${NORMAL}
211 if [ "$LCD_PROG" ]; then
212 sleep 10
213 else
214 read ENTER
215 fi
216 fi
217}
218
219check_script_status()
220{
221 # $i is inherited by the rc script
222 if [ ! -f ${i} ]; then
223 boot_mesg "${i} is not a valid symlink." ${WARNING}
224 echo_warning
225 continue
226 fi
227
228 if [ ! -x ${i} ]; then
229 boot_mesg "${i} is not executable, skipping." ${WARNING}
230 echo_warning
231 continue
232 fi
233}
234
235evaluate_retval()
236{
237 error_value="${?}"
238
239 if [ ${error_value} = 0 ]; then
240 echo_ok
241 else
242 echo_failure
243 fi
244
245 # This prevents the 'An Unexpected Error Has Occurred' from trivial
246 # errors.
247 return 0
248}
249
250print_status()
251{
252 if [ "${#}" = "0" ]; then
253 echo "Usage: ${0} {success|warning|failure}"
254 return 1
255 fi
256
257# boot_mesg_flush
258# echo_warning
259
260 case "${1}" in
261
262 success)
263 echo_ok
264 ;;
265
266 warning)
267 # Leave this extra case in because old scripts
268 # may call it this way.
269 case "${2}" in
270 running)
271 echo -e -n "${CURS_UP}"
272 echo -e -n "\\033[${STRING_LENGTH}G "
273 boot_mesg "Already running." ${WARNING}
274 echo_warning
275 ;;
276 not_running)
277 echo -e -n "${CURS_UP}"
278 echo -e -n "\\033[${STRING_LENGTH}G "
279 boot_mesg "Not running." ${WARNING}
280 echo_warning
281 ;;
282 not_available)
283 echo -e -n "${CURS_UP}"
284 echo -e -n "\\033[${STRING_LENGTH}G "
285 boot_mesg "Not available." ${WARNING}
286 echo_warning
287 ;;
288 *)
289 # This is how it is supposed to
290 # be called
291 echo_warning
292 ;;
293 esac
294 ;;
295
296 failure)
297 echo_failure
298 ;;
299
300 esac
301
302}
303
304reloadproc()
305{
306 if [ "${#}" = "0" ]; then
307 echo "Usage: reloadproc [{program}]"
308 exit 1
309 fi
310
311 getpids "${1}"
312
313 if [ -n "${pidlist}" ]; then
314 failure="0"
315 for pid in ${pidlist}
316 do
317 kill -"${RELOADSIG}" "${pid}" || failure="1"
318 done
319
320 (exit ${failure})
321 evaluate_retval
322
323 else
324 boot_mesg "Process ${1} not running." ${WARNING}
325 echo_warning
326 fi
327}
328
329statusproc()
330{
331 if [ "${#}" = "0" ]
332 then
333 echo "Usage: statusproc {program}"
334 exit 1
335 fi
336
337 getpids "${1}"
338
339 if [ -n "${pidlist}" ]; then
340 echo -e "${INFO}${base} is running with Process"\
341 "ID(s) ${pidlist}.${NORMAL}"
342 else
343 if [ -n "${base}" -a -e "/var/run/${base}.pid" ]; then
344 echo -e "${WARNING}${1} is not running but"\
345 "/var/run/${base}.pid exists.${NORMAL}"
346 else
347 if [ -n "${PIDFILE}" -a -e "${PIDFILE}" ]; then
348 echo -e "${WARNING}${1} is not running"\
349 "but ${PIDFILE} exists.${NORMAL}"
350 else
351 echo -e "${INFO}${1} is not running.${NORMAL}"
352 fi
353 fi
354 fi
355}
356
357# The below functions are documented in the LSB-generic 2.1.0
358
359#*******************************************************************************
360# Function - pidofproc [-s] [-p pidfile] pathname
361#
362# Purpose: This function returns one or more pid(s) for a particular daemon
363#
364# Inputs: -p pidfile, use the specified pidfile instead of pidof
365# pathname, path to the specified program
366#
367# Outputs: return 0 - Success, pid's in stdout
368# return 1 - Program is dead, pidfile exists
369# return 2 - Invalid or excessive number of arguments,
370# warning in stdout
371# return 3 - Program is not running
372#
373# Dependencies: pidof, echo, head
374#
375# Todo: Remove dependency on head
376# This depreciates getpids
377# Test changes to pidof
378#
379#*******************************************************************************
380pidofproc()
381{
382 local pidfile=""
383 local lpids=""
384 local silent=""
385 pidlist=""
386 while true
387 do
388 case "${1}" in
389 -p)
390 pidfile="${2}"
391 shift 2
392 ;;
393
394 -s)
395 # Added for legacy opperation of getpids
396 # eliminates several '> /dev/null'
397 silent="1"
398 shift 1
399 ;;
400 -*)
401 log_failure_msg "Unknown Option: ${1}"
402 return 2
403 ;;
404 *)
405 break
406 ;;
407 esac
408 done
409
410 if [ "${#}" != "1" ]; then
411 shift 1
412 log_failure_msg "Usage: pidofproc [-s] [-p pidfile] pathname"
413 return 2
414 fi
415
416 if [ -n "${pidfile}" ]; then
417 if [ ! -r "${pidfile}" ]; then
418 return 3 # Program is not running
419 fi
420
421 lpids=`head -n 1 ${pidfile}`
422 for pid in ${lpids}
423 do
424 if [ "${pid}" -ne "$$" -a "${pid}" -ne "${PPID}" ]; then
425 kill -0 "${pid}" > /dev/null &&
426 pidlist="${pidlist} ${pid}"
427 fi
428
429 if [ "${silent}" -ne "1" ]; then
430 echo "${pidlist}"
431 fi
432
433 test -z "${pidlist}" &&
434 # Program is dead, pidfile exists
435 return 1
436 # else
437 return 0
438 done
439
440 else
441 pidlist=`pidof -o $$ -o $PPID -x "$1"`
442 if [ "x${silent}" != "x1" ]; then
443 echo "${pidlist}"
444 fi
445
446 # Get provide correct running status
447 if [ -n "${pidlist}" ]; then
448 return 0
449 else
450 return 3
451 fi
452
453 fi
454
455 if [ "$?" != "0" ]; then
456 return 3 # Program is not running
457 fi
458}
459
460# This will ensure compatibility with previous CLFS Bootscripts
461getpids()
462{
463 if [ -z "${PIDFILE}" ]; then
464 pidofproc -s -p "${PIDFILE}" $@
465 else
466 pidofproc -s $@
467 fi
468 base="${1##*/}"
469}
470
471#*******************************************************************************
472# Function - loadproc [-f] [-n nicelevel] [-p pidfile] pathname [args]
473#
474# Purpose: This runs the specified program as a daemon
475#
476# Inputs: -f, run the program even if it is already running
477# -n nicelevel, specifies a nice level. See nice(1).
478# -p pidfile, uses the specified pidfile
479# pathname, pathname to the specified program
480# args, arguments to pass to specified program
481#
482# Outputs: return 0 - Success
483# return 2 - Invalid of excessive number of arguments,
484# warning in stdout
485# return 4 - Program or service status is unknown
486#
487# Dependencies: nice
488#
489# Todo: LSB says this should be called start_daemon
490# LSB does not say that it should call evaluate_retval
491# It checks for PIDFILE, which is deprecated.
492# Will be removed after BLFS 6.0
493# loadproc returns 0 if program is already running, not LSB compliant
494#
495#*******************************************************************************
496loadproc()
497{
498 local pidfile=""
499 local forcestart=""
500 local nicelevel="10"
501
502# This will ensure compatibility with previous CLFS Bootscripts
503 if [ -n "${PIDFILE}" ]; then
504 pidfile="${PIDFILE}"
505 fi
506
507 while true
508 do
509 case "${1}" in
510 -f)
511 forcestart="1"
512 shift 1
513 ;;
514 -n)
515 nicelevel="${2}"
516 shift 2
517 ;;
518 -p)
519 pidfile="${2}"
520 shift 2
521 ;;
522 -*)
523 log_failure_msg "Unknown Option: ${1}"
524 return 2 #invalid or excess argument(s)
525 ;;
526 *)
527 break
528 ;;
529 esac
530 done
531
532 if [ "${#}" = "0" ]; then
533 log_failure_msg "Usage: loadproc [-f] [-n nicelevel] [-p pidfile] pathname [args]"
534 return 2 #invalid or excess argument(s)
535 fi
536
537 if [ -z "${forcestart}" ]; then
538 if [ -z "${pidfile}" ]; then
539 pidofproc -s "${1}"
540 else
541 pidofproc -s -p "${pidfile}" "${1}"
542 fi
543
544 case "${?}" in
545 0)
546 log_warning_msg "Unable to continue: ${1} is running"
547 return 0 # 4
548 ;;
549 1)
550 log_warning_msg "Unable to continue: ${pidfile} exists"
551 return 0 # 4
552 ;;
553 3)
554 ;;
555 *)
556 log_failure_msg "Unknown error code from pidofproc: ${?}"
557 return 4
558 ;;
559 esac
560 fi
561
562 nice -n "${nicelevel}" "${@}"
563 evaluate_retval # This is "Probably" not LSB compliant, but required to be compatible with older bootscripts
564 return 0
565}
566
567#*******************************************************************************
568# Function - killproc [-p pidfile] pathname [signal]
569#
570# Purpose:
571#
572# Inputs: -p pidfile, uses the specified pidfile
573# pathname, pathname to the specified program
574# signal, send this signal to pathname
575#
576# Outputs: return 0 - Success
577# return 2 - Invalid of excessive number of arguments,
578# warning in stdout
579# return 4 - Unknown Status
580#
581# Dependencies: kill
582#
583# Todo: LSB does not say that it should call evaluate_retval
584# It checks for PIDFILE, which is deprecated.
585# Will be removed after BLFS 6.0
586#
587#*******************************************************************************
588killproc()
589{
590 local pidfile=""
591 local killsig=""
592 pidlist=""
593
594# This will ensure compatibility with previous CLFS Bootscripts
595 if [ -n "${PIDFILE}" ]; then
596 pidfile="${PIDFILE}"
597 fi
598
599 while true
600 do
601 case "${1}" in
602 -p)
603 pidfile="${2}"
604 shift 2
605 ;;
606 -*)
607 log_failure_msg "Unknown Option: ${1}"
608 return 2
609 ;;
610 *)
611 break
612 ;;
613 esac
614 done
615
616 if [ "${#}" = "2" ]; then
617 killsig="${2}"
618 elif [ "${#}" != "1" ]; then
619 shift 2
620 log_failure_msg "Usage: killproc [-p pidfile] pathname [signal]"
621 return 2
622 fi
623
624 if [ -z "${pidfile}" ]; then
625 pidofproc -s "${1}"
626 else
627 pidofproc -s -p "${pidfile}" "${1}"
628 fi
629
630 # Change....
631 if [ -n "${pidlist}" ]; then
632 for pid in ${pidlist}
633 do
634 kill -${killsig:-TERM} ${pid} 2>/dev/null
635 if [ -z "${killsig}" ]; then
636 # Wait up to 3 seconds, for ${pid} to terminate
637 local dtime=${KILLDELAY}
638 while [ "${dtime}" != "0" ]
639 do
640 kill -0 ${pid} 2>/dev/null || break
641 sleep 1
642 dtime=$(( ${dtime} - 1))
643 done
644 # If ${pid} is still running, kill it
645 kill -0 ${pid} 2>/dev/null && kill -KILL ${pid} 2>/dev/null
646 fi
647 done
648
649 if [ -z "${killsig}" ]; then
650 pidofproc -s "${1}"
651
652 # Program was terminated
653 if [ "$?" != "0" ]; then
654 # Pidfile Exists
655 if [ -f "${pidfile}" ]; then
656 rm -f "${pidfile}"
657 fi
658 echo_ok
659 return 0
660 else # Program is still running
661 echo_failure
662 return 4 # Unknown Status
663 fi
664 else
665 if [ -z "${pidfile}" ]; then
666 pidofproc -s "${1}"
667 else
668 pidofproc -s -p "${pidfile}" "${1}"
669 fi
670 fi
671
672 evaluate_retval # This is "Probably" not LSB compliant, but required to be compatible with older bootscripts
673
674 else
675 print_status warning not_running
676 fi
677}
678
679
680#*******************************************************************************
681# Function - log_success_msg "message"
682#
683# Purpose: Print a success message
684#
685# Inputs: $@ - Message
686#
687# Outputs: Text output to screen
688#
689# Dependencies: echo
690#
691# Todo: logging
692#
693#*******************************************************************************
694log_success_msg()
695{
696 echo -n -e "${BOOTMESG_PREFIX}${@}"
697 echo -e "${SET_COL}""${BRACKET}""[""${SUCCESS}"" OK ""${BRACKET}""]""${NORMAL}"
698 return 0
699}
700
701#*******************************************************************************
702# Function - log_failure_msg "message"
703#
704# Purpose: Print a failure message
705#
706# Inputs: $@ - Message
707#
708# Outputs: Text output to screen
709#
710# Dependencies: echo
711#
712# Todo: logging
713#
714#*******************************************************************************
715log_failure_msg() {
716 echo -n -e "${BOOTMESG_PREFIX}${@}"
717 echo -e "${SET_COL}""${BRACKET}""[""${FAILURE}"" FAIL ""${BRACKET}""]""${NORMAL}"
718 return 0
719}
720
721#*******************************************************************************
722# Function - log_warning_msg "message"
723#
724# Purpose: print a warning message
725#
726# Inputs: $@ - Message
727#
728# Outputs: Text output to screen
729#
730# Dependencies: echo
731#
732# Todo: logging
733#
734#*******************************************************************************
735log_warning_msg() {
736 echo -n -e "${BOOTMESG_PREFIX}${@}"
737 echo -e "${SET_COL}""${BRACKET}""[""${WARNING}"" WARN ""${BRACKET}""]""${NORMAL}"
738 return 0
739}
740
741# End $rc_base/init.d/functions
Note: See TracBrowser for help on using the repository browser.