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