freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

linux操作系统:浅析linux中的mount挂载
2024-11-25 16:08:27
所属地 广东省

前言

当您的计算机上连接了存储设备(如硬盘)时,负责与硬件通信的 Linux 内核会检测该设备并在 /dev 中创建一个代表该设备的文件,如 /dev/sda。对于从设备分区表中检测到的每个分区,都会创建另一个文件,如 /dev/sda1

在较新的内核中,一些文件也在 sysfs (/sys) 中创建,并向用户公开更高级的控制和信息。(本文未讨论这些文件)

为了能够真正读取/写入设备,您应该先挂载它。mount命令会挂载存储设备或文件系统,使其可访问并将其附加到现有目录结构。

为了挂载卷,您应该调用 mount 命令。首先,您将创建一个目录(应该是空的)

mkdir /mnt/mydata

然后将卷安装到该位置:

mount /dev/sda1 /mnt/mydata

要查看所有已安装的卷及其选项,您可以使用mount命令或findmnt(均由 util-linux 提供,并在所有发行版中可用):

$ findmnt

TARGET                                SOURCE                 FSTYPE          OPTIONS

/                                     /dev/sda4              ext4            rw,relatime,errors=remount-ro
├─/sys                                sysfs                  sysfs           rw,nosuid,nodev,noexec,relatime
│ ├─/sys/kernel/security              securityfs             securityfs      rw,nosuid,nodev,noexec,relatime
│ ├─/sys/fs/cgroup                    tmpfs                  tmpfs           ro,nosuid,nodev,noexec,mode=755
│ │ ├─/sys/fs/cgroup/unified          cgroup2                cgroup2         rw,nosuid,nodev,noexec,relatime,nsdelegate
│ │ ├─/sys/fs/cgroup/systemd          cgroup                 cgroup          rw,nosuid,nodev,noexec,relatime,xattr,name=systemd
│ │ ├─/sys/fs/cgroup/net_cls,net_prio cgroup                 cgroup          rw,nosuid,nodev,noexec,relatime,net_cls,net_prio
│ │ ├─/sys/fs/cgroup/perf_event       cgroup                 cgroup          rw,nosuid,nodev,noexec,relatime,perf_event
│ │ ├─/sys/fs/cgroup/pids             cgroup                 cgroup          rw,nosuid,nodev,noexec,relatime,pids
│ │ ├─/sys/fs/cgroup/cpu,cpuacct      cgroup                 cgroup          rw,nosuid,nodev,noexec,relatime,cpu,cpuacct
│ │ ├─/sys/fs/cgroup/blkio            cgroup                 cgroup          rw,nosuid,nodev,noexec,relatime,blkio
│ │ ├─/sys/fs/cgroup/cpuset           cgroup                 cgroup          rw,nosuid,nodev,noexec,relatime,cpuset
│ │ ├─/sys/fs/cgroup/freezer          cgroup                 cgroup          rw,nosuid,nodev,noexec,relatime,freezer
│ │ ├─/sys/fs/cgroup/devices          cgroup                 cgroup          rw,nosuid,nodev,noexec,relatime,devices
│ │ └─/sys/fs/cgroup/memory           cgroup                 cgroup          rw,nosuid,nodev,noexec,relatime,memory
│ ├─/sys/firmware/efi/efivars         efivarfs               efivarfs        rw,nosuid,nodev,noexec,relatime
│ ├─/sys/fs/bpf                       bpf                    bpf             rw,nosuid,nodev,noexec,relatime,mode=700
│ ├─/sys/kernel/debug                 debugfs                debugfs         rw,relatime
│ └─/sys/fs/fuse/connections          fusectl                fusectl         rw,relatime
├─/proc                               proc                   proc            rw,nosuid,noexec,relatime
│ └─/proc/sys/fs/binfmt_misc          systemd-1              autofs          rw,relatime,fd=36,pgrp=1,timeout=0,minproto=5,maxproto=5,direct
├─/dev                                devtmpfs               devtmpfs        rw,nosuid,size=8144172k,nr_inodes=2036043,mode=755
│ ├─/dev/shm                          tmpfs                  tmpfs           rw
│ │ └─/dev/shm                        none                   tmpfs           rw,relatime
│ ├─/dev/pts                          devpts                 devpts          rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000
│ ├─/dev/mqueue                       mqueue                 mqueue          rw,relatime
│ └─/dev/hugepages                    hugetlbfs              hugetlbfs       rw,relatime,pagesize=2M
├─/run                                tmpfs                  tmpfs           rw,nosuid,nodev,mode=755
│ ├─/run/media/shahriar/Data              /dev/sda2              fuseblk         rw,nosuid,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other,blksize=4096
│ ├─/run/user/1000                    tmpfs                  tmpfs           rw,nosuid,nodev,relatime,size=1638552k,mode=700,uid=1000,gid=1000
│ │ └─/run/user/1000/gvfs             gvfsd-fuse             fuse.gvfsd-fuse rw,nosuid,nodev,relatime,user_id=1000,group_id=1000
│ └─/run/snapd/ns                     tmpfs[/snapd/ns]       tmpfs           rw,nosuid,nodev,mode=755
│   └─/run/snapd/ns/chromium.mnt      nsfs[mnt:[4026532495]] nsfs            rw
├─/tmp                                tmpfs                  tmpfs           rw,nosuid,nodev
├─/snap/slack/7                       /dev/loop0             squashfs        ro,nodev,relatime
├─/snap/sublime-text/26               /dev/loop1             squashfs        ro,nodev,relatime
├─/snap/core/5145                     /dev/loop2             squashfs        ro,nodev,relatime
├─/snap/chromium/412                  /dev/loop4             squashfs        ro,nodev,relatime
├─/snap/core/5328                     /dev/loop3             squashfs        ro,nodev,relatime
└─/snap/telegram-desktop/270          /dev/loop5             squashfs        ro,nodev,relatime
$ mount
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,noexec,relatime)
devtmpfs on /dev type devtmpfs (rw,nosuid,size=8144172k,nr_inodes=2036043,mode=755)
securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev/shm type tmpfs (rw)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run type tmpfs (rw,nosuid,nodev,mode=755)
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
cgroup2 on /sys/fs/cgroup/unified type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)
efivarfs on /sys/firmware/efi/efivars type efivarfs (rw,nosuid,nodev,noexec,relatime)
bpf on /sys/fs/bpf type bpf (rw,nosuid,nodev,noexec,relatime,mode=700)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
/dev/sda4 on / type ext4 (rw,relatime,errors=remount-ro)
mqueue on /dev/mqueue type mqueue (rw,relatime)
hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime,pagesize=2M)
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=36,pgrp=1,timeout=0,minproto=5,maxproto=5,direct)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
tmpfs on /tmp type tmpfs (rw,nosuid,nodev)
/var/lib/snapd/snaps/sublime-text_26.snap on /snap/sublime-text/26 type squashfs (ro,nodev,relatime,x-gdu.hide)
/var/lib/snapd/snaps/slack_7.snap on /snap/slack/7 type squashfs (ro,nodev,relatime,x-gdu.hide)
/var/lib/snapd/snaps/core_5145.snap on /snap/core/5145 type squashfs (ro,nodev,relatime,x-gdu.hide)
/var/lib/snapd/snaps/chromium_412.snap on /snap/chromium/412 type squashfs (ro,nodev,relatime,x-gdu.hide)
/var/lib/snapd/snaps/core_5328.snap on /snap/core/5328 type squashfs (ro,nodev,relatime,x-gdu.hide)
/var/lib/snapd/snaps/telegram-desktop_270.snap on /snap/telegram-desktop/270 type squashfs (ro,nodev,relatime,x-gdu.hide)
fusectl on /sys/fs/fuse/connections type fusectl (rw,relatime)
tmpfs on /run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,size=1638552k,mode=700,uid=1000,gid=1000)
gvfsd-fuse on /run/user/1000/gvfs type fuse.gvfsd-fuse (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000)
tmpfs on /run/snapd/ns type tmpfs (rw,nosuid,nodev,mode=755)
nsfs on /run/snapd/ns/chromium.mnt type nsfs (rw)
none on /dev/shm type tmpfs (rw,relatime)
/dev/sda2 on /run/media/shahriar/Data type fuseblk (rw,nosuid,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other,blksize=4096,uhelper=udisks2)

要卸载设备,您应该使用umount:

可以指定包含文件系统的设备或挂载点。

umount /dev/sda1

umount /mnt/mydata

关于权限的说明

/dev 中创建的所有设备文件都只能由 root 访问。因此,一般来说,只有 root 可以挂载东西。这非常重要,您需要牢记这一点。如果文件系统具有 Linux 权限支持(Linux 原生文件系统,如 ext2、ext3、ext4、btrfs、xfs 等),它们就会被利用,并且驱动器上的文件将被视为 Linux 系统中的其他文件。但某些文件系统(如 FAT 衍生产品(FAT32、exFAT 等))无法存储权限信息。因此,默认情况下,它们只有 root 可用,除非您在挂载时指定一些选项以允许其他用户。考虑以下示例:

replace xxx with uid/gid of user

mount -t vfat /dev/sda6 /media/FAT32 -o rw,uid=xxx,gid=xxx

还有这个简洁的一行程序,可以将它们安装到您的用户可访问的位置:

$ sudo mount -t vfat /dev/sda6 /media/FAT32 -o rw,uid=$(id -u),gid=$(id -g)

或所有用户...

mount -t vfat  /dev/sda6 /media/FAT32 -o rw,umask=0000

文件系统

文件系统控制数据的存储和检索方式。通常,mount 命令会检测必要的选项和文件系统,但您可以像这样手动指定它们:

mount -t ntfs /dev/sda1 /mnt/mydata

您可以通过阅读此文件查看内核支持的所有文件系统:

$ cat /proc/filesystems

nodev  sysfs
nodev  rootfs
nodev  ramfs
nodev  bdev
nodev  proc
nodev  cpuset
nodev  cgroup
nodev  cgroup2
nodev  tmpfs
nodev  devtmpfs
nodev  debugfs
nodev  tracefs
nodev  securityfs
nodev  sockfs
nodev  dax
nodev  bpf
nodev  pipefs
nodev  hugetlbfs
nodev  devpts
            ext3
            ext4
            iso9660
nodev  autofs
            xfs
nodev  efivarfs
nodev  mqueue
            btrfs
            squashfs
            fuseblk
nodev  fuse
nodev  fusectl
nodev  overlay

第一列表示文件系统是否挂载在块设备上。以nodev开头的文件系统未挂载在设备上。第二列列出了支持的文件系统名称。

当没有指定参数时,mount 命令会循环遍历此处列出的文件系统。

要查看驱动器上现有的文件系统,请使用 lsblk 命令,如下所示:

$ lsblk -f

NAME   FSTYPE   LABEL    UUID                                 MOUNTPOINT
loop0  squashfs                                               /snap/slack/7
loop1  squashfs                                               /snap/sublime-text/26
loop2  squashfs                                               /snap/core/5145
loop3  squashfs                                               /snap/core/5328
loop4  squashfs                                               /snap/chromium/412
loop5  squashfs                                               /snap/telegram-desktop/270
sda
├─sda1
├─sda2 ntfs     Data     DCDE47AADE477C30                     /run/media/shahriar/Data
├─sda3 swap              9269aa88-3a31-4299-a1ef-f1472750717f [SWAP]
└─sda4 ext4              7fe5feba-8c3d-4fe9-ab0a-20776aabf441 /
sdb
├─sdb1 ntfs     Recovery 5436D56136D544A0
├─sdb2 vfat              30D6-1226
├─sdb3
└─sdb4 ntfs              560A18780A1856F9
sr0

循环设备显然被 snapd 使用

正如我之前所说,这些是内核支持的文件系统类型,您可能会问,那么还有什么地方可以实现文件系统?答案是 FUSE。

用户空间文件系统 (FUSE) 是类 Unix 操作系统的一种机制,允许非特权用户创建自己的文件系统而无需编辑内核代码。这是通过在用户空间运行文件系统代码来实现的,而 FUSE 内核模块仅提供与实际内核接口的“桥梁”。

但是您应该知道,在 FUSE 文件系统上读取/写入会涉及更多开销,因为提供文件系统功能的代码位于用户空间,并且每次调用该函数都会比涉及内核驱动程序的常规文件操作多遍历内核和用户空间。尽管如此,它在很多情况下都是非常有用的功能。(例如通过网络安装可写的 ntfs 或文件系统)

Linux 世界中还有大量其他文件系统,例如覆盖文件系统,因此我建议您阅读文章末尾的参考资料以进行进一步阅读。

一旦我们了解了 Linux 中挂载的基础知识,我们将学习如何自动化挂载以及 Linux 启动时挂载时会发生什么。

fstab 文件可用于定义如何将磁盘分区、各种其他块设备或远程文件系统挂载到文件系统中。

每个文件系统在单独的一行中描述。每行上的字段由制表符或空格分隔。以“#”开头的行是注释。空白行将被忽略。

如果只给出了目录或设备之一,mount 命令将使用 fstab 来填充另一个参数的值。这样做时,还将使用 fstab 中列出的挂载选项。(可以在 fstab 中设置用户选项以允许非 root 用户挂载)

/etc/fstab 中指定的所有设备将在启动时以及在 mount 中使用-a标志时自动挂载,除非指定了noauto选项。列出但不存在的设备将导致错误,除非使用nofail选项。

$ cat /etc/fstab

<device>             <dir>         <type>    <options>             <dump> <fsck>
/dev/sda1              /             ext4      noatime               0      1
/dev/sda2              none          swap      defaults              0      0
/dev/sda3              /home         ext4      noatime               0      2

强烈建议使用 UUID 或其他唯一标识符,而不是依赖内核名称描述符(sda1、sdb2、...),因为它们可能会在重启后发生变化!

UUID 是首选方法。您可以使用lsblk -f找出 UUID

$ cat /etc/fstab

<device>                                <dir> <type> <options>                                                                                            <dump> <fsck>
UUID=CBB6-24F2                            /boot vfat   defaults                                                                                             0      2
UUID=0a3407de-014b-458b-b5c1-848e92a327a3 /     ext4   defaults                                                                                             0      1
UUID=b411dc99-f0a0-4c87-9e05-184977be8539 /home ext4   defaults                                                                                             0      2
UUID=f9fe0b69-a280-415d-a03a-a32752370dee none  swap   defaults                                                                                             0      0

现代化安装

在 21 世纪初,第一次尝试解决这个问题被称为 HAL - 硬件抽象层,它实现了它的名字,在设备节点和节点用户之间提供了一个层,因此可以添加和删除存储设备(和其他硬件),而无需重新启动系统,也无需重写 /etc/fstab 文件。

在 HAL 弃用之后,随着在硬件开发快速发展的时期发现更好的方法,一切都被替换了令人眼花缭乱的次数(DeviceKit,devfs 等),udev 最终获胜并成为未来十年的主流。

当在系统中添加或删除设备时,Linux 内核会注意到并发出事件。udev 是一个守护进程,它等待监听这些事件,然后做出相应的响应。udev 在用户空间而不是内核空间中运行。

udisks 是基于新技术(D-Bus、udev)创建的。它使用户空间的安装变得现代化。

udisks 提供:

  • 守护进程 udisksd,实现明确定义的 D-Bus 接口,可用于查询和操作存储设备。
  • 命令行工具udisksctl可用于查询和使用守护进程。使用 polkit 限制用户使用 udisks 执行的操作。
    当您将 USB 闪存驱动器插入 PC 后,只需单击桌面上出现的漂亮的 USB 闪存驱动器图标,它就会处理所有工作和权限检查。

在本文中,我们将介绍如何使用udisksctl进行基本的挂载/卸载。但重要的是要知道,这里提供的所有功能只是 D-Bus 调用的包装器,易于编程,在存储管理自动化中非常有用。(比如提到的点击等)

要查看连接到系统的磁盘列表(序列号已被替换):

$ udisksctl status

MODEL                     REVISION  SERIAL               DEVICE
--------------------------------------------------------------------------
Samsung SSD 860 EVO 500GB XXXXXXX  XXXXXXXXXXX      sda
SanDisk SD8S   XXXXXXX  XXXXXXXXXXX         sdb
SlimtypeDVD A    XXXXXXX      XXXXXXXXXXX sr0

查看磁盘的详细信息:

$ udiskctl dump
<output not shown due to length>

要使用这个新工具实际挂载文件系统:

udisksctl mount -b /dev/sdb1

然后卸载:

udisksctl unmount -b /dev/sdb1

systemd 挂载单元

考虑到 udev 和 systemd 的合并,以及 systemd 在现代 Linux 发行版中的普遍性。建议抛弃旧习惯,开始享受可用的炫酷新功能。

在 fstab 中添加条目不再是启动时挂载设备的主要方式。事实上,/etc/fstab 中的所有条目在启动时都会转换为 systemd 挂载单元。

systemd .mount 文件示例:

[Mount]
What=/dev/disk/by-uuid/9269aa88-3a31-4299-bbb1-4e528a89d222
Where=/mnt/mydata
Type=ext4
Options=defaults

重要提示: 挂载单元必须以其控制的挂载点目录命名。

例如:必须在单元文件 home-lennart.mount 中配置挂载点 /home/lennart。

因此我们创建一个这样的文件:

vim /etc/systemd/system/mnt-mydata.mount

[Unit]
Description=Mount Some of my files to empty mydata dir

[Mount]
What=/dev/disk/by-uuid/9269aa88-3a31-4299-bbb1-4e528a89d222
Where=/mnt/mydata
Type=ext4
Options=defaults

当然,编辑完成后你应该通知 systemd 加载单元文件:

systemctl daemon-reload
systemctl start mnt-mydata.mount

您可以像查看其他单元一样查看挂载的状态:

systemctl status mnt-mydata.mount

重要提示: 如果您希望在每次启动时安装它,您还应该在单元文件中包含一个 [Install] 部分:

[Unit]
Description=Mount Some of my files to empty mydata dir

[Mount]
What=/dev/disk/by-uuid/9269aa88-3a31-4299-bbb1-4e528a89d222
Where=/mnt/mydata
Type=ext4
Options=defaults
 
[Install]
WantedBy=multi-user.target

并启用该单元在启动时启动:

systemctl enable mnt-backups.mount
# linux
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者