Systemd startup order

root's picture

How to start services in certain order with Systemd?
Have been reading a bunch of documentation to figure this one out.
By the way, this also includes the SysV startup scripts (which are called by systemd).

So, in this below example (real situation), I have Docker that needs ocfs2 filesystem which runs on top of DRBD.
Default startup configuration was not quite ok because docker almost always started first and ocfs2 was started in the same time with drbd and failed to mount the ocfs2 filesystem.

The error was: mount.ocfs2: I/O error on channel while opening device /dev/drbd0

The main trick is: you do not start services in a certain order but you "ask" your main service to start the others. Bear with me.

1. Disable startup for ocfs2 and drbd

root@candy:~# systemctl disable drbd.service
drbd.service is not a native service, redirecting to systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install disable drbd
root@candy:~# systemctl disable ocfs2.service
Synchronizing state of ocfs2.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install disable ocfs2
Removed /etc/systemd/system/

2. Add drbd.service as requirement for ocfs2.service

NOTE: copy /lib/systemd/system/ocfs2.service to /etc/systemd/system/ocfs2.service and edit the one from /etc and recommended by systemd docs.

The edited lines should be as follows:

root@candy:~# egrep "^Requires|^After" /etc/systemd/system/ocfs2.service 
Requires=o2cb.service drbd.service
After=o2cb.service drbd.service

3. Add ocfs2.service as requirement for docker.service

Please do not forget about the note from point 2.

root@candy:~# egrep "^Requires|^After" /etc/systemd/system/docker.service firewalld.service containerd.service ocfs2.service
Requires=docker.socket ocfs2.service

3. Make sure docker.service is enabled and reloaded

root@candy:~# systemctl daemon-reload
root@candy:~# systemctl enable docker.service
Synchronizing state of docker.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable docker
Created symlink /etc/systemd/system/ → /etc/systemd/system/docker.service.

Now what will happen is:
- docker is configured to start at boot but it needs ocfs2;
- ocfs2 is not configured to start at boot, is stated by docker but it needs drbd;
- drbd is also not configured to start at boot but is started by ocfs2.

And with this chain you have them in the needed order.

PS: as bonus command, systemd-analyze is showing you now what docker-service needs in order to start:

root@candy:~# systemd-analyze critical-chain docker.service
The time after the unit is active or started is printed after the "@" character.
The time the unit takes to start is printed after the "+" character.

docker.service +1.796s
└─ocfs2.service @17.202s +8.290s
  └─drbd.service @5.478s +11.722s
    └─ssh.service @4.242s +1.234s
      └─ @4.230s
        └─networking.service @3.982s +245ms
          └─apparmor.service @3.720s +251ms
            └─ @3.718s
              └─docker-btrfs.mount @26.536s
                └─docker.mount @3.097s +7ms
                  └─dev-mapper-dockervg\x2ddocker.device @3.095s

Thou shalt not steal!

If you want to use this information on your own website, please remember: by doing copy/paste entirely it is always stealing and you should be ashamed of yourself! Have at least the decency to create your own text and comments and run the commands on your own servers and provide your output, not what I did!

Or at least link back to this website.