1

I'm debugging a firewall .service unit and a few questions arise.

One of those questions is the unit's best service type, either exec or oneshot. Virtually no comparisons of the two appear in my searches, probably because exec is a relatively recent addition to systemd (v.249 IIRC).

By way of background, the unit (call it iptables.service) is intended to activate and configure the firewall by running a Bash script (call it iptables.sh) before the network is up (i.e., before network-pre.target), e.g.,

ExecStart=/bin/bash -c '/home/locsh/iptables.sh'

Type=oneshot has the advantage of not entering the "active" state, so it subsequently can be restarted or reactivated, e.g., by a timer unit. It also is the more common of the two types in most examples, albeit without explanation.

Type=exec has the advantage that it will delay startup of follow-up units until the main service has been executed. This seems to make perfect sense for a firewall .service unit because the network should depend on the script running successfully and remain down otherwise, e.g., if the script temporarily can't be read because somehow the relevant .mount unit hasn't yet activated.

Restart=on-failure seems to be an obvious and prudent addition in either case.

The first question is whether one or the other might better for any reason.

The second question is whether Type=exec, because it delays the start of follow-up units, might introduce a subtle ordering cycle in some edge cases, either with or without "Restart=on-failure", in part because the unit's ordering dependency

Before=network-pre.target

is relatively early in the boot process.

1 Answer 1

2

You want type=oneshot. If you use type=exec, other services will be able to start before the firewall is configured. From the systemd.service man page, for exec:

...Or in other words: simple proceeds with further jobs right after fork() returns, while exec will not proceed before both fork() and execve() in the service process succeeded.

And for oneshot:

Behavior of oneshot is similar to simple; however, the service manager will consider the unit up after the main process exits.

In other words, with Type=exec, systemd considers the service to be "up" once the process has successfully started, while for Type=oneshot, systemd considers the service to be "up" once the process has successfully completed.

3
  • 2
    Also, both Type=simple and Type=exec will fundamentally assume that the ExecStart= process is supposed to keep running until the service is intentionally stopped, and will mark the service as failed if it dies on its own. If Restart=on-failure is added, that would mean the firewall script would run again and again, repeatedly, possibly causing periodic hiccups in network connectivity and certainly making any iptables/nftables statistics useless.
    – telcoM
    Commented Jun 11, 2022 at 22:17
  • @telcoM, am I correct that you don't see any difficulty with Restart=on-failure if Type=oneshot?
    – ebsf
    Commented Jun 12, 2022 at 18:11
  • Just that if it failed once, it is likely to fail again, if the failure is caused by something like a typo. That might cause an infinite loop where you cannot easily access the system because networking, sshd and console logins are not yet up.
    – telcoM
    Commented Jun 12, 2022 at 21:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .