source: bootscripts/lfs/init.d/functions @ 0fd55dd

clfs-1.2clfs-2.1clfs-3.0.0-systemdclfs-3.0.0-sysvinitsystemdsysvinit
Last change on this file since 0fd55dd was 00d52bd4, checked in by Jim Gifford <clfs@…>, 17 years ago

Updates for Boot logging hang issue

  • Property mode set to 100644
File size: 16.1 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        if [ "$LOGGING" ]; then
124                DISPLAYLOG="${1}"
125        fi
126       
127}
128
129boot_mesg_flush()
130{
131        # Reset STRING_LENGTH for next message
132        STRING_LENGTH="0"
133        if [ "$LOGGING" ]; then
134                boot_log "${BOOTMESG}${@}"
135        fi
136}
137
138boot_log()
139{
140        if [ "$LOGGING" ]; then
141                /bin/logger -p local2.info -t bootlog "${DISPLAYLOG} ${1}"
142        else
143                return 0
144        fi
145}
146
147echo_ok()
148{
149        echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${SUCCESS}  OK  ${BRACKET}]"
150        echo -e "${NORMAL}"
151        boot_mesg_flush "[  OK  ]"
152        if [ "$LCD_PROG" ]; then
153                if [ "$LCD_LINES" = "2" ]; then
154                        LCD_OUT2="[  OK  ]"
155                        $LCD_PROG "$LCD_OUT1" "$LCD_OUT2" > /dev/null 2>&1
156                else
157                        LCD_OUT2="${LCD_OUT1:0:12} OK"
158                        $LCD_PROG "$LCD_OUT2" > /dev/null 2>&1
159                fi                     
160        fi
161}
162
163echo_failure()
164{
165        echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${FAILURE} FAIL ${BRACKET}]"
166        echo -e "${NORMAL}"
167        boot_mesg_flush "[ FAIL ]"
168        if [ "$LCD_PROG" ]; then
169                if [ "$LCD_LINES" = "2" ]; then
170                        LCD_OUT2="[ FAIL  ]"
171                        $LCD_PROG "$LCD_OUT1" "$LCD_OUT2" > /dev/null 2>&1
172                else
173                        LCD_OUT2="${LCD_OUT1:0:10} FAIL"
174                        $LCD_PROG "$LCD_OUT2" > /dev/null 2>&1
175                fi
176        fi
177}
178
179echo_warning()
180{
181        echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${WARNING} WARN ${BRACKET}]"
182        echo -e "${NORMAL}"
183        if [ "$LCD_PROG" ]; then
184                if [ "$LCD_LINES" = "2" ]; then
185                        LCD_OUT2="[ WARN  ]"
186                        $LCD_PROG "$LCD_OUT1" "$LCD_OUT2" > /dev/null 2>&1
187                else
188                        LCD_OUT2="${LCD_OUT1:0:10} WARN"
189                        $LCD_PROG "$LCD_OUT2" > /dev/null 2>&1
190                fi                     
191        fi
192        boot_mesg_flush "[ WARN ]"
193}
194
195print_error_msg()
196{
197        echo_failure
198        # $i is inherited by the rc script
199        boot_log "\n\n${i} failed and exited with a return value of ${error_value}."
200        boot_mesg_flush
201        boot_mesg -n "FAILURE:\n\nYou should not be reading this error message.\n\n" ${FAILURE}
202        boot_mesg -n " It means that an unforeseen error took"
203        boot_mesg -n " place in ${i}, which exited with a return value of"
204        boot_mesg " ${error_value}.\n"
205        boot_mesg_flush
206        boot_mesg -n "If you're able to track this"
207        boot_mesg -n " error down to a bug in one of the files provided by"
208        boot_mesg -n " the CLFS book, please be so kind to inform us at"
209        boot_mesg " clfs-dev@cross-lfs.org.\n"
210        boot_mesg_flush
211        if [ "$INTERACTIVE" ]; then
212                boot_mesg -n "Press Enter to continue..." ${INFO}
213                boot_mesg "" ${NORMAL}
214                if [ "$LCD_PROG" ]; then
215                        sleep 10
216                else
217                        read ENTER
218                fi
219        fi
220}
221
222check_script_status()
223{
224        # $i is inherited by the rc script
225        if [ ! -f ${i} ]; then
226                boot_mesg "${i} is not a valid symlink." ${WARNING}
227                echo_warning
228                continue
229        fi
230
231        if [ ! -x ${i} ]; then
232                boot_mesg "${i} is not executable, skipping." ${WARNING}
233                echo_warning
234                continue
235        fi
236}
237
238evaluate_retval()
239{
240        error_value="${?}"
241
242        if [ ${error_value} = 0 ]; then
243                echo_ok
244        else
245                echo_failure
246        fi
247
248        # This prevents the 'An Unexpected Error Has Occurred' from trivial
249        # errors.
250        return 0
251}
252
253print_status()
254{
255        if [ "${#}" = "0" ]; then
256                echo "Usage: ${0} {success|warning|failure}"
257                return 1
258        fi
259
260#       boot_mesg_flush
261#       echo_warning
262
263        case "${1}" in
264
265                success)
266                        echo_ok
267                        ;;
268
269                warning)
270                        # Leave this extra case in because old scripts
271                        # may call it this way.
272                        case "${2}" in
273                                running)
274                                        echo -e -n "${CURS_UP}"
275                                        echo -e -n "\\033[${STRING_LENGTH}G   "
276                                        boot_mesg "Already running." ${WARNING}
277                                        echo_warning
278                                        ;;
279                                not_running)
280                                        echo -e -n "${CURS_UP}"
281                                        echo -e -n "\\033[${STRING_LENGTH}G   "
282                                        boot_mesg "Not running." ${WARNING}
283                                        echo_warning
284                                        ;;
285                                not_available)
286                                        echo -e -n "${CURS_UP}"
287                                        echo -e -n "\\033[${STRING_LENGTH}G   "
288                                        boot_mesg "Not available." ${WARNING}
289                                        echo_warning
290                                        ;;
291                                *)
292                                        # This is how it is supposed to
293                                        # be called
294                                        echo_warning
295                                        ;;
296                        esac
297                ;;
298
299                failure)
300                        echo_failure
301                ;;
302
303        esac
304
305}
306
307reloadproc()
308{
309        if [ "${#}" = "0" ]; then
310                echo "Usage: reloadproc [{program}]"
311                exit 1
312        fi
313
314        getpids "${1}"
315
316        if [ -n "${pidlist}" ]; then
317                failure="0"
318                for pid in ${pidlist}
319                do
320                        kill -"${RELOADSIG}" "${pid}" || failure="1"
321                done
322
323                (exit ${failure})
324                evaluate_retval
325
326        else
327                boot_mesg "Process ${1} not running." ${WARNING}
328                echo_warning
329        fi
330}
331
332statusproc()
333{
334        if [ "${#}" = "0" ]
335        then
336                echo "Usage: statusproc {program}"
337                exit 1
338        fi
339
340        getpids "${1}"
341
342        if [ -n "${pidlist}" ]; then
343                echo -e "${INFO}${base} is running with Process"\
344                        "ID(s) ${pidlist}.${NORMAL}"
345        else
346                if [ -n "${base}" -a -e "/var/run/${base}.pid" ]; then
347                        echo -e "${WARNING}${1} is not running but"\
348                                "/var/run/${base}.pid exists.${NORMAL}"
349                else
350                        if [ -n "${PIDFILE}" -a -e "${PIDFILE}" ]; then
351                                echo -e "${WARNING}${1} is not running"\
352                                        "but ${PIDFILE} exists.${NORMAL}"
353                        else
354                                echo -e "${INFO}${1} is not running.${NORMAL}"
355                        fi
356                fi
357        fi
358}
359
360# The below functions are documented in the LSB-generic 2.1.0
361
362#*******************************************************************************
363# Function - pidofproc [-s] [-p pidfile] pathname
364#
365# Purpose: This function returns one or more pid(s) for a particular daemon
366#
367# Inputs: -p pidfile, use the specified pidfile instead of pidof
368#         pathname, path to the specified program
369#
370# Outputs: return 0 - Success, pid's in stdout
371#          return 1 - Program is dead, pidfile exists
372#          return 2 - Invalid or excessive number of arguments,
373#                     warning in stdout
374#          return 3 - Program is not running
375#
376# Dependencies: pidof, echo, head
377#
378# Todo: Remove dependency on head
379#       This depreciates getpids
380#       Test changes to pidof
381#
382#*******************************************************************************
383pidofproc()
384{
385        local pidfile=""
386        local lpids=""
387        local silent=""
388        pidlist=""
389        while true
390        do
391                case "${1}" in
392                        -p)
393                                pidfile="${2}"
394                                shift 2
395                                ;;
396
397                        -s)
398                                # Added for legacy opperation of getpids
399                                # eliminates several '> /dev/null'
400                                silent="1"
401                                shift 1
402                                ;;
403                        -*)
404                                log_failure_msg "Unknown Option: ${1}"
405                                return 2
406                                ;;
407                        *)
408                                break
409                                ;;
410                esac
411        done
412
413        if [ "${#}" != "1" ]; then
414                shift 1
415                log_failure_msg "Usage: pidofproc [-s] [-p pidfile] pathname"
416                return 2
417        fi
418
419        if [ -n "${pidfile}" ]; then
420                if [ ! -r "${pidfile}" ]; then
421                        return 3 # Program is not running
422                fi
423
424                lpids=`head -n 1 ${pidfile}`
425                for pid in ${lpids}
426                do
427                        if [ "${pid}" -ne "$$" -a "${pid}" -ne "${PPID}" ]; then
428                                kill -0 "${pid}" > /dev/null &&
429                                pidlist="${pidlist} ${pid}"
430                        fi
431                       
432                        if [ "${silent}" -ne "1" ]; then
433                                echo "${pidlist}"
434                        fi
435
436                        test -z "${pidlist}" && 
437                        # Program is dead, pidfile exists
438                        return 1
439                        # else
440                        return 0
441                done
442
443        else
444                pidlist=`pidof -o $$ -o $PPID -x "$1"`
445                if [ "x${silent}" != "x1" ]; then
446                        echo "${pidlist}"
447                fi
448
449                # Get provide correct running status
450                if [ -n "${pidlist}" ]; then
451                        return 0
452                else
453                        return 3
454                fi
455
456        fi
457
458        if [ "$?" != "0" ]; then
459                return 3 # Program is not running
460        fi
461}
462
463# This will ensure compatibility with previous CLFS Bootscripts
464getpids()
465{
466        if [ -z "${PIDFILE}" ]; then
467                pidofproc -s -p "${PIDFILE}" $@
468        else
469                pidofproc -s $@
470        fi
471        base="${1##*/}"
472}
473
474#*******************************************************************************
475# Function - loadproc [-f] [-n nicelevel] [-p pidfile] pathname [args]
476#
477# Purpose: This runs the specified program as a daemon
478#
479# Inputs: -f, run the program even if it is already running
480#         -n nicelevel, specifies a nice level. See nice(1).
481#         -p pidfile, uses the specified pidfile
482#         pathname, pathname to the specified program
483#         args, arguments to pass to specified program
484#
485# Outputs: return 0 - Success
486#          return 2 - Invalid of excessive number of arguments,
487#                     warning in stdout
488#          return 4 - Program or service status is unknown
489#
490# Dependencies: nice
491#
492# Todo: LSB says this should be called start_daemon
493#       LSB does not say that it should call evaluate_retval
494#       It checks for PIDFILE, which is deprecated.
495#         Will be removed after BLFS 6.0
496#       loadproc returns 0 if program is already running, not LSB compliant
497#
498#*******************************************************************************
499loadproc()
500{
501        local pidfile=""
502        local forcestart=""
503        local nicelevel="10"
504
505# This will ensure compatibility with previous CLFS Bootscripts
506        if [ -n "${PIDFILE}" ]; then
507                pidfile="${PIDFILE}"
508        fi
509
510  while true
511        do
512                case "${1}" in
513                        -f)
514                                forcestart="1"
515                                shift 1
516                                ;;
517                        -n)
518                                nicelevel="${2}"
519                                shift 2
520                                ;;
521                        -p)
522                                pidfile="${2}"
523                                shift 2
524                                ;;
525                        -*)
526                                log_failure_msg "Unknown Option: ${1}"
527                                return 2 #invalid or excess argument(s)
528                                ;;
529                        *)
530                                break
531                                ;;
532                esac
533        done
534
535        if [ "${#}" = "0" ]; then
536                log_failure_msg "Usage: loadproc [-f] [-n nicelevel] [-p pidfile] pathname [args]"
537                return 2 #invalid or excess argument(s)
538        fi
539
540        if [ -z "${forcestart}" ]; then
541                if [ -z "${pidfile}" ]; then
542                        pidofproc -s "${1}"
543                else
544                        pidofproc -s -p "${pidfile}" "${1}"
545                fi
546
547                case "${?}" in
548                        0)
549                                log_warning_msg "Unable to continue: ${1} is running"
550                                return 0 # 4
551                                ;;
552                        1)
553                                log_warning_msg "Unable to continue: ${pidfile} exists"
554                                return 0 # 4
555                                ;;
556                        3)
557                                ;;
558                        *)
559                                log_failure_msg "Unknown error code from pidofproc: ${?}"
560                                return 4
561                                ;;
562                esac
563        fi
564
565        nice -n "${nicelevel}" "${@}"
566        evaluate_retval # This is "Probably" not LSB compliant, but required to be compatible with older bootscripts
567        return 0
568}
569
570#*******************************************************************************
571# Function - killproc  [-p pidfile] pathname [signal]
572#
573# Purpose:
574#
575# Inputs: -p pidfile, uses the specified pidfile
576#         pathname, pathname to the specified program
577#         signal, send this signal to pathname
578#
579# Outputs: return 0 - Success
580#          return 2 - Invalid of excessive number of arguments,
581#                     warning in stdout
582#          return 4 - Unknown Status
583#
584# Dependencies: kill
585#
586# Todo: LSB does not say that it should call evaluate_retval
587#       It checks for PIDFILE, which is deprecated.
588#         Will be removed after BLFS 6.0
589#
590#*******************************************************************************
591killproc()
592{
593        local pidfile=""
594        local killsig=""
595        pidlist=""
596
597# This will ensure compatibility with previous CLFS Bootscripts
598        if [ -n "${PIDFILE}" ]; then
599                pidfile="${PIDFILE}"
600        fi
601
602        while true
603        do
604                case "${1}" in
605                        -p)
606                                pidfile="${2}"
607                                shift 2
608                                ;;
609                        -*)
610                                log_failure_msg "Unknown Option: ${1}"
611                                return 2
612                        ;;
613                        *)
614                                break
615                                ;;
616                esac
617        done
618
619        if [ "${#}" = "2" ]; then
620                killsig="${2}"
621        elif [ "${#}" != "1" ]; then
622                shift 2
623                log_failure_msg "Usage: killproc  [-p pidfile] pathname [signal]"
624                return 2
625        fi
626
627        if [ -z "${pidfile}" ]; then
628                pidofproc -s "${1}"
629        else
630                pidofproc -s -p "${pidfile}" "${1}"
631        fi
632
633    # Change....
634    if [ -n "${pidlist}" ]; then
635        for pid in ${pidlist}
636        do
637                kill -${killsig:-TERM} ${pid} 2>/dev/null
638                if [ -z "${killsig}" ]; then
639                        # Wait up to 3 seconds, for ${pid} to terminate
640                        local dtime=${KILLDELAY}
641                        while [ "${dtime}" != "0" ]
642                        do
643                                kill -0 ${pid} 2>/dev/null || break
644                                sleep 1
645                                dtime=$(( ${dtime} - 1))
646                        done
647                        # If ${pid} is still running, kill it
648                        kill -0 ${pid} 2>/dev/null && kill -KILL ${pid} 2>/dev/null
649                fi
650        done
651
652        if [ -z "${killsig}" ]; then
653                pidofproc -s "${1}"
654
655                # Program was terminated
656                if [ "$?" != "0" ]; then
657                        # Pidfile Exists
658                        if [ -f "${pidfile}" ]; then
659                                rm -f "${pidfile}"
660                        fi
661                        echo_ok
662                        return 0
663                else # Program is still running
664                        echo_failure
665                        return 4 # Unknown Status
666                fi
667        else
668                if [ -z "${pidfile}" ]; then
669                        pidofproc -s "${1}"
670                else
671                        pidofproc -s -p "${pidfile}" "${1}"
672                fi
673        fi
674
675        evaluate_retval # This is "Probably" not LSB compliant, but required to be compatible with older bootscripts
676
677    else
678        print_status warning not_running
679    fi
680}
681
682
683#*******************************************************************************
684# Function - log_success_msg "message"
685#
686# Purpose: Print a success message
687#
688# Inputs: $@ - Message
689#
690# Outputs: Text output to screen
691#
692# Dependencies: echo
693#
694# Todo: logging
695#
696#*******************************************************************************
697log_success_msg()
698{
699        echo -n -e "${BOOTMESG_PREFIX}${@}"
700        echo -e "${SET_COL}""${BRACKET}""[""${SUCCESS}""  OK  ""${BRACKET}""]""${NORMAL}"
701        return 0
702}
703
704#*******************************************************************************
705# Function - log_failure_msg "message"
706#
707# Purpose: Print a failure message
708#
709# Inputs: $@ - Message
710#
711# Outputs: Text output to screen
712#
713# Dependencies: echo
714#
715# Todo: logging
716#
717#*******************************************************************************
718log_failure_msg() {
719        echo -n -e "${BOOTMESG_PREFIX}${@}"
720        echo -e "${SET_COL}""${BRACKET}""[""${FAILURE}"" FAIL ""${BRACKET}""]""${NORMAL}"
721        return 0
722}
723
724#*******************************************************************************
725# Function - log_warning_msg "message"
726#
727# Purpose: print a warning message
728#
729# Inputs: $@ - Message
730#
731# Outputs: Text output to screen
732#
733# Dependencies: echo
734#
735# Todo: logging
736#
737#*******************************************************************************
738log_warning_msg() {
739        echo -n -e "${BOOTMESG_PREFIX}${@}"
740        echo -e "${SET_COL}""${BRACKET}""[""${WARNING}"" WARN ""${BRACKET}""]""${NORMAL}"
741        return 0
742}
743
744# End $rc_base/init.d/functions
Note: See TracBrowser for help on using the repository browser.