The change from classic init to systemd is a really big one. Some may even say controversial!
A few old standbys still work — for now — as automatic workarounds. We can still do major state changes with
poweroff; by running
init with a numerical argument, and with
shutdown. Also, Red Hat’s
service command still works. Some of these, prominently
service, are accompanied with narration explaining what it’s really doing. It seems like vague disapproval.
It makes sense to start with answering the question of what is going on and how we got here. We can still use
runlevel to get the current system state and the previous one, if there was any. If you booted a server to run level 3, or text-only mode, you would see this:
# runlevel N 3
The second value is the current system state, run level 3. The first value, N, indicates that there was no previous run level. The system booted directly into its current state.
Now imagine that you start graphics by going to run level 5 and then check the system state again:
# init 5 # runlevel 3 5
It was at run level 3, but now it has changed to 5.
Now, just what do run levels 3 and 5 mean? We used to list the services stopped and started to get into those states this way:
# ls /etc/rc.d/rc.d
We might need to read the corresponding scripts in
/etc/init.d to figure out what some of them are. The Linux server administration course shows you how to use the
rpm command to get further information about the specific packages those scripts belong to.
However, with systemd the details are leaving those familiar directories. Part of the design philosophy of systemd is to replace scripts with binaries. Binaries run much faster, but you can’t read them like scripts. And
/etc/rc.d/rc?.d directories are emptying out.
How can we accomplish these same tasks? With the
systemctl command and examination of the files under
Before we get started, stretch your terminal emulator horizontally so it’s as wide as possible. Some of these commands will either trim off details that don’t fit or else wrap lines around so they are more difficult to read.
Remember from our earlier discussion that systemd supports many more target states than the four useful numeric ones we’re used to. Let’s discover the default boot target:
# systemctl get-default runlevel3.target
Now, just what does
# cd /usr/lib/systemd/system # ls -l runlevel3.target lrwxrwxrwx 1 root root 17 Apr 25 2014 runlevel3.target -> multi-user.target
Details appear as we explore further:
# ls -l multi-user.target -rw-r--r-- 1 root root 492 Apr 16 2014 multi-user.target # more multi-user.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=Multi-User System Documentation=man:systemd.special(7) Requires=basic.target Conflicts=rescue.service rescue.target After=basic.target rescue.service rescue.target AllowIsolate=yes
# ls basic.target.wants/ multi-user.target.wants/
We could then trace the dependencies of those services further back.
It gets more interesting when we pick just one of the running services and examine it. Lets see what the SSH service needs:
# systemctl list-dependencies sshd sshd.service |-system.slice `-basic.target |-alsa-restore.service |-alsa-state.service |-firewalld.service |-microcode.service |-rhel-autorelabel-mark.service |-rhel-autorelabel.service |-rhel-configure.service |-rhel-dmesg.service |-rhel-loadmodules.service |-paths.target |-slices.target | |--slice | `-system.slice |-sockets.target | |-avahi-daemon.socket | |-cups.socket | |-dbus.socket | |-dm-event.socket | |-iscsid.socket | |-iscsiuio.socket | |-lvm2-lvmetad.socket | |-rpcbind.socket | |-systemd-initctl.socket | |-systemd-journald.socket | |-systemd-shutdownd.socket | |-systemd-udevd-control.socket | `-systemd-udevd-kernel.socket |-sysinit.target | |-dev-hugepages.mount | |-dev-mqueue.mount | |-dmraid-activation.service | |-iscsi.service | |-kmod-static-nodes.service | |-lvm2-monitor.service | |-multipathd.service | |-plymouth-read-write.service | |-plymouth-start.service | |-proc-sys-fs-binfmt_misc.automount | |-sys-fs-fuse-connections.mount | |-sys-kernel-config.mount | |-sys-kernel-debug.mount | |-systemd-ask-password-console.path | |-systemd-binfmt.service | |-systemd-journal-flush.service | |-systemd-journald.service | |-systemd-modules-load.service | |-systemd-random-seed.service | |-systemd-sysctl.service | |-systemd-tmpfiles-setup-dev.service | |-systemd-tmpfiles-setup.service | |-systemd-udev-trigger.service | |-systemd-udevd.service | |-systemd-update-utmp.service | |-systemd-vconsole-setup.service | |-cryptsetup.target | |-local-fs.target | | |--.mount | | |-boot-efi.mount | | |-boot.mount | | |-rhel-import-state.service | | |-rhel-readonly.service | | |-systemd-fsck-root.service | | `-systemd-remount-fs.service | `-swap.target | |-dev-disk-by\x2did-dm\x2dname\x2drhel\x2dswap.swap | |-dev-disk-by\x2did-dm\x2duuid\x2dLVM\x2dWnBj2W1PMEpck7NLFDV... | |-dev-disk-by\x2duuid-08f20d96\x2d0084\x2d4d86\x2dbf00\x2d41.... | |-dev-dm\x2d1.swap | |-dev-mapper-rhel\x2dswap.swap | |-dev-mapper-rhel\x2dswap.swap | |-dev-rhel-swap.swap `-timers.target `-systemd-tmpfiles-clean.timer
You will probably wonder if there isn’t some way to get a graphical representation of all of the services and target states and their interdependencies. There is, although it’s far too much information. But it’s something to see at least once. Be patient, it may take a few minutes:
# systemd-analyze dot | dot -Tsvg > /tmp/systemd.svg
Then view that vector graphics image with your browser. Wow. Like I said, too much information!
That’s it for this week, come back next time to see how to do service control.