Subversion Repositories configs

Rev

Rev 95 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 - 1
# -*-Shell-script-*-
2
#
3
# functions	This file contains functions to be used by most or all
4
#		shell scripts in the /etc/init.d directory.
5
#
6
 
7
TEXTDOMAIN=initscripts
8
 
9
# Make sure umask is sane
10
umask 022
11
 
12
# Set up a default search path.
13
PATH="/sbin:/usr/sbin:/bin:/usr/bin"
14
export PATH
15
 
16
# Get a sane screen width
17
[ -z "${COLUMNS:-}" ] && COLUMNS=80
18
 
19
[ -z "${CONSOLETYPE:-}" ] && CONSOLETYPE="$(/sbin/consoletype)"
20
 
21
if [ -f /etc/sysconfig/i18n -a -z "${NOLOCALE:-}" -a -z "${LANGSH_SOURCED:-}" ] ; then
22
  . /etc/profile.d/lang.sh 2>/dev/null
23
  # avoid propagating LANGSH_SOURCED any further
24
  unset LANGSH_SOURCED
25
fi
26
 
27
# Read in our configuration
28
if [ -z "${BOOTUP:-}" ]; then
29
  if [ -f /etc/sysconfig/init ]; then
30
      . /etc/sysconfig/init
31
  else
32
    # This all seem confusing? Look in /etc/sysconfig/init,
33
    # or in /usr/doc/initscripts-*/sysconfig.txt
34
    BOOTUP=color
35
    RES_COL=60
36
    MOVE_TO_COL="echo -en \\033[${RES_COL}G"
37
    SETCOLOR_SUCCESS="echo -en \\033[1;32m"
38
    SETCOLOR_FAILURE="echo -en \\033[1;31m"
39
    SETCOLOR_WARNING="echo -en \\033[1;33m"
40
    SETCOLOR_NORMAL="echo -en \\033[0;39m"
41
    LOGLEVEL=1
42
  fi
43
  if [ "$CONSOLETYPE" = "serial" ]; then
44
      BOOTUP=serial
45
      MOVE_TO_COL=
46
      SETCOLOR_SUCCESS=
47
      SETCOLOR_FAILURE=
48
      SETCOLOR_WARNING=
49
      SETCOLOR_NORMAL=
50
  fi
51
fi
52
 
53
# Interpret escape sequences in an fstab entry
54
fstab_decode_str() {
55
	fstab-decode echo "$1"
56
}
57
 
58
# Check if any of $pid (could be plural) are running
59
checkpid() {
60
	local i
61
 
62
	for i in $* ; do
63
		[ -d "/proc/$i" ] && return 0
64
	done
65
	return 1
66
}
67
 
68
__readlink() {
69
    ls -bl "$@" 2>/dev/null| awk '{ print $NF }'
70
}
71
 
72
__fgrep() {
73
    s=$1
74
    f=$2
75
    while read line; do
76
	if strstr "$line" "$s"; then
77
	    echo $line
78
	    return 0
79
	fi
80
    done < $f
81
    return 1
82
}
83
 
57 - 84
__kill_pids_term_kill_checkpids() {
85
    local base_stime=$1
86
    shift 1
87
    local pid=
88
    local pids=$*
89
    local remaining=
90
    local stat=
91
    local stime=
92
 
93
    for pid in $pids ; do
94
        [ -e  "/proc/$pid" ] || continue
95
        read -r line < "/proc/$pid/stat" 2> /dev/null || continue
96
 
97
        stat=($line)
98
        stime=${stat[21]}
99
 
100
        [ -n "$stime" ] && [ "$base_stime" -lt "$stime" ] && continue
101
        remaining+="$pid "
102
    done
103
 
104
    echo "$remaining"
105
    [ -n "$remaining" ] && return 1
106
 
107
    return 0
108
}
109
 
110
__kill_pids_term_kill() {
111
    local try=0
112
    local delay=3;
113
    local pid=
128 - 114
    local stat=
115
    local base_stime=
57 - 116
 
128 - 117
    # We can't initialize stat & base_stime on the same line where 'local'
118
    # keyword is, otherwise the sourcing of this file will fail for ksh...
119
    stat=($(< /proc/self/stat))
120
    base_stime=${stat[21]}
121
 
57 - 122
    if [ "$1" = "-d" ]; then
123
        delay=$2
124
        shift 2
125
    fi
126
 
127
    local kill_list=$*
128
 
129
    kill_list=$(__kill_pids_term_kill_checkpids $base_stime $kill_list)
130
 
131
    [ -z "$kill_list" ] && return 0
132
 
133
    kill -TERM $kill_list >/dev/null 2>&1
134
    usleep 100000
135
 
136
    kill_list=$(__kill_pids_term_kill_checkpids $base_stime $kill_list)
137
    if [ -n "$kill_list" ] ; then
138
        while [ $try -lt $delay ] ; do
139
            sleep 1
140
            kill_list=$(__kill_pids_term_kill_checkpids $base_stime $kill_list)
141
            [ -z "$kill_list" ] && break
142
            let try+=1
143
        done
144
        if [ -n "$kill_list" ] ; then
145
            kill -KILL $kill_list >/dev/null 2>&1
146
            usleep 100000
147
            kill_list=$(__kill_pids_term_kill_checkpids $base_stime $kill_list)
148
        fi
149
    fi
150
 
151
    [ -n "$kill_list" ] && return 1
152
    return 0
153
}
154
 
3 - 155
# __umount_loop awk_program fstab_file first_msg retry_msg retry_umount_args
156
# awk_program should process fstab_file and return a list of fstab-encoded
157
# paths; it doesn't have to handle comments in fstab_file.
158
__umount_loop() {
159
	local remaining sig=
160
	local retry=3 count
161
 
162
	remaining=$(LC_ALL=C awk "/^#/ {next} $1" "$2" | sort -r)
163
	while [ -n "$remaining" -a "$retry" -gt 0 ]; do
164
		if [ "$retry" -eq 3 ]; then
165
			action "$3" fstab-decode umount $remaining
166
		else
167
			action "$4" fstab-decode umount $5 $remaining
168
		fi
169
		count=4
170
		remaining=$(LC_ALL=C awk "/^#/ {next} $1" "$2" | sort -r)
171
		while [ "$count" -gt 0 ]; do
172
			[ -z "$remaining" ] && break
173
			count=$(($count-1))
174
			usleep 500000
175
			remaining=$(LC_ALL=C awk "/^#/ {next} $1" "$2" | sort -r)
176
		done
177
		[ -z "$remaining" ] && break
8 - 178
		kill $sig $(fstab-decode /sbin/fuser -m $remaining 2>/dev/null  | sed -e "s/\b$$\b//g") > /dev/null
3 - 179
		sleep 3
180
		retry=$(($retry -1))
181
		sig=-9
182
	done
183
}
184
 
57 - 185
# Similar to __umount loop above, without calling fuser
186
__umount_loop_2() {
187
    local remaining=
188
    local count
189
    local kill_list
190
 
191
    #call regular umount
192
	remaining=$(LC_ALL=C awk "/^#/ {next} $1" "$2" | sort -r)
193
	action "$3" fstab-decode umount $remaining
194
 
195
	count=4
196
	remaining=$(LC_ALL=C awk "/^#/ {next} $1" "$2" | sort -r)
197
        while [ "$count" -gt 0 ]; do
198
                [ -z "$remaining" ] && break
199
                count=$(($count-1))
200
                usleep 500000
201
                remaining=$(LC_ALL=C awk "/^#/ {next} $1" "$2" | sort -r)
202
        done
203
	[ -z "$remaining" ] && return 0
204
 
205
	devs=$(stat -c "%d" $remaining)
206
	action "$4" fstab-decode umount "-l" $remaining
207
 
208
    # find fds that don't start with /, are not sockets or pipes or other.
209
	# these are potentially detached fds
210
	detached_fds=$(find /proc/ -regex '/proc/[0-9]+/fd/.*' -printf "%p %l\n" 2>/dev/null |\
211
			 grep -Ev '/proc/[0-9]+/fd/[0-9]+ (/.*|inotify|\[.+\]|(socket|pipe):\[[0-9]+\])')
212
 
213
	# check each detached fd to see if it has the same device
214
	# as one of our lazy umounted filesystems
215
	kill_list=
216
	[ -n "$detached_fds" ] && while read fdline; do
217
		fd=${fdline%% *}
218
		pid=$(echo $fdline | sed -r 's/\/proc\/([0-9]+).+/\1/')
219
		fd_dev=$(stat -L -c "%d" $fd)
220
		for dev in $devs ; do
221
			[ "$dev" = "$fd_dev" ] && kill_list+="$pid "
222
		done
223
	done <<< "$detached_fds"
224
 
225
	if [ -n "$kill_list" ] ; then
226
		STRING=$"Killing processes with open filedescriptors on the unmounted disk:"
227
		__kill_pids_term_kill $kill_list && success "$STRING" || failure "$STRING"
228
		echo
229
    fi
230
}
231
 
232
__source_netdevs_fstab() {
233
        NFSFSTAB=$(LC_ALL=C awk '!/^#/ && $3 ~ /^nfs/ && $3 != "nfsd" && $4 !~ /noauto/ { print $2 }' /etc/fstab)
234
        CIFSFSTAB=$(LC_ALL=C awk '!/^#/ && $3 == "cifs" && $4 !~ /noauto/ { print $2 }' /etc/fstab)
235
        NCPFSTAB=$(LC_ALL=C awk '!/^#/ && $3 == "ncpfs" && $4 !~ /noauto/ { print $2 }' /etc/fstab)
236
        GLUSTERFSFSTAB=$(LC_ALL=C awk '!/^#/ && $3 == "glusterfs" && $4 !~ /noauto/ { print $2 }' /etc/fstab)
237
        NETDEVFSTAB=$(LC_ALL=C awk '!/^#/ && $4 ~/_netdev/ && $4 !~ /noauto/ { print $1 }' /etc/fstab)
238
}
239
 
240
__source_netdevs_mtab() {
241
        NFSMTAB=$(LC_ALL=C awk '$3 ~ /^nfs/ && $3 != "nfsd" && $2 != "/" { print $2 }' /proc/mounts)
242
        CIFSMTAB=$(LC_ALL=C awk '$3 == "cifs" { print $2 }' /proc/mounts)
243
        NCPMTAB=$(LC_ALL=C awk '$3 == "ncpfs" { print $2 }' /proc/mounts)
244
        GLUSTERFSMTAB=$(LC_ALL=C awk '$3 == "fuse.glusterfs" { print $2 }' /proc/mounts)
245
        NETDEVMTAB=$(LC_ALL=C awk '$4 ~ /_netdev/ && $2 != "/" { print $2 }' /etc/mtab)
246
 
247
        ALLNETDEVMTAB="$NFSMTAB $CIFSMTAB $NCPMTAB $GLUSTERFSMTAB $NETDEVMTAB"
248
}
249
 
3 - 250
# Similar to __umount loop above, specialized for loopback devices
251
__umount_loopback_loop() {
252
	local remaining devremaining sig=
253
	local retry=3
254
 
57 - 255
        __find_mounts() {
256
                if [ "$1" = "--netdev" ] ; then
257
                       __source_netdevs_mtab
258
                       remaining=
259
                       devremaining=
260
                       local mount= netdev= _rest
261
                       while read -r dev mount _rest ; do
262
                               [ "$dev" = "${dev##/dev/loop}" ] && continue
263
                               local back_file=$(losetup $dev | sed -e 's/^\/dev\/loop[0-9]\+: \[[0-9a-f]\+\]:[0-9]\+ (\(.*\))$/\1/')
264
                               for netdev in $ALLNETDEVMTAB ; do
265
                                        local netdev_decoded=
266
                                        netdev="${netdev}/"
267
                                        netdev_decoded=$(fstab_decode_str ${netdev})
268
                                        if [ "$mount" != "${mount##$netdev}" ] || [ "$back_file" != "${back_file##$netdev_decoded}" ] ; then
269
                                                remaining="$remaining $mount"
270
                                                #device might be mounted in other location,
271
                                                #but then losetup -d will be noop, so meh
272
                                                devremaining="$devremaining $dev"
273
                                                continue 2
274
                                        fi
275
                               done
276
                        done < /proc/mounts
277
                else
278
                        remaining=$(awk '$1 ~ /^\/dev\/loop/ && $2 != "/" {print $2}' /proc/mounts)
279
                        devremaining=$(awk '$1 ~ /^\/dev\/loop/ && $2 != "/" {print $1}' /proc/mounts)
280
                fi
281
        }
282
 
283
        __find_mounts $1
284
 
3 - 285
	while [ -n "$remaining" -a "$retry" -gt 0 ]; do
286
		if [ "$retry" -eq 3 ]; then
287
			action $"Unmounting loopback filesystems: " \
288
				fstab-decode umount $remaining
289
		else
290
			action $"Unmounting loopback filesystems (retry):" \
291
				fstab-decode umount $remaining
292
		fi
57 - 293
 
3 - 294
		for dev in $devremaining ; do
57 - 295
                        if [ "$1" = "--netdev" ] ; then
296
                                #some loopdevices might be mounted on top of non-netdev
297
                                #so ignore failures
298
                                losetup -d $dev > /dev/null 2>&1
299
                        else
300
                                losetup $dev > /dev/null 2>&1 && \
301
                                        action $"Detaching loopback device $dev: " \
302
                                        losetup -d $dev
303
                fi
304
                done
305
                #check what is still mounted
306
                __find_mounts $1
3 - 307
		[ -z "$remaining" ] && break
308
		fstab-decode /sbin/fuser -k -m $sig $remaining >/dev/null
309
		sleep 3
310
		retry=$(($retry -1))
311
		sig=-9
312
	done
313
}
314
 
315
# __proc_pids {program} [pidfile]
316
# Set $pid to pids from /var/run* for {program}.  $pid should be declared
317
# local in the caller.
318
# Returns LSB exit code for the 'status' action.
319
__pids_var_run() {
320
	local base=${1##*/}
321
	local pid_file=${2:-/var/run/$base.pid}
8 - 322
	local pid_dir=$(/usr/bin/dirname $pid_file)
3 - 323
	local binary=$3
324
 
8 - 325
	[ -d "$pid_dir" -a ! -r "$pid_dir" ] && return 4
326
 
3 - 327
	pid=
328
	if [ -f "$pid_file" ] ; then
329
	        local line p
330
 
331
		[ ! -r "$pid_file" ] && return 4 # "user had insufficient privilege"
332
		while : ; do
333
			read line
334
			[ -z "$line" ] && break
335
			for p in $line ; do
336
				if [ -z "${p//[0-9]/}" -a -d "/proc/$p" ] ; then
337
					if [ -n "$binary" ] ; then
8 - 338
						local b=$(readlink /proc/$p/exe | sed -e 's/\s*(deleted)$//')
3 - 339
						[ "$b" != "$binary" ] && continue
340
					fi
341
					pid="$pid $p"
342
				fi
343
			done
344
		done < "$pid_file"
345
 
346
	        if [ -n "$pid" ]; then
347
	                return 0
348
	        fi
349
		return 1 # "Program is dead and /var/run pid file exists"
350
	fi
351
	return 3 # "Program is not running"
352
}
353
 
354
# Output PIDs of matching processes, found using pidof
355
__pids_pidof() {
33 - 356
	pidof -c -m -o $$ -o $PPID -o %PPID -x "$1" || \
357
		pidof -c -m -o $$ -o $PPID -o %PPID -x "${1##*/}"
3 - 358
}
359
 
360
 
361
# A function to start a program.
362
daemon() {
363
	# Test syntax.
364
	local gotbase= force= nicelevel corelimit
365
	local pid base= user= nice= bg= pid_file=
366
	local cgroup=
367
	nicelevel=0
368
	while [ "$1" != "${1##[-+]}" ]; do
369
	  case $1 in
57 - 370
	    '')    echo $"$0: Usage: daemon [+/-nicelevel] {program}" "[arg1]..."
3 - 371
	           return 1;;
372
	    --check)
373
		   base=$2
374
		   gotbase="yes"
375
		   shift 2
376
		   ;;
377
	    --check=?*)
378
	    	   base=${1#--check=}
379
		   gotbase="yes"
380
		   shift
381
		   ;;
382
	    --user)
383
		   user=$2
384
		   shift 2
385
		   ;;
386
	    --user=?*)
387
	           user=${1#--user=}
388
		   shift
389
		   ;;
390
	    --pidfile)
391
		   pid_file=$2
392
		   shift 2
393
		   ;;
394
	    --pidfile=?*)
395
		   pid_file=${1#--pidfile=}
396
		   shift
397
		   ;;
398
	    --force)
399
	    	   force="force"
400
		   shift
401
		   ;;
402
	    [-+][0-9]*)
403
	    	   nice="nice -n $1"
404
	           shift
405
		   ;;
57 - 406
	    *)     echo $"$0: Usage: daemon [+/-nicelevel] {program}" "[arg1]..."
3 - 407
	           return 1;;
408
	  esac
409
	done
410
 
411
        # Save basename.
412
        [ -z "$gotbase" ] && base=${1##*/}
413
 
414
        # See if it's already running. Look *only* at the pid file.
415
	__pids_var_run "$base" "$pid_file"
416
 
417
	[ -n "$pid" -a -z "$force" ] && return
418
 
419
	# make sure it doesn't core dump anywhere unless requested
420
	corelimit="ulimit -S -c ${DAEMON_COREFILE_LIMIT:-0}"
57 - 421
 
3 - 422
	# if they set NICELEVEL in /etc/sysconfig/foo, honor it
423
	[ -n "${NICELEVEL:-}" ] && nice="nice -n $NICELEVEL"
57 - 424
 
3 - 425
	# if they set CGROUP_DAEMON in /etc/sysconfig/foo, honor it
426
	if [ -n "${CGROUP_DAEMON}" ]; then
427
		if [ ! -x /bin/cgexec ]; then
428
			echo -n "Cgroups not installed"; warning
429
			echo
430
		else
431
			cgroup="/bin/cgexec";
432
			for i in $CGROUP_DAEMON; do
433
				cgroup="$cgroup -g $i";
434
			done
435
		fi
436
	fi
437
 
438
	# Echo daemon
439
        [ "${BOOTUP:-}" = "verbose" -a -z "${LSB:-}" ] && echo -n " $base"
440
 
441
	# And start it up.
442
	if [ -z "$user" ]; then
443
	   $cgroup $nice /bin/bash -c "$corelimit >/dev/null 2>&1 ; $*"
444
	else
445
	   $cgroup $nice runuser -s /bin/bash $user -c "$corelimit >/dev/null 2>&1 ; $*"
446
	fi
447
 
448
	[ "$?" -eq 0 ] && success $"$base startup" || failure $"$base startup"
449
}
450
 
451
# A function to stop a program.
452
killproc() {
453
	local RC killlevel= base pid pid_file= delay try binary=
454
 
455
	RC=0; delay=3; try=0
456
	# Test syntax.
457
	if [ "$#" -eq 0 ]; then
458
		echo $"Usage: killproc [-p pidfile] [ -d delay] {program} [-signal]"
459
		return 1
460
	fi
461
	if [ "$1" = "-p" ]; then
462
		pid_file=$2
463
		shift 2
464
	fi
465
	if [ "$1" = "-b" ]; then
466
		if [ -z $pid_file ]; then
467
			echo $"-b option can be used only with -p"
468
			echo $"Usage: killproc -p pidfile -b binary program"
469
			return 1
470
		fi
471
		binary=$2
472
		shift 2
473
	fi
474
	if [ "$1" = "-d" ]; then
475
		delay=$(echo $2 | awk -v RS=' ' -v IGNORECASE=1 '{if($1!~/^[0-9.]+[smhd]?$/) exit 1;d=$1~/s$|^[0-9.]*$/?1:$1~/m$/?60:$1~/h$/?60*60:$1~/d$/?24*60*60:-1;if(d==-1) exit 1;delay+=d*$1} END {printf("%d",delay+0.5)}')
476
		if [ "$?" -eq 1 ]; then
477
			echo $"Usage: killproc [-p pidfile] [ -d delay] {program} [-signal]"
478
			return 1
479
		fi
480
		shift 2
481
	fi
482
 
57 - 483
 
3 - 484
	# check for second arg to be kill level
485
	[ -n "${2:-}" ] && killlevel=$2
486
 
487
        # Save basename.
488
        base=${1##*/}
489
 
490
        # Find pid.
491
	__pids_var_run "$1" "$pid_file" "$binary"
492
	RC=$?
493
	if [ -z "$pid" ]; then
494
		if [ -z "$pid_file" ]; then
495
			pid="$(__pids_pidof "$1")"
496
		else
497
			[ "$RC" = "4" ] && { failure $"$base shutdown" ; return $RC ;}
498
		fi
499
	fi
500
 
501
        # Kill it.
502
        if [ -n "$pid" ] ; then
503
                [ "$BOOTUP" = "verbose" -a -z "${LSB:-}" ] && echo -n "$base "
504
		if [ -z "$killlevel" ] ; then
57 - 505
			__kill_pids_term_kill -d $delay $pid
3 - 506
			RC=$?
57 - 507
			[ "$RC" -eq 0 ] && success $"$base shutdown" || failure $"$base shutdown"
3 - 508
		# use specified level only
509
		else
510
		        if checkpid $pid; then
511
	                	kill $killlevel $pid >/dev/null 2>&1
512
				RC=$?
513
				[ "$RC" -eq 0 ] && success $"$base $killlevel" || failure $"$base $killlevel"
514
			elif [ -n "${LSB:-}" ]; then
515
				RC=7 # Program is not running
516
			fi
517
		fi
518
	else
519
		if [ -n "${LSB:-}" -a -n "$killlevel" ]; then
520
			RC=7 # Program is not running
521
		else
522
			failure $"$base shutdown"
523
			RC=0
524
		fi
525
	fi
526
 
527
        # Remove pid file if any.
528
	if [ -z "$killlevel" ]; then
529
            rm -f "${pid_file:-/var/run/$base.pid}"
530
	fi
531
	return $RC
532
}
533
 
534
# A function to find the pid of a program. Looks *only* at the pidfile
535
pidfileofproc() {
536
	local pid
537
 
538
	# Test syntax.
539
	if [ "$#" = 0 ] ; then
540
		echo $"Usage: pidfileofproc {program}"
541
		return 1
542
	fi
543
 
544
	__pids_var_run "$1"
545
	[ -n "$pid" ] && echo $pid
546
	return 0
547
}
548
 
549
# A function to find the pid of a program.
550
pidofproc() {
551
	local RC pid pid_file=
552
 
553
	# Test syntax.
554
	if [ "$#" = 0 ]; then
555
		echo $"Usage: pidofproc [-p pidfile] {program}"
556
		return 1
557
	fi
558
	if [ "$1" = "-p" ]; then
559
		pid_file=$2
560
		shift 2
561
	fi
562
	fail_code=3 # "Program is not running"
563
 
564
	# First try "/var/run/*.pid" files
565
	__pids_var_run "$1" "$pid_file"
566
	RC=$?
567
	if [ -n "$pid" ]; then
568
		echo $pid
569
		return 0
570
	fi
571
 
572
	[ -n "$pid_file" ] && return $RC
573
	__pids_pidof "$1" || return $RC
574
}
575
 
576
status() {
577
	local base pid lock_file= pid_file= binary=
578
 
579
	# Test syntax.
580
	if [ "$#" = 0 ] ; then
581
		echo $"Usage: status [-p pidfile] {program}"
582
		return 1
583
	fi
584
	if [ "$1" = "-p" ]; then
585
		pid_file=$2
586
		shift 2
587
	fi
588
	if [ "$1" = "-l" ]; then
589
		lock_file=$2
590
		shift 2
591
	fi
592
	if [ "$1" = "-b" ]; then
593
		if [ -z $pid_file ]; then
594
			echo $"-b option can be used only with -p"
595
			echo $"Usage: status -p pidfile -b binary program"
596
			return 1
597
		fi
598
		binary=$2
599
		shift 2
600
	fi
601
	base=${1##*/}
602
 
603
	# First try "pidof"
604
	__pids_var_run "$1" "$pid_file" "$binary"
605
	RC=$?
606
	if [ -z "$pid_file" -a -z "$pid" ]; then
607
		pid="$(__pids_pidof "$1")"
608
	fi
609
	if [ -n "$pid" ]; then
610
	        echo $"${base} (pid $pid) is running..."
611
	        return 0
612
	fi
613
 
614
	case "$RC" in
615
		0)
616
			echo $"${base} (pid $pid) is running..."
617
			return 0
618
			;;
619
		1)
620
	                echo $"${base} dead but pid file exists"
621
	                return 1
622
			;;
623
		4)
624
			echo $"${base} status unknown due to insufficient privileges."
625
			return 4
626
			;;
627
	esac
628
	if [ -z "${lock_file}" ]; then
629
		lock_file=${base}
630
	fi
631
	# See if /var/lock/subsys/${lock_file} exists
632
	if [ -f /var/lock/subsys/${lock_file} ]; then
633
		echo $"${base} dead but subsys locked"
634
		return 2
635
	fi
636
	echo $"${base} is stopped"
637
	return 3
638
}
639
 
640
echo_success() {
641
  [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
642
  echo -n "["
643
  [ "$BOOTUP" = "color" ] && $SETCOLOR_SUCCESS
644
  echo -n $"  OK  "
645
  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
646
  echo -n "]"
647
  echo -ne "\r"
648
  return 0
649
}
650
 
651
echo_failure() {
652
  [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
653
  echo -n "["
654
  [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
655
  echo -n $"FAILED"
656
  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
657
  echo -n "]"
658
  echo -ne "\r"
659
  return 1
660
}
661
 
662
echo_passed() {
663
  [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
664
  echo -n "["
665
  [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
666
  echo -n $"PASSED"
667
  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
668
  echo -n "]"
669
  echo -ne "\r"
670
  return 1
671
}
672
 
673
echo_warning() {
674
  [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
675
  echo -n "["
676
  [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
677
  echo -n $"WARNING"
678
  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
679
  echo -n "]"
680
  echo -ne "\r"
681
  return 1
682
}
683
 
684
# Inform the graphical boot of our current state
685
update_boot_stage() {
686
  if [ -x /bin/plymouth ]; then
687
      /bin/plymouth --update="$1"
688
  fi
689
  return 0
690
}
691
 
692
# Log that something succeeded
693
success() {
694
  [ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_success
695
  return 0
696
}
697
 
698
# Log that something failed
699
failure() {
700
  local rc=$?
701
  [ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_failure
702
  [ -x /bin/plymouth ] && /bin/plymouth --details
703
  return $rc
704
}
705
 
706
# Log that something passed, but may have had errors. Useful for fsck
707
passed() {
708
  local rc=$?
709
  [ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_passed
710
  return $rc
57 - 711
}
3 - 712
 
713
# Log a warning
714
warning() {
715
  local rc=$?
716
  [ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_warning
717
  return $rc
57 - 718
}
3 - 719
 
720
# Run some action. Log its output.
721
action() {
722
  local STRING rc
723
 
724
  STRING=$1
725
  echo -n "$STRING "
726
  shift
727
  "$@" && success $"$STRING" || failure $"$STRING"
728
  rc=$?
729
  echo
730
  return $rc
731
}
732
 
33 - 733
# Run some action. Silently.
734
action_silent() {
735
  local STRING rc
736
 
737
  STRING=$1
738
  echo -n "$STRING "
739
  shift
740
  "$@" >/dev/null && success $"$STRING" || failure $"$STRING"
741
  rc=$?
742
  echo
743
  return $rc
744
}
745
 
3 - 746
# returns OK if $1 contains $2
747
strstr() {
748
  [ "${1#*$2*}" = "$1" ] && return 1
749
  return 0
750
}
751
 
752
# Confirm whether we really want to run this service
753
confirm() {
754
  [ -x /bin/plymouth ] && /bin/plymouth --hide-splash
57 - 755
  while : ; do
3 - 756
      echo -n $"Start service $1 (Y)es/(N)o/(C)ontinue? [Y] "
757
      read answer
758
      if strstr $"yY" "$answer" || [ "$answer" = "" ] ; then
759
         return 0
760
      elif strstr $"cC" "$answer" ; then
761
	 rm -f /var/run/confirm
762
	 [ -x /bin/plymouth ] && /bin/plymouth --show-splash
763
         return 2
764
      elif strstr $"nN" "$answer" ; then
765
         return 1
766
      fi
767
  done
768
}
769
 
770
# resolve a device node to its major:minor numbers in decimal or hex
771
get_numeric_dev() {
772
(
773
    fmt="%d:%d"
774
    if [ "$1" == "hex" ]; then
775
        fmt="%x:%x"
776
    fi
777
    ls -lH "$2" | awk '{ sub(/,/, "", $5); printf("'"$fmt"'", $5, $6); }'
778
) 2>/dev/null
779
}
780
 
781
# Check whether file $1 is a backup or rpm-generated file and should be ignored
782
is_ignored_file() {
783
    case "$1" in
784
	*~ | *.bak | *.orig | *.rpmnew | *.rpmorig | *.rpmsave)
785
	    return 0
786
	    ;;
787
    esac
788
    return 1
789
}
790
 
791
# Evaluate shvar-style booleans
792
is_true() {
793
    case "$1" in
95 - 794
	[tT] | [yY] | [yY][eE][sS] | [tT][rR][uU][eE] | 1)
3 - 795
	return 0
796
	;;
797
    esac
798
    return 1
799
}
800
 
801
# Evaluate shvar-style booleans
802
is_false() {
803
    case "$1" in
95 - 804
	[fF] | [nN] | [nN][oO] | [fF][aA][lL][sS][eE] | 0)
3 - 805
	return 0
806
	;;
807
    esac
808
    return 1
809
}
810
 
811
# Apply sysctl settings, including files in /etc/sysctl.d
812
apply_sysctl() {
813
    sysctl -e -p /etc/sysctl.conf >/dev/null 2>&1
814
    for file in /etc/sysctl.d/* ; do
815
        is_ignored_file "$file" && continue
816
        test -f "$file" && sysctl -e -p "$file" >/dev/null 2>&1
817
    done
818
}
819
 
820
key_is_random() {
821
    [ "$1" = "/dev/urandom" -o "$1" = "/dev/hw_random" \
822
	-o "$1" = "/dev/random" ]
823
}
824
 
825
find_crypto_mount_point() {
826
    local fs_spec fs_file fs_vfstype remaining_fields
827
    local fs
828
    while read fs_spec fs_file remaining_fields; do
829
	if [ "$fs_spec" = "/dev/mapper/$1" ]; then
830
	    echo $fs_file
831
	    break;
832
	fi
833
    done < /etc/fstab
834
}
835
 
836
# Because of a chicken/egg problem, init_crypto must be run twice.  /var may be
837
# encrypted but /var/lib/random-seed is needed to initialize swap.
838
init_crypto() {
839
    local have_random dst src key opt mode owner params makeswap skip arg opt
840
    local param value rc ret mke2fs mdir prompt mount_point
841
 
842
    ret=0
843
    have_random=$1
844
    while read dst src key opt; do
845
	[ -z "$dst" -o "${dst#\#}" != "$dst" ] && continue
846
        [ -b "/dev/mapper/$dst" ] && continue;
847
	if [ "$have_random" = 0 ] && key_is_random "$key"; then
848
	    continue
849
	fi
850
	if [ -n "$key" -a "x$key" != "xnone" ]; then
851
	    if test -e "$key" ; then
852
		owner=$(ls -l $key | (read a b owner rest; echo $owner))
853
		if ! key_is_random "$key"; then
854
		    mode=$(ls -l "$key" | cut -c 5-10)
855
		    if [ "$mode" != "------" ]; then
856
		       echo $"INSECURE MODE FOR $key"
857
		    fi
858
		fi
859
		if [ "$owner" != root ]; then
860
		    echo $"INSECURE OWNER FOR $key"
861
		fi
862
	    else
863
		echo $"Key file for $dst not found, skipping"
864
		ret=1
865
		continue
866
	    fi
867
	else
868
	    key=""
869
	fi
870
	params=""
871
	makeswap=""
872
	mke2fs=""
873
	skip=""
874
	# Parse the src field for UUID= and convert to real device names
875
	if [ "${src%%=*}" == "UUID" ]; then
876
		src=$(/sbin/blkid -t "$src" -l -o device)
877
	elif [ "${src/^\/dev\/disk\/by-uuid\/}" != "$src" ]; then
878
		src=$(__readlink $src)
879
	fi
880
	# Is it a block device?
881
	[ -b "$src" ] || continue
882
	# Is it already a device mapper slave? (this is gross)
883
	devesc=${src##/dev/}
884
	devesc=${devesc//\//!}
885
	for d in /sys/block/dm-*/slaves ; do
886
	    [ -e $d/$devesc ] && continue 2
887
	done
888
	# Parse the options field, convert to cryptsetup parameters and
889
	# contruct the command line
890
	while [ -n "$opt" ]; do
891
	    arg=${opt%%,*}
892
	    opt=${opt##$arg}
893
	    opt=${opt##,}
894
	    param=${arg%%=*}
895
	    value=${arg##$param=}
896
 
897
	    case "$param" in
898
	    cipher)
899
		params="$params -c $value"
900
		if [ -z "$value" ]; then
901
		    echo $"$dst: no value for cipher option, skipping"
902
		    skip="yes"
903
		fi
904
	    ;;
905
	    size)
906
		params="$params -s $value"
907
		if [ -z "$value" ]; then
908
		    echo $"$dst: no value for size option, skipping"
909
		    skip="yes"
910
		fi
911
	    ;;
912
	    hash)
913
		params="$params -h $value"
914
		if [ -z "$value" ]; then
915
		    echo $"$dst: no value for hash option, skipping"
916
		    skip="yes"
917
		fi
918
	    ;;
919
	    verify)
920
	        params="$params -y"
921
	    ;;
922
	    swap)
923
		makeswap=yes
924
		;;
925
	    tmp)
926
		mke2fs=yes
927
	    esac
928
	done
929
	if [ "$skip" = "yes" ]; then
930
	    ret=1
931
	    continue
932
	fi
933
	if [ -z "$makeswap" ] && cryptsetup isLuks "$src" 2>/dev/null ; then
934
	    if key_is_random "$key"; then
935
		echo $"$dst: LUKS requires non-random key, skipping"
936
		ret=1
937
		continue
938
	    fi
939
	    if [ -n "$params" ]; then
940
		echo "$dst: options are invalid for LUKS partitions," \
941
		    "ignoring them"
942
	    fi
943
	    if [ -n "$key" ]; then
944
		/sbin/cryptsetup -d $key luksOpen "$src" "$dst" <&1 2>/dev/null && success || failure
945
		rc=$?
946
	    else
947
		mount_point="$(find_crypto_mount_point $dst)"
948
		[ -n "$mount_point" ] || mount_point=${src##*/}
949
		prompt=$(printf $"%s is password protected" "$mount_point")
950
		plymouth ask-for-password --prompt "$prompt" --command="/sbin/cryptsetup luksOpen -T1 $src $dst" <&1
951
		rc=$?
952
	    fi
953
	else
954
	    [ -z "$key" ] && plymouth --hide-splash
128 - 955
	    /sbin/cryptsetup $params ${key:+-d $key} create "$dst" "$src" <&1 && success || failure
3 - 956
	    rc=$?
957
	    [ -z "$key" ] && plymouth --show-splash
958
	fi
959
	if [ $rc -ne 0 ]; then
960
	    ret=1
961
	    continue
962
	fi
963
	if [ -b "/dev/mapper/$dst" ]; then
964
	    if [ "$makeswap" = "yes" ]; then
965
		mkswap "/dev/mapper/$dst" 2>/dev/null >/dev/null
966
	    fi
967
	    if [ "$mke2fs" = "yes" ]; then
968
		if mke2fs "/dev/mapper/$dst" 2>/dev/null >/dev/null \
969
		    && mdir=$(mktemp -d /tmp/mountXXXXXX); then
970
		    mount "/dev/mapper/$dst" "$mdir" && chmod 1777 "$mdir"
971
		    umount "$mdir"
972
		    rmdir "$mdir"
973
		fi
974
	    fi
975
	fi
976
    done < /etc/crypttab
977
    return $ret
978
}
979
 
980
# A sed expression to filter out the files that is_ignored_file recognizes
981
__sed_discard_ignored_files='/\(~\|\.bak\|\.orig\|\.rpmnew\|\.rpmorig\|\.rpmsave\)$/d'
33 - 982
 
983
#if we have privileges lets log to kmsg, otherwise to stderr
984
if strstr "$(cat /proc/cmdline)" "rc.debug"; then
985
        [ -w /dev/kmsg ] && exec 30>/dev/kmsg && BASH_XTRACEFD=30
986
        set -x
987
fi