检测Linux上的绑定挂载
我想找一种方法来判断一个给定的路径是否是一个绑定挂载点(在Linux系统上)。用来检测普通挂载点的标准方法似乎都不管用。就连mountpoint这个命令也无法检测到绑定挂载。
4 个回答
1
findmnt
命令可以显示绑定挂载的信息:
$ grep /opt /home /etc/fstab
/home/admin/opt /opt none bind 0
LABEL=raidhome /home ext4 defaults,nodiratime,relatime 0 2
$ findmnt --fstab /opt
TARGET SOURCE FSTYPE OPTIONS
/opt /home/admin/opt none bind
$ findmnt /opt
TARGET SOURCE FSTYPE OPTIONS
/opt /dev/md1[/admin/opt] ext4 rw,nodiratime,relatime,stripe=16
$ findmnt -J /opt
{
"filesystems": [
{
"target": "/opt",
"source": "/dev/md1[/admin/opt]",
"fstype": "ext4",
"options": "rw,nodiratime,relatime,stripe=16"
}
]
}
虽然不是特别简单明了,但这些信息确实存在。
2
你可以通过检查一个路径的设备ID和它的父目录的设备ID,来判断这个路径是否是一个挂载点。前提是挂载的文件系统和父目录的文件系统不同(我从来没有尝试过把一个目录绑定到它自己上!)。
这里有一个简单的命令行演示:
$ cut -d ' ' -f2 /proc/mounts | xargs stat -c '%d %n'
18 /sys
4 /proc
6 /dev
19 /dev/pts
20 /run
2049 /
7 /sys/kernel/security
21 /dev/shm
22 /run/lock
23 /sys/fs/cgroup
24 /sys/fs/cgroup/unified
25 /sys/fs/cgroup/systemd
26 /sys/fs/pstore
27 /sys/fs/cgroup/perf_event
28 /sys/fs/cgroup/cpu,cpuacct
29 /sys/fs/cgroup/pids
30 /sys/fs/cgroup/blkio
31 /sys/fs/cgroup/memory
32 /sys/fs/cgroup/cpuset
33 /sys/fs/cgroup/net_cls,net_prio
34 /sys/fs/cgroup/devices
35 /sys/fs/cgroup/freezer
39 /proc/sys/fs/binfmt_misc
17 /dev/mqueue
8 /sys/kernel/debug
37 /dev/hugepages
2066 /home
39 /proc/sys/fs/binfmt_misc
44 /run/user/1000
45 /sys/fs/fuse/connections
2049 /run/schroot/mount/my-chroot-cb43935e-0812-45ea-af4f-965a1e2de91d
4 /run/schroot/mount/my-chroot-cb43935e-0812-45ea-af4f-965a1e2de91d/proc
18 /run/schroot/mount/my-chroot-cb43935e-0812-45ea-af4f-965a1e2de91d/sys
6 /run/schroot/mount/my-chroot-cb43935e-0812-45ea-af4f-965a1e2de91d/dev
19 /run/schroot/mount/my-chroot-cb43935e-0812-45ea-af4f-965a1e2de91d/dev/pts
2066 /run/schroot/mount/my-chroot-cb43935e-0812-45ea-af4f-965a1e2de91d/home
2049 /run/schroot/mount/my-chroot-cb43935e-0812-45ea-af4f-965a1e2de91d/tmp
一旦你确认它是一个挂载点,如果它的设备ID在/proc/mounts
中与多个条目相同,你就可以推测其中一个是绑定挂载。至于哪个是绑定的,哪个是被绑定的,这部分信息在这个回答中还没有提到。
注意,/proc/mounts
中的条目对于某些特殊字符使用了八进制转义,所以一个健壮的脚本需要通过printf %b
或类似的方法来处理这些字符。
6
我不太确定有没有其他方法可以做到这一点(可能通过 /etc/mtab
或 /etc/fstab
),因为我了解到绑定挂载在挂载空间中有点像“硬链接”(而不是文件层级),一旦绑定挂载完成,就无法区分源和目标挂载点。
你为什么会问这个呢?我觉得绑定挂载主要是为了从应用程序的角度“隐藏”某些东西(否则你可以使用符号链接,或者在极少数情况下使用硬链接来处理目录)。
我刚刚通过你的问题发现的 mountpoint
似乎能看到一些东西:
% grep /home /etc/fstab
UUID=000008-0003-000c-9ecd-0f1a /home ext3 defaults 0 2
% grep /usr/src /etc/fstab
/home/Src /usr/src none bind 0 0
% mountpoint /usr/src
/usr/src is a mountpoint
% mountpoint /home/Src
/home/Src is not a mountpoint
通过对 mountpoint
使用 strace
,我发现它在对像 /usr/src
和 /usr/src/..
这样的目录执行 lstat
、stat
和 fstat
系统调用。
(2016年11月添加:)