Linux 基础学习训练教材 - CentOS 8.x

第 6 堂课:基础文件系统管理

文件系统的管理与文件管理不太一样喔!是在底层进行分割、格式化的动作~还有开机过程出问题要如何处理!?来瞧瞧看看!

最近更新时间: 2020/04/11

系统总有容量不足,或者是需要其他文件系统挂载的时刻,毕竟管理员会经常从不同的来源来取得所需要软件与数据。 因此,管理文件系统就是管理员一个很重要的任务。Linux 文件系统最早使用 Ext2 文件系统家族(包括 EXT2/EXT3/EXT4 等等), 但由于磁盘容量越来大,因此适合大容量的 XFS 文件系统在 CentOS 8 被设为缺省文件系统了。因此读者应该要熟悉这些文件系统的管理才行。

6.1:认识 Linux 文件系统

目前 CentOS 8 Linux 文件系统主要支持 EXT2 家族 (目前新版为 EXT4) 以及 XFS 大型文件系统两种。其中 XFS 相当适合大容量磁盘, 格式化的性能非常快。但无论哪种文件系统,都必须要符合 inode 与 block 等文件系统使用的特性。

6.1.1:磁盘文件名与磁盘分割

磁盘内的圆形磁盘盘常见的物理特性如下:

  • 磁区(Sector)为最小的物理保存单位,目前主要有 512bytes 与 4K 两种格式;
  • 将磁区组成一个圆,那就是磁柱(Cylinder)(在此忽略磁道);
  • 分割的最小单位可能是磁柱 (cylinder) 也可能是磁区 (sector),这与分割工具有关
  • 磁盘分割表主要有两种格式,分别是 MSDOS (或称 MBR) 与 GPT 分割表。
  • MSDOS 分割表中,第一个磁区最重要,里面有:
    • (1)主要开机区(Master boot record, MBR) 446 bytes 及
    • (2)分割表(partition table) 64 bytes。
  • GPT 分割表除了分割数量扩充较多之外,支持的磁盘容量也可以超过 2TB。

整颗磁盘必须要经过分割之后,Linux 操作系统才能够读取分区内的文件系统。目前的 Linux 磁盘分割主要有两种分割, 分别为早期的 MSDOS 与现今的 GPT。由于 MBR 会有 2TB 容量的限制,但目前的磁盘容量已经都超过 2TB 来到 8TB 以上的等级, 因此 MSDOS 的分割类型就不太适用了。

磁盘文件名主要为 /dev/sd[a-p] 这种实体磁盘的文件名,以及通过 virtio 模块加速的 /dev/vd[a-p] 的虚拟磁盘文件名。 另外,如果使用了软件磁盘数组,或者是 Intel 主板上面内置的磁盘数组时,磁盘文件名则会增加类似 /dev/md126 这类的名称。 由于虚拟机的环境中,大部分磁盘的容量还是小于 2TB 的条件,因此传统的 MSDOS 分割表还是有其存在的需求的。

由于技术的成熟,近年来 SSD 或 M2 插槽的固态硬盘已经使用的越来越广泛,而这些固态硬盘并没有所谓的磁头、磁柱与磁道,因此, 分割工具渐渐则以磁区 (sector) 为单位去进行分割的行为了!这样对于传统磁盘或固态硬盘来说,就会显的一致!

  • MSDOS (MBR 分割表) 磁盘分割的限制

如前所示,由于 MBR 的纪录区块仅有 64 bytes 用在分割表,因此缺省分割表仅能纪录四笔分割信息。 所谓的分割信息即是纪录开始与结束的磁区。这四笔纪录主要为『主要分区 (primary)』与『延伸分区 (extended)』。延伸分割不能被格式化应用, 需要再从延伸分割当中割出『逻辑分割 (logical)』之后,才能够应用。以 P 代表主要、E 代表延伸、L 代表逻辑分区,则相关性为:

  • 主要分割与延伸分割最多可以有四笔(硬盘的限制)
  • 延伸分割最多只能有一个(操作系统的限制)
  • 逻辑分割是由延伸分割持续切割出来的分区;
  • 能够被格式化且作为数据访问的分区为主要分割与逻辑分割。延伸分割无法被格式化;
  • 逻辑分割的数量依操作系统而不同,在Linux系统中SATA硬盘已经可以突破63个以上的分割限制;
  • GPT 磁盘分割

常见的磁盘磁区有 512bytes 与 4K 容量,为了兼容于所有的磁盘,因此在磁区的定义上面, 大多会使用所谓的逻辑区块地址(Logical Block Address, LBA)来处理。GPT 将磁盘所有区块以此 LBA(缺省为 512bytes) 来规划,而第一个 LBA 称为 LBA0 (从 0 开始编号)。

与 MSDOS 仅使用第一个 512bytes 区块来纪录不同, GPT 使用了 34 个 LBA 区块来纪录分割信息! 同时与过去 MBR 仅有一个区块的情况不同, GPT 除了前面 34 个 LBA 之外,整个磁盘的最后 33 个 LBA 也拿来作为另一个备份! 因此,如果磁盘前面的分割纪录不小心被恶搞而失去,可以通过分割工具,以磁盘最后方的磁区记载的分割表来复原, 对于信息安全来说,也是相当重要的保护!

LBA2 ~ LBA33 为实际纪录分割表的所在,每个 LBA 纪录 4 笔数据,所以共可纪录 32*4=128 笔以上的分割信息。 因为每个 LBA 为 512bytes,因此每笔纪录可占用 512/4=128 bytes 的纪录,因为每笔纪录主要纪录开始与结束两个磁区的位置, 因此纪录的磁区位置最多可达 64 比特,若每个磁区容量为 512bytes ,则单一分区的最大容量就可以限制到 8ZB, 其中 1ZB 为 2^30 TB。

此外,每笔 GPT 的分割纪录,都是属于 primary 的分割纪录,可以直接拿来进行格式化应用的。

例题 6.1.1-1:理解分割表的差异
  1. 超过几个 TB 以上的磁盘,通常缺省会使用 GPT 的分割表?
  2. 某一磁盘的分割为使用 MBR 分割表,该系统当中『共有 5 个可以进行格式化』的分区,假设该磁盘含有 2 个主分割 (primary), 请问该磁盘的分区的磁盘文件名应该是如何? (假设为实体磁盘的文件名,且该系统仅有一颗磁盘时)
  3. 某一个磁盘缺省使用了 MBR 的分割表,目前仅有 2 个主分割,还留下 1TB 的容量。若管理员还有 4 个需要使用的分区, 每个分区需要大约 100GB ,你认为应该如何进行分割较佳?

6.1.2:Linux 的 EXT2 文件系统

新的操作系统在规划文件系统时,一般文件会有属性(如权限、时间、身份数据纪录等)以及实际数据的纪录, 同时整个文件系统会纪录全部的信息,因此通常文件系统会有如下几个部份:

  • superblock:记录此 filesystem 的整体信息,包括inode/block的总量、使用量、剩余量, 以及文件系统的格式与相关信息等;
  • inode:记录文件的属性,一个文件占用一个inode,同时记录此文件的数据所在的 block 号码;
  • block:实际记录文件的内容,若文件太大时,会占用多个 block 。

以 EXT2 文件系统为例,为了简化管理,整个文件系统会将全部的内容分出数个区块群组 (block group), 每个区块群组会有上述的 superblock/inode/block 的纪录,可以下图标意:

图6.1.2-1、EXT2 文件系统示意图
图6.1.2-1、EXT2 文件系统示意图
  • Superblock (超级区块)

superblock 为整个文件系统的总结信息处,要读取文件系统一定要从 superblock 读起。superblock 主要纪录数据为:

  • block 与 inode 的总量;
  • 未使用与已使用的 inode / block 数量;
  • block 与 inode 的大小 (block 为 1, 2, 4K,inode 为 128bytes, 256bytes 或 512bytes);
  • filesystem 的挂载时间、最近一次写入数据的时间、最近一次检验磁盘 (fsck) 的时间等文件系统的相关信息;
  • 一个 valid bit 数值,若此文件系统已被挂载,则 valid bit 为 0 ,若未被挂载,则 valid bit 为 1
  • inode table (inode 表格)

每一个 inode 都有号码,而 inode 的内容在记录文件的属性以及该文件实际数据是放置在哪几号 block 内。 inode 记录的文件数据至少有底下这些:

  • 该文件的访问模式(read/write/excute);
  • 该文件的拥有者与群组(owner/group);
  • 该文件的容量;
  • 该文件创建或状态改变的时间(ctime);
  • 最近一次的读取时间(atime);
  • 最近修改的时间(mtime);
  • 定义文件特性的旗标(flag),如 SetUID...;
  • 该文件真正内容的指向 (pointer);

由于每个文件固定会占用一个 inode,而目前文件所记载的属性数据越来约多,因此 inode 有底下几个特色:

  • 每个 inode 大小均为固定 (可能是 256bytes 或 512bytes,依据文件系统不同而定。旧的系统则只能到 128 bytes);
  • 每个文件都仅会占用一个 inode 而已;
  • 承上,因此文件系统能够创建的文件数量与 inode 的数量有关;
  • 系统读取文件时需要先找到 inode,并分析 inode 所记录的权限与用户是否符合,若符合才能够开始实际读取 block 的内容。
  • data block (数据区块)

文件实际的数据存放在 data block 上面,每个 block 也都会有号码,提供给文件来保存实际数据,也让 inode 可以纪录数据放在哪个 block 号码内。

  • 原则上,block 的大小与数量在格式化完就不能够再改变了(除非重新格式化);
  • 每个 block 内最多只能够放置一个文件的数据;
  • 承上,如果文件大于 block 的大小,则一个文件会占用多个 block 数量;
  • 承上,若文件小于 block ,则该 block 的剩余容量就不能够再被使用了(磁盘空间会浪费)。
  • 文件读写的操作进程

一般来说,文件系统内的一个文件被读取时,流程是这样的:

  1. 读到文件的 inode 号码
  2. 由 inode 内的权限设置判定用户能否访问此文件
  3. 若能读取则开始读取 inode 内所纪录的数据放置于哪些 block 号码内
  4. 读出 block 号码内的数据,组合起来成为一个文件的实际内容。

至于新建文件的流程则是这样的:

  1. 有写入文件的需求时,先到 metadata 区找到没有使用中的 inode 号码
  2. 到该 inode 号码内,将所需要的权限与属性相关数据写入,然后在 metadata 区规范该 inode 为使用中,且更新 superblock 信息
  3. 到 metadata 区找到没有使用中的 block 号码,将所需要的实际数据写入 block 当中,若数据量太大,则继续到 metadata 当中找到更多的未使用中的 block 号码,持续写入,直到写完数据为止。
  4. 同步更新 inode 的纪录与 superblock 的内容。

至于删除文件的流程则是这样的:

  1. 将该文件的 inode 号码与找到所属相关的 block 号码内容抹除
  2. 将 metadata 区域的相对应的 inode 与 block 号码规范为未使用。
  3. 同步更新 superblock 数据。
例题 6.1.2-1:了解文件系统的内容
  1. Linux 的 EXT2 文件系统家族中,格式化之后,除了 metadata 区块之外,还有哪三个很重要的区块?
  2. 文件的属性、权限等数据主要放置于文件系统的哪个区块内?
  3. 实际的文件内容 (代码或者是实际数据) 放置在哪个区块?
  4. 每个文件都会使用到几个 inode 与 block ?
  5. Linux 的 EXT2 文件系统家族中,以 CentOS 8 为例,inode 与 block 的容量大致为多少 byte?请以 dumpe2fs 这个指令,观察我们教学系统的 /dev/vda2, 看看内容是什么?并且尝试分析。

6.1.3:目录与文件名

当用户在 Linux 下的文件系统创建一个目录时,文件系统会分配一个 inode 与至少一块 block 给该目录。其中,inode 记录该目录的相关权限与属性,并可记录分配到的那块 block 号码; 而 block 则是记录在这个目录下的文件名与该文件名占用的 inode 号码数据。也就是说目录所占用的 block 内容在记录如下的信息:

图6.1.3-1、记载于目录所属的 block 内的文件名与 inode 号码对应示意图
图6.1.3-1、记载于目录所属的 block 内的文件名与 inode 号码对应示意图

前一小节提到读取文件数据时,最重要的就是读到文件的 inode 号码。然而读者实际操作系统时,并不会理会 inode 号码, 而是通过『文件名』来读写数据的。因此,目录的重要性就是记载文件名与该文件名对应的 inode 号码。

例题 6.1.3-1:理解目录、文件名、inode 号码的意义与观察
  1. 使用 ls -li /etc/hosts* ,观察出现在最前面的数值,该数值即为 inode 号码。
  2. 使用 student 的身份,创建 /tmp/inodecheck/ 目录,然后观察 /tmp/inodecheck/, /tmp/inodecheck/. 这两个文件名的 inode 号码
  3. 承上,使用 ll -d 观察 /tmp/inodecheck 的第二个字段,亦即链接字段的数值为多少?尝试说明为什么?
  4. 创建 /tmp/inodecheck/check2/ 目录,同时观察 /tmp/inodecheck/ , /tmp/inodecheck/. , /tmp/inodecheck/check2/.. 这三个文件名的 inode 号码, 然后观察第二个字段的数值变成什么?

6.1.4:ln 链接档的应用

从前一小节的练习当中读者可以发现到目录的缺省链接数 (使用 ls -l 观察文件名的第二个字段) 为 2, 这是因为每个目录底下都有 . 这个文件名,而这个文件名代表目录本身,因此目录本身有两个文件名链接到同一个 inode 号码上, 故链接数至少为 2 。又同时每个目录内都有 .. 这个文件名来代表父目录,因此每增加一个子目录,父目录的链接数也会加 1 。

由于链接数增加后,若文件名删除时,其实 inode 号码并没有被删除,因此这个『实体链接』的功能会保护好原本的文件数据。 用户可以通过 ln 这个指令来达成实体链接与符号链接 (类似捷径) 的功能。

例题 6.1.4-1:使用链接档,并认识实体链接与符号链接
  1. 前往 /dev/shm 创建名为 check2 的目录,并更改工作目录到 /dev/shm/check2 当中
  2. 将 /etc/hosts 拷贝到本目录下,同时观察文件名链接数
  3. 使用『 ln hosts hosts.real 』创建 hosts.real 实体链接档,同时观察这两个文件的 inode 号码、属性权限等,是否完全相同?为什么?
  4. 使用『 ln -s hosts hosts.symbo 』创建 hosts.symbo 符号链接,同时观察这两个文件的 inode 号码、属性权限等,是否相同?
  5. 使用 cat hosts; cat hosts.real; cat hosts.symbo ,查阅文件内容是否相同?
  6. 请删除 hosts,然后观察 hosts.real, hosts.symbo 的 inode 号码、链接数文件属性等数据,发现什么情况?
  7. 使用 cat hosts.real; cat hosts.symbo 发生什么状况?为什么?
  8. 在 /dev/shm/check2 底下运行『 ln /etc/hosts . 』会发生什么情况?分析原因为何?

6.1.5:文件系统的挂载

就像U盘放入 windows 操作系统后,需要取得一个 H:\> 或者是其他的磁盘名称后才能够被读取一样, Linux 底下的目录树系统中,文件系统设备要能够被读取,就得要与目录树的某个目录链接在一起,亦即进入该目录即可看到该设备的内容之意。 该目录就被称为挂载点。

观察挂载点的方式最简单为使用 df (display filesystem) 这个指令来观察,而读者也可以通过观察 inode 的号码来了解到挂载点的 inode 号码。

例题 6.1.5-1:了解挂载的功能
  1. 文件系统要通过『挂载 (mount) 』之后才能够让操作系统访问。那么与文件系统挂载的挂载点是一个目录还是文件?
  2. 使用 df -T 指令观察目前的系统中,属于 xfs 文件系统的挂载点有哪几个?
  3. 使用 ls -lid 观察 /, /boot, /home, /etc, /root, /proc, /sys 等目录的 inode 号码
  4. 为什么 /, /boot, /home 的 inode 号码有些会相同?不是说 inode 号码对于不同的文件来说,是独一无二的?

6.2:文件系统管理

一般来说,创建文件系统需要的动作包括:分割、格式化与挂载三个步骤。而分割又有 MBR 与 GPT 两种方式,实做时需要特别留意。

6.2.1:创建分割

创建分割之前,需要先判断:(1)目前系统内的磁盘文件名与(2)磁盘目前的分割格式。这两个工作可以使用底下的指令完成:

例题 6.2.1-1:使用 root 身份完成如下的练习
  1. 先用 lsblk 简单的列出设备文件名
  2. 使用 man lsblk 找出来,(1)使用纯文本 (ASCII) 显示的选项与(2) 列出完整 (full) 的设备文件名的选项
  3. 使用『 parted <完整设备文件名> print 』指令,找出分割表的类型 (MBR/GPT)。

如果是 GPT 的分割表,请使用 gdisk 指令来分割,若为 msdos (MBR) 分割表,则需要使用 fdisk 来分割。当然, 读者也能够直接参考指令型的 parted 来进行分割,只是指令比较麻烦一些些,并且没有默认值而已。由刚刚上面的练习可以发现到训练机为 GPT 分割表, 因此底下将以 gdisk 来进行分割的行为。首先读者先了解一下 gdisk 的操作界面以及在线查找的方式:

[root@study ~]# gdisk /dev/vda
GPT fdisk (gdisk) version 0.8.6

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.  <==找到了 GPT 的分割表!

Command (? for help):     <==这里可以让你输入指令动作,可以按问号 (?) 来查看可用指令
Command (? for help): ?
b       back up GPT data to a file
c       change a partition's name
d       delete a partition           # 删除一个分割
i       show detailed information on a partition
l       list known partition types
n       add a new partition          # 增加一个分割
o       create a new empty GUID partition table (GPT)
p       print the partition table    # 印出分割表 (常用)
q       quit without saving changes  # 不保存分割就直接离开 gdisk
r       recovery and transformation options (experts only)
s       sort partitions
t       change a partition's type code
v       verify disk
w       write table to disk and exit # 保存分割操作后离开 gdisk
x       extra functionality (experts only)
?       print this menu
Command (? for help):  

之后开始列出目前这个 /dev/vda 的整体磁盘信息与分割表信息:

Command (? for help): p  <== 这里可以输出目前磁盘的状态
Disk /dev/vda: 83886080 sectors, 40.0 GiB                     # 磁盘文件名/磁区数与总容量
Logical sector size: 512 bytes                                # 单一磁区大小为 512 bytes 
Disk identifier (GUID): A4C3C813-62AF-4BFE-BAC9-112EBD87A483  # 磁盘的 GPT 识别码
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 83886046
Partitions will be aligned on 2048-sector boundaries
Total free space is 18862013 sectors (9.0 GiB)

Number  Start (sector)    End (sector)  Size       Code  Name # 底下为完整的分割信息了!
   1            2048            6143   2.0 MiB     EF02       # 第一个分区数据
   2            6144         2103295   1024.0 MiB  0700
   3         2103296        65026047   30.0 GiB    8E00
# 分割编号 开始磁区号码  结束磁区号码  容量大小
Command (? for help): q
# 想要不保存离开吗?按下 q 就对了!不要随便按 w 啊!

接下来请管理员直接创建一个 1GB 的分区。

例题 6.2.1-2:请使用 root 的身份完成底下的任务-磁盘分割
  1. 检查 /dev/vda 的容量状态:
    1. 使用 gdisk /dev/vda 进入 gdisk 的界面
    2. 按下 p 取得目前的分割表,并且观察『目前是否还有其他剩余的容量可使用』
  2. 若有剩余容量,则开始处理磁盘的分割动作:
    1. 按下 n 进行添加的动作
    2. 在 Partition number 的地方直接按下 [enter] 使用默认值"4";
    3. 在 First sector 的地方也可以直接按下 [enter] 使用默认值即可;
    4. 在 Last sector 的地方就得要使用类似『 +1G 』的方式来提供 1G 的容量;
    5. 在 Hex code or GUID) 的地方,由于是 Linux 的文件系统,可以保留 8300 的数据,因此直接按下 [enter] 即可
    6. 按下 p 来查阅一下是否取得正确的容量
  3. 开始进行保存分割表的动作:
    1. 上述动作观察后,若没有问题,按下『 w 』来保存后离开
    2. 系统会询问『 Do you want to proceed? (Y/N): 』按下 y 来确认即可。
    3. 观察按下 y 之后出现什么消息?仔细分析该消息。
  4. 确认磁盘分割已经让 Linux kernel 抓到,并且可以开始应用新分割:
    1. 使用 lsblk 是否有查阅到刚刚创建的分区文件名?
    2. 使用『 partprobe 』之后,再次『 lsblk 』,此时是否出现了新的分区文件名?

由于 /dev/vda 磁盘正在使用中,因此内核缺省不会重新去探索分割表的变动,读者需要使用 partprobe 强制内核更新目前使用中的磁盘的分割表, 这样才能够找到正确的设备文件名了。若需要列出内核侦测到的完整分割表,也能使用『 cat /proc/partitions 』来观察。

例题 6.2.1-3:使用如上个例题的流程,再次创建如下两个设备:
  1. 大约 1.5G (1500MB) 的 vfat 分区 (GUID 应该是 0700,但请自己找出来)
  2. 大约 1G 的 swap 分区,同样的请自行找出 filesystem ID
  3. 请注意,分割完毕并且在 gdisk 界面按下 w 保存后,务必使用 lsblk 观察是否有出现刚刚建置的分区设备文件名, 若无该设备文件名,则应该使用 partprobe 或者是 reboot 强制内核重新抓取。

6.2.2:创建文件系统 (磁盘格式化)

文件系统的创建使用 mkfs (make filesystem) 即可处理。另外,内存置换应该要使用 mkswap 才对。目前的操作系统大多已经针对文件系统建置时做好优化设置, 因此除非读者有特殊需求,或者是读者知道自己高端磁盘数组的相关参数,否则使用默认值应该就能够取得不错的文件系统性能。

例题 6.2.2-1:创建文件系统 (make filesystem)
  1. 使用『 mkfs.xfs /dev/vda4 』创建好 XFS 文件系统
  2. 使用『 mkfs.vfat /dev/vda5 』创建好 FAT 文件系统
  3. 使用『 mkswap /dev/vda6 』创建好 swap 内存置换空间
  4. 使用『 blkid 』查找到每个设备的相关文件系统与 UUID 信息

每个磁盘分区的文件系统,都有其各自的识别码,这个识别码应该是独一无二的,建议同学们要认识 UUID 而不要只是记忆磁盘分区的文件名, 这是因为未来要进行挂载时,磁盘的文件名是可能会改变的,但是 UUID 则不会改变!所以,挂载使用时,还是使用 UUID 比较好!

6.2.3:文件系统的挂载/卸载

文件系统要挂载时,请先注意到底下的要求:

  • 单一文件系统不应该被重复挂载在不同的挂载点(目录)中;
  • 单一目录不应该重复挂载多个文件系统;
  • 要作为挂载点的目录,理论上应该都是空目录才是。

常见的挂载方式如下:

[root@localhost ~]# mount -a
[root@localhost ~]# mount [-l]
[root@localhost ~]# mount [-t 文件系统] LABEL=''  挂载点
[root@localhost ~]# mount [-t 文件系统] UUID=''   挂载点  # 建议用这种方式
[root@localhost ~]# mount [-t 文件系统] 设备文件名  挂载点
选项与参数:
-a  :依照设置档 /etc/fstab 的数据将所有未挂载的磁盘都挂载上来
-l  :单纯的输入 mount 会显示目前挂载的信息。加上 -l 可增列 Label 名称!
-t  :可以加上文件系统种类来指定欲挂载的类型。常见的 Linux 支持类型有:xfs, ext3, ext4,
      reiserfs, vfat, iso9660(光盘格式), nfs, cifs, smbfs (后三种为网络文件系统类型)
-n  :在缺省的情况下,系统会将实际挂载的情况即时写入 /etc/mtab 中,以利其他程序的运作。
      但在某些情况下(例如单人维护模式)为了避免问题会刻意不写入。此时就得要使用 -n 选项。
-o  :后面可以接一些挂载时额外加上的参数!比方说帐号、密码、读写权限等:
      async, sync:   此文件系统是否使用同步写入 (sync) 或异步 (async) 的内存机制
      atime,noatime: 是否修订文件的读取时间(atime)。为了性能,某些时刻可使用 noatime
      ro, rw:        挂载文件系统成为唯读(ro) 或可读写(rw)
      auto, noauto:  允许此 filesystem 被以 mount -a 自动挂载(auto)
      dev, nodev:    是否允许此 filesystem 上,可创建设备文件? dev 为可允许
      suid, nosuid:  是否允许此 filesystem 含有 suid/sgid 的文件格式?
      exec, noexec:  是否允许此 filesystem 上拥有可运行 binary 文件?
      user, nouser:  是否允许此 filesystem 让任何用户运行 mount ?一般来说,
                     mount 仅有 root 可以进行,但下达 user 参数,则可让
                     一般 user 也能够对此 partition 进行 mount 。
      defaults:      默认值为:rw, suid, dev, exec, auto, nouser, and async
      remount:       重新挂载,这在系统出错,或重新更新参数时,很有用!

请将 /dev/vda4, /dev/vda5 分别挂载到 /srv/linux, /srv/win 目录内,同时观察挂载的情况。

[root@localhost ~]# mkdir /srv/linux /srv/win
[root@localhost ~]# mount /dev/vda4 /srv/linux
[root@localhost ~]# mount /dev/vda5 /srv/win
[root@localhost ~]# df -T /srv/linux /srv/win
文件系统       类型 1K-区段  已用    可用 已用% 挂载点
/dev/vda4      xfs  1038336 40368  997968    4% /srv/linux
/dev/vda5      vfat 1532984     4 1532980    1% /srv/win

通过 df -T 可以查找到整体系统的文件系统挂载状态,如果只是想要查阅到某几个载点的信息,可以如上所示, 直接将载点放在 df 指令后面即可!这样画面也比较干净!至于 swap,这个内存置换并不是文件系统, 所以只能用开/关 (on/off) 的方式来加入/移除内存置换功能而已!请使用 swapon 的方式来启动 /dev/vda6 这个内存置换空间。

[root@localhost ~]# free
              total        used        free      shared  buff/cache   available
Mem:        1872280      624016      689576       12668      558688     1075544
Swap:       2097148           0     2097148

[root@localhost ~]# swapon /dev/vda6
[root@localhost ~]# swapon -s
Filename                                Type            Size    Used    Priority
/dev/dm-1                               partition       2097148 0       -2
/dev/vda6                               partition       1048572 0       -3

[root@localhost ~]# free
              total        used        free      shared  buff/cache   available
Mem:        1872280      625264      688252       12668      558764     1074272
Swap:       3145720           0     3145720
例题 6.2.3-1:手动处理文件系统的挂载行为!
  1. 仿真无法卸载的行为,亦即有任何进程在使用该载点的情况,就会无法卸载:
    1. 进入到 /srv/linux 目录内
    2. 开始卸载 /srv/linux
    3. 若无法卸载,请使用 lsof | grep /srv/linux 找到使用该目录的进程
    4. 将工作目录移动到家目录
    5. 再次卸载
  2. 请使用 umount 以及 swapoff 的方式,来将 /dev/vda4, /dev/vda5, /dev/vda6 卸载,并自行观察是否卸载成功?

6.2.4:开机自动挂载

开机自动挂载的参数设置档写入在 /etc/fstab 当中,不过在编辑这个文件之前,管理员应该先知道系统挂载的限制:

  • 根目录 / 是必须挂载的﹐而且一定要先于其它 mount point 被挂载进来。
  • 其它 mount point 必须为已创建的目录﹐可任意指定﹐但一定要遵守必须的系统目录架构原则 (FHS)
  • 所有 mount point 在同一时间之内﹐只能挂载一次。
  • 所有 partition 在同一时间之内﹐只能挂载一次。
  • 如若进行卸载﹐您必须先将工作目录移到 mount point(及其子目录) 之外。

训练机的 /etc/fstab 这个文件的内容如下:

[root@localhost ~]# cat /etc/fstab
/dev/mapper/centos-root                   /         xfs     defaults    0 0
UUID=73f13e7b-43c4-43c5-93b4-9e65b962752d /boot     ext4    defaults    1 2
/dev/mapper/centos-home                   /home     xfs     defaults    0 0
/dev/mapper/centos-swap                   swap      swap    defaults    0 0

这个文件主要有六个字段,每个字段的意义如下:

[设备/UUID等]  [挂载点]  [文件系统]  [文件系统参数]  [dump]  [fsck]
  • 第一栏:磁盘设备文件名/UUID/LABEL name:
    这个字段可以填写的数据主要有三个项目:
    • 文件系统或磁盘的设备文件名,如 /dev/vda2 等
    • 文件系统的 UUID 名称,如 UUID=xxx
    • 文件系统的 LABEL 名称,例如 LABEL=xxx
    管理员可以依据自己的喜好来填写适当的设备名称,不过如果是实体分区的文件系统,这里建议使用 Linux 设备内独一无二的设备代号, 亦即是 UUID 这个数据来替代设备文件名较佳。建议使用 blkid 找到 UUID 之后,通过 UUID="XXX" 的方式来设置。
  • 第二栏:挂载点 (mount point):
  • 第三栏:磁盘分区的文件系统:
    在手动挂载时可以让系统自动测试挂载,但在这个文件当中我们必须要手动写入文件系统才行!包括 xfs, ext4, vfat, reiserfs, nfs 等等
  • 第四栏:文件系统参数:
    文件系统参数有底下几个常见的设置值,若无需要,先暂时不要更动缺省的 defaults 设置值。
    参数内容意义
    async/sync
    异步/同步
    设置磁盘是否以异步方式运作!缺省为 async(性能较佳)。所谓的异步,意思是若有变动的文件数据, 该数据会暂时保存于内存中,而非立刻写入磁盘之意。
    auto/noauto
    自动/非自动
    当下达 mount -a 时,此文件系统是否会被主动测试挂载。缺省为 auto。
    rw/ro
    可读写/唯读
    让该分区以可读写或者是唯读的型态挂载上来,如果你想要分享的数据是不给用户随意变更的, 这里也能够设置为唯读。则不论在此文件系统的文件是否设置 w 权限,都无法写入喔!
    exec/noexec
    可运行/不可运行
    限制在此文件系统内是否可以进行『运行』的工作?如果是纯粹用来保存数据的目录, 那么可以设置为 noexec 会比较安全。不过,这个参数也不能随便使用,因为你不知道该目录下是否缺省会有运行档。
    举例来说,如果你将 noexec 设置在 /var ,当某些软件将一些运行档放置于 /var 下时,那就会产生很大的问题喔! 因此,建议这个 noexec 最多仅设置于你自订或分享的一般数据目录。
    user/nouser
    允许/不允许用户挂载
    是否允许用户使用 mount 指令来挂载呢?一般而言,我们当然不希望一般身份的 user 能使用 mount 啰,因为太不安全了,因此这里应该要设置为 nouser 啰!
    suid/nosuid
    具有/不具有 suid 权限
    该文件系统是否允许 SUID 的存在?如果不是运行档放置目录,也可以设置为 nosuid 来取消这个功能!
    defaults 同时具有 rw, suid, dev, exec, auto, nouser, async 等参数。 基本上,缺省情况使用 defaults 设置即可!
  • 第五栏:能否被 dump 备份指令作用:
    dump 仅支持 EXT 家族,若使用 xfs 文件系统,则不用考虑 dump 项目。因此直接输入 0 即可。
  • 第六栏:是否以 fsck 检验磁区:
    早期开机的流程中,会有一段时间去检验本机的文件系统,看看文件系统是否完整 (clean)。 不过这个方式使用的主要是通过 fsck 去做的,我们现在用的 xfs 文件系统就没有办法适用,因为 xfs 会自己进行检验,不需要额外进行这个动作!所以直接填 0 就好了。

针对我们训练机的 /etc/fstab 的内容来说,在第 5, 6 字段上,除了 /boot 这个 ext4 的文件系统还有使用之外, 其余的通通设置为 0 了!基本上,连同 ext4 也都能设置为 0 啦!避免未来改写数据时,忘记修改这个字段! 好了,那么让我们来处理一下我们的新建的文件系统,看看能不能开机就挂载呢?

实际练习:让 /dev/vda4, /dev/vda5 及 /dev/vda6 每次开机都能直接挂载或激活,挂载点分别在 /srv/linux, /srv/win 目录内。
  1. 通过 blkid 找到 /dev/vda4, /dev/vda5, /dev/vda6 这三个设备的 UUID 信息
    [root@localhost ~]# blkid /dev/vda{4,5,6}
    /dev/vda4: UUID="f3f0b058-d9e3-4e78-a4f7-c7d9513513bb" TYPE="xfs" .....
    /dev/vda5: UUID="2F4E-C22A" TYPE="vfat" PARTLABEL="Microsoft basic.....
    /dev/vda6: UUID="d4e164a3-1e73-40ce-93cb-e3558fbbe8a0" TYPE="swap".....
    
  2. 使用 vim 在 /etc/fstab 最底下添加三行数据,如下所示:
    [root@localhost ~]# vim /etc/fstab
    UUID="f3f0b058-d9e3-4e78-a4f7-c7d9513513bb"  /srv/linux  xfs   defaults 0 0
    UUID="2F4E-C22A"                             /srv/win    vfat  defaults 0 0
    UUID="d4e164a3-1e73-40ce-93cb-e3558fbbe8a0"  swap        swap  defaults 0 0
    
  3. 开始测试挂载以及 swap 置换有没有成功的处理好。请注意,测试前请务必确认这三个设备已经卸载且没有使用中。
    [root@locahost ~]# mount -a
    [root@locahost ~]# swapon -a
    
    [root@locahost ~]# df -T /dev/vda{4,5}
    文件系统       类型 1K-区段  已用    可用 已用% 挂载点
    /dev/vda4      xfs  1038336 40368  997968    4% /srv/linux
    /dev/vda5      vfat 1532984     4 1532980    1% /srv/win
    
    [root@locahost ~]# swapon -s
    Filename               Type            Size    Used    Priority
    /dev/dm-1              partition       2097148 0       -2
    /dev/vda6              partition       1048572 0       -3
    

你得要特别注意的是,当上述的设备或挂载点已经被使用时,那么你的 /etc/fstab 内关于该设备或载点的信息,将不会被测试挂载。 所以,上面的练习中,原有的挂载点,亦即是 /, /home 等,其实不会被重新测挂载的。因此,当你要测试时,请先将要被测试的载点卸载, 这样才能够真的测试你的设置是否正确喔!

6.3:开机过程文件系统问题处理

管理员可能因为某些原因需要将文件系统回收利用,例如抽换旧硬盘来使用等等,因此读者仍须学会如何卸载磁盘。 此外,或许因为设置的问题可能导致开机时因为文件系统的问题而导致无法顺利完成开机的流程,此时就需要额外的修复作业。

6.3.1:文件系统的卸载与移除

若需要将文件系统卸载并回收 (旧的数据需要完整删除),一般建议的流程如下:

  • 判断文件系统是否使用中,若使用中则须卸载
  • 查找是否有写入自动挂载设置档,若有则需要将设置内容移除
  • 将文件系统的 superblock 内容删除
例题 6.3.1-1:依据上述的流程,请将练习机的磁盘恢复为原本的状态 (仅有 /dev/vda1, /dev/vda2, /dev/vda3)
  1. 为了测试系统有无问题,请先进行 reboot 的动作
  2. 使用 df -T 以及 swapon -s 查找是否有找到 /dev/vda{4,5,6},若存在,请分别以 umount 及 swapoff 予以卸载或关闭 swap 的使用。
  3. 查找 /etc/fstab ,若存在上述的数据,请注解或删除该行
  4. 使用 mount -a, swapon -a 测试 /etc/fstab 的内容,然后再以 df -T 及 swapon -s 检查是否已经顺利移除
  5. 使用『 dd if=/dev/zero of=/dev/vda4 bs=1M count=10 』的指令,将 superblock 的内容 (最前面的 10MB 处) 清空
  6. 使用 gdisk /dev/vda 搭配 d 的指令,将 4, 5, 6 号删除
  7. 使用 partprobe 更新内核分割表信息,然后使用 lsblk 确认已经正确删除了本堂课所创建的分区。
其实没有清除 superblock 也没啥大不了,只是,如果未来你的添加分割『刚刚好起始点跟原本的就分割相同』时, 那当你创建文件系统前,操作系统可能会误判该分区其实是有文件系统的!也因此,如果你忘记重新格式化,就进行重新开机, 那操作系统可能会判断该分区内的文件系统损毁,这或许会造成些许莫名其妙的问题喔!

6.3.2:开机过程文件系统出错的救援

管理员如果修改过 /etc/fstab 却忘记使用 mount -a 测试,则当设置错误,非常有可能会无法顺利开机。如果是根目录设置出错,问题会比较严重, 如果是一般正规目录设置错误,则依据该目录的重要性,可能会进入单人维护模式或者是依旧可以顺利开机。底下的练习中,读者将实验让 /home 设置错误, 以尝试进入单人维护模式救援文件系统。

实际练习:仿真文件系统设置 /etc/fstab 写错时,导致系统无法顺利开机的状况,并加以排除!
  1. 使用 vim 编辑 /etc/fstab,将 /home 的所在行从原本的设置修改成为错误的设置,如下所示:
    [root@localhost ~]# vim /etc/fstab
    # 先找到这一行:
    /dev/mapper/centos-home  /home xfs  defaults   0 0
    
    # 将上面的数据改成如下的模样
    /dev/mapper/centos-home1  /home xfs  defaults   0 0
    
  2. 上述数据修改完毕保存离开后,重新开机系统。由于文件系统出错 (/home 为相当重要的正规目录),因此系统经过一段时间的探索后,会进入到单人维护模式的环境, 该环境显示如下所示:
    图 6.3.1-1、文件系统出错进入救援模式的情况 图 6.3.1-1、文件系统出错进入救援模式的情况
  3. 在光标上输入 root 的密码,就可以进入终端机模式。不过此时可能从屏幕上找不到问题。请依据上图中显示的 journalctl -xb 这个关键字的提示, 直接输入『 journalctl 』来查找开机流程的问题。进入 journalctl 画面后,先按大写『 G 』,再以『 PageUp 』按钮向前翻页数次, 找到红色字体请仔细观看,应该会发现如下画面:
    图 6.3.1-2、文件系统出错进入救援模式的情况
  4. 由上述的图标可以发现就是 /home 的设置有问题,因此管理员可以: (1)进入 /etc/fstab 暂时注解 /home 所在行或者是 (2)自行找到正确的方案来解决。 因为本案例可以查找到设备设置错误,因此请修改正确的设备名称,然后通过:(1)reboot 来重新开机,或 (2)exit 来加载后续的开机进程。

老实说,文件系统设置错误是一个很常见的情况,很多时候是因为 /etc/fstab 手滑打错字产生的问题。所以, 了解怎么解决问题,对于系统管理员来说,也是一个很重要的训练!

6.4:课后练习操作

  • 上课的课后练习,非作业:
  1. 文件系统的基础观察:
    1. 找出目前系统上面的所有磁盘文件名
    2. 找到根目录所在的那个设备上面,列出其分割表为 gpt 还是 msdos 呢?
    3. 找出目前所有的磁盘分割与个磁盘分区内的文件系统之 UUID 各为何?
    4. 根据各别的文件系统,分别以对应的文件系统观察指令 (dumpe2fs/xfs_info) 查看单个 inode 与 block 的容量大小)
    5. 找出目前有在使用的那个 swap 设备的文件名为何?
    6. 搭配 UUID 显示的设备数据,说明该设备的链接档其实是哪一个?
  2. inode number、目录、文件名与链接档的使用
    1. 以 find 找出来在 /etc 底下的链接档有哪些?
    2. 通过 ls -l 搭配管线与 grep 的功能,通过关键字 (>),找出 /etc (不含子目录) 底下的链接档
    3. 承上,列出该文件群的 inode 号码
    4. 工作目录切换为 /boot,并找出在该目录下,容量最大的是那一个文件?
    5. 先使用 df 观察,目前的 /boot 的文件系统使用状态,并使用 du 观察 /boot 的容量,同时以 ls -l 观察第一行输出的容量总量消息
    6. 将刚刚找到的最大容量文件文件名,创建实体链接的文件为 zzz.img
    7. 再以 df, du, ls -l 分别观察实际使用的容量。
    8. 通过 df 去观察目前的 /boot 使用的 inode 数量
    9. 删除 zzz.img ,再次观察 inode 数量有没有变化?
    10. 使用符号链接,将最大容量文件创建符号链接为 zzz.img,然后再观察 inode 数量的变化。
  3. 文件系统的创建、使用、卸载、移除
    1. 将目前系统所有的剩余容量通通创建到一个单一的分区,并且使用 8300 这个 systemid
    2. 请将此分区格式化成为 ext4 文件系统
    3. 让此系统再开机后,会自动挂载到 /home/othersystem 挂载点上面
    4. 重新开机,测试此系统是否能够顺利的挂载
    5. 开机完成再次登录后,将此设备再次删除,删除过后请重新开机,最终请确认该系统可用,且分割表与文件系统都是正常存在。
  • 作业 (不提供学生答案,仅提供教师参考答案)

作业硬盘一般操作说明:

  • 打开云端虚拟机前,请务必确认你打开的硬盘是『unit06』,否则就会做错题目
  • 若要使用图形界面,请务必使用 student 身份登录,若需要切换身份,再激活终端机处理。
  • 若有简答题需要使用中文,请自行以第一堂课的动作自行处理输入法安装。
  • 每部虚拟机均有独特的网卡地址,请勿使用他人硬盘上传,否则计分为 0 分。
  • 每位同学均有自己的 IP 尾数,请先向老师询问您的 IP 尾数,才可以进行作业上传。
  • 最终上传作业结果,请务必使用 root 身份上传。
  • 进入作业硬盘后,先用 root 身份运行 vbird_book_setup_ip , 运行流程请参考:vbird_book_setup_ip

作业当中,某些部份可能为简答题~若为简答题时,请将答案写入 /home/student/ans.txt 当中,并写好正确题号,方便老师订正答案。 请注意,文件名写错将无法上传!

请使用 root 的身份进行如下实做的任务。直接在系统上面操作,操作成功即可,上传结果的程序会主动找到你的实做结果。

  1. (20%)文件系统救援:管理员在上次处理文件系统时,编辑 /etc/fstab 时,手残将 /home 那个挂载点的挂载参数写错了,导致这次重新开机会失败。 请使用 man mount 之类的方式查找这次失败的可能参数后,订正 /etc/fstab,让系统可以顺利正常的开机。 请特别注意,是『修改有问题的参数』,不能直接将参数取消喔!
  2. (16%)关于磁盘与磁盘分割的问题,请在 /root/partition.txt 文件中,完成底下的问题回应:
    1. 针对传统硬盘 (非 SSD) 来说,(1)磁盘分割常见的最小单位有哪些?(2)每个磁区, sector 的容量有多大?
    2. 一般来说,在 CentOS 8 底下,第一颗实体磁盘与虚拟磁盘 (使用 virtio 模块) 的文件名分别为何?
    3. Linux 上 (1)常见的磁盘分割表有那两种?(2)若安装 linux 的时候,磁盘容量为 1TB 时,缺省的分割表为那一个?
    4. 针对 MBR 分割表格式 (或称为 MSDOS 分割模式) 来说,第一个磁区(sector) 含有那两个重要的信息?每个信息的容量各占多大?
    5. 承上,MBR 分割表格式中,主要有那三种类型的分割?那两种分割才能够被格式化利用?
    6. 承上,MBR 分割表中,主分割与延伸分割的『数量』有什么限制?
    7. 可以安装开机管理程序的位置,基本上有那两个地方?
    8. 在 CentOS 8 上面,根据两种不同的分割表,对应的分割指令是那两个?
  3. (6%)关于文件系统的问题,请将答案写入 /root/filesystem.txt 文件内:
    1. 一般 Linux 传统的 EXT 文件系统家族,当你在格式化的时候,会有哪三个重要的信息被切出来?
    2. CentOS 8 在格式化文件系统时 (针对 XFS),缺省的 inode 与 block 单一一个容量约为多少?
    3. 创建一个文件时,文件的 (1)属性与权限 (2)实际数据内容 (3)文件名 分别纪录在哪些地方?
  4. (16%)关于链接文件的建置行为:(问答题请写入 /root/links.txt )
    1. 在 /srv/examlink 文件,请找出(1)该文件的 inode 号码为几号?(2)这个 inode 共有几个文件名在使用?
    2. 我知道 /srv/examlink 的链接档放置在 /etc 底下,请使用 man find 找关键字 inode ,查到可以使用的选项与参数后, 实际找出 /srv/examlink 的实体链接档,并将文件名写下来。
    3. 创建实体链接,源文件案为 /etc/services 而新的文件文件名为 /srv/myservice
    4. 创建符号链接,源文件案为 /etc/vimrc 而新的文件文件名为 /srv/myvimrc
  5. (10%)关于文件系统与分区的删除: 系统内有个名为 /dev/vda4 的分区,这个分区是做错的,因此,请将这个分区卸载,然后删除分割, 将磁盘容量释放出来。
  6. (32%)完成上面的题目之后,请依据底下的说明创建好所需要的文件系统(所有的新挂载,应该使用 UUID 来挂载较佳。)
    容量文件系统挂载点
    2GBXFS/data/xfs
    1GBVFAT/data/vfat
    1.5GBEXT4/data/ext4
    1GBswap-
    上述四个添加的数据都能够开机后自动的挂载或激活。
  7. 完成上述所有的题目后,请重新开机,并请在开机后 10 分钟内运行上传脚本,否则系统不允许你上传喔!

作业结果传输:请以 root 的身分运行 vbird_book_check_unit 指令上传作业结果。 正常运行完毕的结果应会出现【XXXXXX_aa:bb:cc:dd:ee:ff_unitNN】字样。若需要查阅自己上传数据的时间, 请在操作系统上面使用浏览器查找: http://192.168.251.254 检查相对应的课程文件。 相关流程请参考: vbird_book_check_unit

6.5:参考数据

修改历史:
  • 2016/07/11:文件系统的理解比较困难,实做其实相当容易!
  • 2017/03/16:增加了作业喔!这个作业似乎还挺难的!
  • 2018/08/16:在课后练习的第 4 题,关于链接档的建置行为底下,第 b 点,原本是『man fine』错了!应该是『man find』才对!订正了!
  • 2020/04/11:终于修改完毕!本周有够忙碌!增加了一些课后练习,值得大家玩一玩!
2020/04/11 以来统计人数
计数器
其他链接
环境工程模式篇
鸟园讨论区
鸟哥旧站

今日 人数统计
昨日 人数统计
本月 人数统计
上月 人数统计