What does systemd do?
I mentioned in an earlier post that
systemctl appeared to be tied to
systemd, which looked like a much more important program. In this post, I’m going to explore
systemd and see what it does.
Turns out, it does a LOT. And people are super unhappy about it.
I loosely knew the Unix philosophy, which essentially states that programs should be tiny and do very little, rather than one program taking on monolithic functionality. Doug McIlroy, a former head of the Bell Labs Computing Sciences Research Center, summarized it thus:
This is the Unix philosophy: Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.
systemd does way more than this. It does a bajillion things, and it does them well, but it still does a bajillion things rather than just one.
At its core,
systemd is a Linux init system. It’s designed to kick off programs - every single program that runs on a Unix system. As such, it’s the first process spawned when a system boots:
$ ps -ef | grep "systemd" root 1 0 0 00:40 ? 00:00:04 /usr/lib/systemd/systemd --system --deserialize 21 root 1636 1 0 00:40 ? 00:00:00 /usr/lib/systemd/systemd-journald root 1649 1 0 00:40 ? 00:00:00 /usr/lib/systemd/systemd-udevd dbus 2488 1 0 00:40 ? 00:00:01 /bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation root 2490 1 0 00:40 ? 00:00:00 /usr/lib/systemd/systemd-logind root 15732 15713 0 16:36 pts/3 00:00:00 grep --color=auto systemd
PID 1! The maker of all other services in a Unix operating system! I never knew what PID 1 would be, but there it is:
systemd. This post is going to be heavy, I think. And I’ll probably leave myself asking more questions. I’m not really grokking anything in-depth from the Wikipedia page for
systemd, so off I go to the man pages.
systemd has an entire “Concepts” page devoted to it, which is extremely useful. It states that
systemd has a concept of units - our services, sockets, and other objects we used earlier.
nginx is a unit.
dashboard is a unit. Now we get some meat about what those units can be, and I’m just going to copy and paste the list here.
Service units, which start and control daemons and the processes they consist of.
Socket units, which encapsulate local IPC or network sockets in the system, useful for socket-based activation.
Target units are useful to group units, or provide well-known synchronization points during boot-up.
Device units expose kernel devices in systemd and may be used to implement device-based activation.
Mount units control mount points in the file system.
Automount units provide automount capabilities, for on-demand mounting of file systems as well as parallelized boot-up.
Snapshot units can be used to temporarily save the state of the set of systemd units, which later may be restored by activating the saved snapshot unit.
Timer units are useful for triggering activation of other units based on timers.
Swap units are very similar to mount units and encapsulate memory swap partitions or files of the operating system.
Path units may be used to activate other services when file system objects change or are modified.
Slice units may be used to group units which manage system processes (such as service and scope units) in a hierarchical tree for resource management purposes.
Scope units are similar to service units, but manage foreign processes instead of starting them as well.
I still don’t know what a target unit is, so I’m going to move into the man page for
systemd.target for a moment. This line is helpful from those pages: “They exist merely to group units via dependencies (useful as boot targets), and to establish standardized names for synchronization points used in dependencies between units.” I think I’ve got it now - if you want to smash together a bunch of units into one (like you’d need to do for a multi-user system), you use a target unit.
systemd also manages the dependencies of units, and that’s where those
Before lines came into play earlier. From my dashboard service’s
systemctl show output:
Requires=basic.target Wants=system.slice WantedBy=multi-user.target Conflicts=shutdown.target Before=shutdown.target multi-user.target After=network.target systemd-journald.socket basic.target system.slice
My service Requires
basic.target, Conflicts with
shutdown.target, must be before
multi-user.target, and must come after
system.slice. I’m not sure what most of these mean, but it does make sense that my web program should be loaded after the
network has been loaded.
systemd states that it loads information about unit configuration from system directories and user directories, which I can find by typing the following commands in:
$ pkg-config systemd --variable=systemdsystemunitdir /usr/lib/systemd/system $ pkg-config systemd --variable=systemduserunitdir /usr/lib/systemd/user
Let’s go see what’s in those:
$ cd /usr/lib/systemd/system $ ls
Ooh, I see a bunch of files that look like the
.service files I was tinkering around with last night but didn’t understand! Let’s inspect a few.
$ cat sound.target # This file is part of systemd. # # systemd is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. [Unit] Description=Sound Card Documentation=man:systemd.special(7) StopWhenUnneeded=yes $ cat halt.target # This file is part of systemd. # # systemd is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. [Unit] Description=Halt Documentation=man:systemd.special(7) DefaultDependencies=no Requires=systemd-halt.service After=systemd-halt.service AllowIsolate=yes [Install] Alias=ctrl-alt-del.target $ cat crond.service [Unit] Description=Command Scheduler After=syslog.target auditd.service systemd-user-sessions.service time-sync.target [Service] EnvironmentFile=/etc/sysconfig/crond ExecStart=/usr/sbin/crond -n $CRONDARGS KillMode=process [Install] WantedBy=multi-user.target
.target files are all part of the configuration that
systemd requires. The
crond.service configuration isn’t
crond itself, it’s a file that tells
systemd how to start and manage
crond. I’m getting it now!
systemd can also receive certain signals, such as
SIGRTMIN+15, which are more black magic to me. I’m not sure how I would send those signals to
systemd, but maybe those things aren’t for me in the way I think of them.