systemd: Is it wrong?

JB jb.1234abcd at gmail.com
Fri Jul 8 11:42:34 UTC 2011


Steve Dickson <SteveD <at> redhat.com> writes:

> ... 

Hi,

you are right about the synchronization problem within a service file exec
environment, at least as you showed it in that particular Bugzilla case.

Let's review it once again here (I am on F15), but I reserve the right to be
wrong as I have mostly ignored systemd for the time being :-)

Your nfslock.service file:

[Unit]
Description=NFS file locking service.
After=syslog.target network.target rpcbind.service
ConditionPathIsDirectory=/sys/module/sunrpc

[Service]
Type=forking
PIDFile=/var/run/sm-notify.pid
EnvironmentFile=/etc/sysconfig/nfsservices
ExecStartPre=/sbin/modprobe -q lockd $LOCKDARG
ExecStartPre=/sbin/rm -f /var/run/sm-notify.pid
ExecStart=/sbin/sysctl -w fs.nfs.nlm_tcpport=$LOCKD_TCPPORT
ExecStart=/sbin/sysctl -w fs.nfs.nlm_udpport=$LOCKD_UDPPORT
ExecStart=/sbin/rpc.statd $RPCSTATDARS
ExecStartPost=/sbin/sysctl -w fs.nfs.nlm_tcpport=0
ExecStartPost=/sbin/sysctl -w fs.nfs.nlm_udpport=0

[Install]
WantedBy=multi-user.target
Also=rpcbind.socket

or a variation of the above:

...
ExecStartPre=/sbin/modprobe -q lockd $LOCKDARG
...
ExecStartPre=/sbin/sysctl -w fs.nfs.nlm_tcpport=$LOCKD_TCPPORT
...

and the failure is:

$ systemctl status nfslock.service
nfslock.service - NFS file locking service.
   Loaded: loaded (/lib/systemd/system/nfslock.service)
   Active: failed since Thu, 07 Jul 2011 14:35:39 -0400; 28s ago
  Process: 2186 ExecStartPre=/sbin/sysctl -w fs.nfs.nlm_tcpport=$LOCKD_TCPPORT
(code=exited, status=255)
  Process: 2184 ExecStartPre=/sbin/modprobe -q lockd $LOCKDARG (code=exited,
status=0/SUCCESS)
$

Yes, there is a potential problem as jobs can be created for execution in one
order, but actually scheduled for execution or executed in a different order.

So, what are the solutions ?

- in this particular case
  There is a service file for that purpose already ? 
  $ cat /lib/systemd/system/systemd-modules-load.service
...
[Unit]
Description=Load Kernel Modules
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service
Before=sysinit.target shutdown.target
ConditionDirectoryNotEmpty=/etc/modules-load.d

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/lib/systemd/systemd-modules-load
$

  and this service file too ?
$ cat /lib/systemd/system/systemd-sysctl.service
...
[Unit]
Description=Apply Kernel Variables
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service
Before=sysinit.target shutdown.target
ConditionPathExists=|/etc/sysctl.conf
ConditionDirectoryNotEmpty=|/etc/sysctl.d

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/lib/systemd/systemd-sysctl
$

  The sys admin would:
  - add a required lockd.conf to /etc/modules-load.d/
  - edit /etc/sysctl with required param settings

  I guess you could modify the nfslock.service file like this:
...
Requires=systemd-modules-load.service systemd-sysctl.service 
...
After=syslog.target network.target rpcbind.service ystemd-modules-load.service
systemd-sysctl.service
...

  and without these:
...
ExecStartPre=/sbin/modprobe -q lockd $LOCKDARG
ExecStart=/sbin/sysctl -w fs.nfs.nlm_tcpport=$LOCKD_TCPPORT
ExecStart=/sbin/sysctl -w fs.nfs.nlm_udpport=$LOCKD_UDPPORT
...

  I hope that the env variables used by modprobe and 'sysctl -w' as used here
  ($LOCKDARG, $LOCKD_TCPPORT, $LOCKD_UDPPORT) would be available in the above
  corresponding service execution envs as being "required" "sub-services"
  (see Requires=... and After=...) to nfslock.service, which provides for
  EnvironmentFile=/etc/sysconfig/nfsservices .

  I hope that would work as desired, that is, synchronously.
 
- systemd has to manipulate SYSTEMD.EXEC(5) scheduling environment to make
  sure that sequential execution as in a service file *means* synchronous
  execution, with internal completion code checking and error processing.
  Warning:
    manipulating scheduling environment is always tricky and can cause
    problems and complications, in particular in real-time environment, as
    multithreading programming shows.
- perhaps systemd needs some conditional constructs to check for completion
  code of commands executed (sequentially) in a service file.
  e.g.
  ExecStartPre="/sbin/modprobe -q lockd $LOCKDARG",SetOnError=error1
  ExecStartPre="/sbin/sysctl -w fs.nfs.nlm_tcpport=$LOCKD_TCPPORT",IfError=error1=0

  This would be useful here, but it appears to duplicate options from
  systemd.unit(5) and systemd.service(5).

Well, systemd was supposed to simplify those silly and primitive bash-based
SysV and LSB system init environments, cure the lack of parallelism, etc ...
Sorry, just having a bad hair day :-)

JB

Maria Callas - Bellini - Il Pirata - Part 2 (Final Scene) 
http://www.youtube.com/watch?v=KDQkgjzky44




More information about the devel mailing list