文件系统挂载原理

挂载通常是将一个存储设备挂载到另一个已经存在的文件夹中,访问这个文件夹,就是访问该存储设备的内容了。

在Linux下,设备未挂载前无法使用,未挂在时设备文件无法写入和读取,我们需要在Linux打开一个“入口”,即挂载点(Linux上的一个文件夹),用于对接该设备,实现挂载。


一个新的磁盘插入到机器后,分区,格式化文件系统(ntfs,ext3,ext4,xfs…),此时还未挂载分区,分区还仅仅是一个封闭空间,无法读写,针对分区和Linux文件夹,合并,关联,挂载,即可通过访问被挂载文件夹看到磁盘内的数据了。

mount命令

mount命令能够将指定的文件系统挂载到特定的目录上

语法

1
2
3
4
5
mount [-lhV]
mount -a [选项]
mount [选项] [--source] <源> | [--target] <目录>
mount [选项] <源> <目录>
mount <操作> <挂载点> [<目标>]

选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
-a, --all               挂载 fstab 中的所有文件系统
-c, --no-canonicalize 不对路径规范化
-f, --fake 空运行;跳过 mount(2) 系统调用
-F, --fork 对每个设备禁用 fork(和 -a 选项一起使用)
-T, --fstab <路径> /etc/fstab 的替代文件
-h, --help 显示此帮助并退出
-i, --internal-only 不调用 mount.<类型> 助手程序
-l, --show-labels 列出所有带有指定标签的挂载
-n, --no-mtab 不写 /etc/mtab
-o, --options <列表> 挂载选项列表,以英文逗号分隔
-O, --test-opts <列表> 限制文件系统集合(和 -a 选项一起使用)
-r, --read-only 以只读方式挂载文件系统(同 -o ro)
-t, --types <列表> 限制文件系统类型集合
--source <源> 指明源(路径、标签、uuid)
--target <目标> 指明挂载点
-v, --verbose 打印当前进行的操作
-V, --version 显示版本信息并退出
-w, --rw, --read-write 以读写方式挂载文件系统(默认)

-h, --help 显示此帮助并退出
-V, --version 输出版本信息并退出

mount -o参数详解

  • async 以异步的方式处理文件系统IO,加速希尔,数据不会同步写入磁盘,而是写入一个缓冲区,提高系统新能,损失数据安全性
  • sync 所有IO操作同步处理,数据同步写入到磁盘,性能较弱,提高数据读写的安全性
  • atime/noatime 文件访问时,是否修改时间戳,能够提升磁盘IO石压速度
  • auto/noauto 可以通过-a参数自动挂载,不自动挂载
  • defaults 这个默认参数,涵盖rw,suid,dev,exec,auto,nousr,async等等参数
  • exec/noexec 是否允许挂载点内的可执行命令,使用noexec提升磁盘安全性
  • ro 只读
  • rw 读写

对于centos7新出现的mount选项有

  • att2 磁盘上存储内联拓展属性,提升磁盘性能
  • inode64 允许在文件系统的任意位置创建inode
  • noquota 强制关闭文件系统的限额功能
1
/dev/sda1 on /boot type xfs (rw,relatime,seclabel,attr2,inode64,noquota)

mount实操

查看挂载情况

1
2
3
4
5
6
7
8
9
[root@localhost ~]# df -hT
文件系统 类型 容量 已用 可用 已用% 挂载点
devtmpfs devtmpfs 899M 0 899M 0% /dev
tmpfs tmpfs 910M 0 910M 0% /dev/shm
tmpfs tmpfs 910M 9.6M 901M 2% /run
tmpfs tmpfs 910M 0 910M 0% /sys/fs/cgroup
/dev/mapper/centos-root xfs 17G 2.6G 15G 15% /
/dev/sda1 xfs 1014M 189M 826M 19% /boot
tmpfs tmpfs 182M 0 182M 0% /run/user/0

/dev/sdb3挂载到/mnt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@localhost ~]# lsblk -f
NAME FSTYPE LABEL UUID MOUNTPOINT
sda
├─sda1 xfs 7fdc921b-f892-4c21-8f87-97f26f936673 /boot
└─sda2 LVM2_mem LYVzwm-oAOF-Uxwx-m6tO-Ocrx-D64J-wvpb3G
├─centos-root
xfs 745e580c-314d-4419-b634-97ea40c4ee49 /
└─centos-swap
swap dbb971fd-25ea-43d9-b515-87fd10cba0de [SWAP]
sdb
├─sdb1 ext4 2ddcc1b2-2acf-4011-8c1b-1ee2858775d7
├─sdb2 xfs af6080aa-49e9-4319-a1a7-d0da302cdd01
└─sdb3
sr0 iso9660 CentOS 7 x86_64
2018-11-25-21-21-31-00

通过查看分区文件系统类型发现,sdb3并未进行格式化系统类型!

1
2
3
[root@localhost ~]# mount /dev/sdb3 /mnt
mount: /dev/sdb3 写保护,将以只读方式挂载
mount: 未知的文件系统类型“(null)”

/dev/sdb3进行格式化文件系统类型为xfs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[root@localhost ~]# mkfs.xfs /dev/sdb3
meta-data=/dev/sdb3 isize=512 agcount=4, agsize=700351 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=0, sparse=0
data = bsize=4096 blocks=2801403, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
[root@localhost ~]# lsblk -f
NAME FSTYPE LABEL UUID MOUNTPOINT
sda
├─sda1 xfs 7fdc921b-f892-4c21-8f87-97f26f936673 /boot
└─sda2 LVM2_mem LYVzwm-oAOF-Uxwx-m6tO-Ocrx-D64J-wvpb3G
├─centos-root
xfs 745e580c-314d-4419-b634-97ea40c4ee49 /
└─centos-swap
swap dbb971fd-25ea-43d9-b515-87fd10cba0de [SWAP]
sdb
├─sdb1 ext4 2ddcc1b2-2acf-4011-8c1b-1ee2858775d7
├─sdb2 xfs af6080aa-49e9-4319-a1a7-d0da302cdd01
└─sdb3 xfs a2c0eae1-c538-4213-a97e-2f7e50153a19
sr0 iso9660 CentOS 7 x86_64
2018-11-25-21-21-31-00

成功格式化!


再次挂载

1
2
[root@localhost ~]# mount /dev/sdb3 /mnt
[root@localhost ~]#

无提示是最好的提示!


查看挂载情况

1
2
3
4
5
6
7
8
9
10
[root@localhost ~]# df -hT
文件系统 类型 容量 已用 可用 已用% 挂载点
devtmpfs devtmpfs 899M 0 899M 0% /dev
tmpfs tmpfs 910M 0 910M 0% /dev/shm
tmpfs tmpfs 910M 9.6M 901M 2% /run
tmpfs tmpfs 910M 0 910M 0% /sys/fs/cgroup
/dev/mapper/centos-root xfs 17G 2.6G 15G 15% /
/dev/sda1 xfs 1014M 189M 826M 19% /boot
tmpfs tmpfs 182M 0 182M 0% /run/user/0
/dev/sdb3 xfs 11G 33M 11G 1% /mnt

第10行我们发现成功将磁盘挂载!


使用挂载后的磁盘

切换至/mnt目录下,生成一个大文件

1
2
3
cd /mnt
echo {1..99999} > big.txt
echo {1..99999} >> big.txt
1
2
3
4
5
[root@localhost ~]# cd /mnt
[root@localhost mnt]# echo {1..99999} > big.txt
[root@localhost mnt]# echo {1..99999} >> big.txt
[root@localhost mnt]# du -h *
1.6M big.txt

取消挂载

1
umount <挂载点>或者<设备>

注意!

取消挂载前必须没有人正在使用!

1
2
3
4
[root@localhost mnt]#  umount /mnt
umount: /mnt:目标忙。
(有些情况下通过 lsof(8) 或 fuser(1) 可以
找到有关使用该设备的进程的有用信息)

上面取消挂载失败,是因为我们正处在/mnt目录中

1
2
[root@localhost mnt]# cd /
[root@localhost /]# umount /mnt

取消成功!

以只读形式挂载/dev/sdb3

1
2
3
4
[root@localhost /]# mount -o ro /dev/sdb3 /mnt
[root@localhost /]# cd /mnt/
[root@localhost mnt]# ls
big.txt
1
"big.txt" [readonly] 2L, 1177776C

挂载成功且能够读取big.txt但不能修改!

尝试创建新文件

1
2
[root@localhost mnt]# touch test
touch: 无法创建"test": 只读文件系统

禁止挂载的设备执行二进制文件

先将sdb3取消挂载

1
umount /mnt

再执行挂载

1
mount -o noexec /dev/sdb3 /mnt

创建一个简单脚本

1
2
3
4
[root@localhost mnt]# vi test.sh
[root@localhost mnt]# cat test.sh
#!/bin/bash
echo "Test"

执行脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost mnt]# . test.sh
Test
[root@localhost mnt]# bash test.sh
Test
#######
[root@localhost mnt]# ./test.sh
-bash: ./test.sh: 权限不够
[root@localhost mnt]# chmod +x test.sh
[root@localhost mnt]# ls -l
总用量 1156
-rw-r--r--. 1 root root 1177776 8月 2 11:18 big.txt
-rwxr-xr-x. 1 root root 24 8月 2 12:08 test.sh
[root@localhost mnt]# ./test.sh
-bash: ./test.sh: 权限不够

我们发现使用 .bash 方式能够成功执行test.sh,但无法直接./test.sh执行文件,就算赋予了执行权限也不能执行!这就是noexec的作用!