如何在CentOS/RHEL 7和8中按一定顺序依次挂载文件系统

时间:2020-01-09 10:42:38  来源:igfitidea点击:

现在,既然我们学会了使用systemd单位文件(而不使用/etc/fstab)来挂载和自动挂载文件系统,那么让我们继续收集有关类似主题的知识。

在本文的本文中,我将解释使用systemd单元文件以及fstab文件以特定顺序挂载文件系统的步骤。

随着RHEL 7中systemd的引入,由于现在并行启动了许多服务和进程,因此引导过程变得更快了。

这些后果之一是缺少一致的文件系统挂载顺序。根据/etc/fstab中的条目,不再保证它们的安装顺序。文件系统现在只是另一个systemd单元。由于systemd默认为并行单元执行过程启动,因此特定目标单元的启动顺序不一致。

在RHEL 7和8中,systemd处理挂载顺序,而不处理/etc/fstab中的挂载条目的顺序。

因此,"/etc/fstab"中条目的顺序不必与它们在RHEL 7中的安装顺序相同。

说明:

在撰写本文时,CentOS 8尚不可用,但我认为相同的步骤将在CentOS 8上起作用,类似于RHEL 8.

系统单位文件位置

systemd介绍了systemd单元的概念。

这些单元由位于下表中目录之一中的单元配置文件表示。

目录说明
/usr/lib/systemd/system/systemd与已安装的RPM包一起分发的单位文件。
/run/systemd/system/在运行时创建的systemd单位文件。此目录优先于已安装服务单元文件的目录。
/etc/systemd/system/systemctl enable创建的systemd单位文件以及为扩展服务而添加的单位文件。此目录优先于包含运行时单位文件的目录。

使用systemd以一定顺序挂载文件系统

现在,为了演示本文以特定顺序挂载文件系统,我将创建两个文件系统

/dev/sdb2 -> Mounted on /first_part -> Mapped with first_part.mount unit file
/dev/sdc1 -> Mounted on /second_part -> Mapped with second_part.mount unit file

我们将确保在系统引导时在first_part.mount之前调用" first_part.mount",以便我们可以按一定顺序挂载文件系统。

获取文件系统的UUID

在开始之前,我们需要两个文件系统的UUID来配置我们的systemd单元文件以按特定顺序挂载文件系统。

[root@rhel-8 system]# ls -l /dev/disk/by-uuid/*
lrwxrwxrwx. 1 root root  9 Sep 16 15:09 /dev/disk/by-uuid/2019-04-04-08-40-23-00 -> ../../sr0
lrwxrwxrwx. 1 root root 10 Sep 16 15:09 /dev/disk/by-uuid/2796b6a6-1080-4f7c-a902-b4438f071e6c -> ../../dm-4
lrwxrwxrwx. 1 root root 10 Sep 16 15:09 /dev/disk/by-uuid/3f46ad95-0d39-4f56-975d-2e61fc26230b -> ../../sdc1
lrwxrwxrwx. 1 root root 10 Sep 16 18:25 /dev/disk/by-uuid/716664b6-1475-4c11-9297-5920bb4f0677 -> ../../sdb2
lrwxrwxrwx. 1 root root 10 Sep 16 15:09 /dev/disk/by-uuid/abf4aa90-0b58-499a-b601-bc5f208fd2cd -> ../../sda1
lrwxrwxrwx. 1 root root 10 Sep 16 17:09 /dev/disk/by-uuid/cea0757d-6329-4bf8-abbf-03f9c313b07f -> ../../sdb1
lrwxrwxrwx. 1 root root 10 Sep 16 15:09 /dev/disk/by-uuid/e6024940-527e-4a08-ac77-0e503b219d27 -> ../../dm-3

或者你可以使用blkid命令

[root@rhel-8 system]# blkid /dev/sdb2
/dev/sdb2: UUID="716664b6-1475-4c11-9297-5920bb4f0677" TYPE="ext4" PARTUUID="0b051d7e-02"
[root@rhel-8 system]# blkid /dev/sdc1
/dev/sdc1: UUID="3f46ad95-0d39-4f56-975d-2e61fc26230b" TYPE="ext4" PARTUUID="65a7b241-01"

示例系统单位文件

重要的提示:

创建systemd挂载单元文件时,必须遵循某些命名语法,否则服务将无法启动。

以下是我的第一个分区的systemd单位文件

[root@rhel-8 system]# pwd
/usr/lib/systemd/system
[root@rhel-8 system]# cat first_part.mount
[Unit]
Description=Test Directory (/first_part)
DefaultDependencies=no
Conflicts=umount.target
Before=local-fs.target umount.target
After=swap.target
[Mount]
What=/dev/disk/by-uuid/716664b6-1475-4c11-9297-5920bb4f0677
Where=/first_part
Type=ext4
Options=defaults
[Install]
WantedBy=multi-user.target

以下是我的第二分区的systemd单元文件。

[root@rhel-8 system]# pwd
/usr/lib/systemd/system
[root@rhel-8 system]# cat second_part.mount
#  This file is part of systemd.
[Unit]
Description=Test Directory (/second_part)
DefaultDependencies=no
Conflicts=umount.target
Before=local-fs.target umount.target
RequiresMountsFor=/first_part
[Mount]
What=/dev/disk/by-uuid/3f46ad95-0d39-4f56-975d-2e61fc26230b
Where=/second_part
Type=ext4
Options=defaults,x-systemd.requires-mounts-for=/first_part
[Install]
WantedBy=multi-user.target

其中

RequiresMountsFor=
    Takes a space-separated list of absolute paths. Automatically adds dependencies of type Requires= and After= for all mount units required to access the specified path.
x-systemd.requires-mounts-for=
    Configures a RequiresMountsFor= dependency between the created mount unit and other mount units. The argument must be an absolute path. This option Jan be specified more than once.

本文将介绍所有其他参数。

说明:

如果一个挂载点在文件系统层次结构中的另一个挂载点之下,则会自动创建两个单元之间的依赖关系,因此我们无需为仅需挂载的/test/test1创建" Requires"和" After"条目。/test存在并挂载之后。

在创建这些systemd单元文件之后或者在这些文件中进行的每次修改之后,重新加载systemd守护程序很重要

[root@rhel-8 system]# systemctl daemon-reload

通过示例验证步骤

现在我们都完成了配置,以一定顺序依次使用systemd单元文件挂载文件系统。现在我们可以看到本文中没有文件系统处于挂载状态。

[root@rhel-8 system]# df -h
Filesystem             Size  Used Avail Use% Mounted on
devtmpfs               900M     0  900M   0% /dev
tmpfs                  915M     0  915M   0% /dev/shm
tmpfs                  915M  8.5M  907M   1% /run
tmpfs                  915M     0  915M   0% /sys/fs/cgroup
/dev/mapper/rhel-root   15G  2.1G   12G  16% /
/dev/sda1              483M  258M  225M  54% /boot
tmpfs                  183M     0  183M   0% /run/user/0

让我们开始我们的第一个文件系统挂载服务

[root@rhel-8 system]# systemctl start first_part.mount

如预期的那样,现在已经安装了/first_part,但是尚未安装/second_part。

[root@rhel-8 system]# df -h | grep part
/dev/sdb1              976M  2.6M  907M   1% /first_part

同样,如果我们停止first_mount服务,那么/first_part将会被卸载。

[root@rhel-8 system]# systemctl stop first_part.mount

我们得到此命令的空白输出,这是预期的

[root@rhel-8 system]# df -h | grep part

在此阶段," first_part.mount"处于非活动状态/已死

[root@rhel-8 system]# systemctl show -p ActiveState -p SubState --value second_part.mount
inactive
dead

现在让我们启动" second_part.mount"服务

[root@rhel-8 system]# systemctl start second_part.mount

如我们所见,其中我们能够按一定顺序挂载文件系统。一旦我们尝试了second_part.mount的启动,它就首先安装了/first_part,然后按照我们的计划安装了/second_part

来自/var/log/messages的输出

Sep 17 02:57:53 rhel-8.example systemd[1]: Mounting Test Directory (/first_part)...
Sep 17 02:57:53 rhel-8.example kernel: EXT4-fs (sdb2): mounted filesystem with ordered data mode. Opts: (null)
Sep 17 02:57:53 rhel-8.example systemd[1]: Mounted Test Directory (/first_part).
Sep 17 02:57:53 rhel-8.example systemd[1]: Mounting Test Directory (second_partition)...
Sep 17 02:57:53 rhel-8.example kernel: EXT4-fs (sdc1): mounted filesystem with ordered data mode. Opts: (null)
Sep 17 02:57:53 rhel-8.example systemd[1]: Mounted Test Directory (second_partition).

使用df命令验证相同

[root@rhel-8 system]# df -h | grep part
/dev/sdb2              976M  2.6M  907M   1% /first_part
/dev/sdc1              976M  2.6M  907M   1% /second_part

启用两个systemd单元服务,以使更改在重新引导后永久存在

[root@rhel-8 system]# systemctl enable first_part.mount
[root@rhel-8 system]# systemctl enable second_part.mount

使用/etc/fstab按特定顺序挂载文件系统

我们也可以使用传统的/etc/fstab文件以一定的顺序挂载文件系统。

示例/etc/fstab内容

在我的用例中添加了文件系统并根据环境在/etc/fstab中安装信息,这是针对我有两个文件系统的用例而添加的

[root@rhel-8 ~]# cat /etc/fstab
/dev/mapper/rhel-root  /                     ext4    defaults        1 1
UUID=abf4aa90-0b58-499a-b601-bc5f208fd2cd /boot                   xfs     defaults        0 0
/dev/mapper/rhel-swap   swap                    swap    defaults        0 0
UUID=716664b6-1475-4c11-9297-5920bb4f0677       /first_part     ext4    defaults        0 0
UUID=3f46ad95-0d39-4f56-975d-2e61fc26230b       /second_part    ext4    defaults,x-systemd.requires-mounts-for=/first_part      0 0

现在保存并退出文件。

因为我们已经创建了systemd服务来按一定顺序挂载文件系统,所以我们将禁用那些服务,以便我们可以验证/etc/fstab中的更改。

[root@rhel-8 system]# systemctl disable --now second_part.mount
[root@rhel-8 system]# systemctl disable --now first_part.mount

这将停止该服务,并在以后的重新启动时将其禁用。

验证更改

接下来重启节点并验证更改

[root@rhel-8 system]# reboot
login as: root
[email protected]'s password:
Last login: Tue Sep 17 03:12:05 2019 from 10.0.2.2

我们将检查文件系统是否已挂载

[root@rhel-8 ~]# df -h | grep part
/dev/sdb2              976M  2.6M  907M   1% /first_part
/dev/sdc1              976M  2.6M  907M   1% /second_part

因此我们的/etc/fstab更改按预期工作。

由于我们正在使用fstab来执行这些更改,因此systemd将为/run/systemd/generator /中的各个fstab条目创建一个服务单元文件。

要列出按顺序加载的systemd挂载文件,我们可以在以下命令中运行

[root@rhel-8 ~]# ls -lt /run/systemd/generator/
total 20
-rw-r--r--. 1 root root 254 Sep 17 03:16  boot.mount
-rw-r--r--. 1 root root 230 Sep 17 03:16 'dev-mapper-rhelx2dswap.swap'
-rw-r--r--. 1 root root 261 Sep 17 03:16  first_part.mount
drwxr-xr-x. 2 root root 120 Sep 17 03:16  local-fs.target.requires
drwxr-xr-x. 2 root root  60 Sep 17 03:16  local-fs.target.wants
-rw-r--r--. 1 root root 218 Sep 17 03:16  -.mount
-rw-r--r--. 1 root root 351 Sep 17 03:16  second_part.mount
drwxr-xr-x. 2 root root  60 Sep 17 03:16  swap.target.requires

systemd生成的挂载单元文件看起来类似于我们在本文前面创建的文件

[root@rhel-8 generator]# cat second_part.mount
# Automatically generated by systemd-fstab-generator
[Unit]
SourcePath=/etc/fstab
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
Before=local-fs.target
RequiresMountsFor=/first_part
[Mount]
Where=/second_part
What=/dev/disk/by-uuid/3f46ad95-0d39-4f56-975d-2e61fc26230b
Type=ext4
Options=defaults,x-systemd.requires-mounts-for=/first_part

列出当前已加载并处于活动状态的所有安装点

[root@rhel-8 ~]# systemctl -t mount
UNIT                    LOAD   ACTIVE SUB     DESCRIPTION
-.mount                 loaded active mounted Root Mount
boot.mount              loaded active mounted /boot
dev-hugepages.mount     loaded active mounted Huge Pages File System
dev-mqueue.mount        loaded active mounted POSIX Message Queue File System
first_part.mount        loaded active mounted /first_part
run-user-0.mount        loaded active mounted /run/user/0
second_part.mount       loaded active mounted /second_part
sys-kernel-config.mount loaded active mounted Kernel Configuration File System
sys-kernel-debug.mount  loaded active mounted Kernel Debug File System
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.
9 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.

分析系统管理员

我们还可以获得有关此类挂载相关的systemd单位文件使用的链的更多信息。如我们所见,我的" second_part.mount"显示了在启动服务时将遵循的链。

提示:

配置systemd服务以获取链详细信息后,需要重新启动

[root@rhel-8 ~]# systemd-analyze critical-chain second_part.mount
The time after the unit is active or started is printed after the "@" character.
The time the unit takes to start is printed after the "+" character.
second_part.mount +22ms
└─first_part.mount @939ms +42ms
  └─swap.target @938ms
    └─dev-mapper-rhelx2dswap.swap @819ms +95ms
      └─dev-mapper-rhelx2dswap.device

有关更多信息,请遵循systemd.mount的手册页。

[root@rhel-8 ~]# man systemd.mount