2 ########################################################################
3 # Begin $rc_base/init.d/functions
5 # Description : Run Level Control Functions
7 # Authors : Gerard Beekmans - gerard@linuxfromscratch.org
11 # Notes : With code based on Matthias Benkmann's simpleinit-msb
12 # http://winterdrache.de/linux/newboot/index.html
14 ########################################################################
16 ## Environmental setup
17 # Setup default values for environment
19 export PATH
="/bin:/usr/bin:/sbin:/usr/sbin"
21 # Signal sent to running processes to refresh their configuration
24 # Number of seconds between STOPSIG and FALLBACK when stopping processes
28 # Find current screen size
29 if [ -z "${COLUMNS}" ]; then
30 COLUMNS
=$
(stty size
2>/dev
/null
)
31 COLUMNS
=${COLUMNS##* }
34 # When using remote connections, such as a serial port, stty size returns 0
35 if [ "${COLUMNS}" = "0" ]; then
39 ## Measurements for positioning result messages
40 COL
=$
((${COLUMNS} - 8))
43 ## Set Cursor Position Commands, used via echo -e
44 SET_COL
="\\033[${COL}G" # at the $COL char
45 SET_WCOL
="\\033[${WCOL}G" # at the $WCOL char
46 CURS_UP
="\\033[1A\\033[0G" # Up one line, at the 0'th char
48 ## Set color commands, used via echo -e
49 # Please consult `man console_codes for more information
50 # under the "ECMA-48 Set Graphics Rendition" section
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 NORMAL
="\\033[0;39m" # Standard console grey
57 SUCCESS
="\\033[1;32m" # Success is green
58 WARNING
="\\033[1;33m" # Warnings are yellow
59 FAILURE
="\\033[1;31m" # Failures are red
60 INFO
="\\033[1;36m" # Information is light cyan
61 BRACKET
="\\033[1;34m" # Brackets are blue
63 STRING_LENGTH
="0" # the length of the current message
65 #*******************************************************************************
66 # Function - boot_mesg()
68 # Purpose: Sending information from bootup scripts to the console
70 # Inputs: $1 is the message
71 # $2 is the colorcode for the console
73 # Outputs: Standard Output
75 # Dependencies: - sed for parsing strings.
76 # - grep for counting string length.
79 #*******************************************************************************
92 echo "Unknown Option: ${1}"
101 ## Figure out the length of what is to be printed to be used
102 ## for warning messges.
103 STRING_LENGTH
="`echo "${1}" | sed \
104 -e 's,.,.,g' -e 'l 1' | grep -c \$`"
106 # Print the message to the screen
107 echo ${ECHOPARM} -e "${2}${1}"
113 # Reset STRING_LENGTH for next message
119 # Left in for backwards compatibility
125 echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${SUCCESS} OK ${BRACKET}]"
132 echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${FAILURE} FAIL ${BRACKET}]"
139 echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${WARNING} WARN ${BRACKET}]"
147 # $i is inherited by the rc script
148 boot_mesg -n "FAILURE
:\n\nYou should not be reading this error message.
\n\n" ${FAILURE}
149 boot_mesg -n " It means that an unforeseen error took
"
150 boot_mesg -n " place
in ${i}, which exited with a
return value of
"
151 boot_mesg " ${error_value}.
\n"
153 boot_mesg -n "If you
're able to track this"
154 boot_mesg -n " error down to a bug in one of the files provided by"
155 boot_mesg -n " ipfire, please be so kind to inform us at"
156 boot_mesg " https://bugzilla.ipfire.org.\n"
158 boot_mesg -n "Press Enter to continue or wait a minute..." ${INFO}
159 boot_mesg "" ${NORMAL}
163 check_script_status()
165 # $i is inherited by the rc script
166 if [ ! -f ${i} ]; then
167 boot_mesg "${i} is not a valid symlink." ${WARNING}
172 if [ ! -x ${i} ]; then
173 boot_mesg "${i} is not executable, skipping." ${WARNING}
183 if [ ${error_value} = 0 ]; then
189 # This prevents the 'An Unexpected Error Has Occurred
' from trivial
196 if [ "${#}" = "0" ]; then
197 echo "Usage: ${0} {success|warning|failure}"
208 # Leave this extra case in because old scripts
209 # may call it this way.
212 echo -e -n "${CURS_UP}"
213 echo -e -n "\\033[${STRING_LENGTH}G "
214 boot_mesg "Already running." ${WARNING}
218 echo -e -n "${CURS_UP}"
219 echo -e -n "\\033[${STRING_LENGTH}G "
220 boot_mesg "Not running." ${WARNING}
224 echo -e -n "${CURS_UP}"
225 echo -e -n "\\033[${STRING_LENGTH}G "
226 boot_mesg "Not available." ${WARNING}
230 # This is how it is supposed to
247 if [ "${#}" = "0" ]; then
248 echo "Usage: reloadproc [{program}]"
254 if [ -n "${pidlist}" ]; then
256 for pid in ${pidlist}
258 kill -"${RELOADSIG}" "${pid}" || failure="1"
265 boot_mesg "Process ${1} not running." ${WARNING}
274 echo "Usage: statusproc {program}"
280 if [ -n "${pidlist}" ]; then
281 echo -e "${INFO}${base} is running with Process"\
282 "ID(s) ${pidlist}.${NORMAL}"
284 if [ -n "${base}" -a -e "/var/run/${base}.pid" ]; then
285 echo -e "${WARNING}${1} is not running but"\
286 "/var/run/${base}.pid exists.${NORMAL}"
288 if [ -n "${PIDFILE}" -a -e "${PIDFILE}" ]; then
289 echo -e "${WARNING}${1} is not running"\
290 "but ${PIDFILE} exists.${NORMAL}"
292 echo -e "${INFO}${1} is not running.${NORMAL}"
298 # The below functions are documented in the LSB-generic 2.1.0
300 #*******************************************************************************
301 # Function - pidofproc [-s] [-p pidfile] pathname
303 # Purpose: This function returns one or more pid(s) for a particular daemon
305 # Inputs: -p pidfile, use the specified pidfile instead of pidof
306 # pathname, path to the specified program
308 # Outputs: return 0 - Success, pid's
in stdout
309 # return 1 - Program is dead, pidfile exists
310 # return 2 - Invalid or excessive number of arguments,
312 # return 3 - Program is not running
314 # Dependencies: pidof, echo, head
316 # Todo: Remove dependency on head
317 # This depreciates getpids
318 # Test changes to pidof
320 #*******************************************************************************
336 # Added for legacy opperation of getpids
337 # eliminates several '> /dev/null'
342 log_failure_msg
"Unknown Option: ${1}"
351 if [ "${#}" != "1" ]; then
353 log_failure_msg
"Usage: pidofproc [-s] [-p pidfile] pathname"
357 if [ -n "${pidfile}" ]; then
358 if [ ! -r "${pidfile}" ]; then
359 return 3 # Program is not running
362 lpids
=`head -n 1 ${pidfile}`
365 if [ "${pid}" -ne "$$" -a "${pid}" -ne "${PPID}" ]; then
366 kill -0 "${pid}" > /dev
/null
&&
367 pidlist
="${pidlist} ${pid}"
370 if [ "${silent}" -ne "1" ]; then
374 test -z "${pidlist}" &&
375 # Program is dead, pidfile exists
382 pidlist
=`pidof -o $$ -o $PPID -x "$1"`
383 if [ "x${silent}" != "x1" ]; then
387 # Get provide correct running status
388 if [ -n "${pidlist}" ]; then
396 if [ "$?" != "0" ]; then
397 return 3 # Program is not running
401 # This will ensure compatibility with previous LFS Bootscripts
404 if [ -z "${PIDFILE}" ]; then
405 pidofproc
-s -p "${PIDFILE}" $@
412 #*******************************************************************************
413 # Function - loadproc [-f] [-n nicelevel] [-p pidfile] pathname [args]
415 # Purpose: This runs the specified program as a daemon
417 # Inputs: -f, run the program even if it is already running
418 # -n nicelevel, specifies a nice level. See nice(1).
419 # -p pidfile, uses the specified pidfile
420 # pathname, pathname to the specified program
421 # args, arguments to pass to specified program
423 # Outputs: return 0 - Success
424 # return 2 - Invalid of excessive number of arguments,
426 # return 4 - Program or service status is unknown
430 # Todo: LSB says this should be called start_daemon
431 # LSB does not say that it should call evaluate_retval
432 # It checks for PIDFILE, which is deprecated.
433 # Will be removed after BLFS 6.0
434 # loadproc returns 0 if program is already running, not LSB compliant
436 #*******************************************************************************
444 # This will ensure compatibility with previous LFS Bootscripts
445 if [ -n "${PIDFILE}" ]; then
469 log_failure_msg
"Unknown Option: ${1}"
470 return 2 #invalid or excess argument(s)
478 if [ "${#}" = "0" ]; then
479 log_failure_msg
"Usage: loadproc [-f] [-n nicelevel] [-p pidfile] pathname [args]"
480 return 2 #invalid or excess argument(s)
483 if [ -z "${forcestart}" ]; then
484 if [ -z "${pidfile}" ]; then
487 pidofproc
-s -p "${pidfile}" "${1}"
492 log_warning_msg
"Unable to continue: ${1} is running"
496 log_warning_msg
"Unable to continue: ${pidfile} exists"
502 log_failure_msg
"Unknown error code from pidofproc: ${?}"
510 if [ -n "${nicelevel}" ]; then
511 cmd
="nice -n "${nicelevel}" ${cmd}"
514 if [ -n "${background}" ]; then
521 evaluate_retval
# This is "Probably" not LSB compliant, but required to be compatible with older bootscripts
527 #*******************************************************************************
528 # Function - killproc [-p pidfile] pathname [signal]
532 # Inputs: -p pidfile, uses the specified pidfile
533 # pathname, pathname to the specified program
534 # signal, send this signal to pathname
536 # Outputs: return 0 - Success
537 # return 2 - Invalid of excessive number of arguments,
539 # return 4 - Unknown Status
543 # Todo: LSB does not say that it should call evaluate_retval
544 # It checks for PIDFILE, which is deprecated.
545 # Will be removed after BLFS 6.0
547 #*******************************************************************************
554 # This will ensure compatibility with previous LFS Bootscripts
555 if [ -n "${PIDFILE}" ]; then
567 log_failure_msg
"Unknown Option: ${1}"
576 if [ "${#}" = "2" ]; then
578 elif [ "${#}" != "1" ]; then
580 log_failure_msg
"Usage: killproc [-p pidfile] pathname [signal]"
584 if [ -z "${pidfile}" ]; then
587 pidofproc
-s -p "${pidfile}" "${1}"
591 if [ -n "${pidlist}" ]; then
592 for pid
in ${pidlist}
594 kill -${killsig:-TERM} ${pid} 2>/dev
/null
595 if [ -z "${killsig}" ]; then
596 # Wait up to 3 seconds, for ${pid} to terminate
597 local dtime
=${KILLDELAY}
598 while [ "${dtime}" != "0" ]
600 kill -0 ${pid} 2>/dev
/null ||
break
602 dtime
=$
(( ${dtime} - 1))
604 # If ${pid} is still running, kill it
605 kill -0 ${pid} 2>/dev
/null
&& kill -KILL ${pid} 2>/dev
/null
609 if [ -z "${killsig}" ]; then
612 # Program was terminated
613 if [ "$?" != "0" ]; then
615 if [ -f "${pidfile}" ]; then
620 else # Program is still running
622 return 4 # Unknown Status
625 if [ -z "${pidfile}" ]; then
628 pidofproc
-s -p "${pidfile}" "${1}"
632 evaluate_retval
# This is "Probably" not LSB compliant, but required to be compatible with older bootscripts
635 print_status warning not_running
640 #*******************************************************************************
641 # Function - log_success_msg "message"
643 # Purpose: Print a success message
645 # Inputs: $@ - Message
647 # Outputs: Text output to screen
653 #*******************************************************************************
656 echo -n -e "${BOOTMESG_PREFIX}${@}"
657 echo -e "${SET_COL}""${BRACKET}""[""${SUCCESS}"" OK ""${BRACKET}""]""${NORMAL}"
661 #*******************************************************************************
662 # Function - log_failure_msg "message"
664 # Purpose: Print a failure message
666 # Inputs: $@ - Message
668 # Outputs: Text output to screen
674 #*******************************************************************************
676 echo -n -e "${BOOTMESG_PREFIX}${@}"
677 echo -e "${SET_COL}""${BRACKET}""[""${FAILURE}"" FAIL ""${BRACKET}""]""${NORMAL}"
681 #*******************************************************************************
682 # Function - log_warning_msg "message"
684 # Purpose: print a warning message
686 # Inputs: $@ - Message
688 # Outputs: Text output to screen
694 #*******************************************************************************
696 echo -n -e "${BOOTMESG_PREFIX}${@}"
697 echo -e "${SET_COL}""${BRACKET}""[""${WARNING}"" WARN ""${BRACKET}""]""${NORMAL}"
703 for i
in $
(ls -v ${DIR}* 2> /dev
/null
); do
705 OUT
=$
(echo $
(basename ${i}) |
awk -F- '{ print $2 }')
719 local pagesize
="$(getconf PAGESIZE)"
720 local pages
="$(getconf _PHYS_PAGES)"
722 echo "$(( ${pagesize} * ${pages} / 1024 / 1024 ))"
726 eval $
(/usr
/local
/bin
/readhash
/etc
/sysconfig
/ramdisk
)
728 case "${RAMDISK_MODE}" in
739 # Automatic mode - use ramdisk if sufficient
740 # memory is available
742 local mem_avail
="$(mem_amount)"
744 if [ ${mem_avail} -ge 400 ]; then
751 # Fail for everything else
760 local path_tmpfs
="${path}.tmpfs"
762 # Check if the ramdisk is already mounted
763 if mountpoint
"${path}" &>/dev
/null
; then
768 mkdir
-p "${path_tmpfs}"
769 mount
-t tmpfs none
"${path_tmpfs}"
771 # Restore ramdisk content
772 cp -pR ${path}/* "${path_tmpfs}"
774 # Move ramdisk to final destination
775 mount
--move "${path_tmpfs}" "${path}"
776 rm -rf "${path_tmpfs}"
781 local path_tmpfs
="${path}.tmpfs"
783 # Check if a ramdisk is actually mounted
784 if ! mountpoint
"${path}" &>/dev
/null
; then
789 mkdir
-p "${path_tmpfs}"
790 mount
--move "${path}" "${path_tmpfs}"
792 # Backup ramdisk content
793 cp -pR ${path_tmpfs}/* "${path}"
795 # Destroy the ramdisk
796 umount
"${path_tmpfs}"
797 rm -rf "${path_tmpfs}"
800 # Returns true when this system running in a virtual environment
801 running_on_hypervisor
() {
802 grep -qE "^flags\s+:.*hypervisor" /proc
/cpuinfo
805 # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/identify_ec2_instances.html
809 # Check if the DMI product UUID starts with EC2
810 if [ -r "/sys/devices/virtual/dmi/id/product_uuid" ]; then
811 uuid
=$
(</sys
/devices
/virtual
/dmi
/id
/product_uuid
)
813 # Convert the UUID as uppercase
816 [ "${uuid:0:3}" = "EC2" ] && return 0
819 # We are not running on AWS EC2
824 # Check if the vendor is Microsoft
825 if [ -r "/sys/devices/virtual/dmi/id/sys_vendor" ] && \
826 [ "$(</sys/devices/virtual/dmi/id/sys_vendor)" = "Microsoft Corporation" ]; then
827 # Check if this product is a "Virtual Machine"
828 if [ -r "/sys/devices/virtual/dmi/id/product_name" ] && \
829 [ "$(</sys/devices/virtual/dmi/id/product_name)" = "Virtual Machine" ]; then
830 # Yes, we are running on Azure
835 # We are not running on Azure
839 running_on_exoscale
() {
840 if [ -r "/sys/devices/virtual/dmi/id/sys_vendor" ]; then
841 local sys_vendor
="$(</sys/devices/virtual/dmi/id/sys_vendor)"
843 [ "${sys_vendor}" = "Exoscale" ] && return 0
846 # We are not running on Exoscale
851 # Check if the BIOS vendor is "Google"
852 if [ -r "/sys/devices/virtual/dmi/id/bios_vendor" ]; then
853 local bios_vendor
="$(</sys/devices/virtual/dmi/id/bios_vendor)"
855 [ "${bios_vendor}" = "Google" ] && return 0
858 # We are not running on GCP
863 if [ -r "/sys/devices/virtual/dmi/id/chassis_asset_tag" ]; then
864 local asset_tag
="$(</sys/devices/virtual/dmi/id/chassis_asset_tag)"
866 [ "${asset_tag}" = "OracleCloud.com" ] && return 0
869 # We are not running on OCI
873 # End $rc_base/init.d/functions