Hack and / - 灾难来袭时:恢复主引导记录
以下是关于 Linux 灾难以及如何从中恢复的一系列专栏文章的续篇,部分灵感来自于万圣节 Linux Journal Live 节目,题为“恐怖故事”。您可以在 www.linuxjournal.com/video/linux-journal-live-horror-stories 观看原始节目。
我不得不承认,相比于其他任何方法,我通过破坏和修复 Linux 系统学到了更多关于 Linux 工作原理的知识。没有什么比可能丢失宝贵数据,或者你的唯一一台电脑无法启动的想法更能激励你学习更多关于你的系统。在本月的“灾难来袭时”专栏中,我讨论了计算机中一个非常小的部分,但它在启动和使用计算机方面却发挥着令人惊讶的巨大作用——主引导记录,简称 MBR。我将介绍一些我最喜欢的破坏 MBR 的方法,以及一旦你破坏了 MBR 后恢复它的几种方法。
在你完全理解如何恢复 MBR 之前,你应该对它到底是什么有一个很好的了解。MBR 包含硬盘驱动器的前 512 个字节。现在这是 字节,而不是兆字节甚至千字节。在我们这个 TB 时代,很难体会到它是多么的小,但为了让你有一个概念,在专栏的这一点上,我已经写了大约三个 MBR 大小的文本。
这 512 字节的空间然后被分成两个较小的部分。MBR 的前 446 个字节包含引导代码——像 GRUB 的第一阶段这样的代码,它允许你加载操作系统。最后的 66 个字节包含一个 64 字节的分区表和一个位于末尾的 2 字节签名。该分区表充满了关于磁盘上的主分区和扩展分区的信息,例如它们从哪个柱面开始,在哪个柱面结束,它们是什么类型的分区,以及其他有用的数据,通常在磁盘设置好后你就不会过多考虑——至少,直到它消失为止。
这是专栏中我重复一些我所知的最佳灾难恢复建议的部分——进行备份。在本例中,我们讨论的是 MBR 灾难,所以这里有一些备份 MBR 的方法。毕竟,它只有 512 字节;你完全可以负担得起备份它。甚至,它小到可以纹在你的手臂上,除非我保证一旦你这样做,你最终会迁移到新系统或更改分区布局。
备份 MBR 的最佳工具恰好是破坏它的最佳工具(稍后会详细介绍),dd。事实上,dd 是那些古老、强大且笨拙的 UNIX 工具之一,它盲目地执行你告诉它的任何事情,并且擅长破坏各种有价值的数据(更准确地说,它擅长遵循你的明确命令来破坏你的有价值的数据)。以下命令将 /dev/sda 磁盘上的 MBR 备份到名为 mbr_backup 的文件中
$ sudo dd if=/dev/sda of=mbr_backup bs=512 count=1
基本上,这告诉 dd 从 /dev/sda 每次读取 512 字节,并将结果输出到 mbr_backup 中,但只执行一次 512 字节的读取。现在你可以将 mbr_backup 复制到另一个系统或打印出来并进行我之前提到的纹身操作。稍后,如果你要擦除你的 MBR,你可以使用上述命令的一个稍微的变体来恢复它(很可能从某种救援磁盘):只需交换输入和输出源
$ sudo dd if=mbr_backup of=/dev/sda bs=512 count=1
有很多精心设计的方法可以破坏你的部分或全部 MBR。请小心使用第一个命令。它实际上至少会删除你的 MBR,并且如果输入错误,它可能会删除整个磁盘,所以请小心操作。让我们从最直接的 dd 开始
$ sudo dd if=/dev/zero of=/dev/sda bs=512 count=1
这个命令基本上通过用零覆盖 MBR 来将其清空。现在,除非你是受虐狂,或者你像我一样在 MBR 恢复工具的演示中使用过它,否则你可能永远不会运行这个命令。大多数人最终通过以下两种方式之一破坏了他们的 MBR 的一部分:引导加载程序错误和 fdisk 或其他分区工具的错误。
分区工具的错误可能是人们破坏其 MBR,或更具体地说,他们的分区表的最常见方式。可能是你本打算在 sdb 上运行 fdisk,却在 sda 上运行了它。可能是你在调整分区大小时犯了一个错误,并且在重启后,它无法挂载。需要记住的重要一点是,当你使用分区工具时,它们通常只更新驱动器上的分区表。即使你调整了驱动器的大小,除非你告诉分区工具用新的文件系统重新格式化驱动器,否则驱动器上的实际数据不会改变。所有改变的只是驱动器开始处的 64 个字节,它们说明了分区的开始和结束位置。因此,如果你犯了分区错误,你的数据是完好的。你只需要重建该分区表。
我第一次真正破坏我的 MBR,是通过第二种不太常见的方式——引导加载程序错误。在我的例子中,那是几年前的事了,我当时正在努力将早期版本的 GRUB 安装到磁盘上。在标准的命令行命令不起作用后,我突发奇想,也许可以使用 GRUB 引导软盘映像。毕竟,它是 512 字节,我的 MBR 也是 512 字节,对吧?嗯,它有点奏效了。GRUB 确实出现了;但是,我没有意识到的是,除了将 GRUB 写入我的 MBR 的前 446 个字节之外,我还覆盖了最后的 66 个字节,我的分区表。因此,虽然 GRUB 可以工作,但它在驱动器上看不到任何分区。
我至少使用 Linux 足够长的时间了,以至于在我犯错后,我意识到我的实际数据仍然在那里,并且一定有某种方法可以恢复分区表。那时我第一次遇到了名为 gpart 的出色工具。
gpart 是 Guess Partition(猜测分区)的缩写,这正是它的作用。当你运行 gpart 命令时,它会扫描磁盘以查找分区迹象。例如,如果它找到看起来像是 Windows FAT32 分区的开头,它会将其记录下来并继续,直到最终看到看起来像是结尾。一旦该工具扫描了整个驱动器,它会将结果输出到屏幕上供你检查和编辑。它还可以选择将这个重建的分区表写回磁盘。
gpart 已经存在很长时间了,并且由所有主要的发行版打包,因此你应该能够使用你的标准软件包管理器安装它。不要将它与 gparted 混淆,gparted 是一个图形分区工具。当然,如果你的主系统是出现问题的系统,你需要找到一个包含它的救援磁盘。Knoppix 和许多其他以救援为重点的磁盘都开箱即用地包含了 gpart。
要使用 gpart,请使用 root 权限运行它,并为其提供要扫描的磁盘设备作为参数。这是 gpart 从扫描我的笔记本电脑驱动器得到的输出
greenfly@minimus:~$ sudo gpart /dev/sda Begin scan... Possible partition(Linux ext2), size(9773mb), offset(0mb) Possible partition(Linux swap), size(980mb), offset(9773mb) Possible partition(SGI XFS filesystem), size(20463mb), offset(10754mb) End scan. Checking partitions... Partition(Linux ext2 filesystem): primary Partition(Linux swap or Solaris/x86): primary Partition(Linux ext2 filesystem): primary Ok. Guessed primary partition table: Primary partition(1) type: 131(0x83)(Linux ext2 filesystem) size: 9773mb #s(20016920) s(63-20016982) chs: (0/1/1)-(1023/254/63)d (0/1/1)-(1245/254/56)r Primary partition(2) type: 130(0x82)(Linux swap or Solaris/x86) size: 980mb #s(2008120) s(20016990-22025109) chs: (1023/254/63)-(1023/254/63)d (1246/0/1)-(1370/254/58)r Primary partition(3) type: 131(0x83)(Linux ext2 filesystem) size: 20463mb #s(41909120) s(22025115-63934234) chs: (1023/254/63)-(1023/254/63)d (1371/0/1)-(3979/184/8)r Primary partition(4) type: 000(0x00)(unused) size: 0mb #s(0) s(0-0) chs: (0/0/0)-(0/0/0)d (0/0/0)-(0/0/0)r
为了强调备份 MBR 是多么容易,现在我在本杂志中额外备份了我的笔记本电脑分区表。
正如你所看到的,它正确地识别了我的笔记本电脑上的两个主分区(/ 和 /home)和交换分区,并注意到第四个主分区未使用。现在,在查看此内容后,如果我决定要 gpart 将其数据写入驱动器,我将运行
$ sudo gpart -W /dev/sda /dev/sda
这不是一个错字;-W 参数告诉 gpart 要将分区表写入哪个磁盘,但你仍然需要告诉它要扫描哪个驱动器。gpart 可能会扫描一个驱动器并将分区表写入另一个驱动器。一旦你指定了 -W 选项,gpart 会给出一些警告让你接受,但它也会提示你在 gpart 本身中编辑结果。就我个人而言,我总是觉得以这种方式进行编辑比它需要的要困难一些,所以我跳过编辑器,让它写入磁盘,然后使用像 fdisk 或 cfdisk 这样的工具在之后检查驱动器,并在必要时进行调整。
gpart 是一个很棒的工具,并且多次拯救了我,但它确实有一些局限性。首先,虽然 gpart 在处理主分区方面非常出色,但它更难找到扩展分区,这取决于实际创建它们的工具。其次,对 gpart 的结果持保留态度。它尽力重建驱动器,但你应该始终对它的结果进行健全性检查。例如,我见过它将分区的结尾识别为比实际结尾短一两个兆字节。通常,当我们对驱动器进行分区时,我们会将一个分区紧接在另一个分区之后,因此这些类型的错误很容易发现。
现在,如果你只破坏了分区表,那么你希望此时应该已经恢复了。如果你设法也破坏了引导代码,你也需要恢复它。如今,大多数 Linux 发行版都使用 GRUB,因此在恢复分区表后,如果你当前已启动到受影响的系统,请运行
$ sudo grub-install --recheck /dev/sda
将 /dev/sda 替换为你的主引导设备的路径。如果你使用 Ubuntu 系统,你可以选择使用 update-grub 工具代替。如果你当前启动到救援磁盘,你首先需要将你的根分区挂载到,例如 /mnt/sda1,然后使用 chroot 在其中运行 grub-install
$ sudo mkdir /mnt/sda1 $ sudo mount /dev/sda1 /mnt/sda1 $ sudo chroot /mnt/sda1 /usr/sbin/grub-install ↪--recheck /dev/sda
如果 chrooted grub-install 不起作用,你通常可以使用你的救援磁盘的 grub-install,并带有 --root-directory 选项
$ sudo /usr/sbin/grub-install --recheck ↪--root-directory /mnt/sda1 /dev/sda
好吧,希望如果你之前对硬盘驱动器开头的 512 个字节没有深刻的尊重,那么你现在有了。MBR 就像生活中的许多东西一样,在它们消失之前你不会想念它们,但至少在这种情况下,当它消失时,你也许能够把它带回来。
Kyle Rankin 是旧金山湾区的一名高级系统管理员,也是许多书籍的作者,包括 O'Reilly Media 出版的 Knoppix Hacks 和 Ubuntu Hacks。他目前是 North Bay Linux Users' Group 的主席。