Dealing with Systemd

Once again something new and unnecessary. We liked, even loved, the old shell script based scheme. But there are bored and restless programmers out there without enough imagination to find better things to do. So, like Hollywood remakes of old classics (which again underscore lack of imagination and creativity), we have systemd and are probably stuck with it.

One justification for added complexity that I have heard is that systemd allows things in the boot process to run in parallel when possible. This makes boot faster (supposedly), as if we or anybody cares. It also has broken things by introducing nasty race conditions (notably nfs, which has even bitten me!).

And, I have to point out, most users don't give a flip how fast a system boots. Most of my systems run 30-40 days at a time, with reboots being done for maintenance (typically to pick up a new kernel). So, I could care less if boot takes 1 or 5 minutes, so long as it doesn't take an hour. I am sure that most people feel this way, except a handful of developers. This tiny gain is not balanced by the price of introducting new complexity and breaking important things (like NFS, which still is not adequately fixed).

So, we are stuck with systemd (and plymouth, and gnome3, and grub2), but we don't have to like it.

Starting and Stopping services

The systemctl command now replaces what was previously done via the "service" and "chkconfig" commands. Systemctl calls the entities that it manages "units" (only some of which are called "services"). There are (for the time being) scripts that emulate the old "service" and "chkconfig" commands. Just in case these scripts go away someday, the following is good to know.

To start a service (as "service xxx start" would have done):

systemctl start xxx.service

To enable a service (as "chkconfig xxx on" would have done):

systemctl enable xxx.service
You can probably guess what "disable", "stop", and "restart" will do.

Just typing "systemctl" gives you an overall summary of the units that systemctl is managing at a given moment.

Files that control systemd can be found at:

The files in /etc/systemd take precedence over those in /lib/systemd, but there is more to this that I have yet to hash out.

Changing the run level

In the good old days, you edited the /etc/inittab file, which systemd now merrily ignores, so you have to learn new tricks, and we hate learning new tricks.

To find out the current run level, you can (for the time being anyway) use the runlevel command. But the whole concept of runlevels is going out the window (with the baby?) with systemd. Now you need to think about targets and realize that many targets can be active at once. I suppose this gives you more versatility and fine grained control, maybe. So, to find out what targets are active:

    systemctl list-units --type=target 
What I really had in mind when I found myself tangled up in all of this was to change the default runlevel from 5 to 3. I have a headless server that does not need to run a window system, and I can save resources by doing this, or at least I like to believe I can.

All this is done now by creating (and deleting) symbolic links. The recommended way to do what I think I want to do is:

rm /etc/systemd/system/default.target 
ln -sf /lib/systemd/system/multi-user.target /etc/systemd/system/default.target 
To go back to the moral equivalent of run level 5, I can do:
rm /etc/systemd/system/default.target 
ln -sf /lib/systemd/system/graphical.target /etc/systemd/system/default.target 

When I actually go to try this on my freshly installed fedora 16 system I find:

ls -ld /etc/systemd/system
default.target -> /lib/systemd/system/runlevel5.target
It turns out this is a link (and there is a family of them) like so:
 /lib/systemd/system/runlevel3.target -> multi-user.target
 /lib/systemd/system/runlevel4.target -> multi-user.target
 /lib/systemd/system/runlevel5.target -> graphical.target
So, what I do is:
rm /etc/systemd/system/default.target 
ln -sf /lib/systemd/system/runlevel3.target /etc/systemd/system/default.target 
Seems to work.

Adding a new service

I have decided that I would like to add a new service (unit?). I will call it matlab-lm since it will start the matlab license manager. The first thing to do is create a file:
vi /lib/systemd/system/matlab-lm.service
Once this is done (there are lots of other services to use as examples, not to mention man pages for systemd and so on), the thing to do is to give systemd a kick in the butt so it will notice the new service:
systemctl daemon-reload
To start, just my new service (right now):
systemctl start matlab-lm.service
systemctl status matlab-lm.service
To make this a service that gets started at boot time:
systemctl enable matlab-lm.service

This particular thing gets 3 processes running:

/var/tmp/lm_TMW.ld -z -c /var/tmp/lm_TMW.dat
sh -c while read line; do echo "$line" >> /var/tmp/lm_TMW.log; done
MLM -T myhost.mydomain 11.4 3 -c /var/tmp/lm_TMW.dat --lmgrd_start 50887779
So, starting it is fine, but stopping and restarting will be tricker.
Have any comments? Questions? Drop me a line!

Adventures in Computing / tom@mmto.org