A side-by-side look at run scripts and service units.

http://debianfork.org is a project created by Denis Roio, and "We are Veteran UNIX Admins" should have read "I am a WWW artist". This was discovered within hours of the site going up. Unfortunately, several gullible journalists who didn't do their research swallowed it, hook, line, and sinker. In reaction, it spawned http://forkfedora.org, whose anonymous writer made several foolish mistakes, one in particular of thinking that the only comparison is between System 5 init.d scripts and systemd service and unit files.

In fact, people have been replacing System 5 rc since the late 1990s; and a far more informative and relevant comparison of that kind is to the various softwares that have been created since the days of System 5 rc coming to Linux operating systems, over the past more than a decade and a half. There's a whole daemontools family of service manager programs that began with Daniel J. Bernstein's daemontools package on 1997-07-15 (version 0.51) and that have been in use through the 2000s (Adam Sampson's freedt begun in 2003, Laurent Bercot's s6 begun around 2002–2003) all of the way through to today.

(Yes, there are entirely non-daemontools-family alternatives to System 5 rc created during that time such as the NetBSD rc.d system that came into being in 2000. No, its 221-line sendmail script doesn't really help to make the point. In part that is because it was designed based upon System 5 rc as it existed in Solaris at the time, and is less of a replacement than a port, although it does not copy System 5 init and retains the BSD init mechanisms. Ironically, Solaris itself later gained the Service Access Controller in Solaris 9 and then the Service Management Facility in Solaris 10. AIX had the System Resource Controller since the 1990s, MacOS 10 gained launchd, and Ubuntu Linux had upstart. However, this is not intended, per the title, to be an FGA giving a full review of every service management system in existence.)

http://forkfedora.org would have looked markedly different had it taken into account that people have already invented technologies aimed at being simpler than, more maintainable and portable than, and with more "bang for the buck" in terms of the increase in script complexity that one pays for various dæmon management features than, System 5 init.d scripts. Putting them side by side looks like this.

fetchmail running as an unprivileged user
run script for daemontools, daemontools-encore, and freedt run script for runit run script for s6 rc.main script for perp run and restart scripts for nosh systemd unit
#!/bin/sh -e
# A remote-mail retrieval utility
exec 2>&1
exec \
FETCHMAILHOME="/home/fetchmail" \
setuidgid fetchmail \
fetchmail -v --nodetach --daemon \
551
#!/bin/sh -e
# A remote-mail retrieval utility
exec 2>&1
exec \
FETCHMAILHOME="/home/fetchmail" \
chpst -u fetchmail \
fetchmail -v --nodetach --daemon \
551

— There is a slightly more parameterized fetchmail run script in Gerrit Pape's collection.

#!/command/execlineb -P
# A remote-mail retrieval utility
export 
FETCHMAILHOME "/home/fetchmail"
s6-setuidgid fetchmail 
fetchmail -v --nodetach --daemon 
551 # interval
#!/bin/sh
# A remote-mail retrieval utility
exec 2>&1
start() {
exec \
FETCHMAILHOME="/home/fetchmail" \
runuid fetchmail \
fetchmail -v --nodetach --daemon \
551 ;
}
reset() { exit 0; }
eval "$1" "$@"
#!/bin/nosh
# A remote-mail retrieval utility
setenv 
FETCHMAILHOME "/home/fetchmail"
setuidgid fetchmail
fetchmail -v --nodetach --daemon 
551 # interval

#!/bin/sh -e
exec true
[Unit]
Description=A remote-mail retrieval utility

[Service]
Environment=FETCHMAILHOME="/home/fetchmail"
User=fetchmail
ExecStart=/usr/bin/fetchmail -v --nodetach --daemon 551
Restart=always

— There is a slightly different fetchmail.service in Arch Linux.

SSH started per-connection
run script for daemontools, daemontools-encore, freedt, and runit run script for s6 rc.main script for perp run, service, and restart scripts for nosh systemd units
#!/bin/sh -e
# sshd service using tcpserver
exec 2>&1
exec \
softlimit -m3000000 \
tcpserver -vR -c 51 -x rules.cdb 0 ssh \
sshd -i -e

— There is a slightly different sshd run script in Gerrit Pape's collection, and Wayne Marshall uses a more parameterized version in his daemontools tutorial.

#!/command/execlineb -P
# sshd service using s6-networking
fdmove -c 2 1
s6-softlimit -m3000000
s6-tcpserver -v -c 51 0 ssh
s6-tcpserver-access -i rules/
sshd -i -e
#!/bin/sh
# sshd service using tcpserver
exec 2>&1
start() {
exec \
softlimit -m3000000 \
tcpserver -vR -c 51 -x rules.cdb 0 ssh \
sshd -i -e ;
}
reset() { exit 0; }
eval "$1" "$@"

— perp comes with a more featureful version as an example in the package.

#!/bin/nosh
# on-demand sshd service
hardlimit -m 3M 
softlimit -m 3M 
tcp-socket-listen --combine4and6 "::" ssh
tcp-socket-accept -v -c 51
ucspi-socket-rules-check 
./service

#!/bin/nosh
sshd -i -e

#!/bin/sh -e
exec true
[Unit]

[Socket]
ListenStream=22
Accept=yes
BindIPv6Only=both
MaxConnections=51

— There is a different sshd.socket in Fedora Linux.


[Unit]
Description=Socket-activated sshd

[Service]
ExecStart=/usr/sbin/%P -i -e
StandardInput=socket
LimitAS=3000000
LimitDATA=3000000
LimitMEMLOCK=3000000
LimitSTACK=3000000

— There is a different sshd@.service in Fedora Linux.

SSH listener
run script for daemontools, daemontools-encore, freedt, and runit run script for s6 rc.main script for perp run and restart scripts for nosh systemd unit
#!/bin/sh -e
# listening sshd service
exec 2>&1
exec sshd -D -e

— See the sshd run script in Gerrit Pape's collection. Wayne Marshall uses a more parameterized version in his daemontools tutorial.

#!/command/execlineb -P
# listening sshd service
fdmove -c 2 1
sshd -D -e
#!/bin/sh
# listening sshd service
exec 2>&1
start() {
exec sshd -D -e ;
}
reset() { exit 0; }
eval "$1" "$@"

— perp comes with a more featureful version as an example in the package.

#!/bin/nosh
# listening sshd service
sshd -D -e

#!/bin/sh -e
exec true
[Unit]
Description=Listening sshd

[Service]
ExecStart=/usr/sbin/%P -D -e
Restart=always

— There is a different sshd.service in Fedora Linux.

exim with separately-controllable services for SMTP Relay and queue running
run script for daemontools, daemontools-encore, freedt, and runit run script for s6 rc.main script for perp run, service, and restart scripts for nosh systemd units
#!/bin/sh -e
# exim SMTP Relay service using tcpserver
exec 2>&1
exec \
softlimit -m3000000 \
tcpserver -vR -c 51 -x rules.cdb 0 smtp \
exim4 -bs
#!/command/execlineb -P
# exim SMTP Relay service 
# using s6-networking
fdmove -c 2 1
s6-softlimit -m3000000
s6-tcpserver -v -c 51 0 smtp
s6-tcpserver-access -i rules/
exim4 -bs
#!/bin/sh
# exim SMTP Relay service using tcpserver
exec 2>&1
start() {
exec \
softlimit -m3000000 \
tcpserver -vR -c 51 -x rules.cdb 0 smtp \
exim4 -bs ;
}
reset() { exit 0; }
eval "$1" "$@"
#!/bin/nosh
# on-demand exim SMTP Relay service
hardlimit -m 3M 
softlimit -m 3M 
tcp-socket-listen --combine4and6 "::" smtp
tcp-socket-accept -v -c 51
ucspi-socket-rules-check 
./service

#!/bin/nosh
exim4 -bs

#!/bin/sh -e
exec true
[Unit]

[Socket]
ListenStream=25
Accept=yes
BindIPv6Only=both
MaxConnections=51

[Unit]
Description=Socket-activated exim SMTP Relay

[Service]
ExecStart=/usr/sbin/exim4 -bs
StandardInput=socket
LimitAS=3000000
LimitDATA=3000000
LimitMEMLOCK=3000000
LimitSTACK=3000000
#!/bin/sh -e
# exim queue runner service
exec 2>&1
exec exim4 -q30m

The exim run script in Gerrit Pape's collection does not separate the different services.

#!/command/execlineb -P
# exim queue runner service
fdmove -c 2 1
exim4 -q30m
#!/bin/sh
# exim queue runner service
exec 2>&1
start() {
exec exim4 -q30m ;
}
reset() { exit 0; }
eval "$1" "$@"
#!/bin/nosh
# exim queue runner service
exim4 -q30m

#!/bin/sh -e
exec true
[Unit]
Description=exim queue runner service

[Service]
ExecStart=/usr/sbin/exim4 -q30m
Restart=always

The RedHat exim.service does not separate the different services.

Bonus track!

You don't get technical discussion at either Denis Roio's site or the "fork Fedora" site. But since you've not had to read down as far as the length of /etc/rc.d/sendmail to get to the end of the tables, despite there being four times as many of them, there's room for it here ☺.

The above scripts and unit files differ from what you'll see "in the box" in some packages. This is deliberate; as the intent here is to allow an apples-to-apples comparison. The "in the box" scripts and unit files do not have directly comparable behaviours; what are given here, largely have. (The "fork Fedora" WWW site compares a script that starts two services against a service unit that starts only one. Such distorted comparisons give people on discussion fora endless weeks of fun pointing out what the left hand side does that the right hand side does not.) Some examples:

There are still some differences left, however:

Many of the run scripts are interchangeable across toolsets. Don't be fooled by the use of execlineb, s6-xyz… tools, and nosh package tools, for each package. One can quite happily use execlineb or s6-xyz… tools in a run script with the nosh package, or vice versa for that matter. One could use chpst under perp, or runtool under daemontools-encore. The fact that daemontools, daemontools-encore, freedt, and runit are mostly all in one column should be taken as the stronger indicator here; there's no strict lock-in of run scripts to any toolset.


© Copyright 2014 Jonathan de Boyne Pollard. "Moral" rights asserted.
Permission is hereby granted to copy and to distribute this WWW page in its original, unmodified form as long as its last modification datestamp information is preserved.