深入linux下文件系统磁盘Disk,分区Partition,挂载Mount

2023-05-16

目录

    • Linux 分区简介
    • 挂载点目录简介
    • 实战分区挂载
        • 临时挂载
        • 永久挂载:开机自动挂载
        • 添加硬盘&分区&挂载
        • loop device 回环设备
        • loop mount
        • 绑定式挂载 (bind mount)
        • 重新挂载 (remount)
    • 通过 fstab 设置开机挂载的问题
    • FAQ

Linux 分区简介

  1. 挂载 的本质就是针对某一设备, 分析出其文件系统结构, 并根据其文件系统类型调用 linux 中相应的驱动, 处理其的元数据, 将这些信息附加到 linux 的目录树上呈现出来. – 原文

    当要使用某个设备时,例如要读取硬盘中的一个格式化好的分区、光盘或软件等设备时,必须先把这些设备对应到某个目录(这个目录可以不为空,但挂载后这个目录下以前的内容将不可用),而这个目录就称为“挂载点(mount point)”,这样才可以读取这些设备,而这些对应的动作就是“挂载”。

  2. 主分区 vs 扩展分区
    硬盘分区表中最多能存储四个分区,但我们实际使用时一般只分为两个分区,一个是主分区(Primary Partion)一个是扩展分区(extended partition),主分区可以马上被使用但不能再分区,扩展分区必须再进行分区后才能使用,也就是说它必须还要进行二次分区, 一般留作未来扩展用的。那么由扩展分区再分下去的是什么呢?它就是逻辑分区(Logical Partion),逻辑分区没有数量上限制, 相当于不同目录取不同名字作"逻辑"上的区分。

  3. 驱动器标示的含义
    对Linux用户来说无论有几个分区,都得分给目录使用,它归根结底就只有一个根目录,一个独立且唯一的文件结构。Linux中每个分区都是用来组成整个文件系统的一部分,因为它采用了一种叫“挂载点”的处理方法,它的整个文件系统中包含了一整套的文件和目录,且将一个分区和一个目录联系起来。这时要载入的一个分区就在linux的存储空间的某个目录下获得。
    对于IDE硬盘,驱动器标识符为“hdx1”,其中“hd”表明分区所在设备的类型,这里是指IDE硬盘了。“x”为盘号(a为基本盘,b为基本从属盘,c为辅助主盘,d为辅助从属盘),“1”代表分区,前四个分区用数字1到4表示,它们是主分区或扩展分区,从5开始就是逻辑分区。例,hda3表示为第一个IDE硬盘上的第三个主分区或扩展分区,hdb2表示为第二个IDE硬盘上的第二个主分区或扩展分区。对于SCSI硬盘则标识为“sdx1”,SCSI硬盘是用“sd”来表示分区所在设备的类型的,其余则和IDE硬盘的表示方法一样。
    上面可以看到,Linux的分区是不同于其它操作系统分区的,它的分区格式常用的有Ext3和Swap两种,Ext3用于存放系统文件,Swap则作为Linux的交换分区(相当于windows中的虚拟内存文件)。那么现在我们就可以知道Linux至少需要两个专门的分区(Linux Native(本地)和Linux Swap(交换))。由于不能将Linux安装在Dos/Windows分区。一般来说我们将Linux安装一个或多个类型为“Linux Native”的硬盘分区,但是在Linux的每一个分区都必须要指定一个“Mount Point”(挂载点),告诉Linux在启动时,这个目录要给哪个分区使用。对“Swap”分区来说, 一般也定义一个,且它不必要定义载入点。
    下面我们先对“Linux Native”和“Linux Swap”有个初步的了解。
    SWAP分区是LINUX暂时存储数据的交换分区,它主要是把主内存上暂时不用得数据存起来,在需要的时候再调进内存内,且作为SWAP使用的分区不用指定“Mout Point”(载入点),既然它作为交换分区,我们理所当然应给它指定大小,它至少要等于系统上实际内存的量,一般来说它的大小是内存的一至两倍。另外你也可以创建和使用一个以上的交换分区,最多16个。
    Linux Native是存放系统文件的地方,一般用ext3/ext4的分区类型,对Linux来说,有了较大的选择余地,可以把系统文件分几个区来装(必须要说明挂载点),也可以就装在同一个分区中(挂载点是“/”)。
    在这里插入图片描述

  4. 为什么要自定义多个分区
    a. 在不损失数据的情况下重装系统,比如独立设置/home挂载点,重装系统的时候直接标记回/home,数据不会有任何损失。

    b. 针对不同挂载点的特性分配合适的文件系统以合理发挥性能,比如对/var使用reiserfs,对/home使用xfs,对/使用ext4。

    c. 针对不同的挂载点开启不同的挂载选项,如是否需要即时同步,是否开启日志,是否启用压缩。

    d. 大硬盘搜索范围大,效率低

    e. 磁盘配额只能对分区做设定

    f. /home、/var、/usr/local 经常是单独分区,因为经常会操作,容易产生碎片

挂载点目录简介

  1. 常见的挂载目录结构

在这里插入图片描述

以上是目录结构

以下是文件存储结构
在linux正统的文件系统(eg:ext2、ext3)中,一个文件由以下三个部分组成:
a. 目录项:包括文件名和inode节点号。
b. Inode::又称文件索引节点,记录文件的属性,一个文件占用一个inode,同时记录此文件的数据所在的block号码。
c. data block:实际记录文件的内容,若文件太大时,会占用多个block。
在这里插入图片描述
在这里插入图片描述

  1. 常见的挂载目录说明

/ 根目录,存放系统命令和用户数据等(如果下面挂载点没有单独的分区,它们都将在根目录的分区中)
/boot boot loader 的静态链接文件,存放与Linux启动相关的程序
/home 用户目录,存放普通用户的数据
/tmp 临时文件
/usr 是Linux系统存放软件的地方,如有可能应将最大空间分给它
/usr/local 自已安装程序安装在此
/var 不断变化的数据,服务器的一些服务、日志放在下面
/opt (Option可选的)附加的应用程序软件包
/bin 基本命令执行文
/dev 设备文件
/etc 主机特定的系统配置
/lib 基本共享库以及内核模块
/media 用于移动介质的挂载点
/mnt 用于临时挂载文件系统或者别的硬件设备(如光驱、软驱)
/proc 系统信息的虚拟目录(2.4 和 2.6 内核),这些信息是在内存中,由系统自己产生的
/root root 用户的目录
/sbin 基本系统命令执行文件
/sys 系统信息的虚拟目录(2.6 内核)
/srv 系统提供的用于 service 的数据
/usr/X1186 X-Windows目录,存放一些X-Windows的配置文件
/usr/include 系统头文件,存储一些C语言的头文件
/usr/src Linux内核源代码,Linux系统所安装的内核源代码都保存在此
/usr/bin 对/bin目录的一些补充
/usr/sbin 对/sbin目录的一些补充
/lost+found 这个目录在大多数情况下都是空的。但是如果你正在工作突然停电,或是没有用正常方式关机,在你重新启动机器的时候,有些文件就会找不到应该存放的地方,对于这些文件,系统将他们放在这个目录下
在这里插入图片描述

  1. 为什么 linux 的分区需要有挂载这个动作呢

    因为linux 下一切皆文件!换句说法就是linux操作系统将系统中的一切都作为文件来管理。在windows中我们常见的硬件设备(打印机、网卡、声卡…)、磁盘分区等,在linux中统统都被视作文件,对设备、分区的访问就是读写对应的文件。

实战分区挂载

临时挂载

$ mount /dev/sda3 /data   ##sda3分区挂载在data目录下
$ umount /data   ##卸载data目录下分区

永久挂载:开机自动挂载

需要修改/etc/fstab

LABEL=/data   /data   ext3   defaults   1   2
修改为:
/dev/sda3     /data      ext3    defaults 1    2

PS:fstab 是文件系统分配表的配置文件,该文件有着严格的语法格式限制,类似 crontab 一样,保存时也会对你的输入格式进行校验,请慎重使用,否则会有意想不到的问题发生。其一共有 6 个字段,空格分隔。

添加硬盘&分区&挂载

  1. 运行fdisk -l查看磁盘信息
    在这里插入图片描述

  2. 对sdb进行分区操作,运行fdisk /dev/sdb

    n 创建一个新分区

    p 设置为主分区

    选择分区号(1-4),第一块盘一般选择1

    选择分区大小,默认整块硬盘,回车即可

    w 保存配置,分区完成

在这里插入图片描述

  1. 对创建好的硬盘进行格式化
mkfs -t ext3 -c /dev/sdb1
  1. 挂载分区
mount /dev/sdb1  /cache1/(把sdb1主分区挂载到cache1上)

loop device 回环设备

明白 loop mount 之前, 最好先清除什么是 loop device, 有耐心的话可以参见维基百科中的条目, 比较长, 没耐心的话可以直接看我下面的描述, 简洁些.

简单来说, loop device 能够提供将一个档案挂载到某一目录的功能. 这和 bind mount (下文会介绍) 有些类似, 但并不相同. 原始的 mount 只是为了将正常的设备挂载, bind mount 使得可以挂载目录, 而 loop device 使得可以挂载档案.

在 linux 中, loop device 就是指 /dev/loop0, /dev/loop1, /dev/loop2 … 这些设备, 它们是虚假的设备(pseudo device), 不像 /dev/sda 在你的主机里物理存在. loop device 需要你在编译内核的时候将其静态编译或者编译为动态模块, 然后需要使用modprobe加载其模块(这个模块包含了 loop device 的驱动程序以及 losetup 这种提供给用户来操作 loop device 的程序), 这时其驱动程序就会创建 /dev/loop0, /dev/loop1 … 这几个设备文件.

注意, 我在说档案的时候, 指的是英文中的 archive, 它和文件 file 是不同的东西, 档案 archive 是一个打包的文件集, 里面一般包含许多文件, 比如 tar, jar, iso 就是常见的档案格式.

用过 dd 的人应该知道, 这个强大的命令可以将整个磁盘或者磁盘分区克隆下来, 放到一个文件里, 一般, 这样的文件我们都以 .img 后缀为其命名并称这样的文件为镜像文件. 我所说的档案也包含这类情况.

loop mount

ok, 明白了什么是 loop device, 也明白了档案是什么, 那么到底如何把一个档案挂载到某个目录下呢?

实际上 loop mount 采取了一个瞒天过海的方式, 它先将这个档案映射到某个 loop device 上, 像这样:

losetup /dev/loop0 xxxx.iso 

通过这种方式来欺骗mount命令, 让mount命令以为 /dev/loop0 上面真的有设备. 这时运行mount就行了:

mount -t iso9660 /dev/loop0 /path/to/mount/point 

这么看起来, 当你想挂载某一个档案的时候(比如某个 iso), 你首先得把这个档案和某一个 loop device 关联起来, 使用 losetup 命令. 然后使用 mount 命令将这个 loop device 设备挂载到某个目录上. 实际上不必这样, mount命令自身其实就有一个能把这两步合并的功能, 那就是这样:

 mount -t iso9660 -o loop /dev/loop0 /path/to/mount/point 

最后我们再来想一想, 是不是所有的档案都可以用这种方式挂载? 显然不是的, 根据mount命令有个 -t 参数来看, 在挂载的时候是需要指定文件系统的类型的(不指定的话mount命令会自动识别), 还记得上面说的挂载的本质吗?

“挂载操作, 实际上是把设备 device 中的文件系统附加到 dir 上”

不被识别的文件系统是不能被挂载的, 如果你没有加载 ReiserFS 模块, 那么挂载具有 ReiserFS 文件系统的设备时就会报 “unknown file system” 错误. 像上面说的 tar, jar, zip 这样的档案, 它们只是一种打包/压缩格式, 本身就不是一种文件系统格式, 当然是不能被 linux 识别的. 它们虽然可以映射到某一个 loop device, 但并不能被挂载.

但是像 .iso 文件, 它一般包含 iso 9660 文件系统, 都知道这是一种 CD 上采用的文件系统. 还有就是你可以使用 dd, mkfs 命令来创建一个 ext2, ext3 等文件系统的档案. 这样的档案才是可以被挂载的.

loop mount 一直以来是 Unix-like 系统下很有用的特性, 能帮助你当你拿到一个 iso 文件后, 不必将其刻录到 CD/DVD 里就能查看里面的内容. windows 下直到 windows 7 才支持这一特性, 在此之前都需要借助第三方软件如 Daemon Tools 来实现虚拟光驱的功能.

绑定式挂载 (bind mount)

上面所说的 “挂载” 都是指让你将某个设备挂载到某一目录, 不管这个设备是真实的物理设备, 还是假的 loop 设备, 它都是设备. 而 “绑定式挂载” 能够允许你将已经的存在目录挂载到另一目录. 比如:

mount --bind / /home/username/mnt-point 

这样, 你的 mnt-point 目录下也会有 etc, opt, usr 等目录, 这一过程我们称作 “将根目录绑定到 /home/username/mnt-point 上”, 所以, 你在一处改变目录下的内容的话, 在另一处也能够看到改变.

需要注意的一点是如果根目录树下有某个目录是挂载到另一个磁盘分区的话, 那么它可能不会被绑定到新的目录下. 比如说如果 /usr 和 / 处于不同的磁盘分区(/ 在 sda1, /usr 在 sda2), 那么你可能会发现 /home/username/mnt-point/usr 是空的, 那么这时可以额外挂载一次来使得 /usr 也出现在 /home/username/mnt-point/usr:

mount --bind /usr /home/username/mnt-point/usr 

不过你也可以在一开始就执行:

mount --rbind / /home/username/mnt-point 

关于绑定式挂载,man 2 mount中的描述是 “使一个文件, 或者一个目录树在另一个目录上可见”. 这地方不太理解, 就我所知, 只能将目录绑定到目录, 不能将文件绑定到目录的. 我尝试过将一个普通的文件绑定到目录, 但报错了. 不知道 man 手册里这个说法是什么意思. 我只能这么理解: 目录也是文件, 所以这种说法没错吧….

重新挂载 (remount)

借助于绑定式挂载, 可以实现有趣的效果, 比如说, 你可以将 / 绑定到 /, 将 /tmp/test/ 绑定到 /tmp/test/ (运行 mount 命令就能看到效果). 不过… 这么干有个鸟用啊!! 谁这么无聊会去这么干啊!!

这就是 remount 存在的原因, 我们虽然可以通过绑定式挂载耍点小聪明, 将自己绑定到自己上, 但这与没绑定没有任何区别啊; 然而借助 remount, 我们就可以在重新挂载的时候修改挂载的参数.

remount 最常用的情况就是将一个文件系统由只读重新挂载为读写, 或者相反. 比如:

mount -o remount,rw / 

通过 fstab 设置开机挂载的问题

Linux 在启动的时候通过 fstab 中的信息挂载各个分区,一个典型的分区条目就像这样:

/dev/sda3     /data      ext3    defaults 1    2

/dev/sda3 为需要挂载的分区,sda3是 Linux 检测硬盘时按顺序给分区的命名,一般来讲,这个名称并不会变化,但是如果你有多块硬盘,硬盘在电脑中的顺序变化的时候,相同的名称可能代表着不同的硬盘分区。这样的话上面设置的开机自动挂载就会出现找不到分区上面的文件情况
这个时候 UUID 就派上用场了,UUID 全称是 Universally Unique Identifier,也就是说,每个分区有一个唯一的 UUID 值,这样就不会发生分区识别混乱的问题了。
在 fstab 中用 UUID 挂载分区格式如下:

UUID=7cc82613-5be2-4e58-b359-0920613f9509     /data        ext3    defaults   1    2

可以通过下面命令得到分区的UUID

ls -l  /dev/disk/by-uuid/

FAQ

  1. 挂载点不一定是一个目录, 可以是文件
  2. 一个分区挂载在一个已存在的目录上,这个目录可以不为空,但挂载后这个目录下以前的内容将不可用。对于其他操作系统建立的文件系统的挂载也是这样,卸载后,目录以前的文件都还在,不会有任何丢失
  3. 目录只占磁盘里的一个inode,存放文件属性等信息
  4. 任何一个分区都必须挂载到某个目录上
  5. 目录是逻辑上的。分区是物理上的. f. 磁盘Linux分区都必须挂载到目录树中的某个具体的目录上才能进行读写操作
  6. 根目录是所有Linux的文件和目录所在的地方,需要挂载上一个磁盘分区
  7. 一个分区可以挂在多个目录,但反过来一个目录只能是一个分区的挂载点

原文

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深入linux下文件系统磁盘Disk,分区Partition,挂载Mount 的相关文章

  • 使用 Python 将阿拉伯语或任何从右到左书写系统的字符串打印到 Linux 终端

    非常简单的例子是 city print city 我期望输出是 但实际上输出是相反的字符串 字母看起来有点不同 因为它们有开始 中间和结束形式 我无法将其粘贴到此处 因为复制粘贴会再次更正字符串的顺序 如何在 Linux 终端上正确打印阿拉
  • 如何使用 PyAudio 选择特定的输入设备

    通过 PyAudio 录制音频时 如何指定要使用的确切输入设备 我的电脑有两个麦克风 一个内置 一个通过 USB 我想使用 USB 麦克风进行录音 这流类 https people csail mit edu hubert pyaudio
  • PHP mail() 函数不发送邮件

    我有一个小问题 我正在使用一个工作脚本 在我的测试帐户 共享服务器上工作 使用 mail 函数通过 PHP 发送邮件 我刚刚得到了一个专用服务器 但我还无法让该功能发挥作用 在过去的 10 个小时左右的时间里 我阅读了有关 BIND 用于
  • SIGHUP 用于重新加载配置

    根据signal 7 SIGHUP用于检测控制终端的挂起或控制进程的死亡 然而 我遇到过很多 OSS 守护进程 服务 其中SIGHUP用于启动配置的重新加载 这里有一些例子 hostapd sshd snort etc 这是实现重新加载的标
  • 进程如何知道它已收到信号

    如果我错了 请纠正我 以下是我对信号的理解 据我所知 信号生成 和信号传递有2个不同 事物 为了产生信号 操作系统只是在位数组中设置一个位 在过程控制中维护 工艺块 PCB 每一位 对应于特定信号 当设置一个位时 这意味着 该位对应的信号为
  • 为什么我的代码在编译用于分析 (-pg) 时在多线程下运行比在单线程下运行慢?

    我正在写一个光线追踪器 最近 我在程序中添加了线程 以利用 i5 四核上的附加内核 奇怪的是 应用程序的调试版本现在运行速度变慢 但优化后的构建运行速度比添加线程之前更快 我将 g pg 标志传递给 gcc 以进行调试构建 并将 O3 标志
  • 删除 Python 中某些操作的 root 权限

    在我的 Python 脚本中 我执行了一些需要 root 权限的操作 我还创建并写入文件 我不想由 root 独占所有 而是由运行我的脚本的用户独占所有 通常 我使用以下命令运行脚本sudo 有办法做到上述吗 您可以使用以下方式在 uid
  • X 按键/释放事件捕获,与焦点窗口无关

    我想记录所有传入的按键事件 无论哪个窗口处于焦点状态或指针位于何处 我编写了一个示例代码 它应该捕获当前焦点窗口的按键事件 include
  • 设置 Vim 背景颜色

    当我尝试更改背景颜色时 vimrc或者直接在 Vim 中使用以下命令 set background dark 这根本不影响我的背景 也没有light选项 不过 当我运行 gvim 时 看起来还不错 有没有办法在不更改 Konsole 设置的
  • 为什么“script”命令会生成 ^[ 和 ^M 字符以及如何使用 vim 搜索和替换删除它们?

    在linux上 使用bash shell 当我使用script命令时 生成的文件称为typescript 当我用 vim 打开该文件时 每一行都包含 M字符 并且有几行 由于我的彩色命令提示符 包含一个字符 我想用任何东西替换这些字符 从而
  • 如何获取 bash 中从 Ping 接收到的数据包的百分比?

    当 ping 主机时 我希望输出仅显示收到的数据包 已发送 5 个 的百分比 我想我需要使用grep不知怎的 但我不知道如何 我是 bash 编程的新手 这是我所在的地方 ping c 5 q host grep grep 中应该包含什么
  • SVN 不断提示我输入密码并拒绝缓存我的凭据

    环境 Eclipse Indigo Ubuntu 11 04 Subclipse 1 6 SVN 客户端 Subclipse RabbitVCS 我通过 svn ssh 连接 我的网址如下所示 svn ssh 我的名字 我的域名 路径 我可
  • 如何防止 CMake 在构建时(而不是安装时)为共享库创建符号链接?

    我正在使用 CMake 在 Linux 上使用 Bullet3 构建一个项目 在构建整个解决方案时 它会构建附加了 SOVERSION 的 Bullet 输出库 并创建一个不带版本的符号链接 对于我的特定场景 我不喜欢这种行为 并且我不想编
  • 为什么 RHEL 上的 bash 中 `read -t` 没有超时?

    Why read t在 RHEL5 或 RHEL6 上从管道读取时不会超时 这是我的示例 在从管道读取数据时 我的 RHEL 盒子不会超时 tail f logfile log grep something read t 3 variabl
  • 有没有办法让 Linux CLI IO 重定向持久化?

    我有多个管道命令 如下所示 find options grep options xargs grep options 它们中的每一个都可能产生我不感兴趣的错误 权限错误 文件名空格错误等 因此 我想将所有错误重定向到 dev null 我知
  • /usr/bin/as:无法识别的选项“-EL”

    因此 在为我的1plus手机编译android内核时 经过3天的多次尝试 我放弃了并尝试在这里询问是否有人以前遇到过这个问题 这个错误对我来说有点模糊 但我觉得问题来自于我最近对 GNU Linux 发行版 Gentoo 的更改 它在不应该
  • 尝试编译 git 但在 linux 中找不到 libcurl

    我想编译支持 http https 的 git 我有 ls usr include curl curlbuild h curl h curlrules h curlver h easy h mprintf h multi h stdchea
  • Docker 容器可以访问 DNS,但无法解析主机

    我在运行 docker 容器时遇到一个有趣的问题 突然间 我无法从容器内解析 DNS 这是一个概要 一切都没有解决 apt get pip 一次性 ping 容器等正在运行docker run it dns 8 8 8 8 ubuntu p
  • 对于客户端服务器程序,并行接收多个客户端连接请求的最佳方法是什么?

    该程序是在 Linux 上用 C 语言开发的客户端服务器套接字应用程序 每个客户端都连接到一个远程服务器并将其自身记录为在线 在任何给定时间点很可能有多个客户端在线 所有客户端都尝试连接到服务器以将自己记录为在线 忙碌 空闲等 那么服务器如
  • Tk 初始化失败:无显示名称且无 $DISPLAY 环境变量

    我试图从 Ubuntu 终端调用 Centos 服务器上的工具 我收到以下错误 Tk 初始化失败 没有显示名称 也没有 DISPLAY 环境变量 请帮我解决这个问题 提前致谢 连接到你的 CentOS 机器ssh Y其中 每man ssh

随机推荐