System Administration & Network Administration
systemd
Updated Fri, 22 Jul 2022 00:55:18 GMT

ExecStart has a '-' prefix but the unit is still failed


I have overridden the dnf-makecache not to put my system in a failed state every time there is a problem on the internet (shocker!) but it seems to be ignored.

# sc cat dnf-makecache.service
# /usr/lib/systemd/system/dnf-makecache.service
[Unit]
Description=dnf makecache
# On systems managed by either rpm-ostree/ostree, dnf is read-only;
# while someone might theoretically want the cache updated, in practice
# anyone who wants that could override this via a file in /etc.
ConditionPathExists=!/run/ostree-booted
After=network-online.target
[Service]
Type=oneshot
Nice=19
IOSchedulingClass=2
IOSchedulingPriority=7
Environment="ABRT_IGNORE_PYTHON=1"
ExecStart=/usr/bin/dnf makecache --timer
# /etc/systemd/system/dnf-makecache.service.d/override.conf
[Service]
ExecStart=-/usr/bin/dnf makecache --timer
[root@lxd10 ~]# man systemd.service
[root@lxd10 ~]# sc cat dnf-makecache
# /usr/lib/systemd/system/dnf-makecache.service
[Unit]
Description=dnf makecache
# On systems managed by either rpm-ostree/ostree, dnf is read-only;
# while someone might theoretically want the cache updated, in practice
# anyone who wants that could override this via a file in /etc.
ConditionPathExists=!/run/ostree-booted
After=network-online.target
[Service]
Type=oneshot
Nice=19
IOSchedulingClass=2
IOSchedulingPriority=7
Environment="ABRT_IGNORE_PYTHON=1"
ExecStart=/usr/bin/dnf makecache --timer
# /etc/systemd/system/dnf-makecache.service.d/override.conf
[Service]
ExecStart=-/usr/bin/dnf makecache --timer

but it still fails and the system state is degraded

Jun 28 09:08:35 lxd10.2e-systems.com systemd[1]: dnf-makecache.service: Main process exited, code=exited, status=1/FAILURE
Jun 28 09:08:35 lxd10.2e-systems.com systemd[1]: dnf-makecache.service: Failed with result 'exit-code'.
Jun 28 09:08:35 lxd10.2e-systems.com systemd[1]: Failed to start dnf makecache.

but the manual explicitly says the the exit code will be ignored if the exec path is prefixed by a dash. What am I doing wrong? Maybe because it is run by a timer?




Solution

From systemd.service(5):

Unless Type= is oneshot, exactly one command must be given. When Type=oneshot is used, zero or more commands may be specified. Commands may be specified by providing multiple command lines in the same directive, or alternatively, this directive may be specified more than once with the same effect. If the empty string is assigned to this option, the list of commands to start is reset, prior assignments of this option will have no effect.
[...]

Likewise, from systemd.unit(5):

Note that for drop-in files, if one wants to remove entries from a setting that is parsed as a list (and is not a dependency), such as AssertPathExists= (or e.g. ExecStart= in service units), one needs to first clear the list before re-adding all entries except the one that is to be removed.
[...]

So with current OP's override.conf file since the type is oneshot, ExecStart= is now a two-elements list: /usr/bin/dnf makecache --timer and -/usr/bin/dnf makecache --timer. This then applies:

If more than one command is specified, the commands are invoked sequentially in the order they appear in the unit file. If one of the commands fails (and is not prefixed with "-"), other lines are not executed, and the unit is considered failed.

As the original command without - is still executed, when it fails the service fails.

To replace it, the override.conf file should include something like below:

[Service]
ExecStart=
ExecStart=-/usr/bin/dnf makecache --timer




Comments (1)

  • +1 – Thanks, as it usually goes, I have already figured it out by myself, by a virtue of writing a question about it ;) — Jul 04, 2022 at 09:57