当您“挂载”带有内容的现有文件夹时会发生什么?


80

现在/tmp有一些临时文件。将硬盘驱动器(/dev/sdc1)挂载在上时/tmp,可以看到硬盘驱动器上的文件。/tmp装入硬盘驱动器时的实际内容如何?可以在/tmp安装硬盘驱动器时对实际内容执行读写操作吗?

python@lanix / $ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1       286G   43G  229G  16% /
none            4.0K     0  4.0K   0% /sys/fs/cgroup
udev            3.8G  4.0K  3.8G   1% /dev
tmpfs           766M  1.4M  765M   1% /run
none            5.0M     0  5.0M   0% /run/lock
none            3.8G   38M  3.8G   1% /run/shm
none            100M   24K  100M   1% /run/user
/dev/sdb1       7.5G  2.7G  4.9G  35% /mnt
/dev/sdc1       932G  242G  691G  26% /tmp

Answers:


117

装入硬盘驱动器后,/ tmp的实际内容如何处理?

几乎没有。它们只是隐藏起来,无法通过正常的文件系统遍历来访问。

装入硬盘驱动器后,是否可以对/ tmp的实际内容执行读/写操作?

是。在“原始”文件中具有打开文件句柄的进程/tmp将继续能够使用它们。您也可以通过在其他地方绑定安装来使“重新出现” /在其他地方。

# mount -o bind / /somewhere/else
# ls /somewhere/else/tmp  

您可以进行以下实验,以对发生的事情有更好的感觉(我希望)。

注意:这不是试图完全正确,也不是对真实情况的详尽描述。应该足够准确,但是可以为您提供全面的信息。

我在me计算机上创建了一个名为的用户,并在其家中创建了一个随机目录,其中包含一个文件:

me@home $ pwd
/home/me/tmp
me@home $ echo hello > some_file
me@home $ ls  
some_file
me@home $ cat some_file 
hello

在这一点上,没有什么不寻常的-它只是一个带有纯文件的纯目录。我将其会话保留cwd在测试目录中,并保持打开状态。

作为root,我创建一个小文件系统并将其挂载到/home/me/tmp

root@home # dd if=/dev/zero of=./fs bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.00467318 s, 2.2 GB/s

root@home # mkfs -t ext2 ./fs 
mke2fs 1.42.12 (29-Aug-2014)
[... snip ...]
Writing superblocks and filesystem accounting information: done

root@home # mount ./fs /home/me/tmp

然后,我打开一个新的终端me,并环顾四周:

me@home #2 $ cd tmp
me@home #2 $ ls
lost+found
me@home #2 $ cat some_file
cat: some_file: No such file or directory
me@home #2 $ echo bye bye > some_file
-su: some_file: Permission denied

因此,我们创建的文件显然不存在。该lost+found目录指示ext文件系统的根目录。而且我失去了写许可,所以它显然不是原始目录。

回到第一节me,让我们看看它如何看待世界:

me@home $ echo something else > other_file

写作没问题。

me@home $ cat some_file other_file 
hello
something else

原始文件仍然存在,创建的新文件没有问题。

??这是怎么回事?

第一个会话通过根目录在其上挂载另一个文件系统之前进入了目录。挂载操作完全不影响原始文件系统。Shell进程对原始文件系统中的目录具有完全有效的句柄,并且可以继续与其进行交互。有点像在地毯安装点下面跑来跑去。

放置挂载后,第二个会话进入目录。因此,它将看到新的空文件系统。并且sysadmin取消了权限,因此它无法使用请求的空间...让我们对其进行修复。

root@home # chown me:users /home/me/tmp
me@home #2 $ echo bye bye > some_file
me@home #2 $ ls 
lost+found  some_file
me@home #2 $ cat some_file 
bye bye

会议1可以从地毯下面逃脱吗?(越来越发霉了。)

当然!如果会话1将文件系统树从坐骑中移出,它将丢失该句柄到内部,并将像其他所有人一样跟随坐骑。

me@home $ cd
me@home $ pwd
/home/me
me@home $ cd tmp
me@home $ cat some_file other_file
bye bye
cat: other_file: No such file or directory

与会话2相同的视图,我们已恢复正常。

但是你怎么知道文件没有消失呢?没人在看了!

那是绑定安装变得方便的时刻之一。它们使您可以将已经安装的文件系统挂载到其他位置。

me@home $ mkdir ~/bind
root@home # mount -o bind /home/me /home/me/bind

(是的,您可以“内部安装”文件系统。很酷,是吗?)

me@home $ ls bind/tmp
other_file  some_file
me@home $ cat bind/tmp/*
something else
hello

因此,他们确实在那里,准备采取行动。只是因为它们在其原始位置不可见/无法访问,所以挂载会将它们从常规目录遍历中隐藏起来。


我鼓励您尝试一下,一旦您了解了所玩的“技巧”,它实际上并不复杂。一旦您获得了Got It™,就可以查看并集文件系统以获取更多的地毯信息:-)

不过要注意一点:一旦启动过程完成,在/tmp/var(或任何核心OS目录)上挂载实际上不是一个好主意。许多应用程序在这些目录中保留状态,如果您在它们周围玩坐骑游戏,可能会感到非常困惑。


4
这是一个很好的答案-您超越了我的要求。绑定安装的想法也很酷!感谢您的详细回答。干杯。
用户

11
这是一种神秘地丢失磁盘空间的非常常用的方法。如果在启动脚本中由于某种原因挂载失败,则可以将数据写入根文件系统上的目录。如果随后尝试重新启动,则挂载可能会成功,并且也许没人会注意到(例如,如果文件系统包含tmp文件或日志),但它会占用很多空间。
Dan Sheppard 2015年

2
@DanSheppard这是我喜欢将挂载点设置为chmod 000的原因之一。另外,如果关键挂载失败,为什么systemd无法启动。
Zan Lynx 2015年

难道你还-bind安装/home/me/home/me,而不是“绑定”文件夹?即在地毯上放另一块地毯。还是您必须先卸载fs
jiggunjer

@jiggunjer看来union选项可以提供帮助。
hliu
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.