[HEADS-UP] systemd for F14 - the next steps

Lennart Poettering mzerqung at 0pointer.de
Wed Jul 14 15:43:30 UTC 2010


On Wed, 14.07.10 10:11, Hans de Goede (hdegoede at redhat.com) wrote:

> iscsi-initiator-utils comes with 2 initscripts. 1 to start iscsid and
> 1 to login to iscsi nodes configured in the iscsi database
> (/var/lib/iscsi):
> http://cvs.fedoraproject.org/viewvc/devel/iscsi-initiator-utils/iscsid.init?view=markup
> http://cvs.fedoraproject.org/viewvc/devel/iscsi-initiator-utils/iscsidevs.init?view=markup
> 
> iscsid is a semi-regular daemon, yet its initscript is special as it
> only starts iscsid when needed. Socket based activation is out of the question as iscsid
> is a userspace kernel support daemon. Which needs to be started ASAP,
> so that it is ready to do error recovery when the kernel needs it.

[...]

> So the question is how to deal with stuff like this in systemd.
> I'm thinking myself that maybe the solution here is to just keep
> using systemv style initscripts here, but I'm not sure.

Kay, Harald and I have now discussed this a little, and this is what
we'd propose:

There seem to be three problems here:

1) Your init script loads kernel modules. You could easily cover that by
placing "ExecStartPre=-/sbin/modprobq -qab iscsi_tcp ib_iser cxgb3i bnx2i
be2iscsi" in the systemd service file of iscsid. However, generally
doing stuff like that is an indication that the modules are broken and
should be fixed. i.e. Kay recently made changes to the kernel so that
you can use a macro like MODULE_ALIAS_MISCDEV in modules to make sure
modules are autoloaded when their device node is first accessed, and that
udev creates those device nodes properly in advance. If these modules
offer their services via some kind of device node a scheme like this
should be adopted. Hand-loading modules is always a bit ugly, and
automatic handling via module autoloading would be much
preferable. (Also, instead of starting modprobe 5 times, call it only
once, please. And unloading the modules when the service goes down is a
really bad idea.)

2) You parse some configuration files or similar to figure out whether
you want iscsid to be started. This we believe is just wrong. That's not
how things work on Linux. Whether you want to start a daemon on boot
should be controlled by something like chkconfig or systemd-install
(which is basically chkconfig for systemd), not via some per-daemon
configuration file switch. I mean, what iscsid is doing there would be
like if Apache (and similarly all other daemons we have) would have an
apache.conf config switch StartDaemon=yes or so, and only when that is
set apache would be started by the init script. Or in other words: the
central place where services are enabled or disabled for SysV is
/etc/rc?.d/, not your configuration files. And for systemd the
equivalent is /etc/systemd/systemd. If you add another layer for
enabling/disabling you just complicate things, and slow down things. And
the admins will hate you because they cannot figure why iscsid doesn't
start if they run /etc/init.d/iscsid start. Have a single on/off switch,
in a well known place where everybody else has it too. Don't add more
on/off switches in line there, to confuse people so that they have to
flip them all if they want something started. And don't parse
configuration files from shell, that's just evil.

3) You check mtab to figure out whether the rootdir is on iscsi. That
cannot work, as mtab is not really updated anyway, and if at all you
should look in /proc/mounts, but this won't really give your the
information either. The proper way to handle this in systemd is to start
iscsid if an iscsi block device appears. udev recognizes iscsi block
devices, and this could be used to write a simple udev rule that pulls
in iscsid.service as soon as one of those block devices appear (a simple
trick would be to match against the symlink name
/dev/disk/by-id...). And that should be all that is necessary.

So in summary, the approach would be to write a simple .service file
which loads the modules via the suggested ExecStartPre= line, and then
just executes iscsid. And then this unit is either activated at boot
time which is enabled via "systemd-install" because the admin wanted so,
or when udev notices an iscsid block device. That's a simple scheme
that should be robust, race-free and without any shell madness.

Lennart

-- 
Lennart Poettering - Red Hat, Inc.


More information about the devel mailing list