How to Configure systemd for Graceful Service Shutdown During System Reboot/Shutdown


3 views

When dealing with system services that require cleanup operations or finalization tasks during shutdown, the default systemd behavior often doesn't provide enough time. The service gets terminated abruptly even when configured with proper timeout values.

Your current shutdowntest.service has the basic configuration:

[Service]
ExecStart=/usr/local/bin/shutdowntest.sh
TimeoutStopSec=15

[Install]
WantedBy=multi-user.target

While this works for manual stops (systemctl stop), it fails during system shutdown because systemd applies different timeout policies during system transitions.

Add these critical directives to your service file:

[Unit]
# Wait 90 seconds for the service to stop before killing it
TimeoutStopSec=90s

[Service]
ExecStart=/usr/local/bin/shutdowntest.sh
# Important for shutdown sequence
KillMode=process
# Send SIGTERM first
KillSignal=SIGTERM
# Wait 10 seconds before sending SIGKILL
FinalKillSignal=SIGKILL
SendSIGKILL=yes
Restart=no

Here's the full service file that properly handles shutdown scenarios:

[Unit]
Description=Service with graceful shutdown
After=network.target
StartLimitIntervalSec=0

[Service]
Type=simple
ExecStart=/usr/local/bin/shutdowntest.sh
ExecStop=/bin/kill -TERM $MAINPID
TimeoutStopSec=90s
KillMode=process
KillSignal=SIGTERM
FinalKillSignal=SIGKILL
SendSIGKILL=yes
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

After applying changes:

sudo systemctl daemon-reload
sudo systemctl restart shutdowntest.service

Test the shutdown behavior with:

sudo systemctl stop shutdowntest.service  # Verify manual stop
sudo shutdown -r now                     # Verify reboot behavior

For services that must complete before others during shutdown:

[Unit]
DefaultDependencies=no
Before=shutdown.target reboot.target halt.target
Conflicts=reboot.target halt.target
  • Check journalctl -u yourservice -b for complete logs
  • Increase DefaultTimeoutStopSec in /etc/systemd/system.conf if needed
  • Use systemd-analyze critical-chain yourservice.service to analyze dependencies

When dealing with system services that require cleanup operations during shutdown, we often encounter scenarios where the default systemd behavior doesn't provide enough time for graceful termination. The key observation is that while manual systemctl stop respects the TimeoutStopSec parameter, system-wide shutdowns appear to override this setting.

During a system shutdown or reboot, systemd initiates a special target called shutdown.target which has its own timeout constraints. The default timeout for this phase is typically much shorter than individual service timeouts.

Here's the complete solution that ensures your service gets proper shutdown time:

[Unit]
Description=Service with graceful shutdown
Before=shutdown.target reboot.target halt.target

[Service]
Type=simple
ExecStart=/usr/local/bin/shutdowntest.sh
TimeoutStopSec=15s
KillMode=process
SendSIGKILL=no

[Install]
WantedBy=multi-user.target

1. Explicit Before Dependencies: Forces the service to stop before system targets
2. KillMode=process: Prevents systemd from killing child processes
3. SendSIGKILL=no: Disables the final SIGKILL if shutdown fails

For critical systems where all services need extended shutdown time:

# /etc/systemd/system.conf
DefaultTimeoutStopSec=30s

Test your configuration with:

systemd-analyze critical-chain shutdowntest.service
systemd-analyze verify /etc/systemd/system/shutdowntest.service

For a PostgreSQL-like service requiring flush operations:

[Service]
ExecStop=/usr/bin/pg_ctl stop -m fast -t 30
TimeoutStopSec=35