Linux系统诊断小技巧(13):启停问题之如何修复grub损坏

简介: grub损坏,是导致系统启动失败比较常见的致因之一,重新安装即能修复。但是系统没有启动,怎么重新安装gurb呢?有哪些要注意的事项?

grub损坏,是导致系统启动失败比较常见的原因。如何解决这类问题呢?

解决问题,好用的工具很重要。我们先讨论下好用的工具。

三大利器

关于工具的重要性我们就不絮叨了。解决启停问题,一定要有三大利器的辅助

  • 快照
  • VNC
  • 录屏工具

快照

快照对排查启停问题,有三个方面的用处。一是保留现场。有了这个现场,不管我们排查中做了什么变更,我们总是能够回撤到现场。这是现实版后悔药。二是在没有办法进入系统的情况下,快照可以让我们把问题磁盘挂载到其他实例上。这样我们有了一个排查、诊断和修复的途径。三是快照提供了多种可选择的途径让我们可以使用修复后的数据和结构。比如新建磁盘挂载拷贝、制作安装镜像覆盖有问题的系统盘等等。
988343E03D9EAC6D8E55E38EF760A9EC

VNC

高速公路是有应急车道的。同样我们的业务系统也需要应急车道,用以解决异常、紧急等非常规问题。VNC就是我们的应急车道。

当然,VNC不是唯一可用的方案。这里的关键是在系统异常时,提供一个root shell供排查只用就好。

录屏工具

各主流平台都有好用的录屏工具,功能大同小异,大家使用顺手即可。为什么我们要建议大家都配备录屏工具呢?

系统启停时,Linux控制台上的系统输出很快。有些关键的报错信息,你可能完全没有机会看到就过去了。如果类似信息完全没有记录到日志中。那么,你可能被后面的日志给误导。

题外话:bind挂载

修复启停时经常需要做chroot操作,即我们要在一个新的根文件系统内操作。但是,只执行chroot是不够的。我们还需要挂载/dev/proc/sys目录。

但是,因为/dev/proc/sys不是设备,直接挂载是不可行的。

mount --bind /olddir /newdir # bind挂载选项实例
for d in dev proc sys;do mount /$d /new_root_dir/$d;done # 切换根文件执行chroot前,先挂载需要的系统目录

回到话题

如何复现现场?

我们通过覆盖磁盘第一扇区来破坏grub的引导代码部分,观察下grub被破坏后,实例启动的情况
35480567BC1EBCBFB46CD6D1DD0B2DE4

具体操作的命令如下。注意,危险操作,切勿随意模仿。

fdisk -l -u /dev/{
   xvda,vda} # 确定系统盘设备路径
dd if=path_to_sys_disk bs=448 count=1 2>/dev/null | od -tx1 # 查看MBR内容
dd if=/dev/zero bs=448 count=1 of=path_to_sys_disk # 覆盖MBR
dd if=path_to_sys_disk bs=448 count=1 2>/dev/null | od -tx1 # 验证已经覆盖了MBR
reboot # 重启

执行过程如下(fdisk操作没有显示)

ADD70628FE61D191CA858513D8C69367

修复

那么,怎么修复呢?grub损坏的修复方法简洁明了:重新安装grub即可。但是当前实例启动失败了,无法对问题系统进行读写处理。

所以我们需要解决的问题是两个:

  1. 通过什么方式来处理系统盘。
  2. 怎么重新安装grub。

解决第一个问题的方法很多。这里我们给大家推荐能够使用快照的方法。这个方法虽然稍显啰嗦,但是却能让我们全程掌控。

如何使用快照?

我们为问题实例的系统盘做快照。然后再从快照新建磁盘。新建磁盘和系统盘内容一样,但是可以作为数据盘挂载到正常实例上。

这样我们就可以在正常实例上对新创建的磁盘做处理。调整配置、适当修改,而后重新安装grub。

整个思路图示如下
75944F2FA72CD1D112D3C39D34D5D8DE

具体操作示例如下

首先做快照
D149F323F79A2710F4A3DC0CD5E619BE

给快照个显著的名字
DB7B625AA6286AE201DD71670C375CEE

良好规划和维护的系统盘,一般都尺寸不大
EBED2326730C86E3113F72FA780EB6F8

现在新建磁盘

4A521F26FF0CAD259A80C38293ECAD4E

处理系统盘的问题解决了。那么,怎么重新安装grub呢?

重装grub

主流Linux发行版都提供了grub-install工具(名称也可能是grub2-install),大家直接调用即可。但是有几点大家要注意。

小提示

首先,grub的引导器默认使用BIOS磁盘命名惯例,这与Linux是不同。所以grub提供了配置文件,用来在BIOS的磁盘命名和Linux系统的磁盘命名之间转换。

这些配置文件如下:

版本 应用配置 系统配置
grub /boot/grub/device.map /etc/{sysconfig,default}/grub
grub2 /boot/grub2/device.map /etc/{sysconfig,default}/grub

如果是KVM实例,则磁盘是vda;如果是较老的XEN实例,则磁盘是xvda。

第二,grub-install的操作对象是磁盘还是分区。不要给错参数。

第三,如果您的系统比较老。那么,您可能会碰到已知bug:grub-install工具不能处理/dev/xvda*路径

重装步骤

有了以上的铺垫,我们给出重新安装grub的步骤

  1. 把新建磁盘挂载到正常实例上,以便对之读写、修改。
  2. 挂载目标根文件系统,我们需要改动grub的device.map文件。
  3. 把/dev、/proc和/sys挂载到新挂载文件系统。这样我们就能够使用内核导出的系统数据了。
  4. chroot到目标根文件系统,使之成为当前跟文件系统。
  5. 检查和核实/boot/{grub,grub2}/device.map和/etc/{sysconfig,default}/grub配置文件中磁盘名称是否正确。
  6. 使用grub-install来重新安装grub。

这些步骤,用脚本来表达,如下

# 1. 挂载新建磁盘到正常实例需要在控制台操作
# 2. 把新建磁盘在实例内部挂载上。这里我们假设/dev/vdb是系统盘
mount /dev/vdb1 /mnt
# 3. 通过bind方式,挂载系统目录到新根文件系统
for d in dev proc sys;do mount --bind /$d /mnt/$d;done
# 4. 切换到新根文件系统
chroot /mnt
# 5. 检查/boot/grub/device.map或者/boot/grub2/device.map文件,确认磁盘名称不当。如有则修改
cat /boot/{
   grub,grub2}/device.map
# 6. 重新安装grub。因为是在其他实例上以数据盘的方式,因此是第二块磁盘。
grub-install /dev/vdb

我们按照上面的步骤,把前面破坏的那台实例的grub重新安装下。

首先,挂载磁盘到正常实例

6802FC4BA13B6E205A5830218611DDA7

实例内部挂载

D7BFFDF1F285F94FE3026BF1923B942C

接下来我们bind挂载/dev、/proc和/sys

096FE01912E0A485E4BED7ECD16F0F9E

现在切换到新根文件系统

53870A7B65C809FEBBDFAD97BB05EF24

第五步,检查磁盘名称是否需要修改,需要则修改之

0D43CB5A63537636BEE2954E0019BDDF

最后一步,重新安装grub

94D67B63FFE6F38E150B70D8547C0DEF

再次请快照出场

怎么通过修正完毕的新建磁盘来修复问题实例的系统呢?这里需要注意

  1. 我们没有办法直接使用新建的快照回滚问题实例的系统盘。
  2. 数据盘的快照不能创建安装镜像。但是,开通了白名单就可以。

我们新创建磁盘是数据盘,其创建的快照是不能回滚问题实例的系统盘的。所以我们只能通过把新创建磁盘转为系统盘,而后创建安装镜像的方式来恢复问题实例。当然,这需要开通白名单。

即整体思路是这样的
75944F2FA72CD1D112D3C39D34D5D8DE

怎么把数据盘转为系统盘?我们会专题讨论下。

终焉

祝探索愉快。

相关文章
|
4月前
|
Ubuntu Linux Anolis
Linux系统禁用swap
本文介绍了在新版本Linux系统(如Ubuntu 20.04+、CentOS Stream、openEuler等)中禁用swap的两种方法。传统通过注释/etc/fstab中swap行的方式已失效,现需使用systemd管理swap.target服务或在/etc/fstab中添加noauto参数实现禁用。方法1通过屏蔽swap.target适用于新版系统,方法2通过修改fstab挂载选项更通用,兼容所有系统。
382 3
Linux系统禁用swap
|
4月前
|
Linux
Linux系统修改网卡名为eth0、eth1
在Linux系统中,可通过修改GRUB配置和创建Udev规则或使用systemd链接文件,将网卡名改为`eth0`、`eth1`等传统命名方式,适用于多种发行版并支持多网卡配置。
838 3
|
Ubuntu Linux 网络安全
Linux系统初始化脚本
一款支持Rocky、CentOS、Ubuntu、Debian、openEuler等主流Linux发行版的系统初始化Shell脚本,涵盖网络配置、主机名设置、镜像源更换、安全加固等多项功能,适配单/双网卡环境,支持UEFI引导,提供多版本下载与持续更新。
490 0
Linux系统初始化脚本
|
4月前
|
安全 Linux Shell
Linux系统提权方式全面总结:从基础到高级攻防技术
本文全面总结Linux系统提权技术,涵盖权限体系、配置错误、漏洞利用、密码攻击等方法,帮助安全研究人员掌握攻防技术,提升系统防护能力。
420 1
|
4月前
|
监控 安全 Linux
Linux系统提权之计划任务(Cron Jobs)提权
在Linux系统中,计划任务(Cron Jobs)常用于定时执行脚本或命令。若配置不当,攻击者可利用其提权至root权限。常见漏洞包括可写的Cron脚本、目录、通配符注入及PATH变量劫持。攻击者通过修改脚本、创建恶意任务或注入命令实现提权。系统管理员应遵循最小权限原则、使用绝对路径、避免通配符、设置安全PATH并定期审计,以防范此类攻击。
1107 1
|
Linux Shell
Linux系统诊断小技巧(14):启停问题之如何修复initrd损坏
initrd丢失、损坏或者没有正常工作,是导致系统启动失败比较常见的原因。 如何解决这类问题呢?重新做initrd即可。那么,具体怎么操作呢?我们讨论下。这里我们主要是围绕阿里云的实例问题展开。
3066 0
【云吞铺子之专家来了】linux系统启停问题之如何修复initrd损坏
《专家来了》第四季第2期如期而至!本期我们继续跟随阿里云高级技术专家直寻学习如何排查、诊断和解决Linux系统问题,本期主题【linux系统启停问题之如何修复initrd损坏】,技术干货不可错过哦!
|
4月前
|
Linux 应用服务中间件 Shell
二、Linux文本处理与文件操作核心命令
熟悉了Linux的基本“行走”后,就该拿起真正的“工具”干活了。用grep这个“放大镜”在文件里搜索内容,用find这个“探测器”在系统中寻找文件,再用tar把东西打包带走。最关键的是要学会使用管道符|,它像一条流水线,能把这些命令串联起来,让简单工具组合出强大的功能,比如 ps -ef | grep 'nginx' 就能快速找出nginx进程。
542 1
二、Linux文本处理与文件操作核心命令
|
4月前
|
Linux
linux命令—stat
`stat` 是 Linux 系统中用于查看文件或文件系统详细状态信息的命令。相比 `ls -l`,它提供更全面的信息,包括文件大小、权限、所有者、时间戳(最后访问、修改、状态变更时间)、inode 号、设备信息等。其常用选项包括 `-f` 查看文件系统状态、`-t` 以简洁格式输出、`-L` 跟踪符号链接,以及 `-c` 或 `--format` 自定义输出格式。通过这些选项,用户可以灵活获取所需信息,适用于系统调试、权限检查、磁盘管理等场景。
358 137
|
4月前
|
安全 Ubuntu Unix
一、初识 Linux 与基本命令
玩转Linux命令行,就像探索一座新城市。首先要熟悉它的“地图”,也就是/根目录下/etc(放配置)、/home(住家)这些核心区域。然后掌握几个“生存口令”:用ls看周围,cd去别处,mkdir建新房,cp/mv搬东西,再用cat或tail看文件内容。最后,别忘了随时按Tab键,它能帮你自动补全命令和路径,是提高效率的第一神器。
825 57