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

Lennart Poettering mzerqung at 0pointer.de
Wed Jul 14 23:29:03 UTC 2010


On Wed, 14.07.10 18:00, Bill Nottingham (notting at redhat.com) wrote:

> 
> Lennart Poettering (mzerqung at 0pointer.de) said: 
> > So, here's my call for help, in order to make this all a big success:
> 
> So, I've actually played with this now, instead of just asking questions
> and operating on knowledge from the initial announcement.
> 
> I must admit... at first glance, I'm not the hugest fan, simply because of the
> interface it presents to the admin.
> 
> 1) Jargon/Renaming of concepts
> 
> systemd is heavily invested in jargon specific to systemd. For example,
> the main unit of configuration is:
> 
> - sysv: service file
> - upstart: job file
> - systemd: unit file
> 
> 'service' and 'job' are fairly well-understood (and similar) concepts.
> 'unit' has no overall meaning... it's just a generic word.

Well, the word "job" was introduced by upstart and was previously not
used anywhere. And it also introduced "event" and "goal".

systemd uses "job", and introduces "unit". Wow. New software uses
different terms.

And that comparison is not even fair. The thing that was called service
file in sysv is called service file in systemd too (it even has .service
is suffix, how obvious!). However since in contrast to sysv we not only
maintain services, but also mount points, devices, yadda yadda, we came
up with a more generic term for all these kinds of things, where
"service" is one kind of, and that term is "unit". How else would you
have done this?

If you want to blame somebody, blame upstart for calling what was
previously called a service a job. In systemd we just went back to the
roots in this area and call it services again, and then added one level of
abstraction on top of that, because our focus is not only daemons but a
lot more.

> Similarly, the redefinition of the concept of 'runlevel' as 'target' (well,
> amalgamations of targets) is replacing a concrete concept with a generic word, and
> replacing 'enabled/disabled' with 'active/inactive' seems random.

Well, targets are supersets of runlevels. That's why there is
"runlevel2.target".

The chkconfig man page uses the term enable/disable the same way
as we do:

enable/disable is used to say whether a service or other unit shall be
started during boot. 

active/inactive is just a more generic term for started/stopped, simply
because you cannot really say a device is "started", can you? 

When you speak of services you start and stop them. When you speak of
the more generic form of units (which can be any of service, socket,
device, mount point whatever), then you activate or deactivate them. 

We basically took the terms that have been used in SysV for maintaining
daemons, (i.e. you "start" or "stop" entities called "service"), and
reuse them in systemd for daemons. And for the more generic units we have
generalized this. (i.e. you "activate" or "deactivate" entities called
"units").

Or to explain this with a table, showing you what verbs most people
would probably use for four kinds (of the ten) of objects that are 
managed by systemd:

 Services:     Started | Stopped
 Socket:         Bound | Unbound
 Devices:   Plugged In | Plugged Out
 Mounts:       Mounted | Unmounted

And we noticed that, and when we looked for more abstract terms that
could cover all three cases, we cam up with this:

 Units:         Active | Inactive

And to be honest, I find this very understandable. Maybe not obvious,
but figuring this out should not require a nobel prize. And this is
actually documented in the man page, though in terser words, it's right
the first paragraph under "Concepts" in the systemd man page:

    "systemd provides a dependency system between various entities called
    'units'. Units encapsulate various objects that are relevant for system
    boot-up and maintainance. The majority of units are configured in unit
    configuration files, whose syntax and basic set of options is described
    in systemd.unit(5), however some are created automatically from other
    configuration or dynamically from system state. Units may be active
    (meaning started, bound, plugged in, ... depending on the unit type), or
    inactive (meaning stopped, unbound, unplugged, ...), as well as in the
    process of being activated or deactivated, i.e. between the two states."

> 2) Complexity
> 
> While there's a certain level of complexity to doing complex things, systemd
> seems to go overboard.

Does it? But it also does a lot more...

> Example 1:
> # of jobs/events/whatever files shipped by default (not counting SysV services):
> - sysv: 	1

Oh, that's really not fair... SysV only covers a tiny fraction of what
Upstart cover or even systemd cover.

> - upstart: 	19
> - systemd: 	62

Well, but the systemd unit files are trivial to understand. If you
honestly claim that the systemd unit files are harder to understand than
shell monsters you find ind /etc/init.d then I'll go and shoot myself.

Look at the contents of those files. See how tiny they are!

If you prefer few huge script monsters over a number of tiny
configuration fragments, then I guess this is a matter of taste.

> And in this case, we're not using systemd for much natively. It's a lot of
> data to sort through if you're trying to just figure out what's going on,
> and if you're not clear with all of the systemd concepts, a lot of it looks
> strange, such as:
> 
> - why does everything need *both* mount and automount files?

It doesn't. Dude, this is so not fair.

Systemd has all kinds of magic tricks for you. For example we set up
automount points for various directories like /sys/kernel/security, or
/proc/sys/fs/binfmt_misc, /dev/hugepages and more. Only when people
access them the backing kernel modules will be loaded and the real fs
mounted. How awesome is that?

Note that by default we install those automount points only for kernel
virtual "API" file systems. Because it was an obvious choice. But if you
then compare that with Upstart then you should love systemd, because it
will establish all the filesystem hierachies that they are readily
accessible and that even without loading the kernel modules backing
them. How awesome is that, really? And Upstart doesn't have that.

Or in other words: that Upstart doesn't do automounting like this is a
limitation of Upstart, not a limitation of systemd.

BTW, I think I mentioned this a couple of times, but it would be awesome
to read the blog story I wrote... It explains the logic behind the
automount... http://0pointer.de/blog/projects/systemd.html

So, to say this explicitly: NO YOU DON'T NEED BOTH MOUNT AND AUTOMOUNT
FILES! You don't even mount files, and certainly not automount
files. You can list all mounts you want in /etc/fstab and systemd will
honour them. And then if you want to create an automount point you can
*optionally* create an automount unit for it as well. But that's
OPTIONAL! And please don't blame me that systemd has more features than
sysvinit or upstart.

And btw, you can even create automount points via
comment=systemd.automount as mount option in /etc/fstab. You don't even
have to place an .automount file anywhere. For the API file systems
however we decided to do just that because it is way easier to just drop
those additional files in there than it is to patch /etc/fstab.

> - if swap, local-fs, etc. are all bookkept internally, what's the point of
>   having a target file?

Well, it's called "compatiblity". Because we keep compat with existing
stuff we automatically populate swap.target, local-fs.target and
remote-fs.target with the data from /etc/fstab. How amazing is that? We
treat the existing configuration just as another source of configurationn
that is used alongside native configuration, and then make it appear as
if it was natively configured.

If you don't want /etc/fstab anymore you can also define native unit
files for swaps and mount points. Note sure that makes sense at this
time, but hey, I won't stop you.

> - why does setting of Alias *also* require a symlink? (It may not, but
>   local vs. rc.local seems to imply it might.)

Well, in systemd we only read files that are requested, for perfomance
reasons. if something or somebody requests "foo.service" we load that
file. And if we then find an alias configured in that file we install
that alias too. However, if somebody looks up things under the alias
first then he will only end up with the unit file if there's a symlink
for it.

And that' s actually a feature, not only in minimizing disk
accesses. i.e. postfix.service and sendmail.service could both have an
internally configured alias of mta.service, which makes them mutually
exclusive. And then, in the fs you could use the symlink to select which
of the two units is started when something or somebody requests
"mta.service". That way, if you have running either of them the mta dep
will be fulfilled. And if you have neither running then the symlink
decides which one is started.

> I do wonder if perhaps this could be simplified by:
> 
> - Keeping services and targets separate on the filesystem

Well, we have 10 types of units. If you say every type should get its
own dir then the next guy will come and say "oh, my god, this
complexity, wouldn't one dir suffice?"

I think this is mostly a matter of taste.

> - Merging services and sockets into the same file where appropriate... given
>   that they're tied together inherently anyway, I'm not sure why they
>   need to be separate.

Well, they have different lifecycles and dependencies and can be started
and stopped independently.

Example: Service "dbus.service" wants to be started after
"syslog.service". The former is a socket-activated service (i.e. as in
current Rawhide), the latter is a not socket-activated (i.e. as in
current Rawhide). The dbus socket can be established very early, before
syslog is started, but dbus can only be started if syslog is actually
around and has established its socket itself. Establishing the dbus
socket early has numerous advantages, in particular since everybody can
then just go and use it (it's part if the whole idea of socket
activation).

That's why you want to have independent entities here for sockets and
services: they can be independently activated and when one eventually
triggers activation of the other that can even pull a completely
different slew of dependencies.

Also, there is not even a 1:1 relation between services and sockets. For
example, for ssh we probably should run one sshd instance per
connection. This results in units like these appearing in the system:

 sshd.socket
 sshd at 2-127.0.0.1:22-127.0.0.1:46660.service
 sshd at 3-172.31.0.50:22-172.31.0.4:43289.service

"sshd.socket" is a unit for the socket. And the other two services are
instances of sshd, for two incoming connections. And those two instances
are even labelled after there connection credentials (i.e. IP addresses
local and remote, how awesome is that? the admin can kill those services
individually and by there name). i.e. sshd.socket triggered creation of
two .service units here.

> Example 2:
> 
> I want to configure the number of gettys on the system.
> 
> - sysvinit
> 
> Edit /etc/inittab. Add/delete some obvious lines.
> 
> - upstart
> 
> Edit /etc/sysconfig/init (discoverable by looking in /etc/init at the
> start-ttys.conf file, which is documented in inittab if people look there
> first.)
> 
> - systemd
> 
> Use systemd-install to add or delete the
> /etc/systemd/system/getty.target.wants/getty at tty4.service (or whatever)
> symlink.

Well systemd-install will install the *suggested* configuration for you,
that's all. If you deviate from that you can just create or remove
symlinks as you wish.

I.e. to remove a tty from tty4:

    $ rm /etc/systemd/system/gettys.target/wants/getty at tty4.service

To add one for tty9:

    $ ln -sf /lib/systemd/getty at .service /etc/systemd/system/gettys.target/wants/getty at tty9.service

And you can easily figure that out simply by duplicating what is already
there for the other ttys. 

> This requires knowledge of:
> 
> - what systemd targets are
> - what the target name is that starts gettys
> - what 'wants' means in this systemd context
> - the proper systemd interface to install/remove commands

I think you are misunderstand what systemd-install is about. I have now
added an additional sentence to the man page that explains that
systemd-install is for the *suggested* installation only, and that you
are always welcome to deviate from that.

I have also made sure that attempts to use systemd-install like yours just
did result in a clean error message with suggestions what to do instead.

And also, if we ship an inittab that points people to creating those
symlinks your criticism would go away and things would be the same or
even simpler then with Upstart, right?

Lennart

-- 
Lennart Poettering - Red Hat, Inc.


More information about the devel mailing list