systemd: Is it wrong?

Lennart Poettering mzerqung at 0pointer.de
Fri Jul 8 12:23:07 UTC 2011


On Thu, 07.07.11 22:57, Steve Dickson (SteveD at redhat.com) wrote:

> Hello,
> 
> One of the maintainers of systemd and I  have been working 
> together on trying to convert the NFS SysV init scripts
> into systemd services. Here is the long trail... 
> 
> https://bugzilla.redhat.com/show_bug.cgi?id=699040
> 
> The point is this, with fairly complicated system, 
> some events need to have happen, like loading modules,
> before other events happen, like setting parameters of 
> those loaded modules. 
> 
> Currently the ExecStart commands can be started and end 
> before the ExecStartPre even start. This means setting
> modules parameters within the same service file are 
> impossible.
> 
> I suggested that a boundary be set that all ExecStartPre
> commands finish before any ExecStart commands start, 
> which would allow complicated subsystems, like NFS, 
> to start in a very stable way... 
> 
> So is it wrong? Shouldn't there away to allow certain 
> parts of a system to synchronously configure some
> things so other parts will come up as expected? 

I am pretty sure systemd-devel is the better place to discuss this. But
here are a few comments after reading throught the bug report:

Yes, we want that people place each service in an individual service
file. Only then we can supervise the services properly. It is possible
to spawn multiple high-level processes from a single service, but that
is mostly intended as compat kludge to support SysV init scripts where
this is possible. In general however, we want people to do have a 1:1
mapping. Only then we can restart services if needed, we can catch
crashes, and show proper information about your service.

So, I'd suggest strongly not to try starting all services from a single
file. There's a reason why we explicitly forbid having more than one
ExecStart= in a unit file (except for Type=oneshot services).

Note that systemd unit files are not a programming language. And that
for a reason. If you want shell, then use shell, but don't try to misuse
the purposefully simple service file syntax for that. 

Also, you should not spawn forking processes in ExecStartPre=, that's
not what it is for. In fact I am pretty sure I will change systemd now
to kill off all remaining processes after each ExecStartPre= command now
that I am aware that people are misusing it like this.

ExecStartPre= is executed strictly in order, and in the order they
appear in the unit file.

I believe that services should be enabled/disabled at one place only,
and that is where you can use "systemctl enable" and "systemctl
disable". Adding a service-specific second-level of disabling in
/etc/sysconfig/ is confusing to the user, and not necessary. You'll do a
great service to your users if they can enable/disable all individual
services the same way. (And UI writers will be thankful for that too)

There's no point in ever unloading kernel modules, unless you do it for
debugging or testing reasons. No init script should ever include an
"rmmod" or "modprobe -r". And we try to make static module loading
unnecessary. There's nowadays auto-loading for most modules in one way
or another, using MODALIAS and similar constructs in the kernel
modules. If you really need to load a module statically, then please do
so via /etc/modules-load.d/ so that the user has centralized control on
this.

This is not going to work:

ExecStart=$FOO bar waldo

I.e. variable substitution for the binary path (it will work for the
arguments, just not for the binary path). This limitation is necessary
due to some SELinux innerworkings in systemd. It's a limitation we
probably could fix if we wanted to, but tbh I find it quite questionable
if you spawn two completely different binaries and still call it by the
same service file.

In general if services use a lot of /etc/sysconfig/ settings then this
is probably an indication that the service code should be fixed and
should just get proper configuration files. If you need to interpret
these files, outside of the daemon, and the simple variable substitution
is not sufficient, and you need a programming language to interpret the
settings, then use a programming language, for example shell. You can
start shell scripts from systemd, like any other executable, and then
exec the real binary in the end. Of course, these solutions are somewhat
hacky, and I think in the long run binaries should be stand-alone and
should be able to read their own configuration themselves. But if you
really need a shell script, then go for it, stick it in
/usr/lib/<yourpackage>/scripts/ or so, and execute that from ExecStart=.

I will probably blog about sysconfig in a systemd world soon.

Type=oneshot is for one shot services, not continously running
services. Type=oneshot is for stuff like fsck, that runs once at boot
and finishes, and only after it finished boot will continue. 

I am aware that some things I point out above are not how people used to
do things on SysV, but well, we want to get things right, and if you use
systemd natively, then we ask you to clean up things and not just
translate things 1:1.

Lennart

-- 
Lennart Poettering - Red Hat, Inc.


More information about the devel mailing list