我有一个备份脚本,我在其中卸载了一个 squashfs 文件,我进行备份然后再次将其安装回去。脚本的简化版本是:
umount /home/backup/auto/mnt/os
mksquashfs /src-dir /home/backup/auto/os.sqfs.img
mount -t squashfs -o loop /home/backup/auto/os.sqfs.img /home/backup/auto/mnt/os
这个想法是随时可以访问备份数据。
这工作了很长时间。但是,我收到一个错误,即没有足够的环回设备,并且我看到 umount 不再分离安装有 mount 的循环设备。
最近我有两个主要变化:
- 我将内核更新为 2.6.32-754.11.1.el6.i686
- 我将操作系统移至 SSD。
我刚刚注意到有新的内核更新 2.6.32-754.12.1.el6,所以我更新了,但它并没有解决问题。
操作系统:CentOS 6.10 i686
更新: 这是在故障系统上:
# strace -e trace=ioctl,mount mount -t squashfs -o loop os.sqfs.img mnt/os
ioctl(3, LOOP_GET_STATUS, {number=0, offset=0, flags=0, name="/home/squash/web.img", ...}) = 0
ioctl(3, LOOP_GET_STATUS, {number=0, offset=0, flags=0, name="/home/squash/web.img", ...}) = -1 ENXIO (No such device or address)
ioctl(4, LOOP_SET_FD, 0x3) = 0
ioctl(4, LOOP_SET_STATUS64, {offset=0, number=0, flags=0, file_name="/home/backup/auto/os.sqfs.img", ...}) = 0
mount("/dev/loop1", "mnt/os", "squashfs", MS_MGC_VAL, NULL) = 0
+++ exited with 0 +++
# cat /etc/mtab|grep 'mnt/os'
/dev/loop1 /home/backup/auto/mnt/os squashfs ro,relatime 0 0
# ls -la /etc/mtab
lrwxrwxrwx. 1 root root 12 Apr 17 02:53 /etc/mtab -> /proc/mounts
# notice that here there is no even the umount call. Am I missing something?
# strace -e trace=ioctl,umount,mount umount mnt/os
+++ exited with 0 +++
这是在另一个具有相同版本的所有系统上,但它是 64 位的:
# strace -e trace=ioctl,mount mount -t squashfs -o loop os.sqfs.img mnt/os
ioctl(3, LOOP_GET_STATUS, {number=0, offset=0, flags=0, name="/storage/backup/auto/home.sqfs.img", ...}) = 0
ioctl(3, LOOP_GET_STATUS, {number=1, offset=0, flags=0, name="/storage/backup/auto/mail.sqfs.img", ...}) = 0
ioctl(3, LOOP_GET_STATUS, {number=1, offset=0, flags=0, name="/storage/backup/auto/mail.sqfs.img", ...}) = -1 ENXIO (No such device or address)
ioctl(4, LOOP_SET_FD, 0x3) = 0
ioctl(4, LOOP_SET_STATUS64, {offset=0, number=0, flags=0, file_name="/storage/backup/auto/os.sqfs.img", ...}) = 0
mount("/dev/loop2", "mnt/os", "squashfs", MS_MGC_VAL, NULL) = 0
+++ exited with 0 +++
# strace -e trace=ioctl,umount,mount umount mnt/os
umount("/storage/backup/auto/mnt/os", 0) = 0
ioctl(3, LOOP_CLR_FD) = 0
+++ exited with 0 +++
# losetup -a
/dev/loop0: [0904]:35656625 (/storage/backup/auto/home.sqfs.img)
/dev/loop1: [0904]:35656626 (/storage/backup/auto/mail.sqfs.img)
我也没有在好的系统上看到 LO_FLAGS_AUTOCLEAR。但我确实看到了 umount 的不同。
我重新安装util-linux-ng
了 - 它没有帮助。此软件包没有更新,也从未更新过。也许它与内核有关。我想知道为什么它在 64 位操作系统上运行良好。我可能会安装一个 32 位 VM 来测试它是否会这样做。
- 使固定 -
问题是我在系统复制期间使用 CentOS 7 的实时 CD 将 /etc/mtab 链接到 /proc/mounts 并且我忘记了它。我不得不重新安装 grub,所以我 chroot 到操作系统并建立了链接,因为 grub-install 不起作用。我忘了恢复它。我通过以下方式解决了这个问题:
rm -f /etc/mtab && cat /proc/mounts |grep -v rootfs > /etc/mtab
所以它现在有效:
root@home auto# smount os.sqfs.img mnt/os
root@home auto# losetup -a
/dev/loop0: [0816]:7090072 (/home/squash/web.img)
/dev/loop1: [0816]:7864675 (/home/backup/auto/os.sqfs.img)
/dev/loop4: [0816]:7864569 (/home/backup/auto/web.sqfs.img)
root@home auto# umount mnt/os
root@home auto# losetup -a
/dev/loop0: [0816]:7090072 (/home/squash/web.img)
/dev/loop4: [0816]:7864569 (/home/backup/auto/web.sqfs.img)
这是我在 CentOS 6 中包含的 util-linux-ng 2.17.2 的源代码中收集到的:
在小于 2.6.37 的内核上,Linux 要求
/etc/mtab
为循环挂载的文件系统写入一个条目,以便稍后自动清除循环设备。如果/etc/mtab
在挂载时不可写或条目已从中删除,/etc/mtab
则不会自动清除循环设备。在内核 >= 2.6.37 上,内核会记住循环设备后备存储路径,并且不需要在/etc/mtab
.我能够在 CentOS 6.10 上通过
/etc/mtab
将chattr +i /etc/mtab
. 仅仅删除它是不够的;它将至少使用部分安装表重新创建。这不是正常操作中应该发生的事情,因此如果您发现此文件已被设置为不可变,您应该寻找管理员错误或安全漏洞。如果
/etc/mtab
在您的旧 Linux 系统上不存在或不完整,您可以从/proc/mounts
. 但是不要在现代 Linux 系统上执行此操作,/etc/mtab
取而代之的是一个符号链接,/proc/self/mounts
用于与期望在该位置安装表的古代代码向后兼容。TL;DR:这似乎不是内核问题,但
mount
由于未设置循环设备的LO_FLAGS_AUTOCLEAR
标志,该命令的行为不符合预期。使用更新的分发外挂载命令应该可以解决它。跟踪(最近系统的)命令挂载,导致我到loop(4)的标志
LO_FLAGS_AUTOCLEAR
:所以我的“现代”安装命令成功地发出了这个 ioctl,如下所示:
(这里的 losttup 语法与 CentOS6 不同)。
我想如果问题不在内核中(因为 OP 的 2.6.32 > 2.6.25),它可能来自 mount 命令。为了检查,我安装了一个 centos6-i686 LXC 容器,安装了 strace,创建了丢失的 /dev/loop* 文件并在内部运行了一个完全特权的 shell(使用
lxc-attach
's-e
选项)允许执行挂载操作:显然 ioctl 没有发出 clear 标志,这导致了循环设备泄漏。查看源代码,这个功能似乎已经存在了很长时间,并且存在于 util-linux 2.17.2(CentOS6 的版本)中。CentOS6
man mount
甚至告诉我们:所以我不知道为什么它不起作用,它似乎是一个错误(或者这可能与我的环境有关:64 位内核 5.0.x 等)。