Systemd dependencies

Do you want to make sure two separate services are connected in some way? That one service is up when the other is or even starts first? Thanks to systemd this is now super easy!

In the dark old days of SysV (/etc/init.d) services were started serially during boot and individually on demand. You could adjust the start and stop order by editing a special comment in the init file. For example

# chkconfig: - 85 15

would have the service start at priority 85 and stop at priority 15. Priorities are from 0 to 99 and are done in ascending order. So this would start pretty late in the boot and stop pretty early in the shutdown.

With directives like Requires, Wants, Before, and After you can give systemd more info on what you want. systemd can start things in parallel and will use these hints to build its dependency tree and start or stop everything in the right order.

Packages will install their systemd config files into /usr/lib/systemd/system/ . Don’t edit these files. If you want to make changes, copy them to /etc/systemd/system/ .

I’ll use mariadb and httpd as examples here. It makes sense that we want the database to be up and running before Apache so that we don’t serve broken pages. Lets explore our options and see how they each act under different circumstances.

Requires

This effectively makes one unit cascade the starting of another. If the one is enabled, the other is also effectively enabled. Both units will be started in parallel, but if one of the required units fails to start, the requiring unit will get stopped again.

We’ll add Requires=mariadb.service to the [Unit] section of /etc/systemd/system/httpd.service .

When we issue a start of httpd, mariadb is started in parallel.

When we issue a stop of httpd, mariadb keeps running.

If we break the mariadb config to prevent it from starting, then start httpd, it starts, but shows an error. I think despite what the documentation says, this is just a race condition since both are started in parallel. We’ll get into ordering in a bit.

If when both are running, we stop mariadb, httpd will stop automatically.

Wants

This is just a weaker version of Requires and is the recommended option. If the wanted service fails to start, the wanting service will still start.

When we issue a start of httpd, mariadb is started in parallel.

When we issue a stop of httpd, mariadb keeps running.

If we break the mariadb config to prevent it from starting, then start httpd, it starts with no error.

If when both are running, we stop mariadb, httpd will keep running.

After

Now we can get to some ordering! We’ll tell httpd to start After mariadb.

After=mariadb.service

On its own, it doesn’t enforce the starting of mariadb, just that if both happen to be starting at the same time, mariadb should be started first. And if you are stopping both at the same time, mariadb should be stopped last.

systemctl start httpd mariadb

will start them in order.

Before is just the inverse relationship. You could instead specify in the config for mariadb to start before httpd.

If we combine Requires and After we get what we want. httpd forcing mariadb to start first and fail to start if mariadb fails.

When we issue a start of httpd, mariadb is started first.

When we issue a stop of httpd, mariadb keeps running.

If we break the mariadb config to prevent it from starting, then start httpd, it will fail to start.

If when both are running, we stop mariadb, httpd will stop first.

More info:

Understanding Systemd Units and Unit Files

systemd.unit(5)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s