Linux分区破坏的修复
服务器误操作,删除了系统盘 /dev/sda 上的分区,误操作步骤如下:
fdisk /dev/sda然后执行了 g 命令 - g create a new empty GPT partition table
此时服务器还没有重启,使用 fdisk -l 可以看到sda磁盘分区没有了
# fdisk -l
Disk /dev/sda: 745.2 GiB, 800166076416 bytes, 1562824368 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: 3F269632-A490-4E27-87D3-3677667E3C6C不过,系统还没有重启,当前磁盘还挂载:
# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 126G 0 126G 0% /dev
tmpfs 126G 76K 126G 1% /dev/shm
tmpfs 126G 11M 126G 1% /run
tmpfs 126G 0 126G 0% /sys/fs/cgroup
/dev/sda1 50G 7.2G 41G 15% /
/dev/sda2 296G 63M 295G 1% /home
tmpfs 26G 16K 26G 1% /run/user/0挂载情况
内核中显示分区信息还在
检查
/etc/fstab内容如下
检查uuid
通过blkid可以得知原先的分区表是msdos
通过lsblk也可以直接获得所有分区的uuid
但是需要注意 /dev/sda 被覆盖成GPT了
内核中磁盘分区信息
关键是如何恢复磁盘中的分区表,在操作系统还没有重启之前,恢复预先正确的分区信息。
参考 How to recover a partition accidently deleted with fdisk (Linux)? ,一般可以通过 TestDisk 开源工具修复。
此外,这个案例比较简单,我感觉也可以通过手工方式修复,参考Linux文档的Partition HOWTO 章节 Recovering a Deleted Partition Table ,关键是按照原先分区信息,创建一个 精确一致 的分区表
在 Partition-Rescue 中介绍了当删除了分区表,但是还没有重启Linux情况下,可以从内核存储的信息
内核存储的分区信息
最主要是知道分区开始的位置
通过
hdparm工具可以获得详细信息
(可选)如果知道一个分区的起始位置,但是不知道结束,仍然可以挂载它,然后了解他的结构。也就是先正确设置分区的起始位置,然后设置一个比原先分区 更大 的任意位置。然后使用以下命令检查推测:
甚至可以挂载然后检查
恢复
根据上述调查,我们可以了解到以下信息
原先的分区表是msdos,被误删除修改成了gpt分区表
由于操作系统还没有重启,所以内核中保留了原先分区的完整信息
一共3个分区,分区信息见上述
再次使用
fdisk /dev/sda命令,然后执行o把分区表改成DOS分区表 ,然后执行w保存然后检查分区表,可以看到分区表已经修改成
dos
现在我们来恢复原先的分区表数据 - 根据之前通过
hdparm -g /dev/sda1等命令获取的信息
注意到直接按照 hdparm -g /dev/sda1 输出的 sectors = 104853504 值添加分区会导致多一个扇区,所以我们实际添加sectors应该是输出值减1。所以按下 ctrl-c 终止 fdisk 重新添加分区
启动
fdisk命令,对/dev/sda进行分区
输入 p 打印当前分区(目前是空的)
输入
n命令,添加第一个分区:
输入
p命令,表示添加主分区primary,然后两次回车表示默认分区1,以及默认从扇区2048开始第一个分区
现在需要给第一个分区设置大小,我们已经从
hdparm -g /dev/sda1获得了这个分区的大小是104853504扇区。但是由于分区起始扇区是2048,也就是默认已经有了1个sector,所以我们需要添加的sectors数量是原分区sectors数量-1,也就是+104853503
此时fdisk会检测到之前分区1上有一个ext4文件系统是我们之前已经创建过的文件系统,这个文件系统标记我们不要修改:
这时候提示信息显示分区1包含了ext4标记,实际上就是我们之前旧分区上已经创建过的文件系统,所以我们不需要删除这个标记,输入
N命令
然后再次输入
p打印添加了分区1之后的分区情况,验证我们添加的分区是否和原先完全吻合:
请注意,我们输入的 +104853503 之后获得的分区1的扇区数是 104853504 ,和我们从内核获得的原分区扇区数一致,这表明我们添加的分区正确。
重复以上步骤,添加分区2和分区3,同样需要注意sectors添加时数值需要比原分区sectors值减1,最终完成以后的分区表情况如下:
上述分区数据要仔细和 hdparm -g /dev/sdaX 对比(对比 start 和 sectors),例如我们之前获得数据就是
确认无误以后,输入命令 w 保存退出 fdisk
保存退出时会提示信息表示分区表已经修改,但设备繁忙(因为是系统盘正挂载使用中),所以内核依然使用的是旧表。我们通过
fdisk -l命令再检查一次:
由于文件系统没有重新格式化,所以uuid依然不变,这点可以再次验证
不过
blkid显示分区多了一个PARTUUID:
重启验证
比较不幸,重启系统以后,发现系统进入了无盘状态
通过chroot尝试挂载物理服务器磁盘进行检查
挂载以后检查文件系统:
然后检查挂载的文件系统,可以看到文件系统读写都是正常的。这说明之前修复的的磁盘分区是正确的
由于是系统盘,这说明之前
fdisk破坏的分区表虽然修复正确,但是启动引导信息被抹除以后没有恢复,需要重新修复通过chroot进入磁盘上的Linux系统
现在使用
df查看到的操作系统就是完全和从硬盘启动的系统是一致的,除了内核使用的是我们无盘系统的操作系统内核
这里的操作系统是SUSE,可以很容易找到suse的帮助文档,例如 Boot loader repair with grub2 (on OpenSUSE 13.1) 和 Re-install Grub2 from DVD Rescue
在我们这个案例中,
/boot/grub2/grub.cfg不需要重新生成(因为之前安装是正确的配置),所以只需要执行grub2-install将启动信息写入磁盘就可以:
此时提示:
实际上如果要rescue,在正确挂载了磁盘之后,可以执行2条命令来恢复(如果你安装SUSE过程中安装grub2失败)
再次重启,一切正常了 ^_^
Last updated
Was this helpful?