学会爱上 systemd
启动 引导 初始化 systemd

> 
> systemd 是所有进程之母，负责将 Linux 主机启动到可以做生产性任务的状态。
> 
> 
> 


![](/data/attachment/album/202005/13/085016gy86wj713zh7xq71.jpg)


systemd（是的，全小写，即使在句子开头也是小写），是初始化程序（`init`）和 SystemV 初始化脚本的现代替代者。此外，它还有更多功能。


当我想到 `init` 和 SystemV 初始化时，像大多数系统管理员一样，我想到的是 Linux 的启动和关闭，而不是真正意义上的管理服务，例如在服务启动和运行后对其进行管理。像 `init` 一样，systemd 是所有进程之母，它负责使 Linux 主机启动到可以做生产性任务的状态。systemd 设定的一些功能比老的初始化程序要广泛得多，它要管理正在运行的 Linux 主机的许多方面，包括挂载文件系统、管理硬件、处理定时器以及启动和管理生产性主机所需的系统服务。


本系列文章是基于我的三期 Linux 培训课程《[使用和管理 Linux：从零开始进行学习系统管理](http://www.both.org/?page_id=1183)》部分内容的摘录，探讨了 systemd 在启动和启动完成后的功能。


### Linux 引导


Linux 主机从关机状态到运行状态的完整启动过程很复杂，但它是开放的并且是可知的。在详细介绍之前，我将简要介绍一下从主机硬件被上电到系统准备好用户登录的过程。大多数时候，“引导过程”被作为一个整体来讨论，但这是不准确的。实际上，完整的引导和启动过程包含三个主要部分：


* 硬件引导：初始化系统硬件
* Linux <ruby> 引导 <rp>  （ </rp> <rt>  boot </rt> <rp>  ） </rp></ruby>：加载 Linux 内核和 systemd
* Linux <ruby> 启动 <rp>  （ </rp> <rt>  startup </rt> <rp>  ） </rp></ruby>：systemd 为主机的生产性工作做准备


Linux 启动阶段始于内核加载了 `init` 或 systemd（取决于具体发行版使用的是旧的方式还是还是新的方式）之后。`init` 和 systemd 程序启动并管理所有其它进程，它们在各自的系统上都被称为“所有进程之母”。


将硬件引导与 Linux 引导及 Linux 启动区分开，并明确定义它们之间的分界点是很重要的。理解它们的差异以及它们每一个在使 Linux 系统进入生产状态所起的作用，才能够管理这些进程，并更好地确定大部分人所谓的“启动”问题出在哪里。


启动过程按照三步引导流程，使 Linux 计算机进入可进行生产工作的状态。当内核将主机的控制权转移到 systemd 时，启动环节开始。


### systemd 之争


systemd 引起了系统管理员和其它负责维护 Linux 系统正常运行人员的广泛争议。在许多 Linux 系统中，systemd 接管了大量任务，这在某些开发者和sysadmins群体中引起了反对和不和谐。


SystemV 和 systemd 是执行 Linux 启动环节的两种不同的方法。SystemV 启动脚本和 `init` 程序是老的方法，而使用<ruby> 目标 <rt>  target </rt></ruby>的 systemd 是新方法。尽管大多数现代 Linux 发行版都使用较新的 systemd 进行启动、关机和进程管理，但仍有一些发行版未采用。原因之一是某些发行版维护者和系统管理员喜欢老的 SystemV 方法，而不是新的 systemd。


我认为两者都有其优势。


#### 为何我更喜欢 SystemV


我更喜欢 SystemV，因为它更开放。使用 Bash 脚本来完成启动。内核启动 `init` 程序（这是一个编译后的二进制）后，`init` 启动 `rc.sysinit` 脚本，该脚本执行许多系统初始化任务。`rc.sysinit` 执行完后，`init` 启动 `/etc/rc.d/rc` 脚本，该脚本依次启动 `/etc/rc.d/rcX.d` 中由 SystemV 启动脚本定义的各种服务。其中 `X` 是待启动的运行级别号。


除了 `init` 程序本身之外，所有这些程序都是开放且易于理解的脚本。可以通读这些脚本并确切了解整个启动过程中发生的事情，但是我不认为有太多系统管理员真正做到这一点。每个启动脚本都被编了号，以便按特定顺序启动预期的服务。服务是串行启动的，一次只能启动一个服务。


systemd 是由 Red Hat 的 Lennart Poettering 和 Kay Sievers 开发的，它是一个由大型的、编译的二进制可执行文件构成的复杂系统，不访问其源码就无法理解。它是开源的，因此“访问其源代码”并不难，只是不太方便。systemd 似乎表现出对 Linux 哲学多个原则的重大驳斥。作为二进制文件，systemd 无法被直接打开供系统管理员查看或进行简单更改。systemd 试图做所有事情，例如管理正在运行的服务，同时提供明显比 SystemV 更多的状态信息。它还管理硬件、进程、进程组、文件系统挂载等。systemd 几乎涉足于现代 Linux 主机的每个方面，使它成为系统管理的一站式工具。所有这些都明显违反了“程序应该小，且每个程序都应该只做一件事并做好”的原则。


#### 为何我更喜欢 systemd


我更喜欢用 systemd 作为启动机制，因为它会根据启动阶段并行地启动尽可能多的服务。这样可以加快整个的启动速度，使得主机系统比 SystemV 更快地到达登录屏幕。


systemd 几乎可以管理正在运行的 Linux 系统的各个方面。它可以管理正在运行的服务，同时提供比SystemV 多得多的状态信息。它还管理硬件、进程和进程组、文件系统挂载等。systemd 几乎涉足于现代 Linux 操作系统的每方面，使其成为系统管理的一站式工具。（听起来熟悉吧？）


systemd 工具是编译后的二进制文件，但该工具包是开放的，因为所有配置文件都是 ASCII 文本文件。可以通过各种 GUI 和命令行工具来修改启动配置，也可以添加或修改各种配置文件来满足特定的本地计算环境的需求。


#### 真正的问题


你认为我不能喜欢两种启动系统吗？我能，我会用它们中的任何一个。


我认为，SystemV 和 systemd 之间大多数争议的真正问题和根本原因在于，在系统管理层面[没有选择权](http://www.osnews.com/story/28026/Editorial_Thoughts_on_Systemd_and_the_Freedom_to_Choose)。使用 SystemV 还是 systemd 已经由各种发行版的开发人员、维护人员和打包人员选择了（但有充分的理由）。由于 `init` 极端的侵入性，挖出并替换 `init` 系统会带来很多影响，会带来很多在发行版设计过程之外难以解决的后果。


尽管该选择实际上是为我而选的，但我的Linux主机能不能开机、能不能工作，这是我平时最关心的。作为最终用户，甚至是系统管理员，我主要关心的是我是否可以完成我的工作，例如写我的书和这篇文章，安装更新以及编写脚本来自动化所有事情。只要我能做我的工作，我就不会真正在意发行版中使用的启动系统。


在启动或服务管理出现问题时，我会在意。无论主机上使用哪种启动系统，我都足够了解如何沿着事件顺序来查找故障并进行修复。


#### 替换SystemV


以前曾有过用更现代的东西替代 SystemV 的尝试。大约在两个版本中，Fedora 使用了一个叫作 Upstart 的东西来替换老化的 SystemV，但是它没有取代 `init`，也没有提供我所注意到的任何变化。由于 Upstart 并未对 SystemV 的问题进行任何显著的改变，所以在这个方向上的努力很快就被放弃了，转而使用 systemd。


尽管大部分 Linux 开发人员都认可替换旧的 SystemV 启动系统是个好主意，但许多开发人员和系统管理员并不喜欢 systemd。与其重新讨论人们在 systemd 中遇到的或曾经遇到过的所有所谓的问题，不如带你去看两篇好文章，尽管有些陈旧，但它们涵盖了大多数内容。Linux 内核的创建者 Linus Torvalds 对 systemd 似乎不感兴趣。在 2014 年 ZDNet 的一篇文章《[Linus Torvalds 和其他人对 Linux 上的 systemd 的看法](https://www.zdnet.com/article/linus-torvalds-and-others-on-linuxs-systemd/)》中，Linus 清楚地表达了他的感受。



> 
> “实际上我对 systemd 本身没有任何特别强烈的意见。我对一些核心开发人员有一些问题，我认为他们在对待错误和兼容性方面过于轻率，而且我认为某些设计细节是疯狂的（例如，我不喜欢二进制日志），但这只是细节，不是大问题。”
> 
> 
> 


如果你对 Linus 不太了解的话，我可以告诉你，如果他不喜欢某事，他是非常直言不讳的，很明确，而且相当明确的表示不喜欢。他解决自己对事物不满的方式已经被社会更好地接受了。


2013 年，Poettering 写了一篇很长的博客，他在文章驳斥了[关于 systemd 的迷思](http://0pointer.de/blog/projects/the-biggest-myths.html)，同时对创建 systemd 的一些原因进行了深入的剖析。这是一分很好的读物，我强烈建议你阅读。


### systemd 任务


根据编译过程中使用的选项（不在本系列中介绍），systemd 可以有多达 69 个二进制可执行文件执行以下任务，其中包括：


* `systemd` 程序以 1 号进程（PID 1）运行，并提供使尽可能多服务并行启动的系统启动能力，它额外加快了总体启动时间。它还管理关机顺序。
* `systemctl` 程序提供了服务管理的用户接口。
* 支持 SystemV 和 LSB 启动脚本，以便向后兼容。
* 服务管理和报告提供了比 SystemV 更多的服务状态数据。
* 提供基本的系统配置工具，例如主机名、日期、语言环境、已登录用户的列表，正在运行的容器和虚拟机、系统帐户、运行时目录及设置，用于简易网络配置、网络时间同步、日志转发和名称解析的守护进程。
* 提供套接字管理。
* systemd 定时器提供类似 cron 的高级功能，包括在相对于系统启动、systemd 启动时间、定时器上次启动时间的某个时间点运行脚本。
* 它提供了一个工具来分析定时器规范中使用的日期和时间。
* 能感知分层的文件系统挂载和卸载功能可以更安全地级联挂载的文件系统。
* 允许主动的创建和管理临时文件，包括删除。
* D-Bus 的接口提供了在插入或移除设备时运行脚本的能力。这允许将所有设备（无论是否可插拔）都被视为即插即用，从而大大简化了设备的处理。
* 分析启动环节的工具可用于查找耗时最多的服务。
* 它包括用于存储系统消息的日志以及管理日志的工具。


### 架构


这些以及更多的任务通过许多守护程序、控制程序和配置文件来支持。图 1 显示了许多属于 systemd 的组件。这是一个简化的图，旨在提供概要描述，因此它并不包括所有独立的程序或文件。它也不提供数据流的视角，数据流是如此复杂，因此在本系列文章的背景下没用。


![系统架构](/data/attachment/album/202005/13/085112xl9ukqlulkugszo5.png "systemd architecture")


*图 1：systemd 的架构，作者 Shmuel Csaba Otto Traian (CC BY-SA 3.0)*


如果要完整地讲解 systemd 就需要一本书。你不需要了解图 1 中的 systemd 组件是如何组合在一起的细节。只需了解支持各种 Linux 服务管理以及日志文件和日志处理的程序和组件就够了。但是很明显， systemd 并不是某些批评者所宣称的那样，它是一个单一的怪物。


### 作为 1 号进程的 systemd


systemd 是 1 号进程（PID 1）。它的一些功能，比老的 SystemV3 `init` 要广泛得多，用于管理正在运行的 Linux 主机的许多方面，包括挂载文件系统以及启动和管理 Linux 生产主机所需的系统服务。与启动环节无关的任何 systemd 任务都不在本文讨论范围之内（但本系列后面的一些文章将探讨其中的一些任务）。


首先，systemd 挂载 `/etc/fstab` 所定义的文件系统，包括所有交换文件或分区。此时，它可以访问位于 `/etc` 中的配置文件，包括它自己的配置文件。它使用其配置链接 `/etc/systemd/system/default.target` 来确定将主机引导至哪个状态或目标。`default.target` 文件是指向真实目标文件的符号链接。对于桌面工作站，通常是 `graphical.target`，它相当于 SystemV 中的运行级别 5。对于服务器，默认值更可能是 `multi-user.target`，相当于 SystemV 中的运行级别 3。`emergency.target` 类似于单用户模式。<ruby> 目标 <rt>  target </rt></ruby>和<ruby> 服务 <rt>  service </rt></ruby>是 systemd 的<ruby> 单元 <rt>  unit </rt></ruby>。


下表（图 2）将 systemd 目标与老的 SystemV 启动运行级别进行了比较。systemd 提供 systemd 目标别名以便向后兼容。目标别名允许脚本（以及许多系统管理员）使用 SystemV 命令（如 `init 3`）更改运行级别。当然，SystemV 命令被转发给 systemd 进行解释和执行。




| systemd 目标 | SystemV 运行级别 | 目标别名 | 描述 |
| --- | --- | --- | --- |
| `default.target` |  |  | 此目标总是通过符号连接的方式成为 `multi-user.target` 或 `graphical.target` 的别名。systemd 始终使用 `default.target` 来启动系统。`default.target` 绝不应该设为 `halt.target`，`poweroff.target` 或 `reboot.target` 的别名。 |
| `graphic.target` | 5 | `runlevel5.target` | 带有 GUI 的 `multi-user.target`。 |
|  | 4 | `runlevel4.target` | 未用。在 SystemV 中运行级别 4 与运行级别 3 相同。可以创建并自定义此目标以启动本地服务，而无需更改默认的 `multi-user.target`。 |
| `multi-user.target` | 3 | `runlevel3.target` | 所有服务在运行，但仅有命令行界面（CLI）。 |
|  | 2 | `runlevel2.target` | 多用户，没有 NFS，其它所有非 GUI 服务在运行。 |
| `rescue.target` | 1 | `runlevel1.target` | 基本系统，包括挂载文件系统，运行最基本的服务和主控制台的恢复 shell。 |
| `emergency.target` | S |  | 单用户模式：没有服务运行；不挂载文件系统。这是最基本的工作级别，只有主控制台上运行的一个紧急 Shell 供用户与系统交互。 |
| `halt.target` |  |  | 停止系统而不关闭电源。 |
| `reboot.target` | 6 | `runlevel6.target` | 重启。 |
| `poweroff.target` | 0 | `runlevel0.target` | 停止系统并关闭电源。 |


*图 2：SystemV 运行级别与 systemd 目标和一些目标别名的比较*


每个目标在其配置文件中都描述了一个依赖集。systemd 启动必须的依赖项，这些依赖项是运行 Linux 主机到特定功能级别所需的服务。当目标配置文件中列出的所有依赖项被加载并运行后，系统就在该目标级别运行了。在图 2 中，功能最多的目标位于表的顶部，从顶向下，功能逐步递减。


systemd 还会检查老的 SystemV `init` 目录，以确认是否存在任何启动文件。如果有，systemd 会将它们作为配置文件以启动它们描述的服务。网络服务是一个很好的例子，在 Fedora 中它仍然使用 SystemV 启动文件。


图 3（如下）是直接从启动手册页复制来的。它显示了 systemd 启动期间一般的事件环节以及确保成功启动的基本顺序要求。



```
                                        cryptsetup-pre.target
                                                   |
 (various low-level                                v
     API VFS mounts:                 (various cryptsetup devices...)
  mqueue, configfs,                                |    |
  debugfs, ...)                                    v    |
  |                                  cryptsetup.target  |
  |  (various swap                                 |    |    remote-fs-pre.target
  |   devices...)                                  |    |     |        |
  |    |                                           |    |     |        v
  |    v                       local-fs-pre.target |    |     |  (network file systems)
  |  swap.target                       |           |    v     v                 |
  |    |                               v           |  remote-cryptsetup.target  |
  |    |  (various low-level  (various mounts and  |             |              |
  |    |   services: udevd,    fsck services...)   |             |    remote-fs.target
  |    |   tmpfiles, random            |           |             |             /
  |    |   seed, sysctl, ...)          v           |             |            /
  |    |      |                 local-fs.target    |             |           /
  |    |      |                        |           |             |          /
  \____|______|_______________   ______|___________/             |         /
                              \ /                                |        /
                               v                                 |       /
                        sysinit.target                           |      /
                               |                                 |     /
        ______________________/|\_____________________           |    /
       /              |        |      |               \          |   /
       |              |        |      |               |          |  /
       v              v        |      v               |          | /
  (various       (various      |  (various            |          |/
   timers...)      paths...)   |   sockets...)        |          |
       |              |        |      |               |          |
       v              v        |      v               |          |
 timers.target  paths.target   |  sockets.target      |          |
       |              |        |      |               v          |
       v              \_______ | _____/         rescue.service   |
                              \|/                     |          |
                               v                      v          |
                           basic.target         rescue.target    |
                               |                                 |
                       ________v____________________             |
                      /              |              \            |
                      |              |              |            |
                      v              v              v            |
                  display-    (various system   (various system  |
              manager.service     services        services)      |
                      |         required for        |            |
                      |        graphical UIs)       v            v
                      |              |            multi-user.target
 emergency.service    |              |              |
         |            \_____________ | _____________/
         v                          \|/
 emergency.target                    v
                              graphical.target
```

*图 3: systemd 启动图*


`sysinit.target` 和 `basic.target` 目标可以看作启动过程中的检查点。尽管 systemd 的设计目标之一是并行启动系统服务，但是某些服务和功能目标必须先启动，然后才能启动其它服务和目标。直到该检查点所需的所有服务和目标被满足后才能通过这些检查点。


当 `sysinit.target` 所依赖的所有单元都完成时，就会到达 `sysinit.target`。所有这些单元，包括挂载文件系统、设置交换文件、启动 Udev、设置随机数生成器种子、启动低层服务以及配置安全服务（如果一个或多个文件系统是加密的）都必须被完成，但在 `sysinit.target` 中，这些任务可以并行执行。


`sysinit.target` 启动了系统接近正常运行所需的所有低层服务和单元，它们也是进入 `basic.target` 所需的。


在完成 `sysinit.target` 之后，systemd 会启动实现下一个目标所需的所有单元。`basic.target` 通过启动所有下一目标所需的单元来提供一些额外功能。包括设置为各种可执行程序目录的路径、设置通信套接字和计时器之类。


最后，用户级目标 `multi-user.target` 或 `graphical.target` 被初始化。要满足 `graphical.target` 的依赖必须先达到 `multi-user.target`。图 3 中带下划线的目标是通常的启动目标。当达到这些目标之一时，启动就完成了。如果 `multi-user.target` 是默认设置，那么你应该在控制台上看到文本模式的登录界面。如果 `graphical.target` 是默认设置，那么你应该看到图形的登录界面。你看到的具体的 GUI 登录界面取决于你的默认显示管理器。


引导手册页还描述并提供了引导到初始化 RAM 磁盘和 systemd 关机过程的图。


systemd 还提供了一个工具，该工具列出了完整的启动过程或指定单元的依赖项。单元是一个可控的 systemd 资源实体，其范围可以从特定服务（例如 httpd 或 sshd）到计时器、挂载、套接字等。尝试以下命令并滚动查看结果。



```
systemctl list-dependencies graphical.target
```

注意，这会完全展开使系统进入 `graphical.target` 运行模式所需的顶层目标单元列表。也可以使用 `--all` 选项来展开所有其它单元。



```
systemctl list-dependencies --all graphical.target
```

你可以使用 `less` 命令来搜索诸如 `target`、`slice` 和 `socket` 之类的字符串。


现在尝试下面的方法。



```
systemctl list-dependencies multi-user.target
```

和



```
systemctl list-dependencies rescue.target
```

和



```
systemctl list-dependencies local-fs.target
```

和



```
systemctl list-dependencies dbus.service
```

这个工具帮助我可视化我正用的主机的启动依赖细节。继续花一些时间探索一个或多个 Linux 主机的启动树。但是要小心，因为 systemctl 手册页包含以下注释：



> 
> “请注意，此命令仅列出当前被服务管理器加载到内存的单元。尤其是，此命令根本不适合用于获取特定单元的全部反向依赖关系列表，因为它不会列出被单元声明了但是未加载的依赖项。”
> 
> 
> 


### 结尾语


即使在没有深入研究 systemd 之前，很明显能看出它既强大又复杂。显然，systemd 不是单一、庞大、独体且不可知的二进制文件。相反，它是由许多较小的组件和旨在执行特定任务的子命令组成。


本系列的下一篇文章将更详细地探讨 systemd 的启动，以及 systemd 的配置文件，更改默认的目标以及如何创建简单服务单元。


### 资源


互联网上有大量关于 systemd 的信息，但是很多都很简短、晦涩甚至是带有误导。除了本文提到的资源外，以下网页还提供了有关 systemd 启动的更详细和可靠的信息。


* Fedora 项目有一个很好的实用的 [systemd 指南](https://docs.fedoraproject.org/en-US/quick-docs/understanding-and-administering-systemd/index.html)。它有你需要知道的通过 systemd 来配置、管理和维护 Fedora 主机所需的几乎所有知识。
* Fedora 项目还有一个不错的[速记表](https://fedoraproject.org/wiki/SysVinit_to_Systemd_Cheatsheet)，将老的 SystemV 命令与对比的 systemd 命令相互关联。
* 有关 systemd 的详细技术信息及创建它的原因，请查看 [Freedesktop.org](http://Freedesktop.org) 对 [systemd 描述](http://www.freedesktop.org/wiki/Software/systemd)。
* [Linux.com](http://Linux.com) 的“systemd 的更多乐趣”提供了更高级的 systemd [信息和技巧](https://www.linux.com/training-tutorials/more-systemd-fun-blame-game-and-stopping-services-prejudice/)。


还有针对 Linux 系统管理员的一系列技术性很强的文章，作者是 systemd 的设计师和主要开发者 Lennart Poettering。这些文章是在 2010 年 4 月至 2011 年 9 月之间撰写的，但它们现在和那时一样有用。关于 systemd 及其生态的其它许多好文都基于这些论文。


* [重新思考 1 号进程](http://0pointer.de/blog/projects/systemd.html)
* [systemd 系统管理员篇 I](http://0pointer.de/blog/projects/systemd-for-admins-1.html)
* [systemd 系统管理员篇 II](http://0pointer.de/blog/projects/systemd-for-admins-2.html)
* [systemd 系统管理员篇 III](http://0pointer.de/blog/projects/systemd-for-admins-3.html)
* [systemd 系统管理员篇 IV](http://0pointer.de/blog/projects/systemd-for-admins-4.html)
* [systemd 系统管理员篇 V](http://0pointer.de/blog/projects/three-levels-of-off.html)
* [systemd 系统管理员篇 VI](http://0pointer.de/blog/projects/changing-roots)
* [systemd 系统管理员篇 VII](http://0pointer.de/blog/projects/blame-game.html)
* [systemd 系统管理员篇 VIII](http://0pointer.de/blog/projects/the-new-configuration-files.html)
* [systemd 系统管理员篇 IX](http://0pointer.de/blog/projects/on-etc-sysinit.html)
* [systemd 系统管理员篇 X](http://0pointer.de/blog/projects/instances.html)
* [systemd 系统管理员篇 XI](http://0pointer.de/blog/projects/inetd.html)




---


via: <https://opensource.com/article/20/4/systemd>


作者：[David Both](https://opensource.com/users/dboth) 选题：[lujun9972](https://github.com/lujun9972) 译者：[messon007](https://github.com/messon007) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OK
systemd—yes, all lower-case, even at the beginning of a sentence—is the modern replacement for init and SystemV init scripts. It is also much more.

Like most sysadmins, when I think of the init program and SystemV, I think of Linux startup and shutdown and not really much else, like managing services once they are up and running. Like init, systemd is the mother of all processes, and it is responsible for bringing the Linux host up to a state in which productive work can be done. Some of the functions assumed by systemd, which is far more extensive than the old init program, are to manage many aspects of a running Linux host, including mounting filesystems, managing hardware, handling timers, and starting and managing the system services that are required to have a productive Linux host.

This series of articles, which is based in part on excerpts from my three-volume Linux training course, [ Using and administering Linux: zero to sysadmin](http://www.both.org/?page_id=1183), explores systemd's functions both at startup and beginning after startup finishes.

## Linux boot

The complete process that takes a Linux host from an off state to a running state is complex, but it is open and knowable. Before getting into the details, I'll give a quick overview from when the host hardware is turned on until the system is ready for a user to log in. Most of the time, "the boot process" is discussed as a single entity, but that is not accurate. There are, in fact, three major parts to the full boot and startup process:

**Hardware boot:**Initializes the system hardware**Linux boot:**Loads the Linux kernel and then systemd**Linux startup:**Where systemd prepares the host for productive work

The Linux startup sequence begins after the kernel has loaded either init or systemd, depending upon whether the distribution uses the old or new startup, respectively. The init and systemd programs start and manage all the other processes and are both known as the "mother of all processes" on their respective systems.

It is important to separate the hardware boot from the Linux boot from the Linux startup and to explicitly define the demarcation points between them. Understanding these differences and what part each plays in getting a Linux system to a state where it can be productive makes it possible to manage these processes and better determine where a problem is occurring during what most people refer to as "boot."

The startup process follows the three-step boot process and brings the Linux computer up to an operational state in which it is usable for productive work. The startup process begins when the kernel transfers control of the host to systemd.

## systemd controversy

systemd can evoke a wide range of reactions from sysadmins and others responsible for keeping Linux systems up and running. The fact that systemd is taking over so many tasks in many Linux systems has engendered pushback and discord among certain groups of developers and sysadmins.

SystemV and systemd are two different methods of performing the Linux startup sequence. SystemV start scripts and the init program are the old methods, and systemd using targets is the new method. Although most modern Linux distributions use the newer systemd for startup, shutdown, and process management, there are still some that do not. One reason is that some distribution maintainers and some sysadmins prefer the older SystemV method over the newer systemd.

I think both have advantages.

### Why I prefer SystemV

I prefer SystemV because it is more open. Startup is accomplished using Bash scripts. After the kernel starts the init program, which is a compiled binary, init launches the **rc.sysinit** script, which performs many system initialization tasks. After **rc.sysinit** completes, init launches the **/etc/rc.d/rc** script, which in turn starts the various services defined by the SystemV start scripts in the **/etc/rc.d/rcX.d**, where "X" is the number of the runlevel being started.


Except for the init program itself, all these programs are open and easily knowable scripts. It is possible to read through these scripts and learn exactly what is taking place during the entire startup process, but I don't think many sysadmins actually do that. Each start script is numbered so that it starts its intended service in a specific sequence. Services are started serially, and only one service starts at a time.

systemd, developed by Red Hat's Lennart Poettering and Kay Sievers, is a complex system of large, compiled binary executables that are not understandable without access to the source code. It is open source, so "access to the source code" isn't hard, just less convenient. systemd appears to represent a significant refutation of multiple tenets of the Linux philosophy. As a binary, systemd is not directly open for the sysadmin to view or make easy changes. systemd tries to do everything, such as managing running services, while providing significantly more status information than SystemV. It also manages hardware, processes, and groups of processes, filesystem mounts, and much more. systemd is present in almost every aspect of the modern Linux host, making it the one-stop tool for system management. All of this is a clear violation of the tenets that programs should be small and that each program should do one thing and do it well.

### Why I prefer systemd

I prefer systemd as my startup mechanism because it starts as many services as possible in parallel, depending upon the current stage in the startup process. This speeds the overall startup and gets the host system to a login screen faster than SystemV.

systemd manages almost every aspect of a running Linux system. It can manage running services while providing significantly more status information than SystemV. It also manages hardware, processes and groups of processes, filesystem mounts, and much more. systemd is present in almost every aspect of the modern Linux operating system, making it the one-stop tool for system management. (Does this sound familiar?)

The systemd tools are compiled binaries, but the tool suite is open because all the configuration files are ASCII text files. Startup configuration can be modified through various GUI and command-line tools, as well as adding or modifying various configuration files to suit the needs of the specific local computing environment.

### The real issue

Did you think I could not like both startup systems? I do, and I can work with either one.

In my opinion, the real issue and the root cause of most of the controversy between SystemV and systemd is that there is [no choice](http://www.osnews.com/story/28026/Editorial_Thoughts_on_Systemd_and_the_Freedom_to_Choose) on the sysadmin level. The choice of whether to use SystemV or systemd has already been made by the developers, maintainers, and packagers of the various distributions—but with good reason. Scooping out and replacing an init system, by its extreme, invasive nature, has a lot of consequences that would be hard to tackle outside the distribution design process.

Despite the fact that this choice is made for me, my Linux hosts boot up and work, which is what I usually care the most about. As an end user and even as a sysadmin, my primary concern is whether I can get my work done, work such as writing my books and this article, installing updates, and writing scripts to automate everything. So long as I can do my work, I don't really care about the start sequence used on my distro.

I do care when there is a problem during startup or service management. Regardless of which startup system is used on a host, I know enough to follow the sequence of events to find the failure and fix it.

### Replacing SystemV

There have been previous attempts at replacing SystemV with something a bit more modern. For about two releases, Fedora used a thing called Upstart to replace the aging SystemV, but it did not replace init and provided no changes that I noticed. Because Upstart provided no significant changes to the issues surrounding SystemV, efforts in this direction were quickly dropped in favor of systemd.

Despite the fact that most Linux developers agree that replacing the old SystemV startup is a good idea, many developers and sysadmins dislike systemd for that. Rather than rehash all the so-called issues that people have—or had—with systemd, I will refer you to two good, if somewhat old, articles that should cover most everything. Linus Torvalds, the creator of the Linux kernel, seems disinterested. In a 2014 ZDNet article, * Linus Torvalds and others on Linux's systemd*, Linus is clear about his feelings.

"I don't actually have any particularly strong opinions on systemd itself. I've had issues with some of the core developers that I think are much too cavalier about bugs and compatibility, and I think some of the design details are insane (I dislike the binary logs, for example), but those are details, not big issues."


In case you don't know much about Linus, I can tell you that if he does not like something, he is very outspoken, explicit, and quite clear about that dislike. He has become more socially acceptable in his manner of addressing his dislike about things.

In 2013, Poettering wrote a long blog post in which he debunks the [myths about systemd](http://0pointer.de/blog/projects/the-biggest-myths.html) while providing insight into some of the reasons for creating it. This is a very good read, and I highly recommend it.

## systemd tasks

Depending upon the options used during the compile process (which are not considered in this series), systemd can have as many as 69 binary executables that perform the following tasks, among others:

- The systemd program runs as PID 1 and provides system startup of as many services in parallel as possible, which, as a side effect, speeds overall startup times. It also manages the shutdown sequence.
- The systemctl program provides a user interface for service management.
- Support for SystemV and LSB start scripts is offered for backward compatibility.
- Service management and reporting provide more service status data than SystemV.
- It includes tools for basic system configuration, such as hostname, date, locale, lists of logged-in users, running containers and virtual machines, system accounts, runtime directories and settings, daemons to manage simple network configuration, network time synchronization, log forwarding, and name resolution.
- It offers socket management.
- systemd timers provide advanced cron-like capabilities to include running a script at times relative to system boot, systemd startup, the last time the timer was started, and more.
- It provides a tool to analyze dates and times used in timer specifications.
- Mounting and unmounting of filesystems with hierarchical awareness allows safer cascading of mounted filesystems.
- It enables the positive creation and management of temporary files, including deletion.
- An interface to D-Bus provides the ability to run scripts when devices are plugged in or removed. This allows all devices, whether pluggable or not, to be treated as plug-and-play, which considerably simplifies device handling.
- Its tool to analyze the startup sequence can be used to locate the services that take the most time.
- It includes journals for storing system log messages and tools for managing the journals.

## Architecture

Those tasks and more are supported by a number of daemons, control programs, and configuration files. Figure 1 shows many of the components that belong to systemd. This is a simplified diagram designed to provide a high-level overview, so it does not include all of the individual programs or files. Nor does it provide any insight into data flow, which is so complex that it would be a useless exercise in the context of this series of articles.

![systemd architecture systemd architecture](https://opensource.com/sites/default/files/uploads/systemd-architecture.png)

Fig 1: Architecture of systemd, by Shmuel Csaba Otto Traian (CC BY-SA 3.0)

Fig 1: Architecture of systemd, by Shmuel Csaba Otto Traian (CC BY-SA 3.0)

A full exposition of systemd would take a book on its own. You do not need to understand the details of how the systemd components in Figure 1 fit together; it's enough to know about the programs and components that enable managing various Linux services and deal with log files and journals. But it's clear that systemd is not the monolithic monstrosity it is purported to be by some of its critics.

## systemd as PID 1

systemd is PID 1. Some of its functions, which are far more extensive than the old SystemV3 init program, are to manage many aspects of a running Linux host, including mounting filesystems and starting and managing system services required to have a productive Linux host. Any of systemd's tasks that are not related to the startup sequence are outside the scope of this article (but some will be explored later in this series).

First, systemd mounts the filesystems defined by **/etc/fstab**, including any swap files or partitions. At this point, it can access the configuration files located in **/etc**, including its own. It uses its configuration link, **/etc/systemd/system/default.target**, to determine which state or target it should boot the host into. The **default.target** file is a symbolic link to the true target file. For a desktop workstation, this is typically going to be the **graphical.target**, which is equivalent to runlevel 5 in SystemV. For a server, the default is more likely to be the **multi-user.target**, which is like runlevel 3 in SystemV. The **emergency.target** is similar to single-user mode. Targets and services are systemd units.

The table below (Figure 2) compares the systemd targets with the old SystemV startup runlevels. systemd provides the systemd target aliases for backward compatibility. The target aliases allow scripts—and many sysadmins—to use SystemV commands like **init 3** to change runlevels. Of course, the SystemV commands are forwarded to systemd for interpretation and execution.

systemd targets |
SystemV runlevel |
target aliases |
Description |

default.target | This target is always aliased with a symbolic link to either multi-user.target or graphical.target. systemd always uses the default.target to start the system. The default.target should never be aliased to halt.target, poweroff.target, or reboot.target. |
||

graphical.target | 5 | runlevel5.target | Multi-user.target with a GUI |

4 | runlevel4.target | Unused. Runlevel 4 was identical to runlevel 3 in the SystemV world. This target could be created and customized to start local services without changing the default multi-user.target. |
|

multi-user.target | 3 | runlevel3.target | All services running, but command-line interface (CLI) only |

2 | runlevel2.target | Multi-user, without NFS, but all other non-GUI services running | |

rescue.target | 1 | runlevel1.target | A basic system, including mounting the filesystems with only the most basic services running and a rescue shell on the main console |

emergency.target | S | Single-user mode—no services are running; filesystems are not mounted. This is the most basic level of operation with only an emergency shell running on the main console for the user to interact with the system. | |

halt.target | Halts the system without powering it down | ||

reboot.target | 6 | runlevel6.target | Reboot |

poweroff.target | 0 | runlevel0.target | Halts the system and turns the power off |


Fig. 2: Comparison of SystemV runlevels with systemd targets and some target aliases

Each target has a set of dependencies described in its configuration file. systemd starts the required dependencies, which are the services required to run the Linux host at a specific level of functionality. When all the dependencies listed in the target configuration files are loaded and running, the system is running at that target level. In Figure 2, the targets with the most functionality are at the top of the table, with functionality declining towards the bottom of the table.

systemd also looks at the legacy SystemV init directories to see if any startup files exist there. If so, systemd uses them as configuration files to start the services described by the files. The deprecated network service is a good example of one that still uses SystemV startup files in Fedora.

Figure 3 (below) is copied directly from the bootup man page. It shows a map of the general sequence of events during systemd startup and the basic ordering requirements to ensure a successful startup.

```
cryptsetup-pre.target
|
(various low-level v
API VFS mounts: (various cryptsetup devices...)
mqueue, configfs, | |
debugfs, ...) v |
| cryptsetup.target |
| (various swap | | remote-fs-pre.target
| devices...) | | | |
| | | | | v
| v local-fs-pre.target | | | (network file systems)
| swap.target | | v v |
| | v | remote-cryptsetup.target |
| | (various low-level (various mounts and | | |
| | services: udevd, fsck services...) | | remote-fs.target
| | tmpfiles, random | | | /
| | seed, sysctl, ...) v | | /
| | | local-fs.target | | /
| | | | | | /
\____|______|_______________ ______|___________/ | /
\ / | /
v | /
sysinit.target | /
| | /
______________________/|\_____________________ | /
/ | | | \ | /
| | | | | | /
v v | v | | /
(various (various | (various | |/
timers...) paths...) | sockets...) | |
| | | | | |
v v | v | |
timers.target paths.target | sockets.target | |
| | | | v |
v \_______ | _____/ rescue.service |
\|/ | |
v v |
basic.target rescue.target |
| |
________v____________________ |
/ | \ |
| | | |
v v v |
display- (various system (various system |
manager.service services services) |
| required for | |
| graphical UIs) v v
| | multi-user.target
emergency.service | | |
| \_____________ | _____________/
v \|/
emergency.target v
graphical.target
```


Fig 3: The systemd startup map

The **sysinit.target** and **basic.target** targets can be considered checkpoints in the startup process. Although one of systemd's design goals is to start system services in parallel, certain services and functional targets must be started before other services and targets can start. These checkpoints cannot be passed until all of the services and targets required by that checkpoint are fulfilled.

The **sysinit.target** is reached when all of the units it depends on are completed. All of those units, mounting filesystems, setting up swap files, starting udev, setting the random generator seed, initiating low-level services, and setting up cryptographic services (if one or more filesystems are encrypted), must be completed but, within the **sysinit.target**, those tasks can be performed in parallel.

The **sysinit.target** starts up all of the low-level services and units required for the system to be marginally functional and that are required to enable moving onto the **basic.target**.

After the **sysinit.target** is fulfilled, systemd then starts all the units required to fulfill the next target. The basic target provides some additional functionality by starting units that are required for all of the next targets. These include setting up things like paths to various executable directories, communication sockets, and timers.

Finally, the user-level targets, **multi-user.target** or **graphical.target**, can be initialized. The **multi-user.target** must be reached before the graphical target dependencies can be met. The underlined targets in Figure 3 are the usual startup targets. When one of these targets is reached, startup has completed. If the **multi-user.target** is the default, then you should see a text-mode login on the console. If **graphical.target** is the default, then you should see a graphical login; the specific GUI login screen you see depends on your default display manager.

The bootup man page also describes and provides maps of the boot into the initial RAM disk and the systemd shutdown process.

systemd also provides a tool that lists dependencies of a complete startup or for a specified unit. A unit is a controllable systemd resource entity that can range from a specific service, such as httpd or sshd, to timers, mounts, sockets, and more. Try the following command and scroll through the results.

`systemctl list-dependencies graphical.target`


Notice that this fully expands the top-level target units list required to bring the system up to the graphical target run mode. Use the **--all** option to expand all of the other units as well.

`systemctl list-dependencies --all graphical.target`


You can search for strings such as "target," "slice," and "socket" using the search tools of the **less** command.

So now, try the following.

`systemctl list-dependencies multi-user.target`


and

`systemctl list-dependencies rescue.target`


and

`systemctl list-dependencies local-fs.target`


and

`systemctl list-dependencies dbus.service`


This tool helps me visualize the specifics of the startup dependencies for the host I am working on. Go ahead and spend some time exploring the startup tree for one or more of your Linux hosts. But be careful because the systemctl man page contains this note:


"Note that this command only lists units currently loaded into memory by the service manager. In particular, this command is not suitable to get a comprehensive list at all reverse dependencies on a specific unit, as it won't list the dependencies declared by units currently not loaded."

## Final thoughts

Even before getting very deep into systemd, it's obvious that it is both powerful and complex. It is also apparent that systemd is not a single, huge, monolithic, and unknowable binary file. Rather, it is composed of a number of smaller components and subcommands that are designed to perform specific tasks.

The next article in this series will explore systemd startup in more detail, as well as systemd configuration files, changing the default target, and how to create a simple service unit.

## Resources

There is a great deal of information about systemd available on the internet, but much is terse, obtuse, or even misleading. In addition to the resources mentioned in this article, the following webpages offer more detailed and reliable information about systemd startup.

- The Fedora Project has a good, practical
[guide](https://docs.fedoraproject.org/en-US/quick-docs/understanding-and-administering-systemd/index.html)[to systemd](https://docs.fedoraproject.org/en-US/quick-docs/understanding-and-administering-systemd/index.html). It has pretty much everything you need to know in order to configure, manage, and maintain a Fedora computer using systemd. - The Fedora Project also has a good
[cheat sheet](https://fedoraproject.org/wiki/SysVinit_to_Systemd_Cheatsheet)that cross-references the old SystemV commands to comparable systemd ones. - For detailed technical information about systemd and the reasons for creating it, check out
[Freedesktop.org](http://Freedesktop.org)'s[description of systemd](http://www.freedesktop.org/wiki/Software/systemd). [Linux.com](http://Linux.com)'s "More systemd fun" offers more advanced systemd[information and tips](https://www.linux.com/training-tutorials/more-systemd-fun-blame-game-and-stopping-services-prejudice/).

There is also a series of deeply technical articles for Linux sysadmins by Lennart Poettering, the designer and primary developer of systemd. These articles were written between April 2010 and September 2011, but they are just as relevant now as they were then. Much of everything else good that has been written about systemd and its ecosystem is based on these papers.

[Rethinking PID 1](http://0pointer.de/blog/projects/systemd.html)[systemd for Administrators, Part I](http://0pointer.de/blog/projects/systemd-for-admins-1.html)[systemd for Administrators, Part II](http://0pointer.de/blog/projects/systemd-for-admins-2.html)[systemd for Administrators, Part III](http://0pointer.de/blog/projects/systemd-for-admins-3.html)[systemd for Administrators, Part IV](http://0pointer.de/blog/projects/systemd-for-admins-4.html)[systemd for Administrators, Part V](http://0pointer.de/blog/projects/three-levels-of-off.html)[systemd for Administrators, Part VI](http://0pointer.de/blog/projects/changing-roots)[systemd for Administrators, Part VII](http://0pointer.de/blog/projects/blame-game.html)[systemd for Administrators, Part VIII](http://0pointer.de/blog/projects/the-new-configuration-files.html)[systemd for Administrators, Part IX](http://0pointer.de/blog/projects/on-etc-sysinit.html)[systemd for Administrators, Part X](http://0pointer.de/blog/projects/instances.html)[systemd for Administrators, Part XI](http://0pointer.de/blog/projects/inetd.html)

## 21 Comments