介绍
在本实验中,你将学习在 Linux 环境下管理磁盘分区和文件系统所需的基本技能。你将使用诸如 fdisk 之类的命令行工具来检查可用磁盘、创建新分区,并使用标准文件系统对其进行格式化。为了确保学习过程的安全性,所有操作都将在专用的辅助虚拟磁盘 /dev/sdb 上进行,而不会触及主操作系统磁盘。
注意: 在本实验环境中,/dev/sdb 是作为回环设备(loop device,即充当磁盘的文件)实现的。当你创建分区时,它们会显示为 loop13p1 等名称,但你将创建符号链接以像操作真实硬件一样通过 /dev/sdb1、/dev/sdb2 等名称来访问它们。
在整个练习过程中,你将创建一个标准的 Linux 分区,使用 ext4 文件系统对其进行格式化,并学习如何挂载它以供立即使用。随后,你将通过编辑 /etc/fstab 文件来配置系统,使其在启动时自动挂载该文件系统。最后,你将通过创建和管理专用的 Linux 交换分区(swap partition)来扩展你的技能,这是系统性能的关键组成部分。
使用 fdisk 检查磁盘并创建新的 Linux 分区
在此步骤中,你将学习如何检查可用磁盘及其分区表。然后,你将使用功能强大的命令行工具 fdisk 在辅助磁盘上创建新分区。在现实场景中,修改分区时必须格外小心,因为错误操作可能导致数据丢失。在本实验中,我们将在专用的虚拟磁盘 /dev/sdb 上进行操作,以确保主操作系统磁盘 (/dev/sda) 保持不变。
首先,让我们概览一下连接到系统的所有块设备(磁盘和分区)。lsblk 命令可以提供清晰的树状视图。
lsblk
输出将显示可用磁盘,包括你的主系统磁盘 (vda) 和代表我们实验虚拟磁盘的回环设备 (loop13)。
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
...
loop13 7:13 0 2G 0 loop
vda 252:0 0 40G 0 disk
├─vda1 252:1 0 1M 0 part
├─vda2 252:2 0 200M 0 part /boot/efi
└─vda3 252:3 0 39.8G 0 part /
请注意,该回环设备(通过符号链接可作为 /dev/sdb 访问)是一个 2GB 的虚拟磁盘,目前还没有分区。现在,让我们使用 fdisk 更详细地查看 /dev/sdb 的分区表。-l 标志用于列出指定设备的分区表并退出。由于 fdisk 需要 root 权限才能检查磁盘级信息,因此必须使用 sudo。
sudo fdisk -l /dev/sdb
输出提供了有关磁盘的详细信息,包括其大小、扇区和标识符。由于目前还没有分区,底部的设备列表将为空。
Disk /dev/sdb: 2 GiB, 2147483648 bytes, 4194304 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
注意:如果这是你第一次使用该磁盘,你可能会看到关于创建新 DOS 磁盘标签的消息。
接下来,你将以交互模式启动 fdisk 来创建新分区。此过程涉及一系列单字母命令。运行以下命令开始管理 /dev/sdb:
sudo fdisk /dev/sdb
你现在已进入 fdisk 工具,提示符为 Command (m for help):。请仔细按照以下步骤操作:
- 创建新分区: 输入
n并按回车键。 - 选择分区类型: 系统会询问你选择分区类型(主分区或扩展分区)。默认是主分区 (
p),这正是我们需要的。按回车键接受默认值。 - 选择分区编号: 默认是
1,因为这是第一个分区。按回车键接受它。 - 指定起始扇区: 默认值是磁盘上第一个可用扇区。这几乎总是正确的选择。按回车键接受默认值。
- 指定结束扇区或大小: 无需计算扇区,你可以直接指定人类可读的大小。让我们创建一个 500MB 的分区。输入
+500M并按回车键。 - 打印内存中的分区表: 在保存之前,最好先检查一下你的更改。输入
p并按回车键查看新的分区布局。你应该能看到一个新设备/dev/sdb1。 - 将更改写入磁盘: 你所做的更改目前仅存在于内存中。要将其保存到磁盘的分区表,输入
w并按回车键。这将写入更改并退出fdisk。
以下是交互式会话的摘要:
Welcome to fdisk (util-linux 2.37.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x54041549.
Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-4194303, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-4194303, default 4194303): +500M
Created a new partition 1 of type 'Linux' and of size 500 MiB.
Command (m for help): p
Disk /dev/sdb: 2 GiB, 2147483648 bytes, 4194304 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x54041549
Device Boot Start End Sectors Size Id Type
/dev/sdb1 2048 1026047 1024000 500M 83 Linux
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Re-reading the partition table failed.: Invalid argument
The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or partx(8).
写入分区表后,你可能会注意到一条消息,指示内核无法立即重新读取分区表。在使用回环设备时,这是正常的。partprobe 命令会请求操作系统内核重新读取分区表。
sudo partprobe
现在,再次运行 lsblk 以验证系统是否识别了新分区。
lsblk /dev/sdb
输出应显示回环设备及其新分区。由于回环设备的设置,该分区将显示为 loop13p1:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop13 7:13 0 2G 0 loop
└─loop13p1 259:0 0 500M 0 part
由于分区显示为 loop13p1,但实验需要 /dev/sdb1 才能正常工作,我们需要为该分区创建一个符号链接。首先,让我们确定实际的分区设备。模式 p1$ 确保我们只匹配分区名称,而不匹配父回环设备:
PARTITION_DEVICE=$(lsblk -lno NAME /dev/sdb | grep -E "p1$" | head -1)
echo "Partition device: /dev/$PARTITION_DEVICE"
现在为该分区创建符号链接:
sudo ln -s /dev/$PARTITION_DEVICE /dev/sdb1
验证 /dev/sdb1 现在是否可用:
lsblk /dev/sdb1
输出现在应显示该分区可作为 /dev/sdb1 访问:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop13p1 259:0 0 500M 0 part
你已成功在 /dev/sdb 上创建了一个新的 500MB Linux 分区,并使其可作为 /dev/sdb1 访问。
使用 mkfs.ext4 创建并格式化 ext4 文件系统
在此步骤中,你将使用文件系统格式化你创建的新分区 /dev/sdb1。文件系统提供了存储和组织文件及目录所需的结构。如果没有文件系统,操作系统将无法读取或写入该分区。我们将使用 ext4,它是现代 Linux 发行版中默认且使用最广泛的文件系统,因为它具有良好的性能、可靠性和丰富的功能。
创建文件系统的命令是 mkfs,意为“make filesystem”。它是各种特定文件系统构建工具(如 mkfs.ext4、mkfs.xfs 等)的前端。我们将直接使用 mkfs.ext4。此操作具有破坏性,会擦除分区上的任何现有数据,因此需要 sudo 权限。
要使用 ext4 文件系统格式化 /dev/sdb1 分区,请执行以下命令:
sudo mkfs.ext4 /dev/sdb1
该命令将创建文件系统并显示有关该过程的信息,包括文件系统 UUID、块大小和 inode 数量。
mke2fs x.xx.x (xx-xxx-xxxx)
Creating filesystem with 128000 4k blocks and 32000 inodes
Filesystem UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Superblock backups stored on blocks:
32768, 98304
Allocating group tables: done
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
格式化后,你可以验证文件系统是否已成功创建。blkid 命令是实现此目的的好工具,因为它会打印块设备的属性,包括其文件系统类型。
sudo blkid /dev/sdb1
输出应清楚地显示 /dev/sdb1 的 TYPE 现在为 ext4。
/dev/sdb1: UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="1a2b3c4d-01"
如需更详细的视图,你可以使用带有 -h 标志的 dumpe2fs 命令来显示超级块(superblock)信息。超级块包含有关文件系统的关键元数据。
sudo dumpe2fs -h /dev/sdb1
此命令将产生大量输出。查找诸如 Filesystem magic number 和 Filesystem state 之类的关键行,以确认文件系统的完整性。
dumpe2fs x.xx.x (xx-xxx-xxxx)
Filesystem volume name: <none>
Last mounted on: <not available>
Filesystem UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode dir_index filetype extent 64bit flex_bg sparse_super large_file huge_file dir_nlink extra_isize
Filesystem flags: signed_directory_hash
Default mount options: user_xattr acl
Filesystem state: clean
...
现在你已成功格式化了分区,它已准备好被挂载并用于存储数据。
挂载、测试并卸载文件系统
在此步骤中,你将学习如何使新格式化的文件系统对操作系统可见。此过程称为“挂载”(mounting)。挂载将设备(如 /dev/sdb1)上的文件系统连接到文件系统树中的特定目录,该目录称为“挂载点”。挂载后,你可以像操作任何其他目录一样与该分区进行交互。
首先,你需要创建一个挂载点。这只是一个空目录。在 /mnt 目录下创建临时挂载点是标准做法。让我们创建一个名为 /mnt/data 的目录。由于 /mnt 是系统目录,你需要使用 sudo。
sudo mkdir /mnt/data
现在,使用 mount 命令将 /dev/sdb1 分区挂载到 /mnt/data 目录。
sudo mount /dev/sdb1 /mnt/data
为了验证文件系统是否已挂载,我们先通过检查挂载状态来确认 mount 命令是否成功。我们将使用多个命令来验证挂载:
## 检查挂载点是否已挂载文件系统
mountpoint /mnt/data
如果挂载成功,你应该看到:
/mnt/data is a mountpoint
现在让我们使用 df 检查磁盘使用情况。由于回环设备的设置,分区可能会显示其真实设备名称,而不是符号链接名称:
df -h /mnt/data
你应该看到显示已挂载文件系统的条目:
Filesystem Size Used Avail Use% Mounted on
/dev/loop13p1 488M 2.6M 459M 1% /mnt/data
你也可以使用 mount 命令进行验证:
mount | grep /mnt/data
这应该显示:
/dev/loop13p1 on /mnt/data type ext4 (rw,relatime)
现在,让我们测试是否可以向新文件系统写入数据。首先,检查挂载点的当前所有者和权限:
ls -ld /mnt/data
你应该看到类似以下内容:
drwxr-xr-x 3 root root 4096 Dec 12 10:00 /mnt/data
现在尝试在挂载点中创建一个文件:
touch /mnt/data/testfile
此命令可能会失败,并显示“Permission denied”(权限被拒绝)错误。这是因为挂载的文件系统的根目录归 root 用户所有。要解决此问题,请将挂载点的所有权更改为你当前的用户 labex:
sudo chown labex:labex /mnt/data
现在,再次尝试创建该文件:
touch /mnt/data/testfile
这次,命令应该会成功。验证文件是否已创建:
ls -l /mnt/data
你应该看到:
total 16
drwx------ 2 root root 16384 Dec 12 10:00 lost+found
-rw-r--r-- 1 labex labex 0 Dec 12 10:05 testfile
lost+found 目录是 ext4 文件系统的标准功能,用于在文件系统损坏时恢复文件。
当你使用完文件系统后,应该使用 umount 命令将其卸载。需要注意的是,如果文件系统当前正在使用中(例如,如果你当前的工作目录位于挂载点内),则无法卸载它。让我们看看实际情况。
首先,将你的目录更改为 /mnt/data:
cd /mnt/data
现在,尝试卸载它。你可以通过设备名称或挂载点来引用文件系统。
sudo umount /mnt/data
你将收到一条错误消息,指出目标正忙。
umount: /mnt/data: target is busy.
要成功卸载,你必须先离开该目录。让我们回到你的主目录。
cd ~
现在,再次运行 umount 命令。
sudo umount /mnt/data
该命令应在没有任何输出的情况下执行。你可以通过运行 mountpoint 命令来验证它是否已不再挂载:
mountpoint /mnt/data
你应该看到:
/mnt/data is not a mountpoint
最后,你可以通过删除挂载点目录来进行清理:
sudo rmdir /mnt/data
故障排除提示: 如果你遇到 mount 命令无法工作的问题,可以尝试使用实际的回环设备名称而不是符号链接进行挂载:
## 查找实际设备名称
ACTUAL_DEVICE=$(readlink -f /dev/sdb1)
echo "Actual device: $ACTUAL_DEVICE"
## 使用实际设备名称进行挂载
sudo mkdir /mnt/data
sudo mount $ACTUAL_DEVICE /mnt/data
在 /etc/fstab 中配置持久化挂载
在此步骤中,你将学习如何使你的文件系统在每次系统启动时自动挂载。你在上一步中使用的 mount 命令是临时的;重启后挂载将丢失。要创建持久化挂载,你需要在一个名为 /etc/fstab(文件系统表)的特殊配置文件中添加一个条目。
系统在启动过程中会读取 /etc/fstab 以确定要挂载哪些文件系统。这是一个关键文件,因此在编辑之前备份它总是一个好主意。
首先,让我们备份当前的 fstab 文件。
sudo cp /etc/fstab /etc/fstab.bak
接下来,我们需要一个永久的挂载点。在上一步中,我们使用了 /mnt/data 然后将其删除了。对于永久挂载,通常在根文件系统中创建一个目录。让我们创建一个名为 /data 的目录。
sudo mkdir /data
虽然你可以在 /etc/fstab 中使用设备名称 (/dev/sdb1),但不建议这样做。设备名称有时会在重启之间发生变化,特别是当你添加或移除硬件时。一种更可靠的方法是使用分区的通用唯一标识符(UUID),这是一个在创建文件系统时分配的唯一字符串,不会发生变化。
要查找 /dev/sdb1 的 UUID,请再次使用 blkid 命令:
sudo blkid /dev/sdb1
输出将显示 UUID。复制此值(不带引号)。
/dev/sdb1: UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="1a2b3c4d-01"
现在,你将使用 nano 编辑器编辑 /etc/fstab。你必须使用 sudo,因为它是一个系统文件。
sudo nano /etc/fstab
转到文件末尾并为你的分区添加一行。fstab 条目的格式为:
<device_identifier> <mount_point> <filesystem_type> <options> <dump> <pass>
添加以下行,将 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 替换为你从 blkid 命令复制的实际 UUID。
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /data ext4 defaults 0 2
UUID=...:通过唯一 ID 标识分区。/data:文件系统将被挂载到的目录。ext4:文件系统的类型。defaults:适用于大多数情况的标准挂载选项集。0:dump字段。这是一个过时的备份工具标志,应设为0。2:pass字段。这告诉fsck工具在启动时检查文件系统的顺序。1用于根文件系统,2用于其他永久文件系统,0禁用检查。
添加该行后,按 Ctrl+X,然后按 Y,最后按 Enter 保存文件并退出 nano。
现在,无需重启即可进行测试,你可以使用 mount -a 命令。该命令会挂载 /etc/fstab 中列出的所有尚未挂载的文件系统。
sudo mount -a
如果没有错误,该命令将静默完成。现在你可以使用 df 命令验证你的文件系统是否已正确挂载。
df -h | grep /data
输出应确认 /dev/sdb1 已挂载在 /data 上。
/dev/sdb1 488M 2.6M 459M 1% /data
现在,你的分区将在每次系统启动时自动挂载。
创建并管理 Linux 交换分区
在此步骤中,你将了解另一种特殊类型的分区:Linux 交换分区(swap)。当物理内存(RAM)已满时,操作系统会将交换空间用作虚拟内存。它允许系统将不活动的内存页移动到磁盘,从而为活动进程释放 RAM。虽然它不能替代足够的 RAM,但拥有交换分区可以防止系统因内存不足错误而崩溃。
重要提示: 在创建新分区之前,请确保 /dev/sdb 上的任何现有文件系统都已卸载。如果设备当前已挂载(来自之前的步骤),在尝试修改分区表时,你可能会遇到“Device or resource busy”(设备或资源忙)错误。
我们将在 /dev/sdb 上创建一个新分区并将其配置为交换空间。首先,让我们确保设备未挂载,然后使用 fdisk 创建分区。我们已经创建了 /dev/sdb1,因此这个新分区将是 /dev/sdb2。
## 首先,检查设备是否已挂载,如有必要则卸载
lsblk /dev/sdb
sudo umount /data /mnt/data 2> /dev/null || true
## 现在创建分区
sudo fdisk /dev/sdb
在 fdisk 交互式提示符中,执行以下命令:
- 创建新分区: 输入
n并按回车键。 - 选择分区类型和编号: 按两次回车键接受主分区 (
p) 和分区编号2的默认值。 - 指定扇区: 接受默认的起始扇区。对于大小,让我们创建一个 256MB 的分区。输入
+256M并按回车键。 - 更改分区类型: 这是关键步骤。输入
t以更改分区类型。当提示输入分区编号时,输入2。当询问十六进制代码时,输入82,这对应于“Linux swap / Solaris”。 - 打印并验证: 输入
p以查看更改。你应该看到/dev/sdb2,其类型列为“Linux swap / Solaris”。 - 写入更改: 输入
w以保存新的分区表并退出。
Command (m for help): n
Partition type
p primary (1 primary, 0 extended, 3 free)
e extended (container for logical partitions)
Select (default p): p
Partition number (2-4, default 2): 2
First sector (1026048-4194303, default 1026048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (1026048-4194303, default 4194303): +256M
Created a new partition 2 of type 'Linux' and of size 256 MiB.
Command (m for help): t
Partition number (1,2, default 2): 2
Hex code (type L to list all codes): 82
Changed type of partition 'Linux' to 'Linux swap / Solaris'.
Command (m for help): p
Disk /dev/sdb: 2 GiB, 2147483648 bytes, 4194304 sectors
...
Device Boot Start End Sectors Size Id Type
/dev/sdb1 2048 1026047 1024000 500M 83 Linux
/dev/sdb2 1026048 1550335 524288 256M 82 Linux swap / Solaris
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
创建分区后,我们需要像处理 /dev/sdb1 一样为 /dev/sdb2 创建符号链接。首先,运行 partprobe 以确保内核识别新分区:
sudo partprobe
现在识别并为第二个分区创建符号链接:
PARTITION2_DEVICE=$(lsblk -lno NAME /dev/sdb | grep p2 | head -1)
sudo ln -s /dev/$PARTITION2_DEVICE /dev/sdb2
验证分区是否可访问:
lsblk /dev/sdb2
在将分区格式化为交换空间之前,我们需要确保设备不忙。如果你遇到“Device or resource busy”错误,则意味着设备可能已挂载。让我们先检查并卸载任何现有的挂载:
## 检查当前挂载状态
lsblk /dev/sdb
## 如果设备已挂载,则卸载它
sudo umount /data /mnt/data 2> /dev/null || true
现在分区已创建且可访问,你需要使用 mkswap 命令将其格式化以用作交换空间。
sudo mkswap /dev/sdb2
格式化后,你可以激活交换空间。首先,使用 free -h 命令检查当前的交换使用情况。
free -h
输出可能会显示 Swap 为 0B。
total used free shared buff/cache available
Mem: 1.9Gi 151Mi 1.6Gi 0.0Ki 202Mi 1.7Gi
Swap: 0B 0B 0B
现在,使用 swapon 命令激活新的交换分区。
sudo swapon /dev/sdb2
再次使用 free -h 和 swapon -s(摘要)检查交换使用情况。
free -h
total used free shared buff/cache available
Mem: 1.9Gi 152Mi 1.4Gi 0.0Ki 202Mi 1.6Gi
Swap: 256Mi 0B 256Mi
swapon -s
Filename Type Size Used Priority
/dev/sdb2 partition 262140 0 -2
你可以看到总交换空间已增加。要禁用交换分区,请使用 swapoff 命令。
sudo swapoff /dev/sdb2
再次运行 free -h 以验证它已被禁用。交换空间将恢复为零。这演示了如何在运行的系统上动态管理交换空间。
故障排除提示: 如果在此步骤中遇到“Device or resource busy”错误,通常意味着:
- 设备或其分区之一当前已挂载
- 有进程正在访问该设备
要解决此问题,请在继续进行分区操作之前,确保所有挂载点都已使用 sudo umount /data /mnt/data 卸载。
总结
在本实验中,你学习了在 Linux 系统上管理磁盘分区和文件系统的基本技能。你首先使用 lsblk 检查了可用的块设备,然后利用 fdisk 工具在辅助磁盘上创建了一个新的主分区。分区创建完成后,你使用 mkfs.ext4 将其格式化为 ext4 文件系统。你还练习了将新文件系统挂载到目录、验证其状态以及卸载它。最后,你通过使用分区的 UUID 编辑 /etc/fstab 文件来配置持久化挂载,以确保它在系统启动时自动挂载。
此外,本实验还涵盖了创建和管理专用交换空间的过程。这包括再次使用 fdisk 创建分区并将其类型更改为“Linux swap”。然后,你使用 mkswap 命令将此分区准备为交换区域,并使用 swapon 将其激活。为了使交换空间在重启后保持持久,你还在 /etc/fstab 文件中添加了相应的条目。



