本文改编自: Using the systemctl command to manage systemd units

单元(unit)是 systemd 一切功能的基础。

本文将详细地介绍 systemd 单元以及如何使用 systemctl 命令来探索和管理单元。我还将解释如何停止和禁用单元以及如何创建一个新的 systemd 挂载单元来挂载新的文件系统并使其在启动期间启动。

准备

本文中的所有实验都应以 root 用户身份进行(除非另有说明)。一些简单地列出各种 systemd 单元的命令可以由非 root 用户执行,但进行更改的命令则不能。确保仅在非生产主机或虚拟机 (VM) 上进行所有这些实验。

这些实验其中一些命令需要 sysstat 包,所以在继续之前安装它。对于 Fedora 和其他基于 Red Hat 的发行版,您可以使用以下命令安装 sysstat:

1
# dnf -y install sysstat

对于 Arch Linux 以及基于 Arch Linux 的发行部则可以使用一下命令安装 sysstat:

1
# pacman -S sysstat

sysstat 包安装了多个可用于确定问题的统计工具。一种是系统活动报告 (SAR),它定期(默认情况下每 10 分钟)记录许多系统性能数据点。 sysstat 包安装了两个 systemd 计时器,而不是在后台作为守护程序运行。一个计时器每 10 分钟运行一次以收集数据,另一个计时器每天运行一次以汇总每日数据。在本文中,我将简要介绍这些计时器,但在以后的文章中将解释如何创建计时器。

系统套件

事实上,systemd 不仅仅是一个程序。它是一套大型程序,所有这些程序都旨在协同工作以管理正在运行的 Linux 系统的几乎所有方面。对 systemd 的完整阐述本身就需要一本书。我们大多数人不需要了解有关 systemd 的所有组件如何组合在一起的所有细节,因此我将重点介绍使您能够管理各种 Linux 服务以及处理日志文件和日志的程序和组件。

实用结构

systemd 的结构——在它的可执行文件之外——包含在它的许多配置文件中。尽管这些文件具有不同的名称和标识符扩展名,但它们都被称为“单元”文件。单元是 systemd 一切功能的基础。

单元文件是 ASCII 纯文本文件,系统管理员可以访问并创建或修改这些文件。有多种单元文件类型,每种类型都有自己的手册页。表 1 按文件扩展名列出了其中一些单元文件类型,并对其进行了简短描述。

表 1:一些 systemd 单元文件类型
systemd 单元 描述
.automount .automount 单元用于在启动期间实现按需(即插即用)加载以及文件系统单元的并行安装。
.device .device 单元文件定义了在 /dev/ 目录中向系统管理员公开的硬件和虚拟设备。并非所有设备都有单元文件;通常,块设备,如硬盘驱动器、网络设备和其他一些设备都有单元文件。
.mount .mount 单元定义了 Linux 文件系统目录结构上的一个挂载点。
.scope .scope 单元定义和管理一组系统进程。该单元不是使用单元文件配置的,而是以编程方式创建的。根据 systemd.scope 手册页描述道:scope 单元的主要目的是对系统服务的工作进程进行分组以组织和管理系统资源。
.service .service 单元文件定义了由 systemd 管理的进程。其中包括通用 Unix 打印系统(CUPS)、iptables、多逻辑卷管理 (LVM) 服务、NetworkManager 等服务。
.slice .slice 单元定义了一个“slice”,它是与一组进程相关的系统资源的概念划分。您可以将所有系统资源视为一个馅饼,并将此资源子集视为该馅饼的“切片”。
.socket .socket 单元定义进程间通信套接字,例如网络套接字。
.swap .swap 单元定义交换设备或文件。
.target .target 单元定义了定义启动同步点、运行级别和服务的单元文件组。target 单元定义了为了成功启动而必须处于活动状态的服务和其他单元。
.timer .timer 单元定义了可以在指定时间启动程序执行的定时器。

systemctl

systemd 提供了 systemctl 命令,用于启动和停止服务,配置它们在系统启动时启动(或不启动),并监控正在运行的服务的当前状态。

在作为 root 用户的终端会话中,确保 root 的主目录 ( ~ ) 是当前工作目录。要开始以各种方式查看单元,请列出所有已加载和活动的 systemd 单元。 systemctl 通过 less 寻呼机自动通过管道传输其 stdout 数据流,因此只需要直接使用 systemctl 命令就可以列出所有已加载和活动的 systemd 单元:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# systemctl
---
UNIT LOAD ACTIVE SUB DESCRIPTION
proc-sys-fs-binfmt_misc.automount loaded active waiting Arbitrary Executable File Formats File System Automount Point
sys-devices-platform-serial8250-tty-ttyS0.device loaded active plugged /sys/devices/platform/serial8250/tty/ttyS0
sys-devices-platform-serial8250-tty-ttyS1.device loaded active plugged /sys/devices/platform/serial8250/tty/ttyS1
sys-devices-platform-serial8250-tty-ttyS10.device loaded active plugged /sys/devices/platform/serial8250/tty/ttyS10
sys-devices-platform-serial8250-tty-ttyS11.device loaded active plugged /sys/devices/platform/serial8250/tty/ttyS11
sys-devices-platform-serial8250-tty-ttyS12.device loaded active plugged /sys/devices/platform/serial8250/tty/ttyS12
sys-devices-virtual-misc-rfkill.device loaded active plugged /sys/devices/virtual/misc/rfkill
sys-module-configfs.device loaded active plugged /sys/module/configfs
sys-module-fuse.device loaded active plugged /sys/module/fuse
sys-subsystem-net-devices-enp0s3.device loaded active plugged 82540EM Gigabit Ethernet Controller (PRO/1000 MT Desktop Adapter)
sys-subsystem-net-devices-enp0s8.device loaded active plugged 82540EM Gigabit Ethernet Controller (PRO/1000 MT Desktop Adapter)
-.mount loaded active mounted Root Mount
dev-hugepages.mount loaded active mounted Huge Pages File System
dev-mqueue.mount loaded active mounted POSIX Message Queue File System
run-credentials-systemd\x2dsysusers.service.mount loaded active mounted /run/credentials/systemd-sysusers.service
run-user-1000.mount loaded active mounted /run/user/1000
srv-share.mount loaded active mounted /srv/share
sys-fs-fuse-connections.mount loaded active mounted FUSE Control File System
sys-kernel-config.mount loaded active mounted Kernel Configuration File System
sys-kernel-debug.mount loaded active mounted Kernel Debug File System
sys-kernel-tracing.mount loaded active mounted Kernel Trace File System
tmp.mount loaded active mounted Temporary Directory /tmp
systemd-ask-password-console.path loaded active waiting Dispatch Password Requests to Console Directory Watch
systemd-ask-password-wall.path loaded active waiting Forward Password Requests to Wall Directory Watch
init.scope loaded active running System and Service Manager
<snip – removed lots of lines of data from here>

LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
123 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.

当您在终端会话中滚动浏览数据时,寻找一些特定的东西。第一部分列出了诸如硬盘驱动器、声卡、网络接口卡和 TTY 设备等设备。另一部分显示文件系统挂载点。其他部分包括各种服务以及所有已加载和活动目标的列表。

输出底部的 sysstat 计时器用于收集和生成 SAR 的每日系统活动摘要。 SAR 是一个非常有用的解决问题的工具。

在最底部附近,三行描述了状态(加载、活动和子)的含义。按 q 退出该页面。

使用以下命令(如上面输出的最后一行中所建议的那样)查看已安装的所有单元,无论它们是否已加载。systemctl 程序具有出色的自动补全功能,可以轻松输入复杂的命令,而无需记住所有选项:

1
systemctl list-unit-files

您可以看到某些单位被禁用。 systemctl 手册页中的表 1 列出并提供了您可能在此列表中看到的条目的简短描述。使用 -t(类型)选项仅查看 .timer 单元:

1
2
3
4
5
6
7
8
9
10
11
12
# systemctl list-unit-files -t timer
---
UNIT FILE STATE VENDOR PRESET
btrfs-scrub@.timer disabled disabled
e2scrub_all.timer disabled disabled
fstrim.timer disabled disabled
mdadm-last-resort@.timer static -
shadow.timer static -
systemd-tmpfiles-clean.timer static -
xfs_scrub_all.timer disabled disabled

7 unit files listed.

你可以用这个替代命令做同样的事情,它提供了更多的细节:

1
2
3
4
5
6
7
8
# systemctl list-timers
---
NEXT LEFT LAST PASSED UNIT ACTIVATES
Wed 2021-11-10 00:00:00 UTC 14h left Tue 2021-11-09 08:40:46 UTC 1h 8min ago shadow.timer shadow.service
Wed 2021-11-10 09:03:15 UTC 23h left Tue 2021-11-09 09:03:15 UTC 46min ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service

2 timers listed.
Pass --all to see loaded but inactive timers, too.

虽然没有选项可以做 systemctl list-mounts,但是可以列出挂载点单元文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# systemctl list-unit-files -t mount
---
UNIT FILE STATE
-.mount generated
boot.mount generated
dev-hugepages.mount static
dev-mqueue.mount static
home.mount generated
proc-fs-nfsd.mount static
proc-sys-fs-binfmt_misc.mount disabled
run-vmblock\x2dfuse.mount disabled
sys-fs-fuse-connections.mount static
sys-kernel-config.mount static
sys-kernel-debug.mount static
tmp.mount generated
usr.mount generated
var-lib-nfs-rpc_pipefs.mount static
var.mount generated

15 unit files listed.

这个数据流中的 STATE 列很有趣,需要一些解释。 “generated”状态表示安装单元是在启动期间使用 /etc/fstab 中的信息即时生成的。生成这些挂载单元的程序是 /lib/systemd/system-generators/systemd-fstab-generator,以及生成许多其他单元类型的其他工具。 “static”挂载单元用于 /proc 和 /sys 等文件系统,这些文件位于 /usr/lib/systemd/system 目录中。

现在,看看服务单位。此命令将显示主机上安装的所有服务,无论它们是否处于活动状态:

1
# systemctl --all -t service

单元文件没有文件扩展名(例如 .unit)来帮助识别它们,因此您可以概括为大多数属于 systemd 的配置文件单一类型的单元文件。剩下的几个文件主要是位于 /etc/systemd 中的 .conf 文件。

单元文件存储在 /usr/lib/systemd 目录及其子目录中,而 /etc/systemd/ 目录及其子目录包含指向该主机本地配置所需的单元文件的符号链接。

要探索这一点,请将 /etc/systemd 设为工作目录并列出其内容。然后将 /etc/systemd/system 设为工作目录并列出其内容,并列出至少几个当前工作目录子目录的内容。

查看 default.target 文件,它决定了系统将引导到哪个运行级别目标。花几分钟检查 /etc/systemd/system/default.target 文件的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# cat default.target
---
# SPDX-License-Identifier: LGPL-2.1+
#
# 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=Graphical Interface
Documentation=man:systemd.special(7)
Requires=multi-user.target
Wants=display-manager.service
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target display-manager.service
AllowIsolate=yes

部分发行版没有默认的 /etc/systemd/system/default.target 文件。

请注意,这需要(Requires) multi-user.target,如果 multi-user.target 尚未启动并运行,则 graphics.target 无法启动。除此之外它还“Wants” display-manager.service 单元。不过与“Requires”不同,即使“Wants”没有被满足,也可使单元成功启动。如果无法满足“Wants”,则 systemd 将忽略它,而目标的其余部分将不管。

/etc/systemd/system 中的子目录是各种目标的需求列表。花几分钟时间浏览 /etc/systemd/system/graphical.target.wants 目录中的文件及其内容。

systemd.unit 手册页包含很多关于单元文件、它们的结构、它们可以划分的部分以及可以使用的选项的很好的信息。它还列出了许多单元类型,所有这些都有自己的手册页。如果你想理解一个单元文件,这将是一个很好的起点。

服务单元

Fedora 安装通常会安装和启用特定主机正常运行不需要的服务。相反,有时它不包括需要安装、启用和启动的服务。 Linux 主机不需要按预期运行的服务,但已安装并可能正在运行的服务存在安全风险,至少应停止和禁用,最好应卸载。

systemctl 命令用于管理 systemd 单元,包括服务、目标、挂载等。仔细查看服务列表以定位永远不会使用的服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# systemctl --all -t service
---
UNIT LOAD ACTIVE SUB DESCRIPTION
<snip>
chronyd.service loaded active running NTP client/server
crond.service loaded active running Command Scheduler
cups.service loaded active running CUPS Scheduler
dbus-daemon.service loaded active running D-Bus System Message Bus
<snip>
● ip6tables.service not-found inactive dead ip6tables.service
● ipset.service not-found inactive dead ipset.service
● iptables.service not-found inactive dead iptables.service
<snip>
firewalld.service loaded active running firewalld - dynamic firewall daemon
<snip>
● ntpd.service not-found inactive dead ntpd.service
● ntpdate.service not-found inactive dead ntpdate.service
pcscd.service loaded active running PC/SC Smart Card Daemon

我已经删除了命令的大部分输出以节省空间。显示“loaded”、“active”和“running”的服务很明显是已加载并正在活动的服务。 而“not-found”服务是 systemd 知道但未安装在 Linux 主机上的服务。如果要运行这些服务,则必须安装包含它们的软件包。

注意 pcscd.service 单元。这是 PC/SC 智能卡守护进程。它的功能是与智能卡读卡器通信。许多 Linux 主机(包括 VM)不需要此读取器,也不需要加载并占用内存和 CPU 资源的服务。您可以停止此服务并禁用它,这样它就不会在下次启动时重新启动。首先,检查它的状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
# systemctl status pcscd.service
---
● pcscd.service - PC/SC Smart Card Daemon
Loaded: loaded (/usr/lib/systemd/system/pcscd.service; indirect; vendor preset: disabled)
Active: active (running) since Fri 2019-05-10 11:28:42 EDT; 3 days ago
Docs: man:pcscd(8)
Main PID: 24706 (pcscd)
Tasks: 6 (limit: 4694)
Memory: 1.6M
CGroup: /system.slice/pcscd.service
└─24706 /usr/sbin/pcscd --foreground --auto-exit

May 10 11:28:42 testvm1 systemd[1]: Started PC/SC Smart Card Daemon.

相比于 SystemV 仅报告服务是否正在运行,systemd 提供了更多的附加信息。请注意,这条命令也可以不打出 .service 这个后缀名,systemd 会自动识别出 pcscd 的单元类型。现在停止并禁用该服务,然后重新检查其状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# systemctl stop pcscd ; systemctl disable pcscd
---
Warning: Stopping pcscd.service, but it can still be activated by:
pcscd.socket
Removed /etc/systemd/system/sockets.target.wants/pcscd.socket.

# systemctl status pcscd
---
● pcscd.service - PC/SC Smart Card Daemon
Loaded: loaded (/usr/lib/systemd/system/pcscd.service; indirect; vendor preset: disabled)
Active: failed (Result: exit-code) since Mon 2019-05-13 15:23:15 EDT; 48s ago
Docs: man:pcscd(8)
Main PID: 24706 (code=exited, status=1/FAILURE)

May 10 11:28:42 testvm1 systemd[1]: Started PC/SC Smart Card Daemon.
May 13 15:23:15 testvm1 systemd[1]: Stopping PC/SC Smart Card Daemon...
May 13 15:23:15 testvm1 systemd[1]: pcscd.service: Main process exited, code=exited, status=1/FAIL>
May 13 15:23:15 testvm1 systemd[1]: pcscd.service: Failed with result 'exit-code'.
May 13 15:23:15 testvm1 systemd[1]: Stopped PC/SC Smart Card Daemon.

大多数服务的简短日志条目显示可防止必须搜索各种日志文件来定位此类信息。如果你要检查系统运行级别 .target 的状态需要打出“.target”这个后缀名以指定单元类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# systemctl status multi-user.target
---
● multi-user.target - Multi-User System
Loaded: loaded (/usr/lib/systemd/system/multi-user.target; static; vendor preset: disabled)
Active: active since Thu 2019-05-09 13:27:22 EDT; 4 days ago
Docs: man:systemd.special(7)

May 09 13:27:22 testvm1 systemd[1]: Reached target Multi-User System.

# systemctl status graphical.target
---
● graphical.target - Graphical Interface
Loaded: loaded (/usr/lib/systemd/system/graphical.target; indirect; vendor preset: disabled)
Active: active since Thu 2019-05-09 13:27:22 EDT; 4 days ago
Docs: man:systemd.special(7)

May 09 13:27:22 testvm1 systemd[1]: Reached target Graphical Interface.

# systemctl status default.target
---
● graphical.target - Graphical Interface
Loaded: loaded (/usr/lib/systemd/system/graphical.target; indirect; vendor preset: disabled)
Active: active since Thu 2019-05-09 13:27:22 EDT; 4 days ago
Docs: man:systemd.special(7)

May 09 13:27:22 testvm1 systemd[1]: Reached target Graphical Interface.

默认 target 是 graphical target。可以通过这种方式检查任何单元的状态。

以旧方式挂载

挂载单元定义了在指定挂载点上挂载文件系统所需的所有参数。 systemd 可以比使用 /etc/fstab 文件系统配置文件更灵活地管理挂载单元。尽管如此,systemd 仍然使用 /etc/fstab 文件进行文件系统配置和挂载。 systemd 使用 systemd-fstab-generator 工具从 fstab 文件中的数据创建临时挂载单元。

我将创建一个新的文件系统和一个 systemd 挂载单元来挂载它。如果你的测试系统上有一些可用的磁盘空间,你可以和我一起做。

请注意,卷组和逻辑卷名称在您的测试系统上可能不同。请务必使用与您的系统相关的名称。

您需要创建一个分区或逻辑卷,然后在其上创建 EXT4 文件系统。将标签添加到文件系统 TestFS,并为挂载点 /TestFS 创建一个目录。

要自己尝试此操作,请首先验证卷组上是否有可用空间。这是我的 VM 上的样子,我在卷组上有一些可用空间来创建新的逻辑卷:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# lsblk
---
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 120G 0 disk
├─sda1 8:1 0 4G 0 part /boot
└─sda2 8:2 0 116G 0 part
├─VG01-root 253:0 0 5G 0 lvm /
├─VG01-swap 253:1 0 8G 0 lvm [SWAP]
├─VG01-usr 253:2 0 30G 0 lvm /usr
├─VG01-home 253:3 0 20G 0 lvm /home
├─VG01-var 253:4 0 20G 0 lvm /var
└─VG01-tmp 253:5 0 10G 0 lvm /tmp
sr0 11:0 1 1024M 0 rom

# vgs
---
VG PV LV SN Attr VSize VFree
VG01 1 6 0 wz--n- <116.00g <23.00g

然后在 VG01 上创建一个名为 TestFS 的新卷。它不需要很大; 1GB就好了。然后创建一个文件系统,添加文件系统标签,并创建挂载点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# lvcreate -L 1G -n TestFS VG01
---
Logical volume "TestFS" created.

# mkfs -t ext4 /dev/mapper/VG01-TestFS
---
mke2fs 1.45.3 (14-Jul-2019)
Creating filesystem with 262144 4k blocks and 65536 inodes
Filesystem UUID: 8718fba9-419f-4915-ab2d-8edf811b5d23
Superblock backups stored on blocks:
32768, 98304, 163840, 229376

Allocating group tables: done
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done

# e2label /dev/mapper/VG01-TestFS TestFS
---

# mkdir /TestFS
---

然后,挂载新的文件系统:

1
2
3
# mount /TestFS/
---
mount: /TestFS/: can't find in /etc/fstab.

这将不起作用,因为您在 /etc/fstab 中没有这一项。即使没有 /etc/fstab 中的条目,您也可以使用设备名称(如 /dev 中所示)和挂载点挂载新文件系统。以这种方式挂载比以前更简单——它过去需要文件系统类型作为参数。 mount 命令现在足够智能,可以检测文件系统类型并相应地挂载它。

再试一次:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# mount /dev/mapper/VG01-TestFS /TestFS/
---

# lsblk
---
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 120G 0 disk
├─sda1 8:1 0 4G 0 part /boot
└─sda2 8:2 0 116G 0 part
├─VG01-root 253:0 0 5G 0 lvm /
├─VG01-swap 253:1 0 8G 0 lvm [SWAP]
├─VG01-usr 253:2 0 30G 0 lvm /usr
├─VG01-home 253:3 0 20G 0 lvm /home
├─VG01-var 253:4 0 20G 0 lvm /var
├─VG01-tmp 253:5 0 10G 0 lvm /tmp
└─VG01-TestFS 253:6 0 1G 0 lvm /TestFS
sr0 11:0 1 1024M 0 rom

现在新的文件系统安装在正确的位置。列出挂载单元文件:

1
# systemctl list-unit-files -t mount

此命令不显示 /TestFS 文件系统的文件,因为它不存在文件。命令 systemctl status TestFS.mount 也不显示有关新文件系统的任何信息。您可以通过 systemctl status 命令使用通配符进行尝试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# systemctl status *mount
---
● usr.mount - /usr
Loaded: loaded (/etc/fstab; generated)
Active: active (mounted)
Where: /usr
What: /dev/mapper/VG01-usr
Docs: man:fstab(5)
man:systemd-fstab-generator(8)

<SNIP>
● TestFS.mount - /TestFS
Loaded: loaded (/proc/self/mountinfo)
Active: active (mounted) since Fri 2020-04-17 16:02:26 EDT; 1min 18s ago
Where: /TestFS
What: /dev/mapper/VG01-TestFS

● run-user-0.mount - /run/user/0
Loaded: loaded (/proc/self/mountinfo)
Active: active (mounted) since Thu 2020-04-16 08:52:29 EDT; 1 day 5h ago
Where: /run/user/0
What: tmpfs

● var.mount - /var
Loaded: loaded (/etc/fstab; generated)
Active: active (mounted) since Thu 2020-04-16 12:51:34 EDT; 1 day 1h ago
Where: /var
What: /dev/mapper/VG01-var
Docs: man:fstab(5)
man:systemd-fstab-generator(8)
Tasks: 0 (limit: 19166)
Memory: 212.0K
CPU: 5ms
CGroup: /system.slice/var.mount

这个命令提供了一些关于系统挂载的非常有趣的信息,并且你的新文件系统会出现。 /var 和 /usr 文件系统被识别为从 /etc/fstab 生成,而您的新文件系统只是表明它已加载并提供信息文件在 /proc/self/mountinfo 文件中的位置。

接下来,自动化此安装。首先,通过在 /etc/fstab 中添加一个条目以老式的方式来完成。稍后,我将向您展示如何以新方式进行操作,这将教您如何创建单元并将它们集成到启动序列中。

卸载 /TestFS 并将以下行添加到 /etc/fstab 文件中:

1
/dev/mapper/VG01-TestFS  /TestFS       ext4    defaults        1 2

现在,使用更简单的 mount 命令挂载文件系统并再次列出挂载单元:

1
2
3
4
5
6
7
8
9
10
11
12
# mount /TestFS
---

# systemctl status *mount
---
<SNIP>
● TestFS.mount - /TestFS
Loaded: loaded (/proc/self/mountinfo)
Active: active (mounted) since Fri 2020-04-17 16:26:44 EDT; 1min 14s ago
Where: /TestFS
What: /dev/mapper/VG01-TestFS
<SNIP>

这不会更改此挂载的信息,因为文件系统是手动挂载的。重新启动操作系统。并再次运行命令,这次指定 TestFS.mount 而不是使用通配符。此挂载的结果现在与在启动时挂载的结果一致:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# systemctl status TestFS.mount
---
● TestFS.mount - /TestFS
Loaded: loaded (/etc/fstab; generated)
Active: active (mounted) since Fri 2020-04-17 16:30:21 EDT; 1min 38s ago
Where: /TestFS
What: /dev/mapper/VG01-TestFS
Docs: man:fstab(5)
man:systemd-fstab-generator(8)
Tasks: 0 (limit: 19166)
Memory: 72.0K
CPU: 6ms
CGroup: /system.slice/TestFS.mount

Apr 17 16:30:21 testvm1 systemd[1]: Mounting /TestFS...
Apr 17 16:30:21 testvm1 systemd[1]: Mounted /TestFS.

创建挂载单元

挂载单元可以使用传统的 /etc/fstab 文件或 systemd 单元进行配置。 Fedora 使用 fstab 文件,因为它是在安装过程中创建的。但是,systemd 使用 systemd-fstab-generator 程序将 fstab 文件转换为 fstab 文件中每个条目的 systemd 单元。既然您知道可以使用 systemd .mount 单元文件进行文件系统挂载,请通过为此文件系统创建挂载单元来尝试一下。

首先,卸载 /TestFS。编辑 /etc/fstab 文件并删除或注释掉 TestFS 行。现在,在 /etc/systemd/system 目录中创建一个名为 TestFS.mount 的新文件。编辑它以包含下面的配置数据。单元文件名和挂载点名称必须一致,否则挂载失败:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# This mount unit is for the TestFS filesystem
# By David Both
# Licensed under GPL V2
# This file should be located in the /etc/systemd/system directory

[Unit]
Description=TestFS Mount

[Mount]
What=/dev/mapper/VG01-TestFS
Where=/TestFS
Type=ext4
Options=defaults

[Install]
WantedBy=multi-user.target

[Unit] 部分中的 Description 行适用于我们操作者,它提供了当您使用 systemctl -t mount 列出挂载单元时显示的名称。此文件的 [Mount] 部分中的数据包含的数据基本上与 fstab 文件中的数据相同。

现在启用安装单元:

1
2
3
# systemctl enable TestFS.mount
---
Created symlink /etc/systemd/system/multi-user.target.wants/TestFS.mount → /etc/systemd/system/TestFS.mount.

这将在 /etc/systemd/system 目录中创建符号链接,这将导致此挂载单元以后每次开机就会进行挂载。但是现在文件系统尚未挂载,因此您必须“启动”它:

1
# systemctl start TestFS.mount

验证文件系统是否已挂载:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# systemctl status TestFS.mount
---
● TestFS.mount - TestFS Mount
Loaded: loaded (/etc/systemd/system/TestFS.mount; enabled; vendor preset: disabled)
Active: active (mounted) since Sat 2020-04-18 09:59:53 EDT; 14s ago
Where: /TestFS
What: /dev/mapper/VG01-TestFS
Tasks: 0 (limit: 19166)
Memory: 76.0K
CPU: 3ms
CGroup: /system.slice/TestFS.mount

Apr 18 09:59:53 testvm1 systemd[1]: Mounting TestFS Mount...
Apr 18 09:59:53 testvm1 systemd[1]: Mounted TestFS Mount.

该演示专门针对为挂载创建单元文件,但它也可以应用于其他类型的单元文件。细节会有所不同,但概念是相同的。是的,我知道在 /etc/fstab 文件中添加一行仍然比创建挂载单元更容易。但这是如何创建单元文件的一个很好的例子,因为 systemd 没有为每种类型的单元提供生成器。

总结

本文更详细地介绍了 systemd 单元以及如何使用 systemctl 命令来探索和管理单元。它还展示了如何停止和禁用单元并创建一个新的 systemd 挂载单元来挂载新的文件系统并使其在启动期间启动。