Systemd挂载文件系统(自动)

我在 在软RAID10 + LVM上CentOS 7 部署Gluster 11 时,前置步骤是 mdadm构建RAID10 。我使用了一些简便的脚本命令来快速完成原先的磁盘卸载和分区擦除重建工作:

批量初始化服务器的12块 NVMe存储 磁盘
wipefs -a /dev/nvme{0..11}n1
for i in {0..11};do
    parted -s -a optimal /dev/nvme${i}n1 mklabel gpt
    parted -s -a optimal /dev/nvme${i}n1 mkpart primary 0% 100%
    parted -s -a optimal /dev/nvme${i}n1 set 1 raid on
    parted -s -a optimal /dev/nvme${i}n1 name 1 raid_part
done

但是我万万没有想到,只一转眼,已经卸载掉的XFS磁盘文件系统居然自动挂载好了,使用 df -h 又看到了我刚才卸载并准备不再使用的文件系统:

分区和格式化、挂载好的12块磁盘的文件系统
Filesystem       Size  Used Avail Use% Mounted on
devtmpfs          63G     0   63G   0% /dev
tmpfs             63G   66M   63G   1% /dev/shm
tmpfs             63G  2.2M   63G   1% /run
tmpfs             63G     0   63G   0% /sys/fs/cgroup
/dev/sda3         49G   21G   27G  44% /
/dev/sda5        167G  1.4G  157G   1% /home
/dev/sda2        976M  181M  728M  20% /boot
/dev/nvme0n1p1   3.5T  3.7G  3.5T   1% /data/brick0
/dev/nvme1n1p1   3.5T  3.7G  3.5T   1% /data/brick1
/dev/nvme2n1p1   3.5T  3.7G  3.5T   1% /data/brick2
/dev/nvme3n1p1   3.5T  3.7G  3.5T   1% /data/brick3
/dev/nvme4n1p1   3.5T  3.7G  3.5T   1% /data/brick4
/dev/nvme5n1p1   3.5T  3.7G  3.5T   1% /data/brick5
/dev/nvme6n1p1   3.5T  3.7G  3.5T   1% /data/brick6
/dev/nvme7n1p1   3.5T  3.7G  3.5T   1% /data/brick7
/dev/nvme8n1p1   3.5T  3.7G  3.5T   1% /data/brick8
/dev/nvme9n1p1   3.5T  3.7G  3.5T   1% /data/brick9
/dev/nvme10n1p1  3.5T  3.7G  3.5T   1% /data/brick10
/dev/nvme11n1p1  3.5T  3.7G  3.5T   1% /data/brick11

我揉了揉眼睛,以为自己糊涂了,还是生产环境有什么神秘的监控脚本会自动把破坏的文件系统重新挂载好?

回想了一下之前的操作步骤,这里能够自动挂载是因为我只重建了分区表,但是很不幸实际上分区表和之前完全一致(差别是分区标记从XFS改为RAID),而实际的第一个分区的 XFS文件系统 并没有抹除,所以才会这样被自动挂载。

究竟是什么原因会把我之前的文件系统重新挂载,而且我明明已经删除了 /etc/fstab 中对应配置,所以也不可能是简单的 mount -a 就能挂载的…

我突然想到 systemd 服务,想是不是有类似 autofs 这样的自动文件系统挂载服务…巧了,虽然没有发现 autofs ,我却发现了一些确实和文件系统挂载有关的 mount 服务:

../../../_images/systemd_mount.png

神秘的文件系统自动挂载

但是,这些 data-brick0.mount 配置是怎么注入到 systemd 配置的呢?

How to mount partition using systemd unit file? 提供了在 systemd 中配置unit配置文件来实现磁盘挂载,但是我在 /etc/systemd/system 目录下并没有找到上述这些目录挂载配置…

systemd.mount — Mount unit configuration 说明了 .mount 配置文件,系统中当前有:

系统中现有的 .mount 文件列表
/etc/systemd/system/sys-fs-resctrl.mount
/usr/lib/systemd/system/dev-hugepages.mount
/usr/lib/systemd/system/dev-mqueue.mount
/usr/lib/systemd/system/proc-sys-fs-binfmt_misc.mount
/usr/lib/systemd/system/sys-fs-fuse-connections.mount
/usr/lib/systemd/system/sys-kernel-config.mount
/usr/lib/systemd/system/sys-kernel-debug.mount
/usr/lib/systemd/system/tmp.mount
/usr/lib/systemd/system/sysinit.target.wants/dev-hugepages.mount
/usr/lib/systemd/system/sysinit.target.wants/dev-mqueue.mount
/usr/lib/systemd/system/sysinit.target.wants/sys-fs-fuse-connections.mount
/usr/lib/systemd/system/sysinit.target.wants/sys-kernel-config.mount
/usr/lib/systemd/system/sysinit.target.wants/sys-kernel-debug.mount

systemd.mount — Mount unit configuration 提到了 systemd-mount 命令能够在命令行动态且瞬时创建 .mount.automount units。那么上述这些挂载配置是不是通过 systemd-mount 创建的呢?

使用 systemctl 检查 mount 类型 units
systemctl list-units --type mount

输出显示:

mount 类型 units 可以看到要删除但是没有删除成功的挂载配置
  UNIT                          LOAD   ACTIVE SUB     DESCRIPTION
  -.mount                       loaded active mounted /
  boot.mount                    loaded active mounted /boot
  data-brick0.mount             loaded active mounted /data/brick0
  data-brick1.mount             loaded active mounted /data/brick1
  data-brick10.mount            loaded active mounted /data/brick10
  data-brick11.mount            loaded active mounted /data/brick11
  data-brick2.mount             loaded active mounted /data/brick2
  data-brick3.mount             loaded active mounted /data/brick3
  data-brick4.mount             loaded active mounted /data/brick4
  data-brick5.mount             loaded active mounted /data/brick5
  data-brick6.mount             loaded active mounted /data/brick6
  data-brick7.mount             loaded active mounted /data/brick7
  data-brick8.mount             loaded active mounted /data/brick8
  data-brick9.mount             loaded active mounted /data/brick9
  dev-hugepages.mount           loaded active mounted Huge Pages File System
  dev-mqueue.mount              loaded active mounted POSIX Message Queue File System
● disk10.mount                  loaded failed failed  /disk10
● disk11.mount                  loaded failed failed  /disk11
● disk12.mount                  loaded failed failed  /disk12
● disk2.mount                   loaded failed failed  /disk2
● disk3.mount                   loaded failed failed  /disk3
● disk4.mount                   loaded failed failed  /disk4
● disk5.mount                   loaded failed failed  /disk5
● disk6.mount                   loaded failed failed  /disk6
● disk7.mount                   loaded failed failed  /disk7
● disk8.mount                   loaded failed failed  /disk8
● disk9.mount                   loaded failed failed  /disk9
● home-t4.mount                 loaded failed failed  /home/t4
  home.mount                    loaded active mounted /home
  proc-sys-fs-binfmt_misc.mount loaded active mounted Arbitrary Executable File Formats File System
  sys-fs-fuse-connections.mount loaded active mounted FUSE Control File System
  sys-kernel-config.mount       loaded active mounted Configuration File System
  sys-kernel-debug.mount        loaded active mounted 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.

33 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.
  • 对比 systemctlunit-files 就会看到持久化的配置文件中并没有包含我要找的那些 mounts :

使用 systemctl 检查 mount 类型 units 文件
systemctl list-unit-files --type mount

输出显示持久化的unit配置文件实际不多,并没有我要找的 mounts :

mount 类型 units 文件(持久化的)并不多
UNIT FILE                     STATE
dev-hugepages.mount           static
dev-mqueue.mount              static
proc-sys-fs-binfmt_misc.mount static
sys-fs-fuse-connections.mount static
sys-fs-resctrl.mount          disabled
sys-kernel-config.mount       static
sys-kernel-debug.mount        static
tmp.mount                     disabled

8 unit files listed.

也就是说这些挂载确实是动态的配置(没有配置文件)

systemd-fstab-generator

找到了

这些动态生成的 unit 虽然没有 unit-file ,但是确实可以查看到( 使用 systemctl cat 命令 ):

  • 检查 data-brick0.mount unit:

使用 systemctl cat 输出unit内容
systemctl cat data-brick0.mount

可以看到这个配置unit完全是自动生成的:

使用 systemctl cat 输出 data-brick0.mount 内容
# /run/systemd/generator/data-brick0.mount
# Automatically generated by systemd-fstab-generator

[Unit]
SourcePath=/etc/fstab
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
Before=local-fs.target
RequiresOverridable=systemd-fsck@dev-nvme0n1p1.service
After=systemd-fsck@dev-nvme0n1p1.service

[Mount]
What=/dev/nvme0n1p1
Where=/data/brick0
Type=xfs
Options=rw,inode64,noatime,nouuid

原来 systemctl daemon-reload 就能刷新 systemd-fstab-generator 配置

  • 我以为( 其实不是 )要先通过 stop 来停止 xxxx.mount ,所以尝试:

尝试停止 data-brick0.mount
systemctl stop data-brick0.mount

此时提示:

尝试停止 data-brick0.mount
Warning: data-brick0.mount changed on disk. Run 'systemctl daemon-reload' to reload units.
  • 此时检查 ls -lh /run/systemd/generator/ 会发现该目录下所有units都没有变化,包括 data-brick0.mount 配置文件也还在

  • 我按照提示执行了一次:

执行 daemon-reload 刷新
systemctl daemon-reload

Binggo

  • 我突然发现 /run/systemd/generator/ 所有在 /etc/fstab 删除掉的配置行对应的 units 文件全部消失了…

明白了

原来对应于 systemd-fstab-generator 自动生成的 .mount unit文件,不需要手工去停止或删除,只需要正确修改 /etc/fstab ,然后执行

执行 daemon-reload 刷新
systemctl daemon-reload

就可以完全同步刷新配置。之后就可以手工 umount 挂载文件系统以及做磁盘初始化了 好折腾

参考