X-Git-Url: https://git.pld-linux.org/?a=blobdiff_plain;f=lib%2Ffunctions;h=aee3cc1fff66dddf06e08dbcd3f12c5690132895;hb=9ecaca50bfd26e55c7bae36b9c412c05e182cfdb;hp=d271637e91b7ea0bdcea8b58b95f8428a1332ef3;hpb=667e4dd4a3c66f551370a466e72a57ad565fd112;p=projects%2Frc-scripts.git diff --git a/lib/functions b/lib/functions index d271637e..aee3cc1f 100644 --- a/lib/functions +++ b/lib/functions @@ -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, # 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 @@ -573,12 +643,10 @@ daemon() { ;; --user) shift - [ "$1" != "root" ] && prog="/bin/su $1 -s /bin/sh -c \"" user=$1 ;; --fork) fork=1 - prog="/usr/bin/setsid sh -c \"" end='&' ;; --chdir) @@ -599,6 +667,10 @@ daemon() { shift waittime="$1" ;; + --pidfile=?*) + pidfile="${1#--pidfile=}" + case "$pidfile" in /*);; *) pidfile="/var/run/$pidfile";; esac + ;; --pidfile) shift pidfile="$1" @@ -618,6 +690,12 @@ daemon() { esac shift done + if [ -n "$user" -a "$user" != "root" ]; then + prog="/bin/su $user -s /bin/sh -c \"" + fi + if [ "$fork" = "1" ]; then + prog="/usr/bin/setsid ${prog:-sh -c \"}" + fi # If command to execute ends with quotation mark, add remaining # arguments and close quotation. if [ "$prog" != "${prog%\"}" ]; then @@ -648,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&1 + exec 0&1 + nice -n $nice initlog -c "$prog" 2>&1 &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 @@ -870,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 } @@ -902,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="..." @@ -921,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