Roxen.git / server / start

version» Context lines:

Roxen.git/server/start:1:   #!/bin/sh   # - # $Id: start,v 1.244 2012/09/17 16:38:46 grubba Exp $ + # $Id: start,v 1.245 2012/09/20 11:27:10 grubba Exp $      ### If --silent-start is given as the first argument,   ### nothing will be printed to stdout by the script.      if [ "x$1" = "x--silent-start" ] ; then    SILENT_START="y"    shift   fi      check_owner() {
Roxen.git/server/start:171:    if [ "x$remove_dumped_passed" = "xyes" ]; then :; else    pass="$pass --remove-dumped"    remove_dumped_passed=yes    fi   }      ## Parse all arguments.   ## GNU-style, long options only, except for -D, simply passed on.   ARGS=""    + # + # Descriptions of some of the state variables set during argument processing. + # + # Variable Default + # Value Description + # ----------------------------------------------------------------- + # debug -1 + # -1 No debug. + # 0 Module debug (Pike warnings + -DMODULE_DEBUG). + # 1 Full debug (Pike warnings + -DDEBUG -DMODULE_DEBUG). + # keep_mysql "" + # "" Shut down mysqld between restarts. + # 1 Do not touch mysqld on restart. + # once "" + # "" Loop the program until it exits with success (0). + # 1 Verbose --once mode. + # 2 Quiet --once mode. + # pass "" + # - Arguments to pass to the Pike program. + # passhelp "" + # "" Roxen is being started. + # 1 A custom program has been specified with --program. + # pidfile "$DIR/_roxen_pid"/"" + # Defaults to "" if Roxen is not being started. + # "" Do not generate a pid file or associated lock files. + # other Create a pid file and associated lock files. + # program "base_server/roxen_loader.pike" + # - The Pike program to start. + # verbose 1 + # 0 Quiet mode. + # 1 Default verbosity. + # 2 Verbose mode. + # +    setup_for_tests() {    # Kill roxen mysql if it's running...    if [ -f "$VARDIR/test_config/_mysql/mysql_pid" ] ; then    kill `cat "$VARDIR/test_config/_mysql/mysql_pid"`    fi    self_test=y    DEFINES="-DRUN_SELF_TEST -DSELF_TEST_DIR=\"$SELF_TEST_DIR\" $DEFINES"    rm -rf "$VARDIR/test_config"*    DIR="$VARDIR/test_config"    if [ -f "$SELF_TEST_DIR/scripts/setup.pike" ] ; then
Roxen.git/server/start:733:   ####### START MySQL      if [ -f "mysql-location.txt" ]; then :; else    if [ "x$passhelp" = "x1" ]; then :; else    dp "Warning: No mysql-location.txt"    fi   fi      ####### END MySQL    + # Canonical configuration directory identifier (the inode number). + canonicalconf=`ls -Lid "$DIR/." | awk '{ print $1; }'` +  + if [ $verbose -gt 1 -a "$passhelp" = "" ]; then +  dp "Canonical Roxen configuration identifier: $canonicalconf." + fi +  +    #   # Some useful functions   #    - cleanup_pid_file() { -  rm -f "/tmp/roxen.$$" 2>/dev/null -  rm -f "/var/run/roxen.$$" 2>/dev/null -  [ -z "$pidfile" ] || rm $pidfile + cleanup_pid_file_lock() { +  if [ -z "$pidfile" ]; then return 0; fi +  if [ $verbose -gt 1 ]; then +  dp "Releasing pid-file lock roxen-$2.$1.pid." +  fi +  rm -f "/tmp/roxen-$2.$1.pid" 2>/dev/null +  rm -f "/var/run/roxen-$2.$1.pid" 2>/dev/null   }    -  + # Check whether there's a valid pid lock on pid $1 + # of process type $2 for configuration $3. + check_pid_file_lock() { +  # 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-$2.$1.pid" -o -f "/tmp/roxen-$2.$1.pid" ]; then +  # Check that the pid file belongs to our configuration. +  if [ `cat /var/run/roxen-$2.$1.pid 2>/dev/null || cat /var/run/roxen-$2.$1.pid 2>/dev/null` = "$3" ]; then +  return 0 +  fi +  fi +  return 1 + } +  + # Cleanup after the start-script. + cleanup_start_pid_file() { +  cleanup_pid_file_lock "$$" "start" "$canonicalconf" +  [ -z "$pidfile" ] || rm -f $pidfile + } +  + # Cleanup after Roxen. + cleanup_roxen_pid_file() { +  if [ -z "$pidfile" ]; then return 0; fi +  read roxenpid <"$pidfile" +  if [ "x$roxenpid" = "xx" ]; then :; else +  if check_pid_file_lock "$roxenpid" "server" "$canonicalconf"; then +  # There's a valid pid file lock for the server for this configuration. +  # Delete it. +  cleanup_pid_file_lock "$roxenpid" "server" +  fi +  # Remove the stale pid from the pid-file. +  if [ $verbose -gt 1 ]; then +  dp "Removing stale pids from $pidfile." +  fi +  { echo "x"; echo "$$"; } >"$pidfile" +  fi + } +    # Check if the PID in $1 is an active process.   processp() {    if kill -0 "$1"; then return 0; fi;       # Check that the cause for the failure is that the process doesn't exist.    "$PIKE" $DEFINES -e 'return !kill('"$1"', 0) && (errno() == System.ESRCH);';    return;   }    - # Check if the PID in $1 is an active process and is the Roxen start-script. + # Check if the PID in $1 is an active process and has + # a $2 {start,server} lock-file associated with the + # configuration $3.   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 +  if check_pid_file "$1" "$2" "$3"; then    # Check that the process exists as well. -  processp "$1"; -  return; +  if processp "$1"; then return 0; fi +  # Cleanup the lock, since it is stale. +  cleanup_pid_file_lock "$1" "$2"    fi    return 1;   }    -  + # Create a roxen lock-file for PID $1 of type $2 + # associated with configuration $3. + lock_pid() { +  if [ -z "$pidfile" ]; then return 0; fi +  # Create a lock-file. +  if [ $verbose -gt 1 ]; then +  dp "Creating lockfile roxen-$2.$1.pid for configuration $3." +  fi +  # NB: The subshell is needed to avoid script termination on +  # permission error (this occurs with /bin/sh on Solaris). +  ( echo "$3" >"/var/run/roxen-$2.$1.pid"; ) 2>/dev/null || \ +  echo "$3" >"/tmp/roxen-$2.$1.pid" 2>/dev/null + } +    # NOTE: The following function needs to be reentrant.   signal_exit() {    test "x$once" != x2 && dp "Start script terminating."    trap "" 2 15 -  if [ "x$ROXEN_PID" != "x" ] && \ -  processp $ROXEN_PID 2>/dev/null; then +  if [ "x$ROXEN_PID" != "x" ]; then +  if processp $ROXEN_PID 2>/dev/null; then    kill $ROXEN_PID 2>/dev/null && wait $ROXEN_PID 2>/dev/null -  +  fi +  # Zap the pid lock file if it is still around. +  # NB: We don't need to clean the pid-file, since +  # we will zap it later. +  cleanup_pid_file_lock "$ROXEN_PID" "server" +  ROXEN_PID=""    dp "Roxen WebServer shutdown."    # FIXME: Consider exiting here.    fi    if [ "x$keep_mysql" = "x" ] ; then    if [ -f "$DIR/_mysql/mysql_pid" ] ; then    mysql_pidfile="$DIR/_mysql/mysql_pid"    elif [ -f "$ROXEN_DATADIR/mysql/mysql_pid" ] ; then    mysql_pidfile="$ROXEN_DATADIR/mysql/mysql_pid"    fi    if [ "x$mysql_pidfile" != "x" ] ; then
Roxen.git/server/start:813:    if processp "$mysql_pid" 2>/dev/null; then    dp "Shutting down MySQL the hard way."    kill -9 "$mysql_pid" 2>/dev/null    fi    if [ -f "$mysql_pidfile" ] && \    [ "$mysql_pid" = "`cat $mysql_pidfile`" ]; then    rm -f "$mysql_pidfile" 2>/dev/null    fi    fi    fi -  cleanup_pid_file +  cleanup_start_pid_file    test "x$once" != x2 && dp "Start script terminated."    exit 0   }      exit_fail() {    exitcode=1   }      # This is a trick to get $ROXEN_PID and arguments containing spaces   # correct at the same time.
Roxen.git/server/start:836:    dp "Server start command:"    for arg    do    dp " $arg"    done    fi    "$@" &    ROXEN_PID=$!   }    + # Start Roxen + # + # Entry/exit invariants: + # + # The pid-file does not contain an entry for the roxen process. + # + # The server pid lock file is nonexistant. + # + # During running (NB: updated by the Roxen process): + # + # The pid-file contains the Roxen server process pid as the first entry. + # + # The corresponding server pid lock file exists.   start_roxen() {    check_owner    raise_limit       if [ x$remove_dumped = x1 ] ; then    remove_old_dot_o_files "user request"    fi    if [ "x$DIR" != "x../configurations" ] ; then    args="$PIKEARGS $DEFINES $ARGS $program --config-dir='`echo \"$DIR\" | sed -e \"s/'/'\\\"'\\\"'/g\"`' $pass"    else    args="$PIKEARGS $DEFINES $ARGS $program $pass"    fi    if [ x"$cd_to" != x ] ; then    cd "$cd_to"    fi -  +  exitcode="0"    if [ "x$gdb" = "xno" -a "x$valgrind" = "x" ]; then    if [ "x$once" = "x" ]; then    if [ $verbose -gt 0 ]; then    dp "Executing $pike $args"|sed -e "s!`pwd`!.!g"    fi    eval "fork_roxen \"$pike\" $args 2>>\"${DEBUGLOG}.1\" 1>&2"    dp "Roxen WebServer server pid $ROXEN_PID." -  +  lock_pid_file "$ROXEN_PID" "server" "$canonicalconf"    wait $ROXEN_PID 2>/dev/null 1>&2    exitcode="$?"    ROXEN_PID=""    else    if [ "x$do_pipe" = "x" ] ; then    if [ "x$once" = "x1" ]; then    eval "fork_roxen $truss \"$pike\" $args 2>&1"    wait $ROXEN_PID 2>/dev/null 1>&2    exitcode="$?"    ROXEN_PID=""    else    eval "$truss \"$pike\" $args" 2>&1    exitcode="$?"    fi    else    trap exit_fail 1    eval "(eval \"$truss \\\"$pike\\\" $args\" || kill -1 $$) 2>&1 $do_pipe" -  +  cleanup_roxen_pid_file    exit $exitcode    fi    fi    elif [ "x$gdb" != "xno" ]; then    echo >.gdbinit handle SIGPIPE nostop noprint pass    echo >>.gdbinit handle SIGUSR1 nostop noprint pass    echo >>.gdbinit handle SIGUSR2 nostop noprint pass    echo >>.gdbinit handle SIGLWP nostop noprint pass    if uname | grep 'Linux' >/dev/null 2>&1; then    echo >>.gdbinit handle SIG38 nostop noprint pass
Roxen.git/server/start:913:    else    firstline=`head -1 "$pike" 2>/dev/null`    if expr "x$firstline" : 'x#! */.*' >/dev/null; then    dp "Executing $pike $valgrind $args"    eval "\"$pike\" \"$valgrind\" $args"    else    dp "Executing valgrind $pike $args"    valgrind `expr "$valgrind" : '--valgrind=\(.*\)'` "$pike"    fi    fi +  cleanup_roxen_pid_file   }         #   # Now do the stuff   #      trap signal_exit 2 15   trap "" 1      if [ "$program" = "base_server/roxenloader.pike" ] ; then    # Starting a Roxen server. Fix the pid file.    [ -z "$pidfile" ] && pidfile="${ROXEN_PID_FILE:-$DIR/_roxen_pid}"    pass="$pass --pid-file='`echo \"$pidfile\" | sed -e \"s/'/'\\\"'\\\"'/g\"`'"    # Check for stop.    if [ "$stop"x != x ] && [ -f "$pidfile" ]    then -  if read roxenpid && read scriptpid && roxenp "$scriptpid"; then +  if read roxenpid && read scriptpid && \ +  roxenp "$scriptpid" "start" "$canonicalconf"; then    pids=`cat "$pidfile"`    echo "$pids" | xargs kill    cat "$pidfile" | while read pid; do    while processp $pid 2>/dev/null; do    echo "Waiting for $pid to die." >&2    sleep 1    done    done    else    dp "There is a pid file $pidfile,"
Roxen.git/server/start:952:    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 roxenp $scriptpid 2>/dev/null ; then +  if roxenp "$scriptpid" "start" "$canonicalconf" 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 roxenp "$roxenpid" "server" "$canonicalconf" 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 +  lock_pid $mypid "start" "$canonicalconf"    { echo "x" && echo $mypid; } > "$pidfile" -  trap cleanup_pid_file 0 +  trap cleanup_start_pid_file 0   fi      PIKEVERSION="`\"$pike\" --version 2>&1|head -1`"   LS="`ls -lL \"$pike\" 2>/dev/null`"   LS="$LS `find etc/modules -ls 2>/dev/null`"   LS="$LS `find base_server -ls 2>/dev/null`"      VERSION_DATA="$PIKEVERSION $DEFINES $LS"      if [ "$program" = "base_server/roxenloader.pike" ] ; then
Roxen.git/server/start:999:    DEBUGDIR="`dirname "$DEBUGLOG"`"    fi    LOGFILE="${DEBUGLOG}.1"    export LOGFILE       # This duplicate of the logdir creation code is needed, check the    # redirect below    if [ ! -d "$DEBUGDIR" ] ; then    if ./mkdir -p "$DEBUGDIR" 2>/dev/null; then :; else    dp "Failed to create log directory $DEBUGDIR." -  cleanup_pid_file +  cleanup_start_pid_file    exit 1    fi    fi    if [ -f "bin/setup_nsr.pike" ]; then    # Setup .nsr (Networker) files for the logfile directories.    eval "\"$pike\" $PIKEARGS $DEFINES bin/setup_nsr.pike --logdir=\"$LOGDIR\" --debugdir=\"$DEBUGDIR\""    fi    if [ $verbose -gt 0 ]; then    dp "Using configuration from $DIR"    dp "Storing the debug log in ${DEBUGLOG}.1"    dp "You can use the administration interface in the server to see debug info."    else :; fi       if (    (    # Minor race here wrt pid file cleanup.    exec 3>&-    trap signal_exit 2 15    trap "" 1 -  trap cleanup_pid_file 0 +  trap cleanup_start_pid_file 0       while : ; do    if test -d "$DEBUGDIR/."; then :; else    # Avoid infinite loop if the debug directory is deleted.    # 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 +  cleanup_start_pid_file    exit 1    fi    fi       dp "Server start at `date`"    dp "Debug log in ${DEBUGLOG}.1"    rotate "$DEBUGLOG"    start_roxen       if [ "$exitcode" -eq "0" ] ; then
Roxen.git/server/start:1052:    exit 0    fi    if [ "$exitcode" -lt "0" ] ; then    # Signal death.    dp "Roxen WebServer died of signal $exitcode."    else    case "$exitcode" in    100)    dp "Changing Roxen WebServer version. Restarting."    # We need to clean up the pid file, since we're mentioned in it... -  cleanup_pid_file +  cleanup_start_pid_file    cd .. && exec ./start "$@"    dp 'Failed to spawn start script. -- Permission problem?' -  cleanup_pid_file +     exit 1    ;;    50)    dp "Failed to open any port. Shutdown."    keep_mysql=1    signal_exit    # Not reached, but...    exit 50    ;;    *)
Roxen.git/server/start:1082:    if /bin/sh "$LOCALDIR/restart_rc"; then :; else    dp "$LOCALDIR/restart_rc failed with code $?."    fi    fi    dp "Restarting..."    done    ) &    # Minor race here wrt pid file contents.    pid=$!    trap "" 0 +  lock_pid_file "$pid" "start" "$canonicalconf"    [ -z "$pidfile" ] || { echo "x" && echo $pid; } > "$pidfile"    dp "Forked start script, pid $pid." 2>&3    dp "Start script pid $pid."    ) 3>&2 </dev/null >"$DEBUGDIR/start_$FILES.output" 2>&1; then    trap "" 0    :    else    dp 'Failed to spawn subshell. -- Permission problem?' -  cleanup_pid_file +  cleanup_start_pid_file    exit 1    fi       # Try to get rid of some fd's.    # Some /bin/sh's have problems detaching otherwise.       exec >/dev/null    exec </dev/null   else    start_roxen    if [ "$once" = "1" -a "$exitcode" = "50" ]; then    dp "Failed to open any port. Shutdown."    keep_mysql=1    fi    signal_exit   fi