文件系统
什么是udev机制?
我们都知道在Linux中一切都是文件,添加的设备都会在/dev/目录下有一个唯一的文件与之对应,在Linux的早期版本中/dev包含了系统所有可能的条目,即使某些设备实际并未与系统连接,这意味着/dev会包含数以千计的未使用设备项,从而导致了两个缺点,其一,对于需要扫描该目录内容的应用而言,降低了程序的执行速度;其二,根据该目录下的内容无法发现系统实际存在哪些设备。Linux2.6运用udev程序解决了上述问题,udev 以守护进程的形式运行,通过侦听内核发出来的uevent来管理 /dev目录下的设备文件,可以动态的创建设备文件,还可以自定义设备的命名规则
能否在多个挂载点挂载相同的设备?
内核版本在2.4之前,一个文件系统只能挂载于单个挂载点,从内核版本2.4开始,可以将一个文件系统挂载于文件系统内的多个位置。由于每个挂载点下的目录子树内容都相同,在一个挂载点下对目录子树所做的改变,同样见诸于其它挂载点。
[root@localhost data]# mkdir /data/mnt1
[root@localhost data]# mkdir /data/mnt2
[root@localhost data]# mount /dev/sdb1 /data/mnt1/
[root@localhost data]# mount /dev/sdb1 /data/mnt2/
[root@localhost data]# ls /data/mnt1/
1.c data ls new_data
[root@localhost data]# ls /data/mnt2
1.c data ls new_data
[root@localhost data]# touch /data/mnt1/test
[root@localhost data]# ls /data/mnt2
1.c data ls new_data test
什么是绑定挂载?
始于内核版本2.4,Linux支持了创建绑定挂载,绑定挂载是指在文件系统层级的另一处挂载目录或文件,这将导致文件或目录在两处同时可见,绑定挂载类似于硬链接,但是存在两个方面的差异:
- 绑定挂载可以跨越多个文件系统挂载点
- 可针对目录执行绑定挂载
[root@localhost bind]# mkdir mnt1 mnt2
[root@localhost bind]# touch mnt1/zzz
[root@localhost bind]# mount --bind mnt1 mnt2 //进行目录的绑定挂载
[root@localhost bind]# ls mnt2/
zzz
[root@localhost bind]# touch test1 test2
[root@localhost bind]# echo "1111" > test1
[root@localhost bind]# mount --bind test1 test2 //进行文件的绑定挂载
[root@localhost bind]# cat test2
1111
什么是共享子树(shared subtree)的概念?
自Linux版本2.4.19以后,内核支持针对每个进程的挂载命名空间,这意味着每个进程都可能拥有属于自己的一组文件系统挂载点。比如在进程A的视角下,只能看到/dev/sda1挂载到/根目录下,在进程B的视角下,只能看到/dev/sda2挂载到/home根目录下。在支持了这个特性后就需要考虑下面一个场景:一个进程想要有自己的挂载命名空间,但是仍然想访问CD-ROM所在的挂载点,这个挂载点是在初始的挂载空间中的。其它的挂载空间是看不到这个挂载点的,因此共享子树语义提供了必要的机制来完成上面的这个场景。共享子树提供了四个不同的挂载标志来支持。
- shared mount MS_SHARED
shared mount挂载可以将一个挂载点复制多份,并且后续在任何拷贝的挂载点中再次挂载都会被传播到其他副本。
[root@localhost ~]# mount --make-shared /data/ //设置/data挂载点为shared mount
[root@localhost ~]# mkdir /tmp/data
[root@localhost ~]# mount --bind /data/ /tmp/data/ //进行复制
[root@localhost ~]# ls /data/
test1 test2
[root@localhost ~]# ls /tmp/data/
test1 test2
[root@localhost ~]# touch /data/aaa //两个挂载点共享同一份内容,相互影响
[root@localhost ~]# ls /tmp/data/
aaa test1 test2
[root@localhost ~]# mkdir /tmp/data/mnt //创建一个新的目录
[root@localhost ~]# mount /dev/sdb1 /tmp/data/mnt/ //创建新的挂载点
[root@localhost ~]# ls /tmp/data/mnt/
1.c data ls new_data
[root@localhost ~]# ls /data/mnt/ //发现后续新创建的挂载点也会变成shared mount
1.c data ls new_data
- slave mount MS_SLAVE
slave mount挂载可以将一个挂载点复制多份,但是后续在任何拷贝的挂载点中再次挂载不会被传播到其他副本。并且卸载事件也不会传播到其他挂载点,但是如果是在master挂载点上进行挂载,那么这个事件会被传播到所有的slave mount。
[root@localhost /]# mount --make-shared /data/ //slave mount需要有一个master mount,并且master必须是shared mount
[root@localhost /]# mount --bind /data/ /tmp/data/
[root@localhost /]# mount --make-slave /tmp/data/ //设置为slave mount
[root@localhost /]# mount /dev/sdb1 /tmp/data/mnt/ //挂载事件并不传播
[root@localhost /]# ls /tmp/data/mnt/
1.c data ls new_data
[root@localhost /]# ls /data/mnt/
[root@localhost /]# touch /data/zzz //共享同一份数据
[root@localhost /]# ls /tmp/data/
aaa mnt test1 test2 zzz
[root@localhost data]# unmount /tmp/data/mn1 //卸载
[root@localhost data]# mount /dev/sdb1 /data/mnt/ //在master mount进行挂载
[root@localhost data]# ls /data/mnt/
1.c data ls new_data
[root@localhost data]# ls /tmp/data/mnt/ //发现会传播到slave mount
1.c data ls new_data
- private mount MS_PRIVATE
private mount挂载,这和早期的mount是一样的,也是某些系统的默认挂载类型,可以进行绑定挂载,但是无论在哪个挂载点再次挂载,都不会进行挂载事件的转发和传播。
[root@localhost data]# mount --make-private /data/ //设置private mount
[root@localhost data]# mount --bind /data/ /tmp/data/ //进行绑定挂载
[root@localhost data]# mount /dev/sdb1 /data/mnt/ //再次挂载
[root@localhost data]# ls /data/mnt/
1.c data ls new_data
[root@localhost data]# ls /tmp/data/mnt/ //没有传播到其他的挂载点
[root@localhost data]#
- unbindable mount MS_UNBINDABLE
无法进行绑定挂载,一个设备只能挂载到一个挂载点。
root@localhost:~# mount --make-unbindable /data
root@localhost:~# mount --bind /data/ /tmp/data
mount: wrong fs type, bad option, bad superblock on /data,
missing codepage or helper program, or other error
In some cases useful info is found in syslog - try
dmesg | tail or so.
root@localhost:~#