Differences between revisions 2 and 3
Revision 2 as of 2015-07-25 22:43:56
Size: 4239
Editor: ?FelipeSateler
Comment:
Revision 3 as of 2015-07-27 22:15:17
Size: 4237
Editor: ?FelipeSateler
Comment: use sysinit.target for network and remote fs services
Deletions are marked like this. Additions are marked like this.
Line 57: Line 57:
WantedBy=remote-fs.target WantedBy=sysinit.target
Line 76: Line 76:
WantedBy=network.target WantedBy=sysinit.target

rcS.d migration

Sysvinit booted by executing all scripts in rcS.d , then rcN.d where N is the target runlevel (2 by default in debian). Debian systemd currently has a patch to preserve the rcS.d synchronization point, forcing all rcS.d init scripts to run before the scripts in rcN.d. The problem is solved by providing native units with correct dependencies for each service.

Main dependencies involved

The main issue is that Debian systemd makes all rcS.d ordered Before=sysinit.target , which in turn is ordered Before=basic.target. On the other hand, systemd by default orders all units After=basic.target (this can be removed with ?DefaultDependencies=no).

This causes problems if some service with ?DefaultDependency=yes tries to order itself before any of the services in rcS.d, as this causes a dependency loop, which systemd breaks at a random point.

How to solve this

The sysv generator only applies to sysv init scripts if there is no corresponding service file. Therefore, the solution is to add a native service file to all the services that provide scripts in rcS.d.

Do you really need a service?

Sometimes, the correct solution is not to use a service at all but use another facility provided by systemd. If your service runs in early boot to write files or create runtime directories, consider using systemd-tmpfiles. If your service loads kernel modules, consider installing a file in /usr/lib/modules-load.d instead.

If your service can be replaced by these alternative facilities, then you should instruct systemd to ignore the original SysV init script. Do so by installing a symlink /lib/systemd/system/myscript.service pointing to /dev/null, where myscript is the name of your initscript as installed in /etc/init.d.

What dependencies should you use?

Depending on the services provided, your script needs to hook itself in the correct place in the boot sequence. Here are some guidelines for determining which dependencies to use in your service.

Your service is not really about early boot

The first step is to define if the init script really belongs in early boot. If it doesn't, consider moving your script to runlevel 2 and use WantedBy=multi-user.target. If your script needs to execute before another service because it provides some setup for it, use Before=other.service.

Your service is needed to mount local file systems

In this case, you should create a service with the following dependencies:

[Unit]
Description=An early boot service
DefaultDependencies=no
Wants=local-fs-pre.target
Before=local-fs-pre.target

[Install]
WantedBy=local-fs.target

Your service is needed to mount remote file systems

In this case, you should create a service with the following dependencies:

[Unit]
Description=An early boot service
DefaultDependencies=no
Wants=remote-fs-pre.target
Before=remote-fs-pre.target

[Install]
WantedBy=sysinit.target

If your service requires the network to be already set up, also add After=network.target. If it additionally requires internet connectivity, add After=network-online.target. Please try to avoid network-online.target if at all possible.

FIXME: should these instead use ?WantedBy=network-online.target ? systemd.special(7) tends to suggest so... (?FelipeSateler)

My service is needed to configure network interfaces

If you need to configure network interfaces then you should order the service as follows (eg, if you need to run before ifupdown/networkd):

[Unit]
Description=An early boot service
DefaultDependencies=no
Wants=network-pre.target
Before=network-pre.target

[Install]
WantedBy=sysinit.target

Bugs

See the usertagged bugs.