]> git.pld-linux.org Git - projects/rc-scripts.git/blame_incremental - rc.d/init.d/functions
Silent modprobe.
[projects/rc-scripts.git] / rc.d / init.d / functions
... / ...
CommitLineData
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/rc.d/init.d directory.
4#
5# $Id$
6#
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>
14
15# First set up a default search path.
16export PATH="/sbin:/usr/sbin:/bin:/usr/bin"
17
18# Set defaults
19if [ -z "$COLUMNS" -o -z "$LINES" ]; then
20 _setterm() {
21 set -- $(stty size 2>/dev/null)
22 LINES=${LINES:-$1}
23 COLUMNS=${COLUMNS:-$2}
24 }
25 _setterm
26 unset _setterm
27fi
28[ -z "$LINES" ] || [ "$LINES" -le 0 ] && LINES=40
29[ -z "$COLUMNS" ] || [ "$COLUMNS" -le 0 ] && COLUMNS=80
30export LINES COLUMNS
31INIT_COL=$((COLUMNS - 13))
32
33# Set colors
34RED=1
35GREEN=2
36YELLOW=3
37BLUE=4
38MAGENTA=5
39CYAN=6
40WHITE=7
41NORMAL=15
42# Bold definition (second parameter to termput setaf)
43BOLD=1
44NOBOLD=0
45# Default colors
46CBRACKETS="$CYAN" # brackets [ ] color
47CDONE="$GREEN" # DONE and WORK color
48CBUSY="$MAGENTA" # BUSY color
49CFAIL="$RED" # FAIL and DIED color
50CPOWEREDBY="$CYAN" # "Powered by" color
51CPLD="$GREEN" # "PLD Linux Distribution" color
52CI="$RED" # Capital I color (press I to enter interactive startup)
53CRESMAN="$GREEN" # "Resource Manager" color
54CHARS="" # Characters displayed on the beginning of show line
55CCHARS="$NORMAL" # Color of these characters (look at /etc/sysconfig/init-colors.gentoo example)
56
57# Source configuration if available - may override default values
58[ -r /etc/sysconfig/init-colors ] && . /etc/sysconfig/init-colors
59[ -r /etc/sysconfig/system ] && . /etc/sysconfig/system
60[ -r /etc/sysconfig/bootsplash ] && . /etc/sysconfig/bootsplash
61
62if [ -z "$VSERVER" -o "$VSERVER" = "detect" ]; then
63 {
64 while read _f _ctx; do
65 [ "$_f" = "VxID:" -o "$_f" = "s_context:" ] && break
66 done </proc/self/status
67 } 2>/dev/null
68 if [ -z "$_ctx" -o "$_ctx" = "0" ]; then
69 VSERVER=no
70 else
71 VSERVER=yes
72 fi
73 unset _f _ctx
74fi
75
76# we need to know in functions if we were called from a terminal
77if [ -z "$ISATTY" ]; then
78 [ -t ] && ISATTY=yes || ISATTY=no
79 export ISATTY
80fi
81
82is_yes() {
83 # Test syntax
84 if [ $# = 0 ]; then
85 msg_usage " is_yes {value}"
86 return 2
87 fi
88
89 # Check value
90 case "$1" in
91 yes|Yes|YES|true|True|TRUE|on|On|ON|Y|y|1)
92 # true returns zero
93 return 0
94 ;;
95 *)
96 # false returns one
97 return 1
98 ;;
99 esac
100}
101
102is_no() {
103 # Test syntax
104 if [ $# = 0 ]; then
105 msg_usage " is_no {value}"
106 return 2
107 fi
108
109 case "$1" in
110 no|No|NO|false|False|FALSE|off|Off|OFF|N|n|0)
111 # true returns zero
112 return 0
113 ;;
114 *)
115 # false returns one
116 return 1
117 ;;
118 esac
119}
120
121# checks if file is empty
122# empty lines and lines beginning with hash are ignored
123is_empty_file() {
124 [ -s "$1" ] || return 0
125 grep -vqE "^(#|[[:blank:]]*$)" "$1" && return 1 || return 0
126}
127
128# returns OK if $1 contains $2
129strstr() {
130 local a=$2
131 [ "${1#*$a*}" = "$1" ] && return 1
132 return 0
133}
134
135if is_yes "$FASTRC" || is_yes "$IN_SHUTDOWN"; then
136 RC_LOGGING=no
137fi
138
139if is_no "$RC_LOGGING"; then
140 initlog() {
141 RESULT=0
142 while [ "$1" != "${1##-}" ]; do
143 case $1 in
144 -c)
145 shift
146 $1
147 RESULT=$?
148 break
149 ;;
150 *)
151 shift
152 ;;
153 esac
154 done
155 return $RESULT
156 }
157fi
158
159kernelver() {
160 local _x _y _z v old_IFS ver
161 {
162 read _x _y v _z
163 old_IFS=$IFS
164 IFS='.'
165 set -- $v
166 IFS=$old_IFS
167
168 # strip _* or -* from versions like: "2.6.25_vanilla-1", "2.6.25-1"
169 ver=${3%%[-_]*}
170
171 while [ ${#ver} -lt 3 ]; do ver="0$ver"; done
172 ver="$2$ver"
173 while [ ${#ver} -lt 6 ]; do ver="0$ver"; done
174 ver="$1$ver"
175 while [ ${#ver} -lt 9 ]; do ver="0$ver"; done
176 echo $ver
177 } < /proc/version
178}
179
180kernelverser() {
181 local _x _y _z v old_IFS ver
182 {
183 read _x _y v _z
184 old_IFS=$IFS
185 IFS='.'
186 set -- $v
187 IFS=$old_IFS
188 ver=$2
189 while [ ${#ver} -lt 3 ]; do ver="0$ver"; done
190 ver="$1$ver"
191 while [ ${#ver} -lt 6 ]; do ver="0$ver"; done
192 echo $ver
193 } </proc/version
194}
195
196kernelvermser() {
197 local _x _y _z v old_IFS ver
198 {
199 read _x _y v _z
200 old_IFS=$IFS
201 IFS='.'
202 set -- $v
203 IFS=$old_IFS
204 ver="$1$ver"
205 while [ ${#ver} -lt 3 ]; do ver="0$ver"; done
206 echo $ver
207 } </proc/version
208}
209
210# Colors workaround
211termput() {
212 is_yes "$ISATTY" || return
213
214 if is_yes "$FASTRC" || is_no "$TPUT"; then
215 case "$1" in
216 hpa)
217 echo -ne "\033[$(($2+1))G"
218 ;;
219 cuu*)
220 echo -ne "\033[${2}A"
221 ;;
222 el)
223 echo -ne "\033[0K"
224 ;;
225 setaf)
226 local ISBOLD
227 if [ -n "$3" ]; then
228 ISBOLD="$3"
229 else
230 ISBOLD="$NOBOLD";
231 fi
232 is_yes "$COLOR_INIT" && echo -ne "\033[${ISBOLD};3${2}m"
233 ;;
234 op)
235 termput setaf $NORMAL
236 ;;
237 esac
238 else
239 case "$1" in
240 hpa | cuu* | el)
241 tput "$@"
242 ;;
243 setaf)
244 if [ "$3" = "1" ]; then tput bold; else tput sgr0; fi
245 is_yes "$COLOR_INIT" && tput setaf "$2"
246 ;;
247 op)
248 termput setaf $NORMAL
249 ;;
250 esac
251 fi
252}
253
254if [ ! -x /bin/printf ]; then
255 # printf equivalent
256 # FIXME: buggy when single or double quotes in message!
257 printf() {
258 local text m
259 text="$1"
260 shift
261 if [ $# -gt 0 ]; then
262 m="$1"
263 shift
264 while [ $# -gt 0 ]; do
265 m="$m\",\"$1"
266 shift
267 done
268 fi
269 awk "BEGIN {printf \"$text\", \"$m\"; }"
270 }
271fi
272
273# National language support function
274nls() {
275 local msg_echo nls_domain text message
276 msg_echo='\n'
277 nls_domain="$NLS_DOMAIN"
278 while [ "$1" != "${1##-}" ]; do
279 case "$1" in
280 --nls-domain)
281 shift
282 nls_domain="$1"
283 shift
284 ;;
285 -n)
286 msg_echo=''
287 shift
288 ;;
289 esac
290 done
291 message="$1"
292 shift
293
294 # empty message, so we return --misiek
295 if [ -z "$message" ]; then
296 echo -en "$msg_echo"
297 return
298 fi
299
300 if is_yes "$GETTEXT"; then
301 message=$(TEXTDOMAINDIR="/etc/sysconfig/locale" gettext -e --domain="${nls_domain:-rc-scripts}" "$message")
302 fi
303
304 printf "$message" "$@"
305 echo -en "$msg_echo"
306}
307
308rc_splash() {
309 local action="$1"
310
311 if ! is_no "$BOOT_SPLASH" && ! is_yes "$VSERVER"; then
312 [ -x /bin/splash ] && /bin/splash "$action"
313 fi
314
315 : $((progress++))
316}
317
318msg_network_down() {
319 nls "ERROR: Networking is down. %s can't be run." "$1" >&2
320}
321
322msg_starting() {
323 show "Starting %s service" "$1"
324}
325
326msg_already_running() {
327 nls "%s service is already running." "$1"
328}
329
330msg_stopping() {
331 show "Stopping %s service" "$1"
332}
333
334msg_not_running() {
335 nls "%s service is not running." "$1"
336}
337
338msg_reloading() {
339 show "Reloading %s service" "$1"
340}
341
342msg_usage() {
343 nls "Usage: %s" "$*"
344}
345
346# Some functions to handle PLD Linux-style messages
347show() {
348 local text len
349
350 if is_no "$FASTRC" && is_yes "$GETTEXT"; then
351 text=$(nls -n "$@")
352 else
353 text=$(printf "$@")
354 fi
355 len=${#text}
356 while [ $((len++)) -lt $INIT_COL ]; do
357 text="$text."
358 done
359 if [ -n "$CHARS" ]; then
360 termput setaf $CCHARS
361 echo -n "$CHARS"
362 termput op
363 fi
364 echo -n "$text"
365}
366
367deltext() {
368 termput hpa $INIT_COL
369}
370
371# Displays message in square brackests ("[ DONE ]"). Takes two arguments.
372# First is the text to display, second is color number to use (argument to
373# tput setaf). If second argument is not given, default (2, green) will be
374# used).
375progress() {
376 local COLOR
377 if [ -n "$2" ]; then
378 COLOR="$2"
379 else
380 COLOR="$CDONE"
381 fi
382 deltext
383 echo -n "$(termput setaf $CBRACKETS)[$(termput setaf $COLOR) $(nls --nls-domain rc-scripts "$1") $(termput setaf $CBRACKETS)]$(termput op)"
384}
385
386busy() {
387 echo -n "$_busy"
388}
389
390ok() {
391 echo "$_ok"
392}
393
394started() {
395 echo "$_started"
396}
397
398fail() {
399 echo "$_fail"
400 return 1
401}
402
403died() {
404 echo "$_died"
405 return 1
406}
407
408# Check if $pid (could be plural) are running
409checkpid() {
410 while [ "$1" ]; do
411 [ -d "/proc/$1" ] && return 0
412 shift
413 done
414 return 1
415}
416
417# - outside chroot get only those processes, which are outside chroot.
418# - inside chroot get only those processes, which are inside chroot.
419# - don't filter out pids which do not have corresponding running processes (process died etc)
420# (note: some processes like named are chrooted but run outside chroot)
421# - do nothing inside vserver
422filter_chroot() {
423 if is_yes "$VSERVER"; then
424 echo $@
425 return
426 fi
427 if [ $# -lt 1 -o ! -d /proc/1 ]; then
428 echo $@
429 return
430 fi
431 local root_dir good_pids="" good_add_pid
432 for root_pid in $@; do
433 root_dir=$(resolvesymlink /proc/${root_pid}/root)
434 if [ -n "$root_dir" ]; then
435 good_add_pid=1
436 if [ -n "${SYSTEM_CHROOTS}" ]; then
437 for r_dir in ${SYSTEM_CHROOTS}; do
438 echo "$root_dir" | grep -q "^${r_dir}" && good_add_pid=0
439 done
440 fi
441 [ "$good_add_pid" -eq 1 ] && good_pids="$good_pids $root_pid"
442 elif [ ! -d "/proc/$root_pid" ]; then
443 good_pids="$good_pids $root_pid"
444 fi
445 done
446 echo $good_pids
447}
448
449# Usage run_cmd Message command_to_run
450run_cmd() {
451 local exit_code errors message force_err
452 local force_err=0 exit_code=0
453 case "$1" in
454 -a)
455 force_err=1
456 shift
457 ;;
458 esac
459 message=$1
460 show "$message"; busy
461 shift
462 cd /
463 if errors=$(
464 export HOME=/tmp TMPDIR=/tmp
465 if is_no "$RC_LOGGING"; then
466 "$@" 2>&1
467 else
468 initlog -c "$*" 2>&1
469 fi
470 ); then
471 ok
472 log_success "$1 $message"
473 else
474 fail
475 log_failed "$1 $message"
476 exit_code=1
477 fi
478 [ -n "$errors" ] && [ $exit_code -eq 1 -o $force_err -eq 1 ] && echo "$errors"
479 return $exit_code
480}
481
482_daemon_set_ulimits() {
483 local opt val ksh=${KSH_VERSION:+1}
484 set -- ${SERVICE_LIMITS:-$DEFAULT_SERVICE_LIMITS}
485 while [ $# -gt 0 ]; do
486 opt=$1
487 val=$2
488 if [ "$ksh" ]; then
489 case "$opt" in
490 -Hu)
491 opt=-Hp
492 ;;
493 -Su)
494 opt=-Sp
495 ;;
496 -u)
497 opt=-p
498 ;;
499 esac
500 fi
501 ulimit $opt $val
502 shift 2
503 done
504}
505
506# A function to start a program (now it's useful on read-only filesystem too)
507daemon() {
508 local errors="" prog="" end="" waitname="" waittime=""
509 local exit_code=0
510 local nice=$SERVICE_RUN_NICE_LEVEL
511 local fork user closefds redirfds pidfile makepid chdir=/
512
513 # NOTE: if you wonder how the shellish (by syntax) $prog works in ssd mode,
514 # then the answer is: it totally ignores $prog and uses "$@" itself.
515
516 while [ $# -gt 0 ]; do
517 case $1 in
518 '')
519 msg_usage " daemon [--check] [--user user] [--fork] [--chdir directory] [--closefds] [--redirfds] [--waitforname procname] [--waitfortime seconds] [--pidfile file] [--makepid] [+/-nicelevel] {program} <program args>"
520 return 2
521 ;;
522 --check)
523 # for compatibility with redhat/mandrake
524 nls "warning: --check option is ignored!"
525 shift
526 ;;
527 --user)
528 shift
529 [ "$1" != "root" ] && prog="/bin/su $1 -s /bin/sh -c \""
530 user=$1
531 ;;
532 --fork)
533 fork=1
534 prog="/usr/bin/setsid sh -c \""
535 end='&'
536 ;;
537 --chdir)
538 shift
539 chdir=$1
540 ;;
541 --closefds)
542 closefds=1
543 ;;
544 --redirfds)
545 redirfds=1
546 ;;
547 --waitforname)
548 shift
549 waitname="$1"
550 ;;
551 --waitfortime)
552 shift
553 waittime="$1"
554 ;;
555 --pidfile)
556 shift
557 pidfile="$1"
558 case "$pidfile" in /*);; *) pidfile="/var/run/$pidfile";; esac
559 ;;
560 --makepid)
561 makepid=1
562 ;;
563 -*|+*)
564 nice=$1
565 shift
566 break
567 ;;
568 *)
569 break
570 ;;
571 esac
572 shift
573 done
574 # If command to execute ends with quotation mark, add remaining
575 # arguments and close quotation.
576 if [ "$prog" != "${prog%\"}" ]; then
577 prog="$prog $*$end\""
578 else
579 prog="$prog $*$end"
580 fi
581
582 _daemon_set_ulimits
583
584 [ -z "$DEFAULT_SERVICE_UMASK" ] && DEFAULT_SERVICE_UMASK=022
585 [ -z "$DEFAULT_SERVICE_RUN_NICE_LEVEL" ] && DEFAULT_SERVICE_RUN_NICE_LEVEL=0
586
587 # And start it up.
588 busy
589 cd $chdir
590 [ -n "$SERVICE_CPUSET" ] && is_yes "$CPUSETS" && echo $$ > "/dev/cpuset/${SERVICE_CPUSET}/tasks"
591 if errors=$(
592 umask ${SERVICE_UMASK:-$DEFAULT_SERVICE_UMASK};
593 export USER=root HOME=/tmp TMPDIR=/tmp
594 nice=${nice:-$DEFAULT_SERVICE_RUN_NICE_LEVEL}
595 nice=${nice:-0}
596
597 if [ "$closefds" = 1 ]; then
598 exec 1>&-
599 exec 2>&-
600 exec 0>&-
601 elif [ "$redirfds" = 1 ]; then
602 exec 1>/dev/null
603 exec 2>/dev/null
604 exec 0>/dev/null
605 else
606 exec 2>&1
607 fi
608
609 if is_no "$RC_LOGGING"; then
610 prog=$1; shift
611 if [ ! -x $prog ]; then
612 logger -t rc-scripts -p daemon.debug "daemon: Searching PATH for $prog, consider using full path in initscript"
613 local a o=$IFS
614 IFS=:
615 for a in $PATH; do
616 if [ -x $a/$prog ]; then
617 prog=$a/$prog
618 break
619 fi
620 done
621 IFS=$o
622 fi
623 /sbin/start-stop-daemon -q --start \
624 --nicelevel $nice \
625 ${pidfile:+--pidfile $pidfile} \
626 ${makepid:+--make-pidfile} \
627 ${user:+--chuid $user} \
628 ${chdir:+--chdir "$chdir"} \
629 ${fork:+--background} \
630 ${waitname:+--name $waitname} \
631 ${SERVICE_DROPCAPS:+--dropcap $SERVICE_DROPCAPS} \
632 --exec "$prog" \
633 -- ${1:+"$@"}
634 else
635 nice -n $nice initlog -c "$prog" 2>&1
636 fi
637 ); then
638
639 if [ -n "$waitname" -a -n "$waittime" ]; then
640 # Save basename.
641 base=${waitname##*/}
642 # Find pid.
643 pid=$(pidofproc "$waitname" "$pidfile")
644 [ -z "$pid" ] && pid=$(pidofproc "$base" "$pidfile")
645 i=0
646 while [ "$i" -lt "$waittime" ]; do
647 i=$((i + 1))
648 checkpid $pid && sleep 1 || break
649 done
650 fi
651 log_success "$1 startup"
652 ok
653 else
654 exit_code=1
655 fail
656 log_failed "$1 startup"
657 [ -n "$errors" ] && echo >&2 "$errors"
658 fi
659 return $exit_code
660}
661
662# A function to stop a program.
663killproc() {
664 local notset killlevel base pid pidfile result
665 # Test syntax.
666 if [ $# = 0 ]; then
667 msg_usage " killproc [--pidfile PIDFILE] {program} [-SIGNAME]"
668 return 2
669 fi
670
671 while [ "$1" != "${1##-}" ]; do
672 case $1 in
673 --pidfile)
674 pidfile="$2"
675 case "$pidfile" in /*);; *) pidfile="/var/run/$pidfile";; esac
676 shift 2
677 ;;
678 --waitforname)
679 waitname="$2"
680 shift 2
681 ;;
682 --waitfortime)
683 waittime="$2"
684 shift 2
685 ;;
686 esac
687 done
688
689 busy
690
691 local notset=0
692 # check for second arg to be kill level
693 if [ -n "$2" ]; then
694 killlevel=$2
695 else
696 notset=1
697 fi
698
699 # experimental start-stop-daemon based killing.
700 # works only with pidfile
701 if is_no "$RC_LOGGING" && [ "$pidfile" ]; then
702 local sig=${killlevel:--TERM}
703 /sbin/start-stop-daemon -q --stop \
704 --retry ${sig#-}/10/${sig#-}/60/KILL/10 \
705 -s ${sig#-} \
706 ${pidfile:+--pidfile $pidfile}
707 result=$?
708 if [ "$result" -eq 0 ]; then
709 ok
710 else
711 fail
712 fi
713 return $result
714 fi
715
716
717 # Save basename.
718 base=${1##*/}
719
720 # Find pid.
721 pid=$(pidofproc "$1" "$pidfile")
722 [ -z "$pid" ] && pid=$(pidofproc "$base" "$pidfile")
723
724 # Kill it.
725 if [ -n "$pid" -a "$pid" != "$$" ] && checkpid $pid 2>&1; then
726 if [ "$notset" = "1" ]; then
727 if checkpid $pid 2>&1; then
728 # TERM first, then KILL if not dead
729 kill -TERM $pid
730 usleep 100000
731 if checkpid $pid && sleep 1 &&
732 checkpid $pid && sleep 3 &&
733 checkpid $pid; then
734 # XXX: SIGKILL is sent already on 4th second!
735 # HARMFUL for example to mysqld (which is already workarounded)
736 kill -KILL $pid
737 usleep 100000
738 fi
739 fi
740 checkpid $pid
741 result=$?
742 if [ "$result" -eq 0 ]; then
743 fail
744 log_failed "$1 shutdown"
745 else
746 ok
747 log_success "$1 shutdown"
748 fi
749 result=$(( ! $result ))
750 else
751 # use specified level only
752 if checkpid $pid > /dev/null 2>&1; then
753 kill $killlevel $pid
754 result=$?
755 if [ "$result" -eq 0 ]; then
756 ok
757 log_success "$1 got $killlevel"
758 else
759 result=7
760 fail
761 log_failed "$1 didn't get $killlevel"
762 fi
763 else
764 result=7
765 died
766 log_failed "$1 shutdown"
767 fi
768 fi
769 else
770 died
771 log_failed "$1 shutdown"
772 result=7
773 fi
774
775 if [ -n "$waitname" -a -n "$waittime" ]; then
776 # Save basename.
777 base=${waitname##*/}
778 # Find pid.
779 pid=$(pidofproc "$waitname" "$pidfile")
780 [ -z "$pid" ] && pid=$(pidofproc "$base" "$pidfile")
781 i=0
782 while [ "$i" -lt "$waittime" ]; do
783 i=$(( i + 1 ))
784 checkpid $pid && sleep 1 || break
785 done
786 fi
787
788 # Remove pid file if any.
789 if [ "$notset" = "1" ]; then
790 rm -f /var/run/${base}.pid
791 fi
792
793 return $result
794}
795
796# A function to find the pid of a program.
797pidofproc() {
798 local pid pidfile base=${1##*/}
799 pidfile="$base.pid"
800 [ -n "$2" ] && pidfile="$2"
801
802 # Test syntax.
803 if [ $# = 0 ]; then
804 msg_usage " pidofproc {program}"
805 return 2
806 fi
807
808 # First try pidfile or "/var/run/*.pid"
809 case "$pidfile" in
810 /*)pidfile="${pidfile}";;
811 *) pidfile="/var/run/$pidfile";;
812 esac
813 if [ -f "${pidfile}" ]; then
814 local p pid=""
815 for p in $(< "${pidfile}"); do
816 [ -z "$(echo "$p" | awk '{gsub(/[0-9]/,"");print;}')" ] && pid="$pid $p"
817 done
818 fi
819
820 # Next try "pidof"
821 [ -z "$pid" ] && pidof -o $$ -o $PPID -o %PPID -x "$1"
822 pid=$(filter_chroot "$pid")
823 echo $pid
824}
825
826# status [--pidfile PIDFILE] {subsys} [{daemon}]"
827status() {
828 local pid subsys daemon cpuset_msg pidfile
829 if [ "$1" = "--pidfile" -o "$1" = "-p" ]; then
830 pidfile=$2
831 case "$pidfile" in /*);; *) pidfile="/var/run/$pidfile";; esac
832 shift 2
833 fi
834
835 subsys=$1
836 daemon=${2:-$subsys}
837
838 # Test syntax.
839 if [ $# = 0 ]; then
840 msg_usage " status [--pidfile PIDFILE] {subsys} [{daemon}]"
841 return 2
842 fi
843
844 # if pidfile specified, pid must be there
845 if [ "$pidfile" ]; then
846 [ -f "$pidfile" ] && read pid < $pidfile
847 # filter_chroot does not filter out dead pids, so this extra check, see t/status-pidfile.sh
848 if [ ! -d "/proc/$pid" ]; then
849 pid=
850 fi
851 else
852 pid=$(pidof -o $$ -o $PPID -o %PPID -x $daemon)
853 fi
854 pid=$(filter_chroot "$pid")
855
856 if [ "$pid" ]; then
857 cpuset_msg="..."
858 if [ -n "$SERVICE_CPUSET" ] && is_yes "$CPUSETS"; then
859 if grep -q "$pid" "/dev/cpuset/${SERVICE_CPUSET}/tasks"; then
860 cpuset_msg=$(nls " in cpuset %s..." "$SERVICE_CPUSET")
861 else
862 cpuset_msg=$(nls " outside of configured cpuset %s..." "$SERVICE_CPUSET")
863 fi
864 fi
865 nls "%s (pid %s) is running%s" "$daemon" "$pid" "$cpuset_msg"
866 return 0
867 fi
868
869 # Next try "/var/run/*.pid" files; if pidfile is not set
870 local base=${daemon##*/}
871 if [ -z "$pidfile" -a -f /var/run/${base}.pid ]; then
872 read pid < /var/run/${base}.pid
873 pid=$(filter_chroot "$pid")
874 if [ "$pid" ]; then
875 nls "%s dead but pid file (%s) exists" "$subsys" /var/run/${base}.pid
876 return 1
877 fi
878 fi
879
880 # See if /var/lock/subsys/$subsys exists
881 if [ -f /var/lock/subsys/$subsys ]; then
882 nls "daemon %s dead but subsys (%s) locked" "$daemon" "$subsys"
883 return 2
884 fi
885 nls "%s is stopped" "$subsys"
886 return 3
887}
888
889# Confirm whether we really want to run this service
890confirm() {
891 local answer
892 nls -n "Start service %s (Y)es/(N)o/(C)ontinue? [Y] " "$1"
893 read answer
894 case $answer in
895 y|Y|t|T|j|J|"")
896 return 0
897 ;;
898 c|C|k|K|w|W)
899 return 2
900 ;;
901 n|N)
902 return 1
903 ;;
904 *)
905 confirm $1
906 return $?
907 ;;
908 esac
909}
910
911# module is needed (ie. is requested, is available and isn't loaded already)
912is_module() {
913 # module name without .o at end
914 if ! lsmod | grep -q "$1"; then
915 if ls -R /lib/modules/$(uname -r)/ 2> /dev/null | grep -q "${1}.\(\|k\)o\(\|.gz\)"; then
916 # true
917 return 0
918 fi
919 fi
920 # false
921 return 1
922}
923
924_modprobe() {
925 local parsed single die args foo result
926 parsed=no
927 while is_no "$parsed"; do
928 case "$1" in
929 "single")
930 single=yes
931 shift
932 ;;
933 "die")
934 die=yes
935 shift
936 ;;
937 -*)
938 args="$args $1"
939 shift
940 ;;
941 *)
942 parsed=yes
943 ;;
944 esac
945 done
946 if is_yes "${single}"; then
947 foo="$@"
948 show "Loading %s kernel module(s)" "$foo"
949 busy
950 fi
951 if [ -x /sbin/modprobe ]; then
952 /sbin/modprobe -s $args "$@"
953 result=$?
954 else
955 deltext; fail
956 result=1
957 fi
958 if is_yes "${single}"; then
959 deltext
960 if [ $result = "0" ]; then
961 is_yes "$single" && ok
962 else
963 fail
964 if is_yes "$die"; then
965 nls "Could not load %s kernel module(s)" "$@"
966 exit 1
967 fi
968 fi
969 fi
970}
971
972if is_no "$RC_LOGGING"; then
973 log_success() {
974 :
975 }
976
977 log_failed() {
978 :
979 }
980else
981 log_success() {
982 initlog -n $0 -s "$1 $2" -e 1
983 }
984
985 log_failed() {
986 initlog -n $0 -s "$1 $2" -e 2
987 }
988fi
989
990# Check if any flavor of portmapper is running
991check_portmapper() {
992 if [ -x /usr/sbin/rpcinfo ]; then
993 if /usr/sbin/rpcinfo -p localhost >/dev/null 2>/dev/null; then
994 return 0
995 else
996 return 1
997 fi
998 elif [ -z "$(pidof portmap)" -a -z "$(pidof rpcbind)" ]; then
999 return 1
1000 fi
1001 return 0
1002}
1003
1004# is_fsmounted fstype mntpoint
1005# Check if filesystem fstype is mounted on mntpoint
1006is_fsmounted() {
1007 local fstype=$1
1008 local mntpoint=$2
1009
1010 [ -n "$fstype" -a -n "$mntpoint" ] || return 1
1011
1012 if [ -r /proc/mounts ]; then
1013 grep -qE "[[:blank:]]$mntpoint[[:blank:]]+$fstype[[:blank:]]" /proc/mounts
1014 return $?
1015 else
1016 if [ "$(stat -L -f -c %T $mntpoint 2>/dev/null)" = "$fstype" ]; then
1017 return 0
1018 else
1019 return 1
1020 fi
1021 fi
1022}
1023
1024rc_cache_init() {
1025 # If we have cachefile, use it.
1026 # If we don't, create memory variables and try to save silently,
1027 local cachefile='/var/cache/rc-scripts/msg.cache'
1028
1029 local term
1030 if is_yes "$ISATTY"; then
1031 term=$TERM
1032 else
1033 term=dumb
1034 fi
1035
1036 # We create $check variable which is used to invalidate the cache.
1037 # The $check contains user locale and terminal.
1038 local check="$term.$LC_MESSAGES.$INIT_COL"
1039
1040 if [ -f "$cachefile" -a "$cachefile" -nt /etc/sysconfig/system -a "$cachefile" -nt /etc/sysconfig/init-colors ]; then
1041 if . "$cachefile" 2>/dev/null; then
1042 if [ "$check" = "$_check" ]; then
1043 return
1044 fi
1045 fi
1046 fi
1047
1048 # primitive caching
1049 _busy=$(progress "BUSY" "$CBUSY")
1050 _ok=$(progress "DONE")
1051 _started=$(progress "WORK")
1052 _fail=$(progress "FAIL" "$CFAIL")
1053 _died=$(progress "DIED" "$CFAIL")
1054
1055 # we don't use heredoc, as ksh attempts to create tempfile then
1056 (> "$cachefile" ) 2>/dev/null || return
1057 echo "_busy='$_busy';" >> "$cachefile"
1058 echo "_ok='$_ok';" >> "$cachefile"
1059 echo "_started='$_started';" >> "$cachefile"
1060 echo "_fail='$_fail';" >> "$cachefile"
1061 echo "_died='$_died';" >> "$cachefile"
1062 echo "_check='$check';" >> "$cachefile"
1063}
1064
1065rc_gettext_init() {
1066 if [ -z "$GETTEXT" ]; then
1067 if [ -x /bin/gettext -o -x /usr/bin/gettext ]; then
1068 GETTEXT=yes
1069 else
1070 GETTEXT=no
1071 fi
1072 fi
1073
1074 if [ -z "$TPUT" ]; then
1075 if [ -d /usr/share/terminfo ] && [ -x /usr/bin/tput -o -x /bin/tput ]; then
1076 TPUT=yes
1077 # check if we are on proper terminal
1078 tput longname >/dev/null 2>&1 || TPUT=no
1079 else
1080 TPUT=no
1081 fi
1082 fi
1083}
1084
1085use_upstart () {
1086 # True when upstart-event-based boot should be used
1087 is_yes "$USE_UPSTART" && return 0
1088 is_no "$USE_UPSTART" && return 1
1089 if [ ! -x /sbin/initctl ] ; then
1090 USE_UPSTART="no"
1091 return 1
1092 fi
1093 local cmdline=$(cat /proc/cmdline 2>/dev/null)
1094 if strstr "$cmdline" "pld.no-upstart" ; then
1095 USE_UPSTART="no"
1096 return 1
1097 else
1098 USE_UPSTART="yes"
1099 return 0
1100 fi
1101}
1102
1103emit () {
1104 # emit upstart signal
1105 # only when 'upstart' boot is enabled
1106 use_upstart || return 0
1107 /sbin/initctl emit "$@"
1108}
1109
1110is_upstart_task() {
1111 # Return 0 if the given service is an upstart task.
1112 grep -q '^task' "/etc/init/$1.conf"
1113}
1114is_upstart_running() {
1115 # Return 0 if the given service is running via upstart
1116 initctl status "$1" 2>/dev/null | grep -q running
1117}
1118upstart_start() {
1119 local service=$1
1120 is_upstart_running "${service}" && return 0
1121 msg_starting "${service}"
1122 if errors=$(/sbin/initctl start ${service} 2>&1) ; then
1123 ok
1124 return 0
1125 else
1126 fail
1127 echo "$errors" >&2
1128 return 1
1129 fi
1130}
1131upstart_stop() {
1132 local service=$1
1133 if ! is_upstart_running "${service}" && ! is_upstart_task "${service}" ; then
1134 return 0
1135 fi
1136 msg_stopping "${service}"
1137 if errors=$(/sbin/initctl stop ${service}) ; then
1138 ok
1139 return 0
1140 else
1141 fail
1142 echo "$errors" >&2
1143 return 1
1144 fi
1145}
1146upstart_reload() {
1147 local service=$1
1148 if ! is_upstart_running "${service}" && ! is_upstart_task "${service}" ; then
1149 return 0
1150 fi
1151 msg_reloading "${service}"
1152 if errors=$(/sbin/initctl reload ${service}) ; then
1153 ok
1154 return 0
1155 else
1156 fail
1157 echo "$errors" >&2
1158 return 1
1159 fi
1160}
1161upstart_status() {
1162 # get service status
1163 # should be compliant with
1164 # http://refspecs.freestandards.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
1165 local service=$1
1166 local status
1167 if is_upstart_task "${service}" ; then
1168 # we probably should have a way to handle task status
1169 return 0
1170 fi
1171 if ! status=$(/sbin/initctl status "${service}") ; then
1172 # program or service status is not known
1173 return 4
1174 fi
1175 if strstr "$status" "running" ; then
1176 # program is running or service is OK
1177 echo "$status"
1178 return 0
1179 else
1180 # program is not running
1181 echo "$status"
1182 return 3
1183 fi
1184 # TODO: other statuses
1185}
1186
1187_upstart_controlled () {
1188 # If the service is to be handled by upstart
1189 # execute the start/stop/etc. commands the upstart way
1190 if ! use_upstart ; then
1191 return 0
1192 fi
1193 local script=$1
1194 shift
1195 local command=$1
1196 shift
1197 local name=$(basename "$script")
1198 if [ ! -f /etc/init/${name}.conf ] ; then
1199 return 0
1200 fi
1201 local commands
1202 local extra_commands
1203 local has_configtest
1204 if [ "$1" = "--except" ] ; then
1205 shift
1206 commands="$*"
1207 for cmd in $commands ; do
1208 if [ "$command" = "$cmd" ] ; then
1209 return 0
1210 fi
1211 case "$cmd" in
1212 start|stop|status|reload|restart|try-restart|force-reload)
1213 ;;
1214 configtest)
1215 has_configtest=yes
1216 extra_commands="|$cmd"
1217 ;;
1218 *)
1219 extra_commands="|$cmd"
1220 ;;
1221 esac
1222 done
1223 elif [ -n "$*" ] ; then
1224 commands="$*"
1225 local cmd
1226 local found=0
1227 # is there a better way
1228 for cmd in $commands ; do
1229 if [ "$command" = "$cmd" ] ; then
1230 found=1
1231 break;
1232 fi
1233 done
1234 if [ $found = 0 ] ; then
1235 # let the script handle it
1236 return 0
1237 fi
1238 fi
1239 case "$command" in
1240 start)
1241 upstart_start $name
1242 exit $?
1243 ;;
1244 stop)
1245 upstart_stop $name
1246 exit $?
1247 ;;
1248 status)
1249 upstart_status $name
1250 exit $?
1251 ;;
1252 restart)
1253 if is_yes "$has_configtest" ; then
1254 "$script" configtest || exit 1
1255 fi
1256 upstart_stop $name
1257 upstart_start $name
1258 exit $?
1259 ;;
1260 try-restart)
1261 if ! is_upstart_running "$name" ; then
1262 exit 0
1263 fi
1264 if is_yes "$has_configtest" ; then
1265 "$script" configtest || exit 1
1266 fi
1267 upstart_stop $name
1268 upstart_start $name
1269 exit $?
1270 ;;
1271 reload)
1272 if is_yes "$has_configtest" ; then
1273 "$script" configtest || exit 1
1274 fi
1275 if is_upstart_task "$name" ; then
1276 nls "$command not implemented for $name"
1277 exit 3
1278 else
1279 upstart_reload "$name"
1280 exit $?
1281 fi
1282 ;;
1283 force-reload)
1284 if is_yes "$has_configtest" ; then
1285 "$script" configtest || exit 1
1286 fi
1287 if is_upstart_task "$name" ; then
1288 upstart_stop "$name"
1289 upstart_start "$name"
1290 exit $?
1291 else
1292 upstart_reload "$name"
1293 exit $?
1294 fi
1295 ;;
1296 *)
1297 msg_usage "$0 {start|stop|restart|reload|force-reload|status$extra_commands}"
1298 exit 3
1299 ;;
1300 esac
1301 return 1 # should not happen
1302}
1303
1304# Usage:
1305# somewhere at the begining of init script:
1306# upstart_controlled
1307# - to pass implement all upstart commands via initctl
1308# start, stop, status, restart, reload and force_reload
1309# are implemented
1310# upstart_controlled command...
1311# - to pass handle only specific commands the upstart way
1312# and leave the rest to the script
1313#
1314alias upstart_controlled='_upstart_controlled $0 "$@"'
1315
1316rc_gettext_init
1317rc_cache_init
1318
1319#/*
1320# * Local variables:
1321# * mode: sh
1322# * indent-tabs-mode: notnil
1323# * End:
1324# *
1325# */
This page took 0.055036 seconds and 4 git commands to generate.