最近注意到mount的选项里, 有一个--bind
, 还有一个--rbind
man 手册上有相关介绍:
The bind mount call attaches only (part of) a single filesystem, not possible submounts. The entire file hierarchy including submounts is attached a second place usingmount --rbind olddir newdiror shortoptionmount -R olddir newdir
刚开始对 submounts 的真实含义不是很清楚.
Google 搜 mount bind vs rbind
也没搜到什么结果, 还好在 StackOverflow 上搜到一篇帖子, 是讨论如何 loop 模式挂载. 其中 这个答案 讲的很详细.
(再次赞下 SOF, 现在对国内的技术社区是没什么好感了, 基本也就泡 SOF.)
关于 rbind, r 的意思就是 recursive
, 也就是递归挂载.
举个例子:
1 |
现在在 /mnt 目录下有三个子目录, /mnt/old & /mnt/new & /mnt/bind_old, 执行: |
2 |
mkdir /mnt/old/bind_old |
3 |
mount --bind /mnt/bind_old /mnt/old/bind_old |
4 |
现在 /mnt/bind_old 就以 bind方式 挂载到 /mnt/old/bind_old 上了 |
5 |
touch /mnt/bind_old/hello |
6 |
然后在 /mnt/old/bind_old 目录下也有 hello 文件了 |
7 |
接着把 /mnt/old bind挂载到 /mnt/new 上: |
8 |
mount --bind /mnt/old /mnt/new |
9 |
进入 /mnt/new 目录, 可以看到 /mnt/old 自己的 bind_old 目录 |
10 |
但是 /mnt/old/bind_old 目录下并没有 hello 文件 |
11 |
说明在 /mnt/new 目录里, /mnt/bind_old 并没有被挂载上 |
12 |
这就是 rbind 发挥作用的地方了 |
13 |
bind 方式只挂载当前的目录, 但是目录中的子挂载目录不被递归挂载上去, 而 rbind 就可以 |
14 |
umount /mnt/new |
15 |
mount --rbind /mnt/old /mnt/new |
16 |
这时就可以看到 /mnt/new/bind_old 下的 hello 文件了 |
但是, 在最后 umount /mnt/new 的时候, 无法 umount, 提示说 /mnt/new 正在被使用, lsof 查看 /mnt/new, 发现很多文件都被使用了, 但是看不出来是什么程序占用了. (我的 /mnt 和 / 是在一个分区, 其实这个就是 lsof /
的结果)
网上也有很多关于 can not umount rbind
的文章, 后来看到了一篇博客里写了原因.
因为 mount 可以 递归挂载
, 但是 umount 不能 递归卸载
. 就导致了这样.
我先前知道是递归挂载后, 就以为用 rbind 可以把 /mnt/old bind到 /mnt/new 后, 同时识别 /mnt/old 下的 /mnt/old/bind_old, 现在才发现错了.
看 /proc/mounts
里可以发现, 递归挂载实际上是:
1 |
mount --bind /mnt/old /mnt/new |
2 |
mount --bind /mnt/bind_old /mnt/new/bind_old |
这样就知道为啥无法 umount /mnt/new 了, 因为还有一个 /mnt/new/bind_old 在挂载着在.
1 |
umount /mnt/new/bind_old |
2 |
umount /mnt/new |
这样就可以 umount /mnt/new 了.