主驱动器上的 dd 命令错误 - 如何恢复数据?

主驱动器上的 dd 命令错误 - 如何恢复数据?

好吧,一件令人恼火的蠢事发生了。我想将 Arch Linux ISO 文件复制到我的 USB 拇指驱动器,但当时太着急,不小心输入了我的主驱动器作为参数of

以下是详细信息:

$ sudo dd bs=4MB if=archlinux-2017.08.01-x86_64.iso of=/dev/nvme1n1

/dev/nvme1n1本来应该/dev/sdb

我的主驱动器/dev/nvme1n1包含两个分区:

  • 一个 512 MB EFI 启动分区
  • 一个 ext4 分区跨越 1 TB 驱动器的剩余部分

文件大小为archlinux-2017.08.01-x86_64.iso541065216 字节,或516 兆

计算机仍在运行,似乎工作正常,并且我得到了输出lsblkdf -h 运行该dd命令。输出为一模一样就像我现在运行命令时一样。我假设是因为数据被缓存了:

$ lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
nvme1n1     259:5    0 931.5G  0 disk 
├─nvme1n1p1 259:6    0   512M  0 part /boot
└─nvme1n1p2 259:7    0   931G  0 part /

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme1n1p2  916G   22G  848G   3% /
/dev/nvme1n1p1  511M   36M  476M   7% /boot

ls /boot仍然打印目录内容(可能是缓存的信息),但文件内容已损坏,并且正在运行ls /boot/EFI,或者ls /boot/loader用随机字符填满屏幕,包括大量的Input/output error

以下是更多信息:

$ cat /proc/partitions
major minor  #blocks  name

 259        5  976762584 nvme1n1
 259        6     524288 nvme1n1p1
 259        7  976237255 nvme1n1p2

$ sudo fdisk -l /dev/nvme1n1
Disk /dev/nvme1n1: 931.5 GiB, 1000204886016 bytes, 1953525168 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: 0x282bad86

Device         Boot Start     End Sectors  Size Id Type
/dev/nvme1n1p1 *        0 1056767 1056768  516M  0 Empty
/dev/nvme1n1p2        164  131235  131072   64M ef EFI (FAT-12/16/32)

查看 的输出fdisk,很明显分区表(可能还有启动分区上的所有数据)被破坏了。它应该是gpt磁盘标签类型,分区大小/类型错误。不幸的是,由于 ISO 文件大小(516 MB),它也覆盖了我的根分区的前 4 MB。

输出与以下稍有不同gdisk

$ sudo gdisk /dev/nvme1n1

# selected GPT when asked "Found valid MBR and GPT. Which do you want to use?"

Command (? for help): p
Disk /dev/nvme1n1: 1953525168 sectors, 931.5 GiB
Model: Samsung SSD 960 EVO 1TB                 
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): <guid>
Partition table holds up to 248 entries
Main partition table begins at sector 2 and ends at sector 63
First usable sector is 64, last usable sector is 1056704
Partitions will be aligned on 8-sector boundaries
Total free space is 1 sectors (512 bytes)

Number  Start (sector)    End (sector)  Size       Code  Name
   2             164          131235   64.0 MiB    0700  ISOHybrid1

我发现了几个相关问题:

我已经安装了该testdisk实用程序,它看起来很有希望,但我想确保我执行了正确的步骤当计算机仍在运行时。如果我现在关闭它,它将无法再启动,因此存在以下问题:

  • 摆脱这种情况的最佳方法是什么?
  • 如何将分区表恢复到以前的格式,以及如何重新创建 /boot 分区?我正在运行带有最新内核的 Arch Linux。
  • 有什么方法可以知道我的根分区的前 4 MB 包含什么(以及销毁了什么)?

编辑:根据@WumpusQ.Wumbley 运行dumpe2fs命令的建议,在此添加更多信息和详细信息。

基本输出(前 50 行)dumpe2fshttps://pastebin.com/fBuFRQfE

对我来说它看起来很正常,甚至文件系统魔法数字(0xEF53)也是正确的。

接下来是Group 0

Group 0: (Blocks 0-32767) csum 0x9569 [ITABLE_ZEROED]
  Primary superblock at 0, Group descriptors at 1-117
  Reserved GDT blocks at 118-1141
  Block bitmap at 1142 (+1142)
  Inode bitmap at 1158 (+1158)
  Inode table at 1174-1685 (+1174)
  21349 free blocks, 8177 free inodes, 2 directories, 8177 unused inodes
  Free blocks: 11419-32767
  Free inodes: 16-8192

随后有很多组表示,[...]8192 free inodes, 0 directories, 8192 unused inodes [...]第一个真正报告一些目录的组直到Group 3648,或者大约 25,000 行之后才:

Group 3648: (Blocks 119537664-119570431) csum 0xa9ea [ITABLE_ZEROED]
  Block bitmap at 119537664 (+0)
  Inode bitmap at 119537680 (+16)
  Inode table at 119537696-119538207 (+32)
  23930 free blocks, 1670 free inodes, 614 directories, 1670 unused inodes
  Free blocks: 119546502-119570431
  Free inodes: 29890939-29892608

整个文件系统有很多备份超级块:

$ sudo dumpe2fs /dev/nvme1n1p2 | grep -i superblock | wc -l
dumpe2fs 1.43.5 (04-Aug-2017)
19

答案1

我假设分区表和启动分区可以轻松地重新创建,所以我将重点关注 ext4 分区。

文件系统的布局在某种程度上取决于创建时使用的选项。我将描述常见情况。您可以通过dumpe2fs在设备上运行来查看这是否与您的情况相匹配(希望在缓存中找到所有顶级元数据,而不是从磁盘读取)。

ext4 文件系统的正常块大小为 4096 字节,因此您丢失了 1024 个块。

首先被覆盖的是块 0,即主超级块。这本身不是问题,因为还有备份超级块。之后是组描述符表,它在文件系统中也有备份。

然后是块位图和 inode 位图。这是消息开始变得稍微糟糕的地方。如果其中任何一个低于块 1024(很可能是这样),您就丢失了有关正在使用哪些 inode 和块的信息。这些信息是多余的,如果所有目录和 inode 都完好无损,fsck 将根据遍历所有目录和 inode 时发现的内容重建这些信息。

但接下来是 inode 表,在这里你可能丢失了很多 inode,包括根目录、日志和其他特殊 inode。如果能找回这些就好了。显然,至少根目录仍然可用,否则你尝试运行的所有命令都会失败。

如果您现在运行dd if=/dev/nvme1n1p2 of=/some/external/device bs=4096 count=1024,您将获得当前缓存中所有内容的备份副本,其中混合了未缓存块的坏数据。然后,在启动救援磁盘后,您可以dd反向执行相同操作,将部分好的数据放回磁盘上,覆盖现在所有坏的数据。

在此之后,您可能会发现自动恢复工具(fscktestdisk)工作得很好。如果不是,您可以使用一张地图来帮助手动恢复。使用 中的“空闲块”列表dumpe2fs,您知道要忽略哪些块。

你丢失的大部分内容可能是 inode。实际上,你很可能没有文件内容在磁盘的前 4MB 中。(我mkfs.ext4在 1TB 图像文件上运行了无任何选项,第一个非元数据块竟然是块 9249)

您设法恢复的每个 inode 都将标识整个文件的数据块。这些数据块可能位于磁盘的各处,而不一定位于附近。

第 2 天

pastebin 上发布的转储揭示了好消息:

Group 0: (Blocks 0-32767) csum 0x9569 [ITABLE_ZEROED]
  Primary superblock at 0, Group descriptors at 1-117
  Reserved GDT blocks at 118-1141
  Block bitmap at 1142 (+1142)
  Inode bitmap at 1158 (+1158)
  Inode table at 1174-1685 (+1174)
  21349 free blocks, 8177 free inodes, 2 directories, 8177 unused inodes
  Free blocks: 11419-32767
  Free inodes: 16-8192

由于我们认为文件系统开头的 4MB 被覆盖了,所以我们只需要担心 0-1023 块。而保留的 GDT 块一直延伸到 1141 块!这种损坏应该可以通过简单的方法e2fsck -b $backup_superblock_number(重启后)进行修复。您至少可以尝试一下,-n看看它是怎么想的。

答案2

如果磁盘使用 GPT,则可以使用磁盘末尾的备份 GPT 数据恢复分区表。您可以使用 执行此操作gdisk;请参阅gdisk数据恢复文档了解详情。简而言之:当您gdisk在磁盘上启动时,它将大概注意到损坏并询问您是否要使用备份 GPT 数据或 MBR 数据。如果您选择 GPT 选项然后写入更改,分区表将被修复。如果gdisk没有询问要使用哪个分区表,您可能仍然可以使用恢复和转换菜单上的选项加载备份表c

/sys/block/nvme1n1/nvme1n1p1/start如果失败,您仍然可以使用和/sys/block/nvme1n1/nvme1n1p1/size文件中的数据(以及 中的数据)重新创建分区表(或至少是分区的起点和终点)/dev/nvme1n1p2。但是,如果您求助于这些数据,则必须不是关闭计算机,这与 hek2mgl 的建议相反。话虽如此,hek2mgl 认为继续使用当前状态的磁盘可能会使情况变得更糟,这一点并没有错。总的来说,我认为最好的折衷方案是尽快修复分区表问题,然后关闭计算机并从紧急磁盘修复文件系统问题。

不幸的是,您的 ESP 已损坏。考虑到您的磁盘布局,我猜您将 ESP 安装在了/boot并将内核存储在那里。因此,您需要使用chroot或其他方式重新安装内核包。您的引导加载程序或引导管理器也是如此。

答案3

  1. 立即关闭计算机
  2. 使用救援系统启动它。
  3. 运行testdisk以尝试恢复您的数据。(如果您有足够的空间,请使用该设备获取图像并在该图像上dd运行)testdisk

为什么要立即关闭计算机?如果要创建新文件(可能在 /run 中)或将新文件附加到(/var/log/...),则文件系统需要查看现有(错误!)信息以决定将数据存储在何处。当根据错误信息做出此决定时,现有数据块被覆盖的风险很高。这会使它们永远丢失。即使对于像testdisk和 这样的工具也是如此photorec

相关内容