Course contentsShow
← Linux
Lesson 1320 of 1,81911. Automation and System SchedulingFree lesson

Customizing System Shutdown Sequences

Ensure automation tasks complete gracefully before system power-off using unit hooks.

In this lesson, you will learn how to guarantee your automation tasks complete gracefully by hooking custom scripts directly into the system shutdown sequence using systemd.

When a system initiates a shutdown, systemd sends a SIGTERM signal to running services. While many services stop immediately, your automation tasks—such as flushing database buffers, uploading final logs, or committing state files to remote storage—might need a specific execution window that occurs after standard services stop but before the hardware powers down.

Leveraging Unit Hooks for Shutdown

To ensure a task runs during shutdown, we create a specialized systemd unit file. The secret lies in the [Unit] and [Service] sections, where we define dependencies to ensure the task triggers at the correct time.

Create a service file like /etc/systemd/system/graceful-cleanup.service:

[Unit]
Description=Perform Final Automation Cleanup
DefaultDependencies=no
Before=shutdown.target reboot.target halt.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/cleanup-script.sh
TimeoutStartSec=0

[Install]
WantedBy=shutdown.target reboot.target halt.target

Understanding the Mechanics

  • DefaultDependencies=no: This is critical. By default, systemd units include dependencies that might stop your service too early. Disabling this gives you full control over when your service executes.
  • Before=shutdown.target: By declaring that your unit must run before these targets, you ensure that the system holds the shutdown process in a suspended state until your ExecStart script finishes its job.
  • Type=oneshot: This tells systemd to wait for the process to exit completely before moving to the next step in the shutdown sequence.

If your script takes a long time to complete, be mindful that systemd will eventually send a SIGKILL if the timeout is exceeded. You can extend this window by adding TimeoutStopSec=30 to your [Service] section to provide sufficient buffer for your cleanup tasks to finalize.

By hooking into the shutdown target, you transform your automation from a collection of "best-effort" scripts into a robust pipeline that guarantees state consistency even when the system is powering off.

Key Takeaway: By using Before=shutdown.target and DefaultDependencies=no, you can force the system to wait for your critical automation cleanup tasks to finish before completing the power-off sequence.