最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

焦点播报:记录一次系统恢复的经历

来源:博客园

记录一次系统恢复的经历

开始

我的PC中装有两块NVME硬盘,其中nvme1n1用于测试性能,nvme0n1上安装有Linux/Archlinux

之前就想着,两个盘符这么相似,是不是可能会误操作,果然,今天就遇到了。


(资料图片仅供参考)

当时将nvme1n1的format格式调整为logical blocksize = 4k,所以我想验证下非4K对齐的写是不是会报错。于是:

dd if=/dev/zero of=/dev/nvme0n1 bs=4096 count=1 seek=512 oflag=direct,seek_bytes

果然把盘符写成/dev/nvme0n1了。本来这个应该还好,最多也就分区表坏了。结果这条命令成功了,我很诧异,所以想着是不是下层做了read-modify-write,所以这个差异会体现在带宽上,,所以我把count=1去掉了!!! 作大死

dd if=/dev/zero of=/dev/nvme0n1 bs=4096 seek=512 oflag=direct,seek_bytes

等我打开iostat看的时候,才发现写的是/dev/nvme0n1,于是赶紧Ctrl-C,但是dd告诉我已经写入了1.7GiB的数据了,,GG,,,,

So, what‘s next

我感觉lsblk看了下,发现了我当时的分区表如下:

nvme0n1     259:1    0 953.9G  0 disk ├─nvme0n1p1 259:2    0   500M  0 part /boot ├─nvme0n1p2 259:3    0   400G  0 part / ├─nvme0n1p3 259:4    0    16M  0 part ├─nvme0n1p4 259:5    0 552.7G  0 part └─nvme0n1p5 259:6    0   719M  0 part

所以分区表、boot分区、Root分区的开头1.2GiB全部挂了。

分区表还好说,通过查看内核分区表,还是可以恢复的

$ cd /dev/nvme0n1; ls -d nvme0n1p* | while read i; do echo start:$(cat $i/start) size:$(cat $i/size); done | column -tstart:2048        size:1024000start:1026048     size:838860800start:839886848   size:32768start:839919616   size:1159014400start:1998934016  size:1472512

boot分区也还好,linux kernel文件mkinitcpio -p就行,grub相关的grub-install/grub-mkconfig也还可以。不过由于boot分区也是我的EFI分区,所以windows的boot项也挂了,还得想办法修复。

但是,,Root分区也被写坏了,这就很麻烦了。 好在目前系统似乎还能正常运行,我猜想由于开头的数据可能都是写入很早的数据,也就是都是系统文件,所以大部分应该在Pagecache中,所以系统还能跑。 赶紧备份吧:

  1. 家目录还能读,还行整体备份到NAS

  2. 备份全部软件列表:

    • pacman -Qqe > pkglist.txt

    • pacman -Qtqe > pkglist.nodeps.txt

    • pacman -Qtnqe > pkglist.nodeps.noaur.txt

  3. 打包Root分区

    • 结果发现 ls / 已经报error了,但是 cd usr之类的还可以成功,但是考虑到ls 失败,所以我放弃了备份root分区,后来证明,这是一个错误的决定

  4. 试图重装全部软件包,从而保证root分区上的数据被重新写一遍,后来反思,这也是一个错误的决定,至少不应该在备份盘之前做

    • pacman -S - < pkglist.txt 结果报了version不匹配之类的错误,于是:

    • pacman -S -d - < pkglist.txt,然后成功

    • 后来发现,这个操作对于fsck没有任何帮助,由于root inode以及其他一些inode的损坏,fsck完全无法重建整个目录树。反而,这个操作可能导致写入到原先有效的block中,从而导致有效数据被覆盖

  5. 备份整个分区

    • dd if=/dev/nvme0n1p2 of=/mnt/nas/raw_disk bs=1024k

  6. 试图找资料,能否强制下刷全部page cache下盘,无论其是否dirty。 结果没有发现,page cache似乎只提供了/proc/sys/vm/drop_caches功能,只能discard cache。

  7. 重新格式化boot分区,然后mkinitcpio -p, grub-install, grub-mkconfig,试图重建boot分区,但是grub-mkconfig报错,无法生成合法的grub.cfg文件

然后,,就无可奈何了,只能reboot,听天由命了。

趟坑

reboot之后,果然,只能进入到grub cmdline。 我试图从grub cmdline中boot linux分区,结果linux root分区损坏无法启动,然后试图从grub cmdline中boot windows分区,结果也因为windows存放在EFI分区的bootmgr丢失,无法启动。

然后,我想从U盘启动,先恢复Windows,结果发现按/进入bios时,显示屏总是一片黑屏,完全无法操作。

我使用的主板是:rog-strix-b650e-e,之前进入BIOS都没有问题。

我怀疑了好几个地方:

  • BIOS对DP的支持不好 → 使用HDMI,无改变。仍旧黑屏

  • BIOS对AMD核显支持不好 → 从Nas上拆下GTX1060,连在PC以及显示器上。仍旧黑屏

  • 查看BIOS QCode报错 → QCode显示A9,含义为正常进入Bios

  • 主板灰尘太多 → 清灰。 无效果

由于无法进入Bios,所以每次开机之后都只能进入grub cmdline,我抱着死马当作活马医的想法,进入到linux 的emergency mode之后,直接fsck.ext4 /dev/nvme0n1p2,直接显示root inode都不是个directory,然后还有好多其他的报错。最后没办法,硬着头皮上不断yes。最后fsck跑完之后,整个分区直接空了,全部文件都到了lost+found目录中,然后全是一堆inode编号的目录,大约有几百个。这下Linux分区算是挂到底了。

最后,我突然想到,既然每次都从内置nvme0n1启动的话,我直接把这块盘拆了看看可不可以从USB启动。结果神奇的事情发现了,,可以进BIOS了

恢复Windows

能进BIOS就好做多了,先恢复windows。

按照这篇教程:https://woshub.com/how-to-repair-deleted-efi-partition-in-windows-7/走了一遍:

  1. 启动进入到windows 安装盘

  2. 在第一个界面,按Shift+F10得到一个cmd

  3. 进入到diskpart命令,list disk选中nvme0n1,list partition选中新创建的boot分区(nvme0n1p1),然后format quick fs=fat32 label="System"格式化,然后list vol选中boot分区,assign letter=G挂载到一个盘符。

  4. 然而我发现我的windows分区nvme0n1p4没有挂载到一个盘符,从而无法下一步。然后diskpart也无法将nvme0n1p4识别为一个ntfs分区。我进入到usb-live archlinux中发现ntfs其实可以挂载这个分区,所以感觉非常奇怪。 我搜索资料之后,并没有什么发现,但是突然我注意到fdisk中的分区类型,nvme0n1p4仍旧标记的是Linux filesystem,我尝试把它改成Microsoft basic data之后,再次进入到windows 安装盘后,diskpart就可以成功识别了,然后将nvme0n1p4挂载到C:

  5. bcdboot c:\windows /s G: /f UEFI

  6. bcdedit可以发现显示了一个Windows Boot Manager条目,device显示partition=G:因此创建成功

  7. wpeutil reboot重启电脑

重启之后,系统成功进入Windows,查看了一遍,一切正常。

恢复Linux

在我的fsck之后,我就意识到Linux分区彻底挂了。所以重装吧。

按着usb-live archlinux的安装步骤,又来了一遍,然后安装包的时候,使用之前备份的package list: pacman -S - < pkglist.txt

然后从Nas中恢复home分区的内容,在enable一些service:

  • systemctl enable lightdm

  • systemctl start NetworkManager && systemctl enable NetworkManager

然后yay安装aur的包,目前看上去终于一切正常了。

可惜了一个美好的周末了。

Last updated 2023-05-21 23:49:52 +0800

关键词: