Solved daemon not killing (grand)child process on service stop

Hello,

I tried to follow this tutorial to make a rc.d script for a program I would like to run as a service in one of my jails (In this case, a keycloak server - installed manually since it is not available as a port/package yet.): https://redbyte.eu/en/blog/supervised-freebsd-init-script-for-go-deamon/

So I ended up with the following in /usr/local/etc/rc.d/keycloak:
Code:
#!/bin/sh
#
# PROVIDE: keycloak
# REQUIRE: networking
# KEYWORD:

. /etc/rc.subr

name="keycloak"
rcvar="keycloak_enable"

load_rc_config $name
: ${keycloak_enable:=no}
: ${keycloak_chdir="/usr/local/www/keycloak"}
: ${keycloak_bind_ip="127.0.0.1"}

keycloak_command="bin/standalone.sh -b ${keycloak_bind_ip}"

pidfile="/var/run/${name}.pid"
command="/usr/sbin/daemon"
command_args="-P ${pidfile} -r -f ${keycloak_command}"

run_rc_command "$1"
I also added some configuration in my rc.conf to make it work:
Code:
keycloak_enable="YES"
keycloak_chdir="/root/keycloak-11.0.3"
keycloak_bind_ip="192.168.1.27"
keycloak_env="PROXY_ADDRESS_FORWARDING=true;JAVA=/usr/local/bin/java"
It works fine when I start the service:
Code:
root@iam:~ # service keycloak start
Starting keycloak.
PROXY_ADDRESS_FORWARDING=true
PATH=/sbin:/bin:/usr/sbin:/usr/bin
OLDPWD=/
PWD=/root/keycloak-11.0.3
HOME=/
RC_PID=18214
root@iam:~ #

Code:
root@iam:~ # pstree
-+= 18220 root daemon: bin/standalone.sh[18221] (daemon)
\-+- 18221 root /bin/sh bin/standalone.sh -b 192.168.1.27
   \--- 18306 root /usr/local/openjdk8-jre/bin/java -D[Standalone] -server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.head
root@iam:~ #

The issue is when I do a service keycloak stop, the java process does not get terminated:
Code:
root@iam:~ # service keycloak stop
Stopping keycloak.
Waiting for PIDS: 18220.
root@iam:~ # pstree
--- 18306 root /usr/local/openjdk8-jre/bin/java -D[Standalone] -server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless
root@iam:~ #

What could I do to make sure it gets killed?

Note that I checked the contents of the /root/keycloak-11.0.3/bin/standalone.sh and it launches java in the foreground, so I would guess signals get transferred to the child, is that right? I tried to make it launch it in the background, in which case it does set traps for various signals, but it did not change anything.

Edit: Okay so I fixed my syntax with keycloak_env in /etc/rc.conf (had to use " " between vars, not ";"). Now I can ask the /root/keycloak-11.0.3/bin/standalone.sh script to start java in the background and setup traps to forward the signal. Which it does. But then /bin/sh goes crazy for memory (I guess) and half of my system gets shut down by the host (including other jails and host processes...)

On the jail:
Code:
root@iam:~ # service keycloak stop
Stopping keycloak.
Waiting for PIDS: 20493, 20493.
root@iam:~ # pstree
--- 20494 root /bin/sh bin/standalone.sh -b 192.168.1.27

On the host, in /var/log/messages:
Code:
2020-12-30T21:26:01.051636+01:00 host kernel: pid 20494 (sh), jid 30, uid 0, was killed: out of swap space
2020-12-30T21:26:01.395003+01:00 host kernel: pid 20415 (python3.7), jid 0, uid 0, was killed: out of swap space
2020-12-30T21:26:01.395034+01:00 host kernel: pid 28888 (python3.7), jid 0, uid 0, was killed: out of swap space
2020-12-30T21:26:01.395043+01:00 host kernel: pid 702 (ntpd), jid 0, uid 0, was killed: out of swap space
2020-12-30T21:26:01.395051+01:00 host kernel: pid 53955 (php-cgi), jid 22, uid 80, was killed: out of swap space
2020-12-30T21:26:01.395057+01:00 host kernel: swap_pager: indefinite wait buffer: bufobj: 0, blkno: 91388, size: 4096
2020-12-30T21:26:01.395064+01:00 host kernel: swap_pager: indefinite wait buffer: bufobj: 0, blkno: 205300, size: 32768
2020-12-30T21:26:01.395076+01:00 host kernel: swap_pager: indefinite wait buffer: bufobj: 0, blkno: 196682, size: 16384
2020-12-30T21:26:01.395084+01:00 host kernel: pid 2507 (perl), jid 6, uid 225, was killed: out of swap space
2020-12-30T21:26:01.395091+01:00 host kernel: swap_pager: indefinite wait buffer: bufobj: 0, blkno: 76051, size: 45056
2020-12-30T21:26:01.395098+01:00 host kernel: swap_pager: indefinite wait buffer: bufobj: 0, blkno: 141575, size: 8192
2020-12-30T21:26:01.395113+01:00 host kernel: swap_pager: indefinite wait buffer: bufobj: 0, blkno: 91388, size: 4096
2020-12-30T21:26:01.395121+01:00 host kernel: swap_pager: indefinite wait buffer: bufobj: 0, blkno: 205300, size: 32768
2020-12-30T21:26:01.507987+01:00 host kernel: swap_pager: indefinite wait buffer: bufobj: 0, blkno: 196682, size: 16384
2020-12-30T21:26:01.508032+01:00 host kernel: swap_pager: indefinite wait buffer: bufobj: 0, blkno: 76051, size: 45056
2020-12-30T21:26:01.508041+01:00 host kernel: pid 8814 (wireguard-go), jid 8, uid 0, was killed: out of swap space
2020-12-30T21:26:01.508049+01:00 host kernel: swap_pager: indefinite wait buffer: bufobj: 0, blkno: 141575, size: 8192
2020-12-30T21:26:01.508056+01:00 host kernel: pid 968 (rsyslogd), jid 1, uid 0, was killed: out of swap space
2020-12-30T21:26:01.508081+01:00 host kernel: pid 83386 (nginx), jid 1, uid 0, was killed: out of swap space
2020-12-30T21:26:01.508105+01:00 host kernel: swap_pager: indefinite wait buffer: bufobj: 0, blkno: 91388, size: 4096
2020-12-30T21:26:01.508120+01:00 host kernel: swap_pager: indefinite wait buffer: bufobj: 0, blkno: 205300, size: 32768
2020-12-30T21:26:01.508133+01:00 host kernel: swap_pager: indefinite wait buffer: bufobj: 0, blkno: 196682, size: 16384
2020-12-30T21:26:01.508142+01:00 host kernel: pid 4908 (nginx), jid 1, uid 80, was killed: out of swap space
2020-12-30T21:26:01.508149+01:00 host kernel: swap_pager: indefinite wait buffer: bufobj: 0, blkno: 76051, size: 45056
2020-12-30T21:26:01.508156+01:00 host kernel: wg0: link state changed to DOWN
2020-12-30T21:26:11.134069+01:00 host kernel: pid 20494 (sh), jid 30, uid 0: exited on signal 11 (core dumped)

Any idea what is going on?

Here is the code of that /root/keycloak-11.0.3/bin/standalone.sh script if it can help you understand:
keycloak's bin/standalone.sh
Code:
#!/bin/sh

# Use --debug to activate debug mode with an optional argument to specify the port.
# Usage : standalone.sh --debug
#         standalone.sh --debug 9797

# By default debug mode is disabled.
DEBUG_MODE="${DEBUG:-false}"
DEBUG_PORT="${DEBUG_PORT:-8787}"
GC_LOG="$GC_LOG"
SERVER_OPTS=""
while [ "$#" -gt 0 ]
do
    case "$1" in
      --debug)
          DEBUG_MODE=true
          if [ -n "$2" ] && [ "$2" = `echo "$2" | sed 's/-//'` ]; then
              DEBUG_PORT=$2
              shift
          fi
          ;;
      -Djava.security.manager*)
          echo "ERROR: The use of -Djava.security.manager has been removed. Please use the -secmgr command line argument or SECMGR=true environment variable."
          exit 1
          ;;
      -secmgr)
          SECMGR="true"
          ;;
      --)
          shift
          break;;
      *)
          SERVER_OPTS="$SERVER_OPTS '$1'"
          ;;
    esac
    shift
done

DIRNAME=`dirname "$0"`
PROGNAME=`basename "$0"`
GREP="grep"

. "$DIRNAME/common.sh"

# Use the maximum available, or set MAX_FD != -1 to use that
MAX_FD="maximum"

# tell linux glibc how many memory pools can be created that are used by malloc
MALLOC_ARENA_MAX="${MALLOC_ARENA_MAX:-1}"
export MALLOC_ARENA_MAX

# OS specific support (must be 'true' or 'false').
cygwin=false;
darwin=false;
linux=false;
solaris=false;
freebsd=false;
other=false
case "`uname`" in
    CYGWIN*)
        cygwin=true
        ;;

    Darwin*)
        darwin=true
        ;;
    FreeBSD)
        freebsd=true
        ;;
    Linux)
        linux=true
        ;;
    SunOS*)
        solaris=true
        ;;
    *)
        other=true
        ;;
esac

# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
    [ -n "$JBOSS_HOME" ] &&
        JBOSS_HOME=`cygpath --unix "$JBOSS_HOME"`
    [ -n "$JAVA_HOME" ] &&
        JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
    [ -n "$JAVAC_JAR" ] &&
        JAVAC_JAR=`cygpath --unix "$JAVAC_JAR"`
fi

# Setup JBOSS_HOME
RESOLVED_JBOSS_HOME=`cd "$DIRNAME/.." >/dev/null; pwd`
if [ "x$JBOSS_HOME" = "x" ]; then
    # get the full path (without any relative bits)
    JBOSS_HOME=$RESOLVED_JBOSS_HOME
else
SANITIZED_JBOSS_HOME=`cd "$JBOSS_HOME"; pwd`
if [ "$RESOLVED_JBOSS_HOME" != "$SANITIZED_JBOSS_HOME" ]; then
   echo ""
   echo "   WARNING:  JBOSS_HOME may be pointing to a different installation - unpredictable results may occur."
   echo ""
   echo "             JBOSS_HOME: $JBOSS_HOME"
   echo ""
   sleep 2s
fi
fi
export JBOSS_HOME

# Read an optional running configuration file
if [ "x$RUN_CONF" = "x" ]; then
    RUN_CONF="$DIRNAME/standalone.conf"
fi
if [ -r "$RUN_CONF" ]; then
    . "$RUN_CONF"
fi

# Set debug settings if not already set
if [ "$DEBUG_MODE" = "true" ]; then
    DEBUG_OPT=`echo $JAVA_OPTS | $GREP "\-agentlib:jdwp"`
    if [ "x$DEBUG_OPT" = "x" ]; then
        JAVA_OPTS="$JAVA_OPTS -agentlib:jdwp=transport=dt_socket,address=$DEBUG_PORT,server=y,suspend=n"
    else
        echo "Debug already enabled in JAVA_OPTS, ignoring --debug argument"
    fi
fi

# Setup the JVM
if [ "x$JAVA" = "x" ]; then
    if [ "x$JAVA_HOME" != "x" ]; then
        JAVA="$JAVA_HOME/bin/java"
    else
        JAVA="java"
    fi
fi

if $linux; then
    # consolidate the server and command line opts
    CONSOLIDATED_OPTS="$JAVA_OPTS $SERVER_OPTS"
    # process the standalone options
    for var in $CONSOLIDATED_OPTS
    do
       # Remove quotes
       p=`echo $var | tr -d "'"`
       case $p in
         -Djboss.server.base.dir=*)
              JBOSS_BASE_DIR=`readlink -m ${p#*=}`
              ;;
         -Djboss.server.log.dir=*)
              JBOSS_LOG_DIR=`readlink -m ${p#*=}`
              ;;
         -Djboss.server.config.dir=*)
              JBOSS_CONFIG_DIR=`readlink -m ${p#*=}`
              ;;
       esac
    done
fi

if $solaris; then
    # consolidate the server and command line opts
    CONSOLIDATED_OPTS="$JAVA_OPTS $SERVER_OPTS"
    # process the standalone options
    for var in $CONSOLIDATED_OPTS
    do
       # Remove quotes
       p=`echo $var | tr -d "'"`
      case $p in
        -Djboss.server.base.dir=*)
             JBOSS_BASE_DIR=`echo $p | awk -F= '{print $2}'`
             ;;
        -Djboss.server.log.dir=*)
             JBOSS_LOG_DIR=`echo $p | awk -F= '{print $2}'`
             ;;
        -Djboss.server.config.dir=*)
             JBOSS_CONFIG_DIR=`echo $p | awk -F= '{print $2}'`
             ;;
      esac
    done
fi

# No readlink -m on BSD
if $darwin || $freebsd || $other ; then
    # consolidate the server and command line opts
    CONSOLIDATED_OPTS="$JAVA_OPTS $SERVER_OPTS"
    # process the standalone options
    for var in $CONSOLIDATED_OPTS
    do
       # Remove quotes
       p=`echo $var | tr -d "'"`
       case $p in
         -Djboss.server.base.dir=*)
              JBOSS_BASE_DIR=`cd ${p#*=} ; pwd -P`
              ;;
         -Djboss.server.log.dir=*)
              if [ -d "${p#*=}" ]; then
                JBOSS_LOG_DIR=`cd ${p#*=} ; pwd -P`
             else
                #since the specified directory doesn't exist we don't validate it
                JBOSS_LOG_DIR=${p#*=}
             fi
             ;;
         -Djboss.server.config.dir=*)
              JBOSS_CONFIG_DIR=`cd ${p#*=} ; pwd -P`
              ;;
       esac
    done
fi

# determine the default base dir, if not set
if [ "x$JBOSS_BASE_DIR" = "x" ]; then
   JBOSS_BASE_DIR="$JBOSS_HOME/standalone"
fi
# determine the default log dir, if not set
if [ "x$JBOSS_LOG_DIR" = "x" ]; then
   JBOSS_LOG_DIR="$JBOSS_BASE_DIR/log"
fi
# determine the default configuration dir, if not set
if [ "x$JBOSS_CONFIG_DIR" = "x" ]; then
   JBOSS_CONFIG_DIR="$JBOSS_BASE_DIR/configuration"
fi

if [ "x$JBOSS_MODULEPATH" = "x" ]; then
    JBOSS_MODULEPATH="$JBOSS_HOME/modules"
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
    JBOSS_HOME=`cygpath --path --windows "$JBOSS_HOME"`
    JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
    JBOSS_MODULEPATH=`cygpath --path --windows "$JBOSS_MODULEPATH"`
    JBOSS_BASE_DIR=`cygpath --path --windows "$JBOSS_BASE_DIR"`
    JBOSS_LOG_DIR=`cygpath --path --windows "$JBOSS_LOG_DIR"`
    JBOSS_CONFIG_DIR=`cygpath --path --windows "$JBOSS_CONFIG_DIR"`
fi



if [ "$PRESERVE_JAVA_OPTS" != "true" ]; then
    # Check for -d32/-d64 in JAVA_OPTS
    JVM_D64_OPTION=`echo $JAVA_OPTS | $GREP "\-d64"`
    JVM_D32_OPTION=`echo $JAVA_OPTS | $GREP "\-d32"`

    # Check If server or client is specified
    SERVER_SET=`echo $JAVA_OPTS | $GREP "\-server"`
    CLIENT_SET=`echo $JAVA_OPTS | $GREP "\-client"`

    if [ "x$JVM_D32_OPTION" != "x" ]; then
        JVM_OPTVERSION="-d32"
    elif [ "x$JVM_D64_OPTION" != "x" ]; then
        JVM_OPTVERSION="-d64"
    elif $darwin && [ "x$SERVER_SET" = "x" ]; then
        # Use 32-bit on Mac, unless server has been specified or the user opts are incompatible
        "$JAVA" -d32 $JAVA_OPTS -version > /dev/null 2>&1 && PREPEND_JAVA_OPTS="-d32" && JVM_OPTVERSION="-d32"
    fi

    if [ "x$CLIENT_SET" = "x" -a "x$SERVER_SET" = "x" ]; then
        # neither -client nor -server is specified
        if $darwin && [ "$JVM_OPTVERSION" = "-d32" ]; then
            # Prefer client for Macs, since they are primarily used for development
            PREPEND_JAVA_OPTS="$PREPEND_JAVA_OPTS -client"
        else
            PREPEND_JAVA_OPTS="$PREPEND_JAVA_OPTS -server"
        fi
    fi

    # Set flag if JVM is modular
    setModularJdk

    if [ "$GC_LOG" = "true" ]; then
        # Enable rotating GC logs if the JVM supports it and GC logs are not already enabled
        mkdir -p $JBOSS_LOG_DIR
        NO_GC_LOG_ROTATE=`echo $JAVA_OPTS | $GREP "\-Xlog\:\?gc"`
        if [ "x$NO_GC_LOG_ROTATE" = "x" ]; then
            # backup prior gc logs
            mv -f "$JBOSS_LOG_DIR/gc.log" "$JBOSS_LOG_DIR/backupgc.log" >/dev/null 2>&1
            mv -f "$JBOSS_LOG_DIR/gc.log.0" "$JBOSS_LOG_DIR/backupgc.log.0" >/dev/null 2>&1
            mv -f "$JBOSS_LOG_DIR/gc.log.1" "$JBOSS_LOG_DIR/backupgc.log.1" >/dev/null 2>&1
            mv -f "$JBOSS_LOG_DIR/gc.log.2" "$JBOSS_LOG_DIR/backupgc.log.2" >/dev/null 2>&1
            mv -f "$JBOSS_LOG_DIR/gc.log.3" "$JBOSS_LOG_DIR/backupgc.log.3" >/dev/null 2>&1
            mv -f "$JBOSS_LOG_DIR/gc.log.4" "$JBOSS_LOG_DIR/backupgc.log.4" >/dev/null 2>&1
            mv -f "$JBOSS_LOG_DIR"/gc.log.*.current "$JBOSS_LOG_DIR/backupgc.log.current" >/dev/null 2>&1

            "$JAVA" -Xverbosegclog:"$JBOSS_LOG_DIR/gc.log" -version > /dev/null 2>&1 && OPEN_J9_JDK=true || OPEN_J9_JDK=false
            if [ "$OPEN_J9_JDK" = "true" ]; then
                TMP_PARAM="-Xverbosegclog:\"$JBOSS_LOG_DIR/gc.log\""
            elif [ "$MODULAR_JDK" = "true" ]; then
                TMP_PARAM="-Xlog:gc*:file=\"$JBOSS_LOG_DIR/gc.log\":time,uptimemillis:filecount=5,filesize=3M"
            else
                TMP_PARAM="-verbose:gc -Xloggc:\"$JBOSS_LOG_DIR/gc.log\" -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=3M -XX:-TraceClassUnloading"
            fi

            eval "$JAVA" $JVM_OPTVERSION $TMP_PARAM -version >/dev/null 2>&1 && PREPEND_JAVA_OPTS="$PREPEND_JAVA_OPTS $TMP_PARAM"
            # Remove the gc.log file from the -version check
            rm -f "$JBOSS_LOG_DIR/gc.log" >/dev/null 2>&1
        fi
    fi

    # Set default modular JVM options
    setDefaultModularJvmOptions $JAVA_OPTS
    JAVA_OPTS="$JAVA_OPTS $DEFAULT_MODULAR_JVM_OPTIONS"

    JAVA_OPTS="$PREPEND_JAVA_OPTS $JAVA_OPTS"
fi

# Process the JAVA_OPTS and fail the script of a java.security.manager was found
SECURITY_MANAGER_SET=`echo $JAVA_OPTS | $GREP "java\.security\.manager"`
if [ "x$SECURITY_MANAGER_SET" != "x" ]; then
    echo "ERROR: The use of -Djava.security.manager has been removed. Please use the -secmgr command line argument or SECMGR=true environment variable."
    exit 1
fi

# Set up the module arguments
MODULE_OPTS=""
if [ "$SECMGR" = "true" ]; then
    MODULE_OPTS="$MODULE_OPTS -secmgr";
fi

# Display our environment
echo "========================================================================="
echo ""
echo "  JBoss Bootstrap Environment"
echo ""
echo "  JBOSS_HOME: $JBOSS_HOME"
echo ""
echo "  JAVA: $JAVA"
echo ""
echo "  JAVA_OPTS: $JAVA_OPTS"
echo ""
echo "========================================================================="
echo ""

while true; do
   if [ "x$LAUNCH_JBOSS_IN_BACKGROUND" = "x" ]; then
      # Execute the JVM in the foreground
      eval \"$JAVA\" -D\"[Standalone]\" $JAVA_OPTS \
         \"-Dorg.jboss.boot.log.file="$JBOSS_LOG_DIR"/server.log\" \
         \"-Dlogging.configuration=file:"$JBOSS_CONFIG_DIR"/logging.properties\" \
         -jar \""$JBOSS_HOME"/jboss-modules.jar\" \
         $MODULE_OPTS \
         -mp \""${JBOSS_MODULEPATH}"\" \
         org.jboss.as.standalone \
         -Djboss.home.dir=\""$JBOSS_HOME"\" \
         -Djboss.server.base.dir=\""$JBOSS_BASE_DIR"\" \
         "$SERVER_OPTS"
      JBOSS_STATUS=$?
   else
      # Execute the JVM in the background
      eval \"$JAVA\" -D\"[Standalone]\" $JAVA_OPTS \
         \"-Dorg.jboss.boot.log.file="$JBOSS_LOG_DIR"/server.log\" \
         \"-Dlogging.configuration=file:"$JBOSS_CONFIG_DIR"/logging.properties\" \
         -jar \""$JBOSS_HOME"/jboss-modules.jar\" \
         $MODULE_OPTS \
         -mp \""${JBOSS_MODULEPATH}"\" \
         org.jboss.as.standalone \
         -Djboss.home.dir=\""$JBOSS_HOME"\" \
         -Djboss.server.base.dir=\""$JBOSS_BASE_DIR"\" \
         "$SERVER_OPTS" "&"
      JBOSS_PID=$!
      # Trap common signals and relay them to the jboss process
      trap "kill -HUP  $JBOSS_PID" HUP
      trap "kill -TERM $JBOSS_PID" INT
      trap "kill -QUIT $JBOSS_PID" QUIT
      trap "kill -PIPE $JBOSS_PID" PIPE
      trap "kill -TERM $JBOSS_PID" TERM
      if [ "x$JBOSS_PIDFILE" != "x" ]; then
        echo $JBOSS_PID > $JBOSS_PIDFILE
      fi
      # Wait until the background process exits
      WAIT_STATUS=128
      while [ "$WAIT_STATUS" -ge 128 ]; do
         wait $JBOSS_PID 2>/dev/null
         WAIT_STATUS=$?
         if [ "$WAIT_STATUS" -gt 128 ]; then
            SIGNAL=`expr $WAIT_STATUS - 128`
            SIGNAL_NAME=`kill -l $SIGNAL`
            echo "*** JBossAS process ($JBOSS_PID) received $SIGNAL_NAME signal ***" >&2
         fi
      done
      if [ "$WAIT_STATUS" -lt 127 ]; then
         JBOSS_STATUS=$WAIT_STATUS
      else
         JBOSS_STATUS=0
      fi
      if [ "$JBOSS_STATUS" -ne 10 ]; then
            # Wait for a complete shudown
            wait $JBOSS_PID 2>/dev/null
      fi
      if [ "x$JBOSS_PIDFILE" != "x" ]; then
            grep "$JBOSS_PID" $JBOSS_PIDFILE && rm $JBOSS_PIDFILE
      fi
   fi
   if [ "$JBOSS_STATUS" -eq 10 ]; then
      echo "Restarting application server..."
   else
      exit $JBOSS_STATUS
   fi
done
 
Last edited by a moderator:
Code:
command_args="-P ${pidfile} -r -f ${keycloak_command}"
Try with -p instead of -P:
Code:
     -p child_pidfile
             Write the ID of the created process into the child_pidfile using
             the pidfile(3) functionality.  The program is executed in a
             spawned child process while the daemon waits until it terminates
             to keep the child_pidfile locked and removes it after the process
             exits.  The child_pidfile owner is the user who runs the daemon
             regardless of whether the -u option is used or not.

     -P supervisor_pidfile
             Write the ID of the daemon process into the supervisor_pidfile
             using the pidfile(3) functionality.  The program is executed in a
             spawned child process while the daemon waits until it terminates
             to keep the supervisor_pidfile locked and removes it after the
             process exits.  The supervisor_pidfile owner is the user who runs
             the daemon regardless of whether the -u option is used or not.

You want to kill the child (that sounds soooo bad...) when stopping the service, not the daemon(8) process.
 
Thank you for moving the topic to the right part of the forums.

Try with -p instead of -P:
The issue if you that will using -r is that daemon will stay alive and spawn another child.

Anyway I found the solution (see my Edit), now my issue is the script eating all memory on exit. :-/

Edit: So I changed the swap setup for this machine, moving from a 1GB file on the filesystem to a 2GB partition, that for some reason was not used, and now sh manages to shutdown properly, although it still eats 800MB+ memory on the way before releasing everything, I really wonder why.

Anyway, case solved.
Reason for the original issue was: if your daemon(8)()-spawned process is a shell script starting other stuff, make sure you trap the signals to forward them to that other stuff. Otherwise your shell will die but not the children processes it started.
 
Last edited:
Back
Top