在一个文件上造出文件系统
目标
在一个普通文件上创建真正的 ext4 文件系统,读取并调整超级块,并查看其中的内容。最后,用 UUID 写出挂载该文件系统的 fstab 行。
为什么重要
mkfs 并不区分目标是块设备还是普通文件,它只是把规定的结构写进去。正因为这一特性,无需特权也能学习文件系统的内部结构,而且在实际工作中,创建镜像文件再进行检查也很常见。尤其是inode 数量在格式化时就已固定,以后无法增加这一事实,以及默认 5% 的保留块在大容量磁盘上造成了多大的浪费,只有看到具体数字才有切身体会。
这个环境没有 mount 权限,所以不会真正挂载。取而代之的是,评分的对象是能否准确写出 fstab——在实际工作中,事故同样不是出在 mount 命令上,而是出在 fstab 的一行上。
步骤
- 创建目录
/root/disk,并把/root/disk/lab.img创建为 256MiB 的稀疏文件。然后把逻辑大小和实际占用大小各写一行,保存到/root/disk/sparse.txt(单位为字节,逻辑大小在前)。 - 把该文件用标签
LABHUB格式化为 ext4。 - 只把文件系统 UUID 写成一行,保存到
/root/disk/uuid.txt。 - 从超级块中提取块大小 / inode 数量 / 保留块数量三个值,以下面的格式写入
/root/disk/super.txt。BLOCK_SIZE=<값>/INODE_COUNT=<값>/RESERVED_BLOCKS=<값>(各项的占位符为对应的值) - 把保留块比例降到 1%,并把修改后的保留块数量以一行数字写入
/root/disk/reserved-after.txt。它必须小于第 4 步的值。 - 用
debugfs在镜像根目录下创建data目录,并把根目录列表保存到/root/disk/rootls.txt。列表中必须同时有lost+found和data。 - 在
/root/disk/fstab.line中,用一行写出把这个文件系统挂载到/mnt/labdata的 fstab 行。设备必须用UUID=的写法,类型为ext4,选项中必须同时包含defaults、noatime、nofail,dump 为0,pass 为2。 - 把
/root/disk/report.txt写成下面这 5 行。LABEL=LABHUB/UUID=<3번 값>/BLOCK_SIZE=<4번 값>/INODE_COUNT=<4번 값>/MOUNTPOINT=/mnt/labdata(第 2 项到第 4 项的占位符依次为第 3 步的值、第 4 步的值、第 4 步的值)
参考
- 顺序是
truncate -s 256M <파일>、mkfs.ext4 -F -L LABHUB <파일>、blkid <파일>、dumpe2fs -h <파일>、tune2fs -m 1 <파일>(各命令中的占位符均为文件名)。 - 实际占用大小用
du -B1 <파일>,逻辑大小用du -B1 --apparent-size <파일>(占位符均为文件名)或stat -c %s。 - 写入操作用
debugfs -w -R 'mkdir /data' <파일>(占位符为文件名),查询用debugfs -R 'ls -l /' <파일>(占位符为文件名)。 - 常见错误 1:
mkfs.ext4询问“not a block special device”时,不加-F就无法继续。 - 常见错误 2:在第 7 步给 UUID 值加了引号。fstab 中不使用引号。
创建稀疏镜像文件
创建目录 /root/disk,并把 /root/disk/lab.img 创建为 256MiB 的稀疏文件。然后把逻辑大小和实际占用大小各写一行,保存到 /root/disk/sparse.txt(单位为字节,逻辑大小在前)。
truncate 不会分配实际的块,只是指定大小。请比较 du 的两种大小。
格式化为 ext4
把该文件用标签 LABHUB 格式化为 ext4。
如果出现“不是块设备”的警告,就需要强制选项。也请同时使用指定标签的选项。
提取 UUID
只把文件系统 UUID 写成一行,保存到 /root/disk/uuid.txt。
blkid 对文件也有效。要只提取输出中的 UUID 值,请使用格式指定选项或字符串处理。
读取超级块
从超级块中提取块大小 / inode 数量 / 保留块数量三个值,以下面的格式写入 /root/disk/super.txt。
BLOCK_SIZE=<값> / INODE_COUNT=<값> / RESERVED_BLOCKS=<값>(各项的占位符为对应的值)
dumpe2fs 的 -h 只输出超级块信息。请想一想这三个项目的值各自表示什么。
修改保留块比例
把保留块比例降到 1%,并把修改后的保留块数量以一行数字写入 /root/disk/reserved-after.txt。它必须小于第 4 步的值。
tune2fs 的 -m 以百分比指定。修改后请用 dumpe2fs 再次确认。
查看镜像内部
用 debugfs 在镜像根目录下创建 data 目录,并把根目录列表保存到 /root/disk/rootls.txt。列表中必须同时有 lost+found 和 data。
debugfs 用 -R 执行一条命令。写入操作需要另外的选项。
编写 fstab 行
在 /root/disk/fstab.line 中,用一行写出把这个文件系统挂载到 /mnt/labdata 的 fstab 行。设备必须用 UUID= 的写法,类型为 ext4,选项中必须同时包含 defaults、noatime、nofail,dump 为 0,pass 为 2。
六个字段用空格分隔。设备用 UUID= 的写法,选项中必须包含这三项。
镜像汇总报告
把 /root/disk/report.txt 写成下面这 5 行。
LABEL=LABHUB / UUID=<3번 값> / BLOCK_SIZE=<4번 값> / INODE_COUNT=<4번 값> / MOUNTPOINT=/mnt/labdata(第 2 项到第 4 项的占位符依次为第 3 步的值、第 4 步的值、第 4 步的值)
把前面步骤中提取的值汇总成 键=值 即可。数字请不带单位地写。