]> git.pld-linux.org Git - projects/rc-scripts.git/blobdiff - lib/functions
daemon ssd mode: always setsid, so programs that properly don't daemonize get detache...
[projects/rc-scripts.git] / lib / functions
index 3b9fc394e33dff0fb0287be68b2a357c2705960c..aee3cc1fff66dddf06e08dbcd3f12c5690132895 100644 (file)
@@ -2,7 +2,6 @@
 # functions    This file contains functions to be used by most or all
 #              shell scripts in the /etc/rc.d/init.d directory.
 #
-# $Id$
 #
 # Author:      Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
 # Hacked by:   Greg Galloway and Marc Ewing
@@ -62,6 +61,17 @@ env_upstart=$USE_UPSTART
 [ -r /etc/sysconfig/system ] && . /etc/sysconfig/system
 [ -r /etc/sysconfig/bootsplash ] && . /etc/sysconfig/bootsplash
 
+# if initscript is invoked via bash, enable RedHat/Fedora compatibility
+# RC_FEDORA is "set" if enabled and "unset" when not, but it's "value" is always empty
+# this is useful for inline constructs
+if [ "${BASH_VERSION+set}" = "set" ]; then
+       RC_LOGGING=yes
+       FASTRC=no
+       RC_FEDORA=
+else
+       unset RC_FEDORA || :
+fi
+
 [ "$env_upstart" ] && USE_UPSTART=$env_upstart
 
 if [ -z "$VSERVER" -o "$VSERVER" = "detect" ]; then
@@ -158,6 +168,29 @@ strstr() {
        return 0
 }
 
+# Apply sysctl settings, including files in /etc/sysctl.d
+apply_sysctl() {
+       if [ -x /lib/systemd/systemd-sysctl ]; then
+               /lib/systemd/systemd-sysctl
+               return
+       fi
+
+       local file
+       for file in /usr/lib/sysctl.d/*.conf; do
+               [ -f /run/sysctl.d/${file##*/} ] && continue
+               [ -f /etc/sysctl.d/${file##*/} ] && continue
+               test -f "$file" && sysctl -q -e -p "$file"
+       done
+       for file in /run/sysctl.d/*.conf; do
+               [ -f /etc/sysctl.d/${file##*/} ] && continue
+               test -f "$file" && sysctl -q -e -p "$file"
+       done
+       for file in /etc/sysctl.d/*.conf; do
+               test -f "$file" && sysctl -q -e -p "$file"
+       done
+       sysctl -q -e -p /etc/sysctl.conf
+}
+
 if is_yes "$FASTRC" || is_yes "$IN_SHUTDOWN"; then
        RC_LOGGING=no
 fi
@@ -381,12 +414,16 @@ msg_usage() {
 
 # Some functions to handle PLD Linux-style messages
 show() {
-       local text len
+       local text len time
+
+       if is_yes "$RC_UPTIME"; then
+               time=$(awk '{printf("[%8.2f] ", $1)}' /proc/uptime)
+       fi
 
        if is_no "$FASTRC" && is_yes "$GETTEXT"; then
-               text=$(nls -n "$@")
+               text=$time$(nls -n "$@")
        else
-               text=$(printf "$@")
+               text=$time$(printf "$@")
        fi
        len=${#text}
        while [ $((len++)) -lt $INIT_COL ]; do
@@ -424,7 +461,7 @@ busy() {
 }
 
 ok() {
-       echo "$_ok"
+       echo -ne "$_ok${RC_FEDORA+\\r}${RC_FEDORA-\\n}"
 }
 
 started() {
@@ -432,7 +469,7 @@ started() {
 }
 
 fail() {
-       echo "$_fail"
+       echo -ne "$_fail${RC_FEDORA+\\r}${RC_FEDORA-\\n}"
        return 1
 }
 
@@ -456,14 +493,23 @@ checkpid() {
 # (note: some processes like named are chrooted but run outside chroot)
 # - do nothing inside vserver
 filter_chroot() {
+       # filter by pid namespace if such dir exists for current process
+       # we do filter in containers as stacked containers are possible with LXC
+       if [ -d /proc/$$/ns ]; then
+               local pids
+               pids=$(filter_ns "$@") && set -- "$pids"
+       fi
+
        if is_yes "$VSERVER"; then
                echo $@
                return
        fi
+
        if [ $# -lt 1 -o ! -d /proc/1 ]; then
                echo $@
                return
        fi
+
        local root_dir good_pids="" good_add_pid
        for root_pid in $@; do
                root_dir=$(resolvesymlink /proc/${root_pid}/root)
@@ -482,6 +528,30 @@ filter_chroot() {
        echo $good_pids
 }
 
+# similar to filter_chroot, but filter based on /proc/PID/ns/pid value
+filter_ns() {
+       local cur_ns=$(resolvesymlink /proc/$$/ns/pid)
+       [ "$cur_ns" ] || return 1
+
+       local pid ns pids=""
+       # add pids if it matches current pid namespace
+       # we should add pids what do not exist (dead processes),
+       # but not add pids whose namespace does not match
+       # (processes belonging to different NS do exist in /proc)
+       for pid in "$@"; do
+               if [ ! -d /proc/$pid ]; then
+                       pids="$pids $pid"
+                       continue
+               fi
+               ns=$(resolvesymlink /proc/$pid/ns/pid)
+               if [ "$ns" = "$cur_ns" ]; then
+                       pids="$pids $pid"
+               fi
+       done
+       echo $pids
+       return 0
+}
+
 # Usage:
 # run_cmd Message command_to_run
 # run_cmd -a Message command_to_run
@@ -597,6 +667,10 @@ daemon() {
                        shift
                        waittime="$1"
                        ;;
+               --pidfile=?*)
+                       pidfile="${1#--pidfile=}"
+                       case "$pidfile" in /*);; *) pidfile="/var/run/$pidfile";; esac
+                       ;;
                --pidfile)
                        shift
                        pidfile="$1"
@@ -652,13 +726,14 @@ daemon() {
                if [ "$closefds" = 1 ]; then
                        exec 1>&-
                        exec 2>&-
-                       exec 0>&-
+                       exec 0<&-
                elif [ "$redirfds" = 1 ]; then
                        exec 1>/dev/null
                        exec 2>/dev/null
-                       exec 0>/dev/null
+                       exec 0</dev/null
                else
                        exec 2>&1
+                       exec 0</dev/null
                fi
 
                if is_no "$RC_LOGGING"; then
@@ -675,6 +750,14 @@ daemon() {
                                done
                                IFS=$o
                        fi
+                       set -- "$prog" "$@"
+
+                       # use setsid to detach from terminal,
+                       # needs pidfile or ssd would check setsid program instead of real program
+                       if [ "$pidfile" ]; then
+                               set -- /usr/bin/setsid "$@"
+                       fi
+
                        /sbin/start-stop-daemon -q --start \
                                --nicelevel $nice \
                                ${pidfile:+--pidfile $pidfile} \
@@ -684,8 +767,8 @@ daemon() {
                                ${fork:+--background} \
                                ${waitname:+--name $waitname} \
                                ${SERVICE_DROPCAPS:+--dropcap $SERVICE_DROPCAPS} \
-                               --exec "$prog" \
-                               -- ${1:+"$@"}
+                               --exec "$1" \
+                               -- "$@"
                else
                        nice -n $nice initlog -c "$prog" 2>&1 </dev/null
                fi
@@ -716,15 +799,19 @@ daemon() {
 
 # A function to stop a program.
 killproc() {
-       local notset killlevel base pid pidfile result
+       local notset killlevel base pid pidfile result delay=3 try
        # Test syntax.
        if [ $# = 0 ]; then
-               msg_usage " killproc [--pidfile PIDFILE] {program} [-SIGNAME]"
+               msg_usage " killproc [--pidfile|-p PIDFILE] [-d DELAY] {program} [-SIGNAME]"
                return 2
        fi
 
        while [ "$1" != "${1##-}" ]; do
                case $1 in
+               -d)
+                       delay="$2"
+                       shift 2
+                       ;;
                --pidfile|-p)
                        pidfile="$2"
                        case "$pidfile" in /*);; *) pidfile="/var/run/$pidfile";; esac
@@ -754,9 +841,17 @@ killproc() {
        # experimental start-stop-daemon based killing.
        # works only with pidfile
        if is_no "$RC_LOGGING" && [ "$pidfile" ]; then
-               local sig=${killlevel:--TERM}
+               local sig=${killlevel:--TERM} retry
+               # retry only if signal is not specified,
+               # as otherwise impossible to send HUP if process pid stays in pidfile.
+               if [ "${killlevel+set}" = "set" ]; then
+                       # if we send HUP it's ok if process does not die
+                       retry="--oknodo"
+               else
+                       retry="--retry ${sig#-}/10/${sig#-}/60/KILL/10"
+               fi
                /sbin/start-stop-daemon -q --stop \
-                       --retry ${sig#-}/10/${sig#-}/60/KILL/10 \
+                       $retry \
                        -s ${sig#-} \
                        ${pidfile:+--pidfile $pidfile}
                result=$?
@@ -782,14 +877,19 @@ killproc() {
                        if checkpid $pid 2>&1; then
                                # TERM first, then KILL if not dead
                                kill -TERM $pid
-                               usleep 100000
-                               if checkpid $pid && sleep 1 &&
-                                       checkpid $pid && sleep 3 &&
-                                       checkpid $pid; then
+                               usleep 50000
+
+                               try=0
+                               while [ $try -lt $delay ]; do
+                                       checkpid $pid || break
+                                       sleep 1
+                                       try=$((try+1))
+                               done
+                               if checkpid $pid; then
                                        # XXX: SIGKILL is sent already on 4th second!
                                        # HARMFUL for example to mysqld (which is already workarounded)
                                        kill -KILL $pid
-                                       usleep 100000
+                                       usleep 50000
                                fi
                        fi
                        checkpid $pid
@@ -874,7 +974,7 @@ pidofproc() {
 
        # Next try "pidof"
        [ -z "$pid" ] && pidof -o $$ -o $PPID -o %PPID -x "$1"
-       pid=$(filter_chroot "$pid")
+       pid=$(filter_chroot $pid)
        echo $pid
 }
 
@@ -906,7 +1006,7 @@ status() {
        else
                pid=$(pidof -o $$ -o $PPID -o %PPID -x $daemon)
        fi
-       pid=$(filter_chroot "$pid")
+       pid=$(filter_chroot $pid)
 
        if [ "$pid" ]; then
                cpuset_msg="..."
@@ -925,7 +1025,7 @@ status() {
        local base=${daemon##*/}
        if [ -z "$pidfile" -a -f /var/run/${base}.pid ]; then
                read pid < /var/run/${base}.pid
-               pid=$(filter_chroot "$pid")
+               pid=$(filter_chroot $pid)
                if [ "$pid" ]; then
                        nls "%s dead but pid file (%s) exists" "$subsys" /var/run/${base}.pid
                        return 1
This page took 0.050966 seconds and 4 git commands to generate.