How to Force Kill a Process with start-stop-daemon After SIGTERM Timeout in Linux


7 views

The start-stop-daemon utility in Linux provides a powerful --retry option that's often underutilized. When stopping services like Redis that might need graceful termination, this parameter becomes crucial for proper process management.

Your current approach is close, but needs adjustment for proper timeout handling. Here's the corrected command:

/sbin/start-stop-daemon --stop \
    --retry TERM/5/KILL/10 \
    --quiet \
    --oknodo \
    --pidfile /var/run/redis/redis.pid \
    --exec /usr/bin/redis-server

The magic happens in --retry TERM/5/KILL/10 which means:

  • First send SIGTERM (graceful shutdown)
  • Wait 5 seconds for process termination
  • If still running, send SIGKILL (forceful termination)
  • Allow 10 seconds for SIGKILL to take effect

For more complex scenarios, consider these variations:

# Multiple retry attempts with increasing timeouts
--retry TERM/5/TERM/10/KILL/20

# Using signal names instead of abbreviations
--retry SIGTERM/5/SIGKILL/10

# Combining with other useful parameters
/sbin/start-stop-daemon --stop \
    --retry TERM/30/TERM/15/KILL/5 \
    --user redis \
    --name redis-server \
    --pidfile /var/run/redis.pid

If the process isn't terminating as expected:

  1. Verify the PID file contains the correct process ID
  2. Check process ownership matches the --user parameter
  3. Test with --verbose instead of --quiet for troubleshooting
  4. Ensure SELinux/AppArmor isn't blocking signal delivery

When using this in init scripts, the complete stop function might look like:

stop() {
    echo "Stopping redis-server"
    /sbin/start-stop-daemon --stop \
        --retry TERM/10/KILL/5 \
        --pidfile "$PIDFILE" \
        --exec "$DAEMON"
    rm -f "$PIDFILE"
    return 0
}

When managing Redis server processes through init systems, we often need a balanced approach between graceful shutdown and forceful termination. The start-stop-daemon utility provides this capability through its --retry parameter, but its syntax can be confusing.

The --retry option accepts two formats:

--retry=TIMEOUT/SIGNAL
--retry=SCHEME/SIGNAL

Where SCHEME can be either forever or TERM, and TIMEOUT is in seconds.

For Redis server, we want to first send SIGTERM, then SIGKILL after a timeout. Here's the optimal command:

/sbin/start-stop-daemon --stop \
    --retry 30/TERM/15/KILL \
    --quiet \
    --oknodo \
    --pidfile /var/run/redis/redis.pid \
    --exec /usr/bin/redis-server
  • 30/TERM/15/KILL: Wait 30 seconds for SIGTERM to work, then send SIGKILL and wait 15 more seconds
  • --oknodo: Return success if process wasn't running
  • --quiet: Suppress output messages

For systems where start-stop-daemon isn't available, you can implement similar functionality with:

timeout 30s redis-cli shutdown || \
kill -9 $(cat /var/run/redis/redis.pid)

If the process isn't terminating as expected:

  1. Verify the PID file contains the correct process ID
  2. Check if Redis has proper permissions to write its persistence files
  3. Test with --verbose flag first to see what's happening