1 #!/bin/sh - keep it for file(1) to get bourne shell script result
2 # functions This file contains functions to be used by most or all
3 # shell scripts in the /etc/init.d directory.
7 # Author: Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
8 # Hacked by: Greg Galloway and Marc Ewing
9 # Modified for PLD Linux by:
10 # Marek Obuchowicz <elephant@pld-linux.org>
11 # Arkadiusz Mi¶kiewicz <misiek@pld-linux.org>
12 # Micha³ Kochanowicz <mkochano@pld-linux.org>
13 # £ukasz Pawelczyk <havner@pld-linux.org>
15 # First set up a default search path.
16 export PATH="/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin"
21 [ -z "${CONSOLETYPE}" ] && CONSOLETYPE="$(/sbin/consoletype)"
32 # Bold definition (second parameter to termput setaf)
36 CBRACKETS="$CYAN" # brackets [ ] color
37 CDONE="$GREEN" # DONE and WORK color
38 CBUSY="$MAGENTA" # BUSY color
39 CFAIL="$RED" # FAIL and DIED color
40 CPOWEREDBY="$CYAN" # "Powered by" color
41 CPLD="$GREEN" # "PLD Linux Distribution" color
42 CI="$RED" # Capital I color (press I to enter interactive startup)
43 CRESMAN="$GREEN" # "Resource Manager" color
44 CHARS="" # Characters displayed on the begining of show line
45 CCHARS="$NORMAL" # Color of these characters (look at /etc/sysconfig/init-colors.gentoo example)
47 # Source configuration if available - may override default values
48 [ -r /etc/sysconfig/init-colors ] && . /etc/sysconfig/init-colors
49 [ -r /etc/sysconfig/system ] && . /etc/sysconfig/system
50 [ -r /etc/sysconfig/bootsplash ] && . /etc/sysconfig/bootsplash
52 [ -z "$COLUMNS" ] && COLUMNS=80
54 if [ -z "$VSERVER" -o "$VSERVER" = "detect" ]; then
55 _ctx="$(awk '/(s_context|VxID):.*/ { print $2 }' /proc/self/status 2>/dev/null)"
56 if [ -z "$_ctx" -o "$_ctx" = "0" ]; then
64 if [ -n "$INITNG" ]; then
69 if [ -z "$GETTEXT" ]; then
70 if [ -x /bin/gettext -o -x /usr/bin/gettext ]; then
77 if [ -n "$TPUT" ]; then
78 if [ -d /usr/share/terminfo ] && [ -x /usr/bin/tput -o -x /bin/tput ] ; then
80 # check if we are on proper terminal
81 tput longname >/dev/null 2>&1 || TPUT=no
91 msg_usage " is_yes {value}"
97 yes|Yes|YES|true|True|TRUE|on|On|ON|Y|y|1)
112 msg_usage " is_no {value}"
117 no|No|NO|false|False|FALSE|off|Off|OFF|N|n|0)
128 if is_yes "$FASTRC"; then
129 INIT_DOTS=$(awk "BEGIN{for(\$i=0;\$i<$INIT_COL;\$i++)printf(\".\");}")
133 if is_yes "${IN_SHUTDOWN}" || is_no "${RC_LOGGING}" ; then
137 while [ "$1" != "${1##-}" ] || [ "$1" != "${1##+}" ]; do
156 awk '{split($3,v,"."); printf("%03d%03d%03d\n", v[1],v[2],v[3]);}' /proc/version
161 awk '{split($3,v,"."); printf("%03d%03d\n", v[1],v[2]);}' /proc/version
166 awk '{split($3,v,"."); printf("%03d\n", v[1]);}' /proc/version
173 if is_yes "$FASTRC" || is_no "$TPUT"; then
176 echo -ne "\033[$(($2+1))G"
179 echo -ne "\033[${2}A"
191 is_yes "$COLOR_INIT" && echo -ne "\033[${ISBOLD};3${2}m"
194 termput setaf $NORMAL
203 if [ "$3" == "1" ]; then tput bold; else tput sgr0; fi
204 is_yes "$COLOR_INIT" && tput setaf "$2"
207 termput setaf $NORMAL
213 if [ ! -x /bin/printf ]; then
215 # FIXME: buggy when single or double quotes in message!
221 if [ $# -gt 0 ]; then
224 while [ $# -gt 0 ]; do
229 awk "BEGIN {printf \"$text\", \"$m\"; }"
233 # National language support function
236 typeset msg_echo nls_domain text message
238 nls_domain="$NLS_DOMAIN"
239 while [ "$1" != "${1##-}" ] || [ "$1" != "${1##+}" ]; do
255 # empty message, so we return --misiek
256 if [ -z "$message" ]; then
261 if is_yes "$FASTRC"; then
262 printf "$message" "$@"
263 elif is_yes "$GETTEXT"; then
264 text=$(TEXTDOMAINDIR="/etc/sysconfig/locale" gettext -e --domain="${nls_domain:-rc-scripts}" "$message")
267 printf "$message" "$@"
279 if ! is_no "$BOOT_SPLASH" && ! is_yes "$VSERVER"; then
280 [ -x /bin/splash ] && /bin/splash "$action"
288 nls "ERROR: Networking is down. %s can't be run." "$1" >&2
293 show "Starting %s service" "$1"
296 msg_already_running()
298 nls "%s service is already running." "$1"
303 show "Stopping %s service" "$1"
308 nls "%s service is not running." "$1"
313 show "Reloading %s service" "$1"
321 # Some functions to handle PLD Linux-style messages
326 if is_yes "$FASTRC"; then
329 if [ -n "$CHARS" ]; then
330 termput setaf $CCHARS
335 termput hpa $INIT_COL
338 if [ -n "$CHARS" ]; then
339 termput setaf $CCHARS
344 awk "BEGIN { for (j=length(\"$CHARS$text\"); j<$INIT_COL; j++) printf \".\" }"
348 # Displays message in square brackests ("[ DONE ]"). Takes two arguments.
349 # First is the text to display, second is color number to use (argument to
350 # tput setaf). If second argument is not given, default (2, green) will be
355 if [ -n "$2" ]; then COLOR="$2"; else COLOR="$CDONE"; fi
357 echo -n "$(termput setaf $CBRACKETS)[$(termput setaf $COLOR) $(nls --nls-domain rc-scripts "$1") $(termput setaf $CBRACKETS)]$(termput op)"
362 progress "BUSY" "$CBUSY"
379 progress "FAIL" "$CFAIL"
386 progress "DIED" "$CFAIL"
393 termput hpa $INIT_COL
396 # Check if $pid (could be plural) are running
400 [ -d "/proc/$1" ] && return 0
406 # - outside chroot get only those processes, which are outside chroot.
407 # - inside chroot get only those processes, which are inside chroot.
408 # - don't filter out pids which do not have corresponding running processes (process died etc)
409 # (note: some processes like named are chrooted but run outside chroot)
410 # - do nothing inside vserver
413 if is_yes "$VSERVER"; then
417 if [ $# -lt 1 -o ! -d /proc/1 ] ; then
422 for root_pid in $@; do
423 root_dir=$(resolvesymlink /proc/${root_pid}/root)
424 if [ -n "$root_dir" ]; then
426 if [ -n "${SYSTEM_CHROOTS}" ]; then
427 for r_dir in ${SYSTEM_CHROOTS}; do
428 echo "$root_dir" | grep -q "^${r_dir}" && good_add_pid=0
431 [ "$good_add_pid" -eq 1 ] && good_pids="$good_pids $root_pid"
432 elif [ ! -d "/proc/$root_pid" ]; then
433 good_pids="$good_pids $root_pid"
439 # Usage run_cmd Message command_to_run
442 typeset exit_code errors message force_err
443 typeset -i force_err=0
444 typeset -i exit_code=0
452 show "$message"; busy
455 if errors=$(HOME=/tmp TMPDIR=/tmp initlog -c "$*" 2>&1); then
457 log_success "$1 $message"
460 log_failed "$1 $message"
463 [ -n "$errors" ] && [ $exit_code -eq 1 -o $force_err -eq 1 ] && echo "$errors"
467 # A function to start a program (now it's useful on read-only filesystem too)
470 typeset errors="" prog="" limits="" waitname="" waittime=""
471 typeset -i exit_code=0
472 [ -z "$DEFAULT_SERVICE_RUN_NICE_LEVEL" ] && DEFAULT_SERVICE_RUN_NICE_LEVEL=0
473 # "-u unlimited" (-p for ksh) to make sure daemons will be able to fork.
474 # "-c 0" to make sure it doesn't core dump anywhere; while this could mask
475 # problems with the daemon, it also closes some security problems.
476 # Users' limits are set via pam_limits.
477 [ -z "$DEFAULT_SERVICE_LIMITS" ] && DEFAULT_SERVICE_LIMITS_HARD="-u unlimited -c 0"
478 # Test syntax. Don't use -o instead || here - this will break ksh --misiek
479 while [ "$1" != "${1##-}" ] || [ "$1" != "${1##+}" ]; do
482 msg_usage " daemon [--user user] [--fork] [+/-nicelevel] {program}"
486 # for compatibility with redhat/mandrake
487 nls "warning: --check option is ignored!"
493 [ "$1" != "root" ] && prog="/bin/su $1 -s /bin/sh -c \""
497 prog="/usr/bin/setsid sh -c \""
511 -*|+*) SERVICE_RUN_NICE_LEVEL=$1
516 # If command to execute ends with quotation mark, add remaining
517 # arguments and close quotation.
518 if [ "$prog" != "${prog%\"}" ]; then
519 prog="$prog $*$end\""
524 if [ -n "$KSH_VERSION" ]; then
525 limits="`echo "${SERVICE_LIMITS:-$DEFAULT_SERVICE_LIMITS}" | awk '/-Su/ {sub(/-Su/,"-Sp");} /-Hu/ {sub(/-Hu/,"-Hp");} /-u/ {sub(/-u/,"-p");} {print;}'`"
526 elif [ -n "$ZSH_VERSION" ]; then
527 limits="${SERVICE_LIMITS:-$DEFAULT_SERVICE_LIMITS}"
528 elif [ -n "$BASH_VERSION" ]; then
529 limits="${SERVICE_LIMITS:-$DEFAULT_SERVICE_LIMITS}"
530 # elif [ -n "`$SH -c 'echo ${.sh.version}' 2>/dev/null`" ]; then
533 [ -n "$limits" ] && eval `echo "$limits" | awk 'BEGIN {RS="[\n-]";} !/^ *$/ { printf("ulimit -%s ;", $0); }'`
535 [ -z "$DEFAULT_SERVICE_UMASK" ] && DEFAULT_SERVICE_UMASK=022
540 is_yes "$CPUSETS" && [ -n "$SERVICE_CPUSET" ] && echo $$ > "/dev/cpuset/${SERVICE_CPUSET}/tasks"
541 if errors=$(umask ${SERVICE_UMASK:-$DEFAULT_SERVICE_UMASK}; USER=root HOME=/tmp TMPDIR=/tmp nice -n ${SERVICE_RUN_NICE_LEVEL:-$DEFAULT_SERVICE_RUN_NICE_LEVEL} initlog -c "$prog" 2>&1); then
542 if [ -n "$waitname" -a -n "$waittime" ]; then
544 base=$(basename "$waitname")
546 pid=$(pidofproc "$waitname" "$pidfile")
547 [ -z "$pid" ] && pid=$(pidofproc "$base" "$pidfile")
549 while [ "$i" -lt "$waittime" ]; do
551 checkpid $pid && sleep 1 || break
554 log_success "$1 startup"
559 log_failed "$1 startup"
560 [ -n "$errors" ] && echo "$errors"
565 # A function to stop a program.
568 typeset notset killlevel base pid pidfile result
571 msg_usage " killproc {program} [signal]"
575 while [ "$1" != "${1##-}" ] || [ "$1" != "${1##+}" ]; do
598 # check for second arg to be kill level
599 if [ -n "$2" ] ; then
607 base=$(basename "$1")
610 pid=$(pidofproc "$1" "$pidfile")
611 [ -z "$pid" ] && pid=$(pidofproc "$base" "$pidfile")
614 if [ -n "$pid" -a "$pid" != "$$" ] && checkpid $pid 2>&1 ; then
615 if [ "$notset" = "1" ] ; then
616 if checkpid $pid 2>&1; then
617 # TERM first, then KILL if not dead
620 if checkpid $pid && sleep 1 &&
621 checkpid $pid && sleep 3 &&
629 if [ "$result" -eq 0 ]; then
631 log_failed "$1 shutdown"
634 log_success "$1 shutdown"
636 result=$(( ! $result ))
638 # use specified level only
639 if checkpid $pid > /dev/null 2>&1; then
642 if [ "$result" -eq 0 ]; then
644 log_success "$1 got $killlevel"
648 log_failed "$1 didn't get $killlevel"
653 log_failed "$1 shutdown"
658 log_failed "$1 shutdown"
662 if [ -n "$waitname" -a -n "$waittime" ]; then
664 base=$(basename "$waitname")
666 pid=$(pidofproc "$waitname" "$pidfile")
667 [ -z "$pid" ] && pid=$(pidofproc "$base" "$pidfile")
669 while [ "$i" -lt "$waittime" ]; do
671 checkpid $pid && sleep 1 || break
675 # Remove pid file if any.
676 if [ "$notset" = "1" ]; then
677 rm -f /var/run/${base}.pid
683 # A function to find the pid of a program.
686 typeset pid pidfile base
687 base=$(basename "$1")
689 [ -n "$2" ] && pidfile="$2"
693 msg_usage " pidofproc {program}"
697 # First try pidfile or "/var/run/*.pid"
698 if (echo "${pidfile}" | grep -Eq "^/"); then
701 pidfile="/var/run/${pidfile}";
703 if [ -f "${pidfile}" ] ; then
706 read line < "${pidfile}"
708 [ -z "$(echo "$p" | awk '{gsub(/[0-9]/,"");print;}')" ] && pid="$pid $p"
713 [ -z "$pid" ] && pidof -o $$ -o $PPID -o %PPID -x "$1"
714 pid=$(filter_chroot "$pid")
720 typeset base pid subsys daemon cpuset_msg
723 base=$(basename $daemon)
727 msg_usage " status {subsys} [{daemon}]"
732 pid=$(pidof -o $$ -o $PPID -o %PPID -x $daemon)
733 pid=$(filter_chroot "$pid")
735 if [ "$pid" != "" ]; then
737 if is_yes "$CPUSETS" && [ -n "$SERVICE_CPUSET" ]; then
738 if $(grep -q "$pid" "/dev/cpuset/${SERVICE_CPUSET}/tasks"); then
739 cpuset_msg=$(nls " in cpuset %s..." "$SERVICE_CPUSET")
741 cpuset_msg=$(nls " outside of configured cpuset %s..." "$SERVICE_CPUSET")
744 nls "%s (pid %s) is running%s" "$daemon" "$pid" "$cpuset_msg"
747 # pid=`ps ax | awk 'BEGIN { prog=ARGV[1]; ARGC=1 }
748 # { if ((prog == $5) || (("(" prog ")") == $5) ||
749 # (("[" prog "]") == $5) ||
750 # ((prog ":") == $5)) { print $1 ; exit 0 } }' $1`
751 # if [ "$pid" != "" ]; then
753 # if is_yes "$CPUSETS" && [ -n "$SERVICE_CPUSET" ]; then
754 # if $(grep -q "$pid" "/dev/cpuset/${SERVICE_CPUSET}/tasks"); then
755 # cpuset_msg=$(nls " in cpuset %s..." "$SERVICE_CPUSET")
757 # cpuset_msg=$(nls " outside of configured cpuset %s..." "$SERVICE_CPUSET")
760 # nls "%s (pid %s) is running%s" "$daemon" "$pid" "$cpuset_msg"
765 # Next try "/var/run/*.pid" files
766 if [ -f /var/run/${base}.pid ]; then
767 read pid < /var/run/${base}.pid
768 pid=$(filter_chroot "$pid")
769 if [ "$pid" != "" ]; then
770 nls "%s dead but pid file exists" "$subsys"
775 # See if /var/lock/subsys/$subsys exists
776 if [ -f /var/lock/subsys/$subsys ]; then
777 nls "%s dead but subsys locked" "$subsys"
780 nls "%s is stopped" "$subsys"
784 # Confirm whether we really want to run this service
787 nls -n "Start service %s (Y)es/(N)o/(C)ontinue? [Y] " "$1"
806 # module is needed (ie. is requested, is available and isn't loaded already)
809 # module name without .o at end
810 if ! (lsmod | grep -q "$1"); then
811 if (ls -R /lib/modules/$(uname -r)/ 2> /dev/null | grep -q "${1}.\(\|k\)o\(\|.gz\)"); then
822 typeset parsed single die args foo result
824 while is_no "$parsed" ; do
843 if is_yes "${single}" ; then
845 show "Loading %s kernel module(s)" "$foo"
848 if [ -x /sbin/modprobe ] ; then
849 /sbin/modprobe -s $args "$@"
855 if is_yes "${single}" ; then
857 if [ $result == "0" ] ; then
858 is_yes "$single" && ok
861 if is_yes "$die" ; then
862 nls "Could not load %s kernel module(s)" "$@"
871 initlog -n $0 -s "$1 $2" -e 1
876 initlog -n $0 -s "$1 $2" -e 2
879 # RedHat/Mandrake specific functions
880 action () { STRING=$1; shift; run_cmd "$STRING" "$*"; }
881 success () { return 0; }
882 failure () { return 1; }
885 selinuxfs=`awk '/ selinuxfs / { print $2 }' /proc/mounts`
886 echo "*** Warning -- SELinux is active"
887 echo "*** Disabling security enforcement for system recovery."
888 echo "*** Run 'setenforce 1' to reenable."
889 echo "0" > $selinuxfs/enforce
893 selinuxfs=`awk '/ selinuxfs / { print $2 }' /proc/mounts`
895 *** Warning -- SELinux relabel is required. ***
896 *** Disabling security enforcement. ***
897 *** Relabeling could take a very long time, ***
898 *** depending on file system size. ***
900 echo "0" > $selinuxfs/enforce
901 /sbin/fixfiles -F relabel > /dev/null 2>&1
903 echo "*** Enabling security enforcement. ***"
904 echo $SELINUX > $selinuxfs/enforce
907 # Remove duplicate entries from mtab (for vserver guest use only)
908 clean_vserver_mtab() {
910 cat /etc/mtab | while read device mountpoint line ; do
911 grep -qs "$mountpoint" /etc/mtab.clean || \
912 echo "$device $mountpoint $line" >> /etc/mtab.clean
914 mv -f /etc/mtab.clean /etc/mtab
920 # * indent-tabs-mode: notnil