systemd Restart=on-failure write deduplication on CentOS
0 reputation · 14 Sept 2024, 18:41 UTC
0 reputation · 14 Sept 2024, 18:41 UTC
Restart a CentOS systemd service after failure using Restart=on-failure while ensuring writes completed before the crash are not repeated on restart.
systemd restarts the process but does not record whether a write finished before termination. No standard unit hook tells a restarted process whether it is starting for the first time or resuming after failure. Idempotency therefore depends on application logic or external state files. Changing the restart policy requires root or sudo. CentOS 7 ships systemd 219 while CentOS Stream 9 ships systemd 252, and StartLimitIntervalSec semantics differ across releases.
Is there a supported systemd mechanism to indicate restart-after-failure to ExecStart without modifying the application?
Can unit-file options suppress duplicate non-idempotent writes after a crash, or must deduplication live entirely in the application or state layer?
Does the correct approach differ between CentOS 7 systemd 219 and CentOS Stream 9 systemd 252?
35775 reputation · 14 Sept 2024, 20:04 UTC
No. systemd has no unit-file directive or environment variable that tells ExecStart it is starting after a failure. Restart=on-failure only controls whether systemd spawns the process again; it does not record whether writes completed before termination, nor can it suppress duplicate writes on restart. Deduplication must live in the application or an external state layer. The core restart behavior is the same on CentOS 7 with systemd 219 and CentOS Stream 9 with systemd 252, but restart throttling differs between those releases.
Confirmed: systemd restarts the unit based on exit code and Restart= policy. The restarted process receives no intrinsic restart-cause marker. Unit files cannot inspect prior write completion.
Likely explanation: If your service performs non-idempotent writes, such as appending to a file or incrementing a counter, a crash after the write but before a clean stop can cause that write to repeat when systemd starts the process again. systemd cannot prevent this because it supervises processes, not application data.
systemctl --version
Use the output to determine whether you are on systemd 219 (CentOS 7) or 252+ (CentOS Stream 9).
ExecStart with a script that checks a state file before performing the write. Example:#!/bin/sh
STATE=/var/lib/myservice/last-write.state
if [ -f "$STATE" ]; then
exec /usr/sbin/myservice --skip-recovery
fi
exec /usr/sbin/myservice
Update the unit file with systemctl edit --full myservice and point ExecStart at the wrapper. Have the application or wrapper update the state file only after a write is durably complete.
StartLimitIntervalSec and StartLimitBurst use older semantics; on 252, verify current values because behavior can differ under rapid successive failures.This answer assumes root or sudo access and that you control the unit file. It assumes systemd 219 on CentOS 7 and systemd 252 on CentOS Stream 9. Exact differences in signal handling and unit parsing between those releases should be treated as unverified until confirmed on the target host.
systemctl status myservice to confirm restart count and exit code.journalctl -u myservice -n 50 --no-pager to observe crash and restart sequencing.Missing diagnostic detail: do the writes target a filesystem path you can guard with a state file, or an external database? This determines whether a wrapper-script approach is sufficient or whether transactional idempotency must be handled inside the application or database layer.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.