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