记录一次诡异的 grub2 引导修复

事情是这样的,刚才突然间我的 openSUSE 13.1 在重启后 grub2 就变成这样了:

Error :attempt to read or write outside of disk hd0

简单搜索了一下,感觉主要有三种可能:

  1. grub2 升级导致的配置不兼容。

  2. udev 或者别的升级导致 /etc/fstab 里所谓的 UUID 发生了变化,从而找不到硬盘。

    /dev/disk/by-id/ata-SAMSUNG_HN-M101MBB_S2R8J9BB808817-part6 / ext4 acl,user_xattr 1 1
    /dev/disk/by-id/ata-SAMSUNG_HN-M101MBB_S2R8J9BB808817-part5 /home ext4 acl,user_xattr 1 2
    /dev/disk/by-id/ata-SAMSUNG_HN-M101MBB_S2R8J9BB808817-part2 /boot ext4 acl,user_xattr 1 2
    /dev/disk/by-id/ata-SAMSUNG_HN-M101MBB_S2R8J9BB808817-part1 swap swap defaults 0 0
    debugfs /sys/kernel/debug debugfs noauto 0 0
    usbfs /proc/bus/usb usbfs noauto 0 0

SAMSUNG_HN-M101MBB_S2R8J9BB808817 这个就是 UUID。

  1. /boot/grub2/grub.cfg 不在硬盘靠最前的 8GB 当中。

为了验证以上可能,我首先需要一个 Live CD/DVD。毕竟 grub rescue> 这个环境是一个限制极大的环境(基本上只能用 ls,set,insmod 这几个命令),无助于调试。当然如果是简单的 grub2 问题,你也可以试试在这个环境下修复(就是尝试把你的系统引导起来,具体见:

zh.opensuse.org/%E4%BF%AE%E5%A4%8DGRUB2
zh.opensuse.org/SDB:%E4%BF%AE%E5%BE%A9_GRUB

但我面临的一个首要问题就是我没有 LiveCD,甚至连 openSUSE 的 ISO 都在进不去的这个系统里面。翻箱倒柜找到一张 11.4 的光盘,可惜光驱似乎是年久失修了,无法从光驱引导… 最后找到了一块老硬盘,上面是我换 1TB 硬盘前那个 128GB 笔记本硬盘,装着 openSUSE 12.1。于是关机,换硬盘,把 openSUSE 13.1 的硬盘装到移动硬盘盒里备用。

结果发现开不了机,于是我把 /etc/fstab 里用 /dev/disk/by-id/ata-SAMSUNG_HN-M101MBB_S2R8J9BB808817-part6 这种 UUID 表示的路径全部粗快猛地替换为了 /dev/sda6。怀疑可能是拆装硬盘会导致 UUID 变化。于是进去 openSUSE 12.1 了。

可是我又忘了当初之所以换硬盘很大一部分原因是我的 openSUSE 12.1 是 btrfs 文件系统,而那时的 btrfs 是实验性的,特别卡,于是我在图形界面那里连鼠标都动不了… 只好在内核引导选项那里 init 3 了。

现在进去了,开始修复:

  1. 由于刚才我修 openSUSE 12.1 的时候改 UUID 的成功误导了我,于是我在

    fdisk -l
    mount /dev/sda6 /mnt
    mount -t proc proc /mnt/proc
    mount --rbind /sys /mnt/sys
    mount --rbind /dev /mnt/dev
    chroot /mnt

(/dev/sda6 是我的 / 根分区,看前面的 fstab,我没有 /boot 单独分区,当然这是一个坑后面会讲)

后把 openSUSE 13.1 上的 /etc/fstab 里的 UUID 也替换成 /dev/sda6 这样的格式了。接着拆硬盘,发现 openSUSE 13.1 还是启动不了。看来不是 UUID 的问题。

于是我来实验是不是 grub2 版本的问题,可能需要更新 grub2 软件包一下。下面我直接面对的一个困难就是:我现在的无线连接不是以前那个了,而 openSUSE 12.1 里只保存了以前的 wifi 连接。我这种超人又不会简简单单的去禁用 NetworkManager 然后换 ifup 联网的(那样太简单了),于是想起用 NetworkManager 的命令行版本 nmcli 来做:

nmcli nm wifi on
nmcli dev wifi list

按道理接下来使用

nmcli dev wifi con ESSID password PASSWORD name CONN_NAME
nmcli con list
nmcli con up id MY_ID

就可以连接上了。可惜第一条命令报错了,后来各种手机连无线搜索发现原来在 0.9 版本以下的 nmcli 里不支持创建连接。于是想法破灭了。

按理现在该去用 ifup 联网去升级 grub2 软件包了吧。嘿别说,在鼓捣 nmcli 的过程里我想明白了一件事:grub2 唯一可能出现的问题就是没有装到 MBR 里去,或者装在 MBR 里的和更新过的不兼容… 那我直接 grub2-mkconfig -o /boot/grub2/grub.cfg && grub2-install /dev/sdb 不就好了(注意,因为我的 openSUSE 13.1 这时在移动硬盘盒里,所以是 sdb)。

尝试,发现没有用还是开不了机。

但是在这个过程中,我发现了一件奇妙的事:我的 /dev/sdb2 居然是一个 /boot 的内容,里面的内核版本还是 3.6.7 呢。那么就说明我在几年前安装 openSUSE 的时候我是单独分了 /boot 的,那为什么现在单独的 /boot 不挂载分区了,反而在我的 / 所在分区里面又建了一个 /boot,还抹去了我的 /etc/fstab 的部分内容呢!要知道,我的 / 分区可是在扩展分区上的,sda6 啊,磁盘的最后面。肯定超出 grub 可以识别的范围了呢!

于是进行第三种尝试:把 / 所在分区的 boot 文件及里的东西装到不知多久之前我那个 /boot 分区里去!

于是很简单:

mount /dev/sdb2 /media
mount /dev/sdb6 /mnt
rm -rf /media/*
cp -r /mnt/boot/* /media
mv /mnt/boot /mnt/boot_bak

对拷完毕,挂载之:

mount /dev/sdb6 /mnt
mount /dev/sdb2 /mnt/boot

这时还没完,因为没写到 /etc/fstab 里,/boot 所在分区根本不会自动挂载,于是加了一个

/dev/sdb2 /boot ext4 acl,user_xattr 1 2

以确保我的 /boot 能挂载。顺便学了下 fstab 格式,原来之前一直以为没什么用的 1, 2,第一个数字表示 dump 的时候是否 dump 它,0 为否 1 为是 ; 第二个数字表示 fsck 时候检查的顺序,/ 根分区必须为 1 而其它的分区为 2。

然后再重新 grub2-mkconfig 了一下,不要问我为什么,你的新的 /boot 的 UUID 跟原来 / 的肯定不一样,而 grub2 是基于 UUID 来制作 grub.cfg 的。总之不这么做你肯定启动不来。

接着重启,出现了久违的 grub2 图形界面。

但问题又来了,开不了机。检查了一下,发现原来是当初 openSUSE 13.1 在移动硬盘上,是 /dev/sdb 于是 grub2-install /dev/sdb,而现在换了硬盘 openSUSE 13.1 是唯一的一块硬盘应该是 /dev/sda,而 grub2 配置里的 root=/dev/sdb6 显然不对,按 e 修改为 sda,这回进入到 openSUSE 了。

但是我发现我的引导选项里居然有两个 Windows 7,一个在 sda 上,一个在 sdb 上。原来我之前那块 openSUSE 12.1 的硬盘里也有一个 Windows 7,于是 grub2-mkconfig 的时候就也弄上了。

于是在引导起来的 openSUSE 13.1 里再次 grub2-mkconfig,现在一切都回来了。

总结一下:

Error :attempt to read or write outside of disk hd0

这个错误是由于:3. /boot/grub2/grub.cfg 不在硬盘靠最前的 8GB 当中。简单说就是你需要一个独立的 /boot 分区。

但为什么「那为什么现在单独的 /boot 不挂载分区了,反而在我的 / 所在分区里面又建了一个 /boot,还抹去了我的 /etc/fstab 的部分内容呢!」,而且之前又能正常引导呢?!我怀疑可能跟 grub2 升级有关。回头看下 YaST2 日志看看是不是升级 KDE 4.13 的时候连带升级了 grub2 吧。

结束。

学习了 还好手上有
Windows PE + Mac PE + opensuse live Gnome

万事在手 不怕崩溃

BIOS 开 LBA 还是不行吗。用 UEFI 应该没这个问题了。
话说写的真详细。

Sent from my iPhone using Tapatalk

linux 就是这样, 用久了才偶尔出个问题, 而各种变化已经很多了, 搞得手忙脚乱的, 这个问题真没见过, 连网络上面也没见过

用 liveCD 修复 grub ,我就没成功过。。。。。。

修复引导,尝试过,失败过,没成功过。

Mark

只要能正确 chroot,一般来说都没有问题。

其实只要有一个最小化的 live 启动盘就可以了,dd 到一个老 U 盘里(比如那种 1G 的淘汰没人用的),然后和机器放在一起备用着。
用过 gentoo minimal live,里面工具基本上够用了。openSUSE Rescue CD 我还没有试过。