source: bootscripts-standard/bootscripts/clfs/init.d/functions@ 2167cfe

Last change on this file since 2167cfe was 2167cfe, checked in by William Harrington <kb0iic@…>, 10 years ago

bootscripts are the scripts used for the sysvinit book.

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