Prepare finalrd for Reliable Shutdown Cleanup
You will enable finalrd as a systemd service, identify which shutdown hooks are available, and verify the installed setup before relying on it to clean up storage or network resources. Allow about fifteen minutes for a read-only review, or longer if you are writing and testing a custom hook.
The route
Jump straight to the step you need, or tick off Done means at the end.
This guide describes the installed finalrd package version 9build1 and its manual page, which identifies the program as finalrd 2. The examples assume a system using systemd and a shell with sudo access. Enabling the service is a persistent, privileged change that affects shutdown, so do it during a maintenance window and keep a way to access the machine if shutdown behaviour is not what you expect.
1. Check the installed service and version
Start with ordinary, read-only checks. They confirm the package and show the service unit without running the generator:
$ command -v finalrd
/usr/bin/finalrd
$ dpkg-query -W -f='${Package} ${Version}\n' finalrd
finalrd 9build1
$ systemctl cat finalrd.service
[Service]
RemainAfterExit=yes
Type=oneshot
ExecStart=/bin/true
ExecStop=/usr/bin/finalrd
The service is intentionally a oneshot unit whose stop action runs finalrd. The normal workflow is to activate finalrd.service, not to invoke finalrd by hand. The generator prepares /run/initramfs for the later systemd shutdown pivot.
Checkpoint
If the package query fails, stop here and install or repair the package through your normal system administration process. Do not copy a random script into /usr/bin.
2. Activate finalrd before the next shutdown
When you have a recovery path and a suitable maintenance window, enable and start the documented service. This requires elevated privileges:
$ sudo systemctl enable --now finalrd.service
The command enables the unit for future boots and starts its systemd state now. Check both pieces separately:
$ systemctl is-enabled finalrd.service
enabled
$ systemctl is-active finalrd.service
active
Do not interpret active as proof that shutdown hooks have already run. The unit's service process is /bin/true; finalrd is called by the unit's stop action as shutdown begins. The useful result at this checkpoint is that systemd knows the unit and has it enabled.
If you need to undo this activation before testing further, disable and stop the unit with root privileges:
$ sudo systemctl disable --now finalrd.service
That removes the enablement and stops the currently active unit. It does not remove the finalrd package or delete hook files.
3. Understand the three hook locations
finalrd looks for executable files ending in .finalrd in three directories:
/usr/share/finalrd/*.finalrd
/etc/finalrd/*.finalrd
/run/finalrd/*.finalrd
They have different ownership meanings. Distribution hooks belong in /usr/share/finalrd, administrator-managed hooks in /etc/finalrd, and temporary or generated hooks in /run/finalrd. Inspect what is present without changing it:
$ find /usr/share/finalrd /etc/finalrd /run/finalrd \\
-maxdepth 1 -type f -name '*.finalrd' -printf '%p %m\n' 2>/dev/null
/usr/share/finalrd/mdadm.finalrd 755
/usr/share/finalrd/open-iscsi.finalrd 755
Your list can be shorter, and the permissions can differ. A hook must be executable to be useful. The installed examples handle mdadm arrays and open-iSCSI; their presence does not mean that either technology is configured on your machine.
Names are significant. During setup, every matching hook in the /usr, /etc, then /run directories is run. If identical names occur in more than one directory, all copies are used for setup, but only the last copy is placed in the shutdown directory. Avoid duplicate names unless that replacement is deliberate.
4. Treat the hook interface as two different phases
A hook is a multi-purpose executable. During preparation it receives setup as its first argument and runs from the normal root filesystem. finalrd sets DESTDIR and DESTROOTDIR to the shutdown directory so the hook can copy its programs and configuration with initramfs-tools or dracut tooling.
case "$1" in
setup)
# Copy every binary, library and configuration file needed later.
;;
halt|poweroff|reboot|kexec)
# Perform only the shutdown action needed for this operation.
;;
esac
At shutdown, hooks are copied into finalrd and run from there, in parallel, with one of halt, poweroff, reboot or kexec as the first argument. They are no longer running against the ordinary root filesystem. A hook that works interactively in /usr can fail after the pivot if its interpreter, libraries, configuration or device tools were not copied during setup.
Safety boundary
A shutdown hook can stop storage, log out iSCSI sessions or wait for hardware. Test it with the exact host configuration and keep timeouts in any operation that can wait. Because hooks run in parallel, do not make one hook depend on another hook completing unless you provide an explicit coordination mechanism.
5. Check whether hooks can be copied
On systems with initramfs-tools available, finalrd can use its copy functions during setup. On a system without it, the shutdown directory is still created, but hooks are not copied or executed. This is called hookless operation in the manual. It gives systemd-shutdown somewhere to pivot, but it is not a working custom-hook deployment.
$ test -r /usr/share/initramfs-tools/hook-functions && echo 'hook support available' || echo 'hookless operation'
hook support available
This test is read-only and does not require sudo. If it reports hookless operation, do not claim that a new hook will perform shutdown cleanup. Review the platform's initramfs and shutdown design first.
Checkpoint
Before adding a hook, write down every executable and configuration file it needs, the expected shutdown action, and how you will tell that it completed. A successful setup stage alone does not prove that the later off-root action can run.
6. Verify the boundary without forcing a shutdown
Do not run a new cleanup hook by calling it with halt or poweroff from an ordinary shell. That bypasses the finalrd environment and can stop live resources. Instead, review the service and hook inputs, then use a maintenance-window reboot only after the hook has been tested on a disposable or non-critical target.
$ systemctl status finalrd.service --no-pager
$ systemctl show finalrd.service -p ExecStart -p ExecStop -p ActiveState
ExecStart={ path=/bin/true ; ... }
ExecStop={ path=/usr/bin/finalrd ; ... }
Exact status formatting varies between systemd releases. The points to verify are that the unit is loaded, ExecStart is /bin/true, and ExecStop names /usr/bin/finalrd. Do not treat a manually created /run/initramfs directory as proof that the service's full shutdown preparation succeeded.
Done means
- The installed package and finalrd version are known.
finalrd.serviceis enabled only when the host has a tested recovery path.- Hooks are kept in the correct directory and duplicate names are understood.
- Each custom hook supplies everything it needs for the off-root shutdown phase.
- You have checked whether initramfs-tools hook support is available.
- No shutdown action has been forced from an ordinary shell, and the next test has a maintenance window and rollback plan.