Branch: Tag:

2012-09-17

2012-09-17 16:38:46 by Henrik Grubbström (Grubba) <grubba@grubba.org>

Start-script: Refactored pid file handling. Fixes [bug 6516 (#6516)].

The start script now creates a lockfile in /var/run/ (if possible,
otherwise in /tmp/), that is checked for presence before trusting
the pids in the pid file. Since /var/run/ and /tmp/ are cleared
on reboot this should protect against pid conflicts due to reuse.

Rev: server/start:1.244

1:   #!/bin/sh   # - # $Id: start,v 1.243 2012/01/17 10:52:44 grubba Exp $ + # $Id: start,v 1.244 2012/09/17 16:38:46 grubba Exp $      ### If --silent-start is given as the first argument,   ### nothing will be printed to stdout by the script.
745:   #      cleanup_pid_file() { +  rm -f "/tmp/roxen.$$" 2>/dev/null +  rm -f "/var/run/roxen.$$" 2>/dev/null    [ -z "$pidfile" ] || rm $pidfile   }   
757:    return;   }    + # Check if the PID in $1 is an active process and is the Roxen start-script. + roxenp() { +  # Check that there's a lock-file. +  # +  # Primary check is in /var/run/ which often is restricted to root. +  # Secondary check is in /tmp/ to allow for normal users running +  # the script unmodified. +  if [ -f "/var/run/roxen.$1" -o -f "/tmp/roxen.$1" ]; then +  # Check that the process exists as well. +  processp "$1"; +  return; +  fi +  return 1; + } +    # NOTE: The following function needs to be reentrant.   signal_exit() {    test "x$once" != x2 && dp "Start script terminating."
803:    fi    fi    fi +  cleanup_pid_file    test "x$once" != x2 && dp "Start script terminated."    exit 0   }
919:    # Check for stop.    if [ "$stop"x != x ] && [ -f "$pidfile" ]    then +  if read roxenpid && read scriptpid && roxenp "$scriptpid"; then    pids=`cat "$pidfile"`    echo "$pids" | xargs kill    cat "$pidfile" | while read pid; do
927:    sleep 1    done    done +  else +  dp "There is a pid file $pidfile," +  dp "but the corresponding processes do not exist." +  dp "Stale pid file? Deleting the pid file." +  rm "$pidfile" +  : +  fi < "$pidfile"    exit    fi    # Avoid duplicate start scripts if we got a pid file.    mypid=$$    test -f "$pidfile" && {    if read roxenpid && read scriptpid; then -  if processp $scriptpid 2>/dev/null; then +  if roxenp $scriptpid 2>/dev/null ; then    dp "According to the pid file $pidfile,"    dp "there is already a start script running with pid $scriptpid. Specify "    dp "another pid file with --pid-file if this is a different server."    dp "Server not started."    : -  elif processp $roxenpid 2>/dev/null; then -  dp "According to the pid file $pidfile," -  dp "there is already a server running with pid $roxenpid, but its start " -  dp "script seems to have died. You should shut it down and restart " -  dp "it, since it won't restart automatically. Server not started." -  : +     else false; fi    else false; fi    } < "$pidfile" && exit 1    # Minor race here. -  +  { touch "/var/run/roxen.$mypid" || touch "/tmp/roxen.$mypid"; } 2>/dev/null    { echo "x" && echo $mypid; } > "$pidfile"    trap cleanup_pid_file 0   fi
985:    if [ ! -d "$DEBUGDIR" ] ; then    if ./mkdir -p "$DEBUGDIR" 2>/dev/null; then :; else    dp "Failed to create log directory $DEBUGDIR." +  cleanup_pid_file    exit 1    fi    fi
1012:    # Thanks to Emils Klotins <emils@dot.lv> for reporting it.    if ./mkdir -p "$DEBUGDIR" 2>/dev/null; then :; else    dp "Failed to create log directory $DEBUGDIR." +  cleanup_pif_file    exit 1    fi    fi
1039:    cleanup_pid_file    cd .. && exec ./start "$@"    dp 'Failed to spawn start script. -- Permission problem?' +  cleanup_pid_file    exit 1    ;;    50)
1073:    :    else    dp 'Failed to spawn subshell. -- Permission problem?' +  cleanup_pid_file    exit 1    fi