Welcome back for another installment of the systemd series. Throughout this
series, we discuss ways to use systemd to understand and manage your system.
This article focuses on how to convert legacy scripts you may have customized on
your system.
SysV init scripts
The init system used previously in Linux was called SysVinit. Before we start, it’s
helpful to know that systemd has a lot of compatibility features for SysVinit. In
some cases, you may not have to edit �les to maintain your custom solutions. But
in others, it’s helpful to know how to adapt to and use new systemd technology.
A script used to manage a service in SysVinit was known as a SysV init script. With
some additions, it was known as a LSB, or Linux Standards Base, init script. Fear
not, backwards compatibility for legacy scripts remains 99.9% intact with systemd.
That means you don’t need to rush to convert all your scripts simply to adopt a
systemd-based OS like Fedora. However, there are a number of advantages to
doing so.
systemd: Converting sysvinit scripts
systemd: Converting sysvinit scripts - Fedora M...
https://fedoramagazine.org/systemd-converting-...
1 of 8
28-12-15 10:35
Init scripts are actually imperative shell scripts executed by an interpreter. Here,
“imperative” means they contain the commands the system runs to manage the
service. However, systemd unit �les are declarative statements of intent. They give
hints to systemd to manage a service, but systemd takes care of execution. As a
result, unit �les are typically much shorter than the SysV init scripts that they
replace. That’s because they don’t have to worry about implementation, just the
intent of the service.
The �rst step in migrating a SysV init script is to examine the script that you wish
to convert. Let’s use the sshd init script from Fedora 16 as an example. The
previous link will show you the script before it was converted to a systemd unit �le.
Here’s a fun fact: everything handled by that 184 line shell script is now handled by
27 lines of systemd con�guration, spread across two unit �les.
Runlevels vs. targets
Reviewing the init script linked above, let’s look more closely at a few important
parts. First is this line:
# chkconfig: 2345 55 25
The �rst set of numbers, 2345, indicates in which runlevels in the SysV world this
script should run. A SysV runlevel is a de�nition of a system state where certain
processes and services should run. There are a speci�c set of runlevels de�ned:
0: halt
1: single-user
2: multi-user
3: multi-user with networking
4: unde�ned (user de�ned)
5: multi-user with display manager (graphical login)
6: reboot
In systemd, there is no concept of runlevels. These are replaced by targets. In
systemd, there can be an unlimited set of targets, each represented by a unit �le
with a .target suf�x. The analogous target to SysV runlevel 3 in systemd is called
multi-user.target. Similarly, a unit corresponding to runlevel 5 is called
graphical.target.
Targets can and do depend on each other. So only once the system has reached
multi-user.target does it start the services speci�ed in graphical.target. There are
systemd: Converting sysvinit scripts - Fedora M...
https://fedoramagazine.org/systemd-converting-...
2 of 8
28-12-15 10:35
also implicit dependencies on basic.target which, as the name suggests,
establishes basic system services and functions. Some of these happen through
their own target dependencies, like network.target.
Service ordering
The next two numbers in the SysV init script, 55 and 25, determine the order for
starting and stopping the service. Under SysVinit, scripts run strictly in order. The
order is determined by naming a set of links in folders. If a new script is placed in
the wrong order to start or stop, the service may fail, the system may appear to
hang, or other errors may result.
On the other hand, directives in systemd unit �les like Requires= and After= ensure
that units run in the correct order. They don’t require prior knowledge about other
units or services on the system. For instance, if your unit runs a service that
requires the network, you can add Requires=network.target
and After=network.target to the unit �le. It will only be run once the network is
activated.
There are also dependencies included in the old SysV init script. However, they’re
not enforced if you simply run the script outside the control of the init system. One
of the major features of systemd is deterministic results from running an action.
That’s a lot of code
Following header information, such as hard and soft dependencies (Required-Start,
Required-Stop, Should-Start, and Should-Stop) is the description of the service.
In this case that’s Start up the OpenSSH server daemon. Following are various
functions that implement what the script does. The standards refer to certain
verbs the script must implement, such as start, stop, and restart.
As mentioned earlier, though, the systemd way of doing things is declarative.
Rather than having to de�ne and code a set of functions, you specify the process
to execute. There’s no need, for example, for a large amount of code for a common
task such as retrieving the process ID (PID) the service starts.
Let’s look at the start() function of this script to see what it does, and let’s examine
it line by line. This is a shell script, a program of instructions to be run by the shell
started by the init system. Don’t worry if you don’t know the language; the
instructions are explained below.
systemd: Converting sysvinit scripts - Fedora M...
https://fedoramagazine.org/systemd-converting-...
3 of 8
28-12-15 10:35
start()
{
[ -x $SSHD ] || exit 5
[ -f /etc/ssh/sshd_config ] || exit 6
# Create keys if necessary
/usr/sbin/sshd-keygen
echo -n $"Starting $prog: "
$SSHD $OPTIONS && success || failure
RETVAL=$?
[ $RETVAL -eq 0 ] && touch $lockfile
[ $RETVAL -eq 0 ] && cp -f $XPID_FILE $PID_FILE
echo
return $RETVAL
}
In order, here’s what the init system does:
Checks if the sshd binary exists and is executable, and if not, exits with a status
code of 5.
Checks whether the con�guration �le /etc/ssh/sshd_con�g exists, and if not,
exits with status code 6
Runs the sshd-keygen binary to make keys, if they don’t already exist
Sends a message to the screen/log that it’s about to start the service
Runs the service, and outputs a success or failure message for startup of the
sshd process
Captures a return value for the sshd process itself; 0 means sshd has
successfully become a service daemon
Based on the return value, marks several marker �les to indicate the service is
running, in case the system administrator tries to run it again
Sends out a “next line” message for the screen/log
Passes the return value out in case it’s needed elsewhere
Note this is only one function in the SysV sshd init script. Many other functions
also need to be coded, including stop, restart, and others. Those are over a
hundred more lines of code! But what does the systemd unit �le look like in
comparison?
systemd: cuts down on code
In contrast, here’s the sshd.service unit �le from a Fedora 23 installation. Notice
how much smaller and easier to read this �le is:
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
systemd: Converting sysvinit scripts - Fedora M...
https://fedoramagazine.org/systemd-converting-...
4 of 8
28-12-15 10:35
After=network.target sshd-keygen.service
Wants=sshd-keygen.service
[Service]
EnvironmentFile=/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target
The �rst few lines again describe the systemd unit, and where you can read more
about it. Here are what the remainder of the lines mean, with links to systemd
documentation:
After declares ordering, and describes that network.target
and sshd-keygen.service should run �rst.
Wants describes that sshd-keygen should be run in order for this service to
start. Note the subtle difference from ordering. systemd considers order and
dependencies orthogonal, meaning just because sshd-keygen comes �rst
doesn’t mean it is a dependency of sshd — although in this case it is.
Wants means systemd should run sshd-keygen.service, but if that doesn’t
complete successfully (for instance, if SSH server keys already exist), sshd will
still run. If sshd-keygen.service needed to complete successfully, you’d
use Requires instead.
EnvironmentFile, similar to SysVinit, is a con�guration �le with options for sshd.
It contains a set of key=value pairs that will be passed to sshd.
ExecStart is the command that runs to start sshd. This replaces the entire start
function in the old initscript. The $OPTIONS variable here is what is speci�ed in
EnvironmentFile for the variable OPTIONS.
ExecReload is the command that runs if the sysadmin reloads the
sshd daemon. This replaces the entire reload function in the old initscript.
KillMode sets how systemd will stop the service. In this case, systemd will stop
the main sshd process only. Any additional sshd child processes will continue
to manage their open SSH sessions. This is not an option used often, but it is
important here. For instance, it stops you from killing your own SSH session
when you run systemctl!
Restart determines how systemd manages the service if it stops unexpectedly.
In this case, on-failure means virtually any unexpected failure will cause
systemd to restart sshd. If sshd stops normally, though, such as with
a systemctl stop command, it will not be restarted.
RestartSec allows 42 seconds of sleep time before sshd is restarted due to an
systemd: Converting sysvinit scripts - Fedora M...
https://fedoramagazine.org/systemd-converting-...
5 of 8
28-12-15 10:35
unexpected stop.
WantedBy means when the command systemctl enable sshd.service is run, a
link is placed in the multi-user.target.wants directory by default. This is one of
the mechanisms systemd uses to determine units to run for speci�c targets.
So multi-user.target and any target that depends on it, will include
running sshd.service.
There are of course many other directives available, and the systemd docs cover
all of them. But if you were to write your own unit �le for a simple service, you
needn’t use even all the options shown here. You might only need a few directives
like After, ExecStart, and WantedBy. If you look in /usr/lib/systemd/system/ on your
own Fedora system, you can �nd many other .service unit �les that you can follow
as a template.
Additional hints
Another notable feature of systemd, though, is that it doesn’t abandon
compatibility for SysVinit. Some administrators have created their own custom
startup scripts such as /etc/rc.d/rc.local. If you’re not prepared to convert it, don’t
worry — systemd will honor it, using the rc-local.service �le already included.
Remember, if you are building custom system services for your Fedora, it’s best to
place them into /etc/systemd/system. Typically /etc/ is where all
system con�guration or customization is kept. This allows you to avoid putting
customizations in /usr/lib/systemd/system which is managed by Fedora’s package
system.
If you’d like to read another example and explanation of converting, check out this
blog entry from the “systemd for administrators” series.
Share:
Tumblr
Jon Stanley
Jon is a longtime contributor to Fedora, and a
former member of FESCo, the Fedora Board, as
well as a current member of the Server Working
Group. He lives in New York City, USA.
systemd: Converting sysvinit scripts - Fedora M...
https://fedoramagazine.org/systemd-converting-...
6 of 8
28-12-15 10:35
2 Comments
ADD YOURS
Leave a Reply
Samuel Sieb
November 5, 2015 at 14:16
Under the ExecStart section, there is an incomplete sentence:
“The $OPTIONS variable here is”
jstanley
November 5, 2015 at 21:55
Thanks! I can’t edit it at this point, but wil bring it to the attention of
folks that can.
Your email address wil not be published.
Previous post
Next post
systemd: Converting sysvinit scripts - Fedora M...
https://fedoramagazine.org/systemd-converting-...
7 of 8
28-12-15 10:35
Post Comment
Notify me of follow-up comments by email.
Notify me of new posts by email.
SUBSCRIBE TO FEDORA MAGAZINE
Subscribe with RSS
or
Enter your email address below to receive
noti�cations of new posts by email.
Email Address
Subscribe
The opinions expressed on this website are those of each author, not of the author's employer or of Red Hat. Fedora
Magazine aspires to publish all content under a Creative Commons license but may not be able to do so in all cases.
You are responsible for ensuring that you have the necessary permission to reuse any work on this site. The Fedora
logo is a trademark of Red Hat, Inc. Terms and Conditions
systemd: Converting sysvinit scripts - Fedora M...
https://fedoramagazine.org/systemd-converting-...
8 of 8
28-12-15 10:35