zoukankan      html  css  js  c++  java
  • mount --bind的使用

    我们可以通过mount --bind命令来将两个目录连接起来,mount --bind命令是将前一个目录挂载到后一个目录上,所有对后一个目录的访问其实都是对前一个目录的访问,如下所示:

    ## test1 test2为两个不同的目录
    linux-UMLhEm:/home/test/linux # ls test1
    11.test  1.test
    linux-UMLhEm:/home/test/linux # ls test2
    22.test  2.test
    linux-UMLhEm:/home/test/linux # ls -lid test1
    1441802 drwx------ 2 root root 4096 Feb 13 09:50 test1
    linux-UMLhEm:/home/test/linux # ls -lid test2
    1441803 drwx------ 2 root root 4096 Feb 13 09:51 test2
    
    ## 执行mount --bind 将test1挂载到test2上,inode号都变为test1的inode
    linux-UMLhEm:/home/test/linux # mount --bind test1 test2
    linux-UMLhEm:/home/test/linux # ls -lid test1
    1441802 drwx------ 2 root root 4096 Feb 13 09:50 test1
    linux-UMLhEm:/home/test/linux # ls -lid test2
    1441802 drwx------ 2 root root 4096 Feb 13 09:50 test2
    linux-UMLhEm:/home/test/linux # ls test2
    11.test  1.test
    
    ## 对test2的访问或修改实际上是改动test1目录
    linux-UMLhEm:/home/test/linux # cd test2
    linux-UMLhEm:/home/test/linux/test2 # touch 3.test
    linux-UMLhEm:/home/test/linux/test2 # ls
    11.test  1.test  3.test
    linux-UMLhEm:/home/test/linux/test2 # cd ..
    linux-UMLhEm:/home/test/linux # ls test1
    11.test  1.test  3.test
    
    ## 解挂载后,test1目录保持修改,test2保持不变
    linux-UMLhEm:/home/test/linux # umount test2
    linux-UMLhEm:/home/test/linux # ls test1
    11.test  1.test  3.test
    linux-UMLhEm:/home/test/linux # ls test2
    22.test  2.test
    
    ## 将test2挂载到test1上
    linux-UMLhEm:/home/test/linux # ls -lid test2
    1441803 drwx------ 2 root root 4096 Feb 13 09:51 test2
    linux-UMLhEm:/home/test/linux # mount --bind test2 test1
    linux-UMLhEm:/home/test/linux # ls -lid test1
    1441803 drwx------ 2 root root 4096 Feb 13 09:51 test1
    linux-UMLhEm:/home/test/linux # ls -lid test2
    1441803 drwx------ 2 root root 4096 Feb 13 09:51 test2
    linux-UMLhEm:/home/test/linux # ls test1
    22.test  2.test
    
    mount --bind test1 test2为例,当mount --bind命令执行后,Linux将会把被挂载目录的目录项(也就是该目录文件的block,记录了下级目录的信息)屏蔽,即test2的下级路径被隐藏起来了(注意,只是隐藏不是删除,数据都没有改变,只是访问不到了)。同时,内核将挂载目录(test1)的目录项记录在内存里的一个s_root对象里,在mount命令执行时,VFS会创建一个vfsmount对象,这个对象里包含了整个文件系统所有的mount信息,其中也会包括本次mount中的信息,这个对象是一个HASH值对应表(HASH值通过对路径字符串的计算得来),表里就有 /test1 到 /test2 两个目录的HASH值对应关系。
    
    命令执行完后,当访问 /test2下的文件时,系统会告知 /test2 的目录项被屏蔽掉了,自动转到内存里找VFS,通过vfsmount了解到 /test2 和 /test1 的对应关系,从而读取到 /test1 的inode,这样在 /test2 下读到的全是 /test1 目录下的文件。
    

    1.mount --bind连接的两个目录的inode号码并不一样,只是被挂载目录的block被屏蔽掉,inode被重定向到挂载目录的inode(被挂载目录的inode和block依然没变)。

    2.两个目录的对应关系存在于内存里,一旦重启挂载关系就不存在了。

    在固件开发过程中常常遇到这样的情况:为测试某个新功能,必需修改某个系统文件。而这个文件在只读文件系统上(总不能为一个小小的测试就重刷固件吧),或者是虽然文件可写,但是自己对这个改动没有把握,不愿意直接修改。这时候mount --bind就是你的好帮手。 
    

    假设我们要改的文件是/etc/hosts,可按下面的步骤操作:

    1. 把新的hosts文件放在/tmp下。当然也可放在硬盘或U盘上。
    2. mount --bind /tmp/hosts /etc/hosts 此时的/etc目录是可写的,所做修改不会应用到原来的/etc目录,可以放心测试。测试完成了执行 umount /etc/hosts 断开绑定。

    mount --bind的特殊使用方法:
    将一个文件夹mount --bind 为自己,这样可以得到一个挂载点,可以通过使用mount重新挂载给这个挂载点设置只读等属性限定文件夹的使用,如下:
    举个例子,可以通过这种方式来创造一个挂在点。
    ➜ ~ mkdir test_dir
    ➜ ~ mount --bind test_dir test_dir
    ➜ ~ mount |grep test_dir
    /dev/nvme0n1p6 on /home/xion/test_dir type ext4 (rw,relatime,errors=remount-ro,data=ordered) 注意这里显示的是test_dir文件夹所在的block块设备而不是显示文件夹本身(这是因为mount的正常使用就是挂载block设备的),如果mount test_dir test_dir 会直接提示如下的错误:mount: /home/xion/test_dir is not a block device

    这样就可以使用一些mount的属性,最简单的例子,例如:
    mount,ro --bind test_dir test_dir
    可以让test_dir成为一个是read only的目录。无论改目录中的文件夹或者文件的权限是什么,这个文件夹都是只读的。
    除此之外,mount有很多别的属性

    参考:
    https://xionchen.github.io/2016/08/25/linux-bind-mount/
    https://www.cnblogs.com/xingmuxin/p/8446115.html

    mount的-o参数
    1)nodev含义 文件系统的 nodev 挂载选项有什么用?https://feichashao.com/nodev/

    2)其中auto 参考archlinux的mount选项说明 https://wiki.archlinux.org/index.php/Fstab_(简体中文)
    其中auto应该是指开机自动可以挂载该项或者mount -a自动挂载,如果某项挂载设定为了noauto,那么不能通过重启或者mount -a来挂载只能通过手动的方式来挂载上。

  • 相关阅读:
    谋哥:搞APP,做得累的都不对!
    我在3天内众筹到1.8万的经验分享!
    微价值创始人想要加入“秦王会”啦!
    学习IOS开发UI篇--控制器的管理
    学习IOS开发UI篇--程序启动原理
    学习IOS开问题篇--类中的成员变量如果不实例化是什么情况
    学习IOS开问题篇--IOS程序启动的加载顺序
    学习IOS开问题篇--layoutSubviews什么情况下调用
    学习IOS开发UI篇--UIAlertView/UIActionSheet
    学习IOS开发UI篇--NSNotificationCenter通知中心
  • 原文地址:https://www.cnblogs.com/weihua2020/p/13872964.html
Copyright © 2011-2022 走看看