Linux各种作死故障与修复方法,全面复盘全程高能,系统级故障救援经验汇总

发布时间 2023-07-11 11:17:05作者: 寻梦99

1 linux启动过程

  1. 启动过程分析
  2. 启动级别init 0,init3, init5 init6。
  3. systemd 服务管理。
  4. systemd 导致系统反复重启:

2 磁盘与分区配置文件

  1. 磁盘UUID 和磁盘设备路径。
  2. /etc/inittab, /etc/fstab 等文件配置、丢失、格式错误影响启动。
    1. /etc/fstab 故障——fstab文件丢失:
    2. (/etc/fstab 文件丢失 情况2)系统尚未重启时:
    3. ( /etc/fstab 故障实际练习3):文件系统格式写法,错误,导致的系统引导失败
    4. /etc/fstab 故障实际练习4:硬盘分区的UUID变化导致系统引导失败
  3. 分区维护命令,特别是LVM分区方式。
  4. 强制断电引起的无法引导修复。

3 进入救援模式讲解

  1. grub >命令模式 ,
  2. shell 救援模式
  3. RHEL 7/ Centos7 Linux发行版的grub配置文件及排错, 恢复grub启动文件

4 shell故障:

  1. 丢失bash文件(文件缺失、依赖库文件破坏)
  2. bash 依赖的库文件缺失
  3. 环境变量相关的配置文件,及其导致的shell故障

5 MBR和GPT

  1. 修复分区表丢失
    1. 模拟 过去曾备份过分区表:
    2. 模拟误删 分区表(分区MBR转换为GPT,导致分区表丢失)
    3. 用备份的分区表恢复 分区信息:
  2. 5.2 修复 /boot分区下文件被删的问题:
    1. 恢复 /boot 下的vmlinuz (内核可执行文件) initramfs (系统启动时的内存临时根文件系统)文件:
    2. 恢复 /boot下的grub2相关文件: (适合于/boot/ 目录下文件丢失的情况)
  3. /lib/modules/XXX 内核(开发用的)模块文件被删,
  4. 误删数据文件恢复原理。
  5. linux下两种数据恢复软件(extundelete,testdisk)实操。

6 库文件缺失导致软件/系统无法正常运行/yum 无法正常使用。

图片

1 linux启动过程

1.1 启动过程分析

概括: 内核文件放在/boot分区. boot分区有引导标记(如下图Boot 列的星号,为可引导分区,标记) 

系统启动前,GRUB或者其他初始引导软件,知道从Boot flag为*的分区找操作系统的内核文件,把引导权限,从GRUB交给操作系统内核.(双系统或多系统引导,所以需要有grub这样的工具先接管硬件,然后才能接受用户输入,选择进入那个操作系统),所以GRUB有这个存在的必要性。

图片

​ 图释:使用fdisk -l 命令查看Linux分区的基本信息

由 grub 接管硬件后,要能(1)显示到屏幕上,(2)要能处理按键输入事件.这两个是让用户了解系统正常启动的基本功能。为了支持这两个功能,内核核心就要根据引导配置文件,依次加载显示驱动、输入按键驱动。那么此时读取的配置文件在哪里?

在 /etc/grub.d/ 目录下,有一些文件以两位数字开头,如00_header、01_users 等

图片

​ 图释:GRUB引导配置文件

所以我们看到 /etc/grub.d/00_header 这个设定启动第一步骤的文件,里面有这些内容:显示驱动等的初始化.(insmod 就是 insert modules 的缩写,加载内核驱动的意思,内核驱动文件是 后缀为.ko 的文件)实际这些驱动文件已经在系统安装或生成/boot内容的时候通过 grub2-mkconfig 和grub2-intstall 命令,已经集合到一个文件中了。所以在/目录内找不到 具体的 efi_gop.ko 这样的文件。因为这些文件是非常基础的,所以已经集成到grub软件中。

图片

​ 图释:/etc/grub.d/00_header 文件内容

然后/etc/grub.d/00_tuned 文件、其他还有01、10文件名开头的,按名称数字递增的顺序依次发挥作用。

其中最主要的是 /etc/grub.d/10_linux ,这个文件帮助把 硬件管理权交给linux内核引导。

图片

grub.cfg文件的内容:

这里有很多BEGIN 和 END 段,每段就是根据 /etc/grub.d/里面的配置内容得到的。从中可以确认加载的顺序。是从00-01-10-20-30-40.

cat /boot/grub2/grub.cfg

#

# DO NOT EDIT THIS FILE #说明这个文件是工具自动生成的,对grub2的引导有控制作用.

#

# It is automatically generated by grub2-mkconfig using templates

# from /etc/grub.d and settings from /etc/default/grub #说明这目录和文件是以后boot里面文件丢失或者grub人为破坏后

# 修复grub时候,的两个重要参考文件.里面控制grub的系统启动等待时间.等一些参数.内容确定后,用grub2-mkconfig 重新生

#  成/boot/grub2下的文件.

         

### BEGIN /etc/grub.d/00_header ###

set pager=1

         

if [ -s $prefix/grubenv ]; then

  load_env

fi

if [ "${next_entry}" ] ; then

   set default="${next_entry}"

   set next_entry=

   save_env next_entry

   set boot_once=true

else

   set default="${saved_entry}"

fi

         

if [ x"${feature_menuentry_id}" = xy ]; then

  menuentry_id_option="--id"

else

  menuentry_id_option=""

fi

         

export menuentry_id_option

         

if [ "${prev_saved_entry}" ]; then

  set saved_entry="${prev_saved_entry}"

  save_env saved_entry

  set prev_saved_entry=

  save_env prev_saved_entry

  set boot_once=true

fi

         

function savedefault {

  if [ -z "${boot_once}" ]; then

    saved_entry="${chosen}"

    save_env saved_entry

  fi

}

         

function load_video {

  if [ x$feature_all_video_module = xy ]; then

    insmod all_video

  else

    insmod efi_gop

    insmod efi_uga

    insmod ieee1275_fb

    insmod vbe

    insmod vga

    insmod video_bochs

    insmod video_cirrus

  fi

}

         

terminal_output console

if [ x$feature_timeout_style = xy ] ; then

  set timeout_style=menu

  set timeout=5

# Fallback normal timeout code in case the timeout_style feature is

# unavailable.

else

  set timeout=5

fi

### END /etc/grub.d/00_header ###

         

### BEGIN /etc/grub.d/00_tuned ###

set tuned_params=""

set tuned_initrd=""

### END /etc/grub.d/00_tuned ###

         

### BEGIN /etc/grub.d/01_users ###

if [ -f ${prefix}/user.cfg ]; then

  source ${prefix}/user.cfg

  if [ -n "${GRUB2_PASSWORD}" ]; then

    set superusers="root"

    export superusers

    password_pbkdf2 root ${GRUB2_PASSWORD}

  fi

fi

### END /etc/grub.d/01_users ###

         

### BEGIN /etc/grub.d/10_linux ###

menuentry 'CentOS Linux (3.10.0-1160.2.2.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-862.el7.x86_64-advanced-d6258e7b-616d-4073-9234-7ea0227ad5be' {

        load_video

        set gfxpayload=keep

        insmod gzio

        insmod part_msdos

        insmod ext2

        set root='hd0,msdos1'

        if [ x$feature_platform_search_hint = xy ]; then

          search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1'  a2828f1e-dfa7-4cc8-b6e5-6ec203d87feb

        else

          search --no-floppy --fs-uuid --set=root a2828f1e-dfa7-4cc8-b6e5-6ec203d87feb

        fi

        linux16 /vmlinuz-3.10.0-1160.2.2.el7.x86_64 root=UUID=d6258e7b-616d-4073-9234-7ea0227ad5be ro crashkernel=auto rhgb quiet LANG=en_US.UTF-8

        initrd16 /initramfs-3.10.0-1160.2.2.el7.x86_64.img

}

menuentry 'CentOS Linux (3.10.0-862.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-862.el7.x86_64-advanced-d6258e7b-616d-4073-9234-7ea0227ad5be' {

        load_video

        set gfxpayload=keep

        insmod gzio

        insmod part_msdos

        insmod ext2

        set root='hd0,msdos1'

        if [ x$feature_platform_search_hint = xy ]; then

          search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1'  a2828f1e-dfa7-4cc8-b6e5-6ec203d87feb

        else

          search --no-floppy --fs-uuid --set=root a2828f1e-dfa7-4cc8-b6e5-6ec203d87feb

        fi

        linux16 /vmlinuz-3.10.0-862.el7.x86_64 root=UUID=d6258e7b-616d-4073-9234-7ea0227ad5be ro crashkernel=auto rhgb quiet LANG=en_US.UTF-8

        initrd16 /initramfs-3.10.0-862.el7.x86_64.img

}

menuentry 'CentOS Linux (0-rescue-5bd1513401ee49449329603b92b4bc5c) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-0-rescue-5bd1513401ee49449329603b92b4bc5c-advanced-d6258e7b-616d-4073-9234-7ea0227ad5be' {

        load_video

        insmod gzio

        insmod part_msdos

        insmod ext2

        set root='hd0,msdos1'

        if [ x$feature_platform_search_hint = xy ]; then

          search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1'  a2828f1e-dfa7-4cc8-b6e5-6ec203d87feb

        else

          search --no-floppy --fs-uuid --set=root a2828f1e-dfa7-4cc8-b6e5-6ec203d87feb

        fi

        linux16 /vmlinuz-0-rescue-5bd1513401ee49449329603b92b4bc5c root=UUID=d6258e7b-616d-4073-9234-7ea0227ad5be ro crashkernel=auto rhgb quiet

        initrd16 /initramfs-0-rescue-5bd1513401ee49449329603b92b4bc5c.img

}

         

### END /etc/grub.d/10_linux ###

         

### BEGIN /etc/grub.d/20_linux_xen ###

### END /etc/grub.d/20_linux_xen ###

         

### BEGIN /etc/grub.d/20_ppc_terminfo ###

### END /etc/grub.d/20_ppc_terminfo ###

         

### BEGIN /etc/grub.d/30_os-prober ###

### END /etc/grub.d/30_os-prober ###

         

### BEGIN /etc/grub.d/40_custom ###

# This file provides an easy way to add custom menu entries.  Simply type the

# menu entries you want to add after this comment.  Be careful not to change

# the 'exec tail' line above.

### END /etc/grub.d/40_custom ###

         

### BEGIN /etc/grub.d/41_custom ###

if [ -f  ${config_directory}/custom.cfg ]; then

  source ${config_directory}/custom.cfg

elif [ -z "${config_directory}" -a -f  $prefix/custom.cfg ]; then

  source $prefix/custom.cfg;

fi

### END /etc/grub.d/41_custom ###

重点关注 00_linux 这段的内容:每一个 menuentry 都是 开机后 grub 启动选项中的一个可回车的引导项目。

insmod ext2 这个 ,是让grub能读取ext类型的文件系统的内容。这里的语法,就是grub> 救援模式可以用的语法。我们手动在 grub> 模式 手动输入命令救援启动的时候,就是执行

load_video

set gfxplayload=keep

insmod gzio

其中 set root='hd0,msdos1'这一步非常重要。hd0代表第一块硬盘。msdos1代表该硬盘的第一块分区。注意硬盘是0开始,分区是1开始计数。

search 这个是查找boot=* (boot flag 为*)的分区。

### BEGIN /etc/grub.d/10_linux ###

menuentry 'CentOS Linux (3.10.0-1160.2.2.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-862.el7.x86_64-advanced-d6258e7b-616d-4073-9234-7ea0227ad5be' {

        load_video

        set gfxpayload=keep

        insmod gzio

        insmod part_msdos

        insmod ext2

        set root='hd0,msdos1'

        if [ x$feature_platform_search_hint = xy ]; then

          search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1'  a2828f1e-dfa7-4cc8-b6e5-6ec203d87feb

        else

          search --no-floppy --fs-uuid --set=root a2828f1e-dfa7-4cc8-b6e5-6ec203d87feb

        fi

        linux16 /vmlinuz-3.10.0-1160.2.2.el7.x86_64 root=UUID=d6258e7b-616d-4073-9234-7ea0227ad5be ro crashkernel=auto rhgb quiet LANG=en_US.UTF-8

        initrd16 /initramfs-3.10.0-1160.2.2.el7.x86_64.img

}

menuentry 'CentOS Linux (3.10.0-862.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-862.el7.x86_64-advanced-d6258e7b-616d-4073-9234-7ea0227ad5be' {

        load_video

        set gfxpayload=keep

        insmod gzio

        insmod part_msdos

        insmod ext2

        set root='hd0,msdos1'

        if [ x$feature_platform_search_hint = xy ]; then

          search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1'  a2828f1e-dfa7-4cc8-b6e5-6ec203d87feb

        else

          search --no-floppy --fs-uuid --set=root a2828f1e-dfa7-4cc8-b6e5-6ec203d87feb

        fi

        linux16 /vmlinuz-3.10.0-862.el7.x86_64 root=UUID=d6258e7b-616d-4073-9234-7ea0227ad5be ro crashkernel=auto rhgb quiet LANG=en_US.UTF-8

        initrd16 /initramfs-3.10.0-862.el7.x86_64.img

}

menuentry 'CentOS Linux (0-rescue-5bd1513401ee49449329603b92b4bc5c) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-0-rescue-5bd1513401ee49449329603b92b4bc5c-advanced-d6258e7b-616d-4073-9234-7ea0227ad5be' {

        load_video

        insmod gzio

        insmod part_msdos

        insmod ext2

        set root='hd0,msdos1'

        if [ x$feature_platform_search_hint = xy ]; then

          search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1'  a2828f1e-dfa7-4cc8-b6e5-6ec203d87feb

        else

          search --no-floppy --fs-uuid --set=root a2828f1e-dfa7-4cc8-b6e5-6ec203d87feb

        fi

        linux16 /vmlinuz-0-rescue-5bd1513401ee49449329603b92b4bc5c root=UUID=d6258e7b-616d-4073-9234-7ea0227ad5be ro crashkernel=auto rhgb quiet

        initrd16 /initramfs-0-rescue-5bd1513401ee49449329603b92b4bc5c.img

}

         

### END /etc/grub.d/10_linux ###

图片

手动删掉这几句search的是否会影响启动?

可发现删掉search 这几句后,并不影响启动。

但不能删linux16 和 initrd16 这两行的内容。否则无法引导。上图是,在grub时按e (进入启动参数编辑模式)手动补充linux引导被删的linux16 和 initrd16 两句,然后按CTRL+x 启动,启动成功。

虽然启动成功。但/boot/grub2/grub.cfg 文件里的linux16 和 initrd16 这两行,记得要手动补回来,才不影响下次启动。因为上面界面我们输入的,并不会保存。

那么上图中,linux16 和 initrd16 这两行到底在做什么呢?

UUID=d6258e7b-616d-4073-9234-7ea0227ad5be 这个分区 ,我们下文会有图片(/etc/fstab 文件内容),是/ 根 目录对应的物理分区的UUID。

linux16 /vmlinuz-3.10.0-862.el7.x86_64 root=UUID=d6258e7b-616d-4073-9234-7ea0227ad5be ro crashkernel=auto rhgb quiet LANG=en_US.UTF-8

initrd16 /initramfs-3.10.0-862.el7.x86_64.img

这里/vmlinuz-3.10.0-862.el7.x86_64 代表的意思是hd0硬盘 msdos1 分区(也就是第一块硬盘,第一个分区)里的 vmlinuz-3.10.0-862.el7.x86_64 文件。

在系统最终启动后,相当于 挂载到 /boot分区的 /boot/vmlinuz-3.10.0-862.el7.x86_64 文件,用file 命令看到,是一个 6MB大小的Linux kernel x86 boot executable bzImage文件。

[root@osboxes ~]# file  /boot/vmlinuz-3.10.0-862.el7.x86_64

/boot/vmlinuz-3.10.0-862.el7.x86_64: Linux kernel x86 boot executable bzImage, version 3.10.0-862.el7.x86_64 (builder@kbuilder.dev.centos.org) #1 SMP , RO-rootFS, swap_dev 0x5, Normal VGA

[root@osboxes ~]# ls /boot/vmlinuz-3.10.0-862.el7.x86_64  -lht

-rwxr-xr-x. 1 root root 6.0M 4月  20 2018 /boot/vmlinuz-3.10.0-862.el7.x86_64

[root@osboxes ~]#

(1)vmlinuz指的是内核,作用:进程管理、内存管理、文件管理、驱动管理、网络管理。(2)initrd.img是一个小的映象, 放的是和启动相关的驱动模块。

通常的步骤是先启动内核,然后内核挂载initrd.img,并执行里面的脚本来进一步挂载各种各样的模块。

其中最重要的就是根文件系统驱动模块,有了它才能挂载根文件系统,继而运行用户空间的第一个应用程序(init或者systemd, 作为Linux的pid=0的进程,负责初始化linux启动时的其他进程管理),直至完成系统后续软件的所有初始化动作。

到此。GRUB把硬件管理权交给了 linux,linux有了根文件系统挂载驱动(ext4格式的文件系统需要ext4驱动,而grub只有简单的ext2驱动。linux内核还可以加载xfs、reiserfs、zfs等各种高级驱动,都不是grub所能承担的,所以要让linux内核做)。

练习:用命令生成 /etc/grub2/grub.cfg 新的引导文件。指定启动等待时间从默认的5s 改到10s:

grub2-mkconfig

由于GRUB系统启动阶段, linux 的/ 根分区并没有挂载 所以/etc/fstab 文件里面的挂载关系这时候对内核来说是未知的.

只有在 内核通过加载根文件系统驱动后,就能支持 特定格式的分区,才能读取分区里面的文件,根据GRUB 引导命令中的 root=UUID=d6258e7b-616d-4073-9234-7ea0227ad5be 指定的分区,Linux内核会把那个分区作为/ 根分区 挂载。

这样就能读取 /下面的 /etc/fstab 文件,以及 /etc/inittab 文件。

关于 /etc/fstab 文件,可以阅读 本公众号一篇专题文章: Linux的/etc/fstab文件一些常识。很重要也很简单,现在就看懂它!

实际内核开始运行后逐步做的 事情:

内核功能全部载入内存后,内核会马上查找/sbin下的“init”程序(/sbin/init)并执行它。从这里开始init成为了Linux系统的父进程(PID=1)。init读取的第一个文件是/etc/inittab,通过它init会确定我们Linux操作系统的运行级别。它会从文件/etc/fstab里查找分区表信息然后做相应的挂载。

(所以常见的系统无法启动,会跟/etc/inittab 和 /etc/fstab 的错误有关。)

然后init会启动/etc/init.d里指定的默认启动级别的所有服务/脚本。所有服务在这里通过init一个一个被初始化。在这个过程里,init每次只启动一个服务,所有服务/守护进程都在后台执行并由init来管理。

# ls /etc/init.d

functions  netconsole  network  README

但是:注意:cat /etc/inittab

# inittab is no longer used when using systemd.

# ADDING CONFIGURATION HERE WILL HAVE NO EFFECTON YOUR SYSTEM.

#

# Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target

#

# systemd uses 'targets' instead of runlevels. By default, there are two main targets:

#

# multi-user.target: analogous to runlevel 3

# graphical.target: analogous to runlevel 5

#

# To view current default target, run:

# systemctl get-default

#

# To set a default target, run:

# systemctl set-default TARGET.target

上面这段意思是:

现在主流的linux版本中,都用systemd 代替了过期的init 方式管理linux的后台服务的启动方式。以前iinit 3,init 5这样的方式,现在systemd的方式是:

systemctl set-default  TARGET.target #这个 TARGET 具体可选择 multi-user 或者graphical 。

图形界面下练习:修改为multi-user 然后重启看效果。multi-user的意思是多用户模式。多图形用户是否也属于多用户?还是命令行才算多用户模式?

systemctl set-default multi-user.target

效果:证明 multi-user是 启动后默认进入命令多用户模式。而不是图形模式。虽然图形下用vnc-server软件也可以实现多用户图形方式访问linux的效果。

图片

看下这里提到的 ctrl+alt+del 按键后系统的systemd 怎么处理这个按键请求的:重启。

cat  /usr/lib/systemd/system/ctrl-alt-del.target

#  This file is part of systemd.

#

#  systemd is free software; you can redistribute it and/or modify it

#  under the terms of the GNU Lesser General Public License as published by

#  the Free Software Foundation; either version 2.1 of the License, or

#  (at your option) any later version.



[Unit]

Description=Reboot

Documentation=man:systemd.special(7)

DefaultDependencies=no

Requires=systemd-reboot.service

After=systemd-reboot.service

AllowIsolate=yes

JobTimeoutSec=30min

JobTimeoutAction=reboot-force



[Install]

Alias=ctrl-alt-del.target

systemd 的配置文件所在的目录 路径:/usr/lib/systemd/system/

该路径下还有大量其他服务的启动控制文件:

# ls /usr/lib/systemd/system

abrt-ccpp.service                        plymouth-read-write.service

abrtd.service                            plymouth-reboot.service

abrt-oops.service                        plymouth-start.service

abrt-pstoreoops.service                  plymouth-switch-root.service

abrt-vmcore.service                      polkit.service

abrt-xorg.service                        postfix.service

accounts-daemon.service                  poweroff.target

alsa-restore.service                     poweroff.target.wants

alsa-state.service                       printer.target

anaconda-direct.service                  proc-fs-nfsd.mount

anaconda-nm-config.service               proc-sys-fs-binfmt_misc.automount

anaconda-noshell.service                 proc-sys-fs-binfmt_misc.mount

anaconda-pre.service                     psacct.service

anaconda.service                         qemu-guest-agent.service

anaconda-shell@.service                  quotaon.service

anaconda-sshd.service                    radvd.service

anaconda.target                          rc-local.service

anaconda-tmux@.service                   rdisc.service

arp-ethers.service                       rdma-hw.target

atd.service                              rdma-load-modules@.service

auditd.service                           rdma-ndd.service

auth-rpcgss-module.service               rdma.service

autofs.service                           realmd.service

autovt@.service                          reboot.target

avahi-daemon.service                     reboot.target.wants

avahi-daemon.socket                      remote-cryptsetup.target

basic.target                             remote-fs-pre.target

basic.target.wants                       remote-fs.target

blk-availability.service                 rescue.service

bluetooth.service                        rescue.target

bluetooth.target                         rescue.target.wants

bolt.service                             rhel-autorelabel-mark.service

brandbot.path                            rhel-autorelabel.service

brandbot.service                         rhel-configure.service

brltty.service                           rhel-dmesg.service

canberra-system-bootup.service           rhel-domainname.service

canberra-system-shutdown-reboot.service  rhel-import-state.service

canberra-system-shutdown.service         rhel-loadmodules.service

certmonger.service                       rhel-readonly.service

cgconfig.service                         rngd.service

cgdcbxd.service                          rpcbind.service

cgred.service                            rpcbind.socket

chrony-dnssrv@.service                   rpcbind.target

chrony-dnssrv@.timer                     rpc-gssd.service

chronyd.service                          rpcgssd.service

chrony-wait.service                      rpcidmapd.service

clean-mount-point@.service               rpc_pipefs.target

colord.service                           rpc-rquotad.service

configure-printer@.service               rpc-statd-notify.service

console-getty.service                    rpc-statd.service

console-shell.service                    rsyncd.service

container-getty@.service                 rsyncd@.service

cpupower.service                         rsyncd.socket

crond.service                            rsyslog.service

cryptsetup-pre.target                    rtkit-daemon.service

cryptsetup.target                        runlevel0.target

ctrl-alt-del.target                      runlevel1.target

cups-browsed.service                     runlevel1.target.wants

cups.path                                runlevel2.target

cups.service                             runlevel2.target.wants

cups.socket                              runlevel3.target

dbus-org.freedesktop.hostname1.service   runlevel3.target.wants

dbus-org.freedesktop.import1.service     runlevel4.target

dbus-org.freedesktop.locale1.service     runlevel4.target.wants

dbus-org.freedesktop.login1.service      runlevel5.target

dbus-org.freedesktop.machine1.service    runlevel5.target.wants

dbus-org.freedesktop.timedate1.service   runlevel6.target

…………

注意到其中 有runlevel 0 - 6,并且有 runlevel0-6.target.wants 这样以wants后缀结尾的目录。wants目录不分析。

runlevel0.target        runlevel2.target        runlevel3.target.wants/ runlevel5.target

runlevel1.target        runlevel2.target.wants/ runlevel4.target        runlevel5.target.wants/

runlevel1.target.wants/ runlevel3.target        runlevel4.target.wants/ runlevel6.target

下面分析下 这些 runlevel*.target 等文件的作用:

runlevel0.target 文件:关机模式

# cat /usr/lib/systemd/system/runlevel0.target



[Unit]

Description=Power-Off

Documentation=man:systemd.special(7)

DefaultDependencies=no

Requires=systemd-poweroff.service

After=systemd-poweroff.service

AllowIsolate=yes

JobTimeoutSec=30min

JobTimeoutAction=poweroff-force



[Install]

Alias=ctrl-alt-del.target


runlevel1.target文件:救援模式

# cat /usr/lib/systemd/system/runlevel1.target



[Unit]

Description=Rescue Mode

Documentation=man:systemd.special(7)

Requires=sysinit.target rescue.service

After=sysinit.target rescue.service

AllowIsolate=yes



[Install]

Alias=kbrequest.target

runlevel2.target文件:多用户命令行模式。

# cat /usr/lib/systemd/system/runlevel2.target



[Unit]

Description=Multi-User System

Documentation=man:systemd.special(7)

Requires=basic.target

Conflicts=rescue.service rescue.target

After=basic.target rescue.service rescue.target

AllowIsolate=yes

runlevel3.target文件:多用户命令行模式。内容跟 runlevel2.target 完全一样。所以执行 init 2 跟init 3命令的效果是一样的。

另外还有runlevel3.target、runlevel4.target 、 runlevel5.target 、 runlevel6.target 。

各级别的功能,看表格介绍:

图片

真机上过几遍,验证下。涉及到哪些配置文件 )

1.2 启动级别init 0,init3, init5 init6。

1.3 systemd 服务管理。

使用systemd代替 init的目的是加快启动速度,因为Systemd引入了并行启动的效果。

systemd 常见命令练习:

systemd 控制服务启停:

例如

(1). sshd服务 重启:

systemctl restart sshd   =   systemctl stop sshd  +  systemctl start sshd

2). 禁止sshd服务开机自动运行:

# systemctl disable  sshd
Removed symlink /etc/systemd/system/multi-user.target.wants/sshd.service.

(3).设置sshd服务开机自动运行:

# systemctl enable   sshd

Created symlink from /etc/systemd/system/multi-user.target.wants/sshd.service to /usr/lib/systemd/system/sshd.service.

可见,如果一个服务执行systemd方式启动,那么软件安装后,它的systemd配置文件存放在 /etc/systemd/system/运行级别-user.target.wants/目录下,在被systemctl enable 以后,systemd的备用配置文件倍创建了一个软链接(快捷方式)到 systemd的正式目录/usr/lib/systemd/system/下。保存的文件名格式,是

服务名.service
1.3.1 systemd 导致系统反复重启:

如果要通过systemd 让系统反复重启,可以设置默认启动方式为 init6:

# systemctl  set-default  init6

这样就造成开机就默认进入init 6 级别,也就是开机则不断重启。

注意:这个做法对系统正常启动就要有干扰,仅用于测试验证练习。

2 磁盘与分区配置文件

2.1 磁盘UUID 和磁盘设备路径。

linux 所有的设备都被作为文件,有路径:/dev/xxxx

传统的分区路径:/dev/sdX0 等

新型分区路径:UUID表示:/dev/disk/by-uuid/ba894dab-f6f1-4840-93d0-0a126119b7bc 。

UUID的重要优势:不随磁盘顺序而变化。因为传统的/dev/sdX0 ,如果硬盘原来在第1位,后来在第2位,那么X就变化了。导致系统无法根据/boot/grub2/grub.cfg 文件中指定的原始/dev/sdX0 启动和挂载分区!导致无法启动。而UUID不随磁盘接线顺序而改变,那么换位置,就不会影响启动。

#ls /dev/disk/by-

by-id/    by-label/ by-path/  by-uuid/

# mount /dev/disk/by-uuid/ba894dab-f6f1-4840-93d0-0a126119b7bc   /home/   #disk UUID可直接用于挂载分区。

图片

2.2 /etc/inittab, /etc/fstab 等文件配置、丢失、格式错误影响启动。

先说结论:/etc/inittab 文件在centos7 中没用,可有可无。

/etc/fstab文件必须,并且内容要对。关于 /etc/fstab 文件格式,可以阅读 本公众号一篇专题文章: Linux的/etc/fstab文件一些常识。很重要也很简单,现在就看懂它!

2.2.1 /etc/fstab 故障——fstab文件丢失:

正常运行的系统,/etc/fstab 文件误删,这时候如果重启系统,肯定无法启动。

若已重启了并且重启失败:启动过程中提示大量错误,很多服务都无法启动,正是因为分区的挂载失败(linux不知道挂载哪个分区为/home /boot 等分区,但知道/根分区是哪个,因为 /etc/grub2/grub.cfg 文件里的root=UUID=那句指定了 /分区是哪个 ,就能在启动后挂载/分区 ):

图片

这时,重启系统,在grub选择菜单那里 进入rescue (命令行)模式:

图片

首先文件系统变成了只读的:

图片

图片

要用 mount -o rw,remount / #将根分区 重新挂载为可读写,以手动恢复/etc/fstab 文件的内容

图片

图片

或者用u盘版的linux引导进入其他linux,然后打开根分区的 /etc/fstab 文件,增加内容。就可以正常启动系统了。

2.2.2(/etc/fstab 文件丢失 情况2)文件丢失且系统尚未重启过的情况下:

尽快从内存中找回/etc/fstab 内容:

使用/etc/mtab (相当于系统内存中记录的挂载关系文件 /proc/self/mounts)找回/etc/fstab 内容:

# file /etc/mtab

/etc/mtab: symbolic link to `/proc/self/mounts'

[root@osboxes ~]# ls -l  /etc/mtab

lrwxrwxrwx. 1 root root 17 9月   9 2018 /etc/mtab -> /proc/self/mounts

[root@osboxes ~]# cat /etc/mtab

sysfs /sys sysfs rw,seclabel,nosuid,nodev,noexec,relatime 0 0

proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0

devtmpfs /dev devtmpfs rw,seclabel,nosuid,size=491856k,nr_inodes=122964,mode=755 0 0

securityfs /sys/kernel/security securityfs rw,nosuid,nodev,noexec,relatime 0 0

tmpfs /dev/shm tmpfs rw,seclabel,nosuid,nodev 0 0

devpts /dev/pts devpts rw,seclabel,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0

tmpfs /run tmpfs rw,seclabel,nosuid,nodev,mode=755 0 0

tmpfs /sys/fs/cgroup tmpfs ro,seclabel,nosuid,nodev,noexec,mode=755 0 0

cgroup /sys/fs/cgroup/systemd cgroup rw,seclabel,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd 0 0

pstore /sys/fs/pstore pstore rw,nosuid,nodev,noexec,relatime 0 0

cgroup /sys/fs/cgroup/net_cls,net_prio cgroup rw,seclabel,nosuid,nodev,noexec,relatime,net_prio,net_cls 0 0

cgroup /sys/fs/cgroup/memory cgroup rw,seclabel,nosuid,nodev,noexec,relatime,memory 0 0

cgroup /sys/fs/cgroup/devices cgroup rw,seclabel,nosuid,nodev,noexec,relatime,devices 0 0

cgroup /sys/fs/cgroup/cpu,cpuacct cgroup rw,seclabel,nosuid,nodev,noexec,relatime,cpuacct,cpu 0 0

cgroup /sys/fs/cgroup/pids cgroup rw,seclabel,nosuid,nodev,noexec,relatime,pids 0 0

cgroup /sys/fs/cgroup/hugetlb cgroup rw,seclabel,nosuid,nodev,noexec,relatime,hugetlb 0 0

cgroup /sys/fs/cgroup/freezer cgroup rw,seclabel,nosuid,nodev,noexec,relatime,freezer 0 0

cgroup /sys/fs/cgroup/blkio cgroup rw,seclabel,nosuid,nodev,noexec,relatime,blkio 0 0

cgroup /sys/fs/cgroup/cpuset cgroup rw,seclabel,nosuid,nodev,noexec,relatime,cpuset 0 0

cgroup /sys/fs/cgroup/perf_event cgroup rw,seclabel,nosuid,nodev,noexec,relatime,perf_event 0 0

configfs /sys/kernel/config configfs rw,relatime 0 0

/dev/sda3 / ext4 rw,seclabel,relatime,data=ordered 0 0

selinuxfs /sys/fs/selinux selinuxfs rw,relatime 0 0

debugfs /sys/kernel/debug debugfs rw,relatime 0 0

hugetlbfs /dev/hugepages hugetlbfs rw,seclabel,relatime 0 0

systemd-1 /proc/sys/fs/binfmt_misc autofs rw,relatime,fd=34,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=11051 0 0

mqueue /dev/mqueue mqueue rw,seclabel,relatime 0 0

fusectl /sys/fs/fuse/connections fusectl rw,relatime 0 0

/dev/sda1 /boot ext4 rw,seclabel,relatime,data=ordered 0 0

/dev/sda2 /home ext4 rw,seclabel,relatime,data=ordered 0 0

sunrpc /var/lib/nfs/rpc_pipefs rpc_pipefs rw,relatime 0 0

tmpfs /run/user/0 tmpfs rw,seclabel,nosuid,nodev,relatime,size=101476k,mode=700 0 0

根据作用判断,跟物理分区挂载相关的,只有这几句,抄录到/etc/fstab 里面:

/dev/sda3 / ext4 rw,seclabel,relatime,data=ordered 0 0

/dev/sda1 /boot ext4 rw,seclabel,relatime,data=ordered 0 0

/dev/sda2 /home ext4 rw,seclabel,relatime,data=ordered 0 0

从中可见系统运行必须的/ ,/boot、 /home 目录,的挂载关系,在/etc/mtab 里面都有了。这内容可以用于 /etc/fstab。

(可选)改进:如果要更完善象原始的/etc/fstab那样的写法,就要采用UUID的写法,类似这样:

/etc/fstab 文件正式内容。其中 swap 那行,可要可不要。

UUID=d6258e7b-616d-4073-9234-7ea0227ad5be /                       ext4    defaults        1 1

UUID=a2828f1e-dfa7-4cc8-b6e5-6ec203d87feb /boot                   ext4    defaults        1 2

UUID=ba894dab-f6f1-4840-93d0-0a126119b7bc /home                   ext4    defaults        1 2

UUID=51fb268f-4b81-4232-ac4c-f3dc3b4efd9d swap                    swap    defaults        0 0
2.2.3( /etc/fstab 故障实际练习3):文件系统格式写法,错误,导致的系统引导失败

正确语法格式:请用帮助命令 查看:man 5 fstab

写法错误的情况:

UUID=d6258e7b-616d-4073-9234-7ea0227ad5be /                  ext3    defaults        1 1

UUID=a2828f1e-dfa7-4cc8-b6e5-6ec203d87feb /boot              ext3    defaults        1 2

UUID=ba894dab-f6f1-4840-93d0-0a126119b7bc /home              ext3    defaults        1 2

UUID=51fb268f-4b81-4232-ac4c-f3dc3b4efd9d swap               swap    defaults        0 0
UUID=d6258e7b-616d-4073-9234-7ea0227ad5be /                   ext4    defaults        1

UUID=a2828f1e-dfa7-4cc8-b6e5-6ec203d87feb /boot               ext4    defaults        1 2

UUID=ba894dab-f6f1-4840-93d0-0a126119b7bc /home                ext4    defaults        1

UUID=51fb268f-4b81-4232-ac4c-f3dc3b4efd9d swap                swap    defaults        0 0
UUID=d6258e7b-616d-4073-9234-7ea0227ad5be /                    ext4    default        1 1

UUID=a2828f1e-dfa7-4cc8-b6e5-6ec203d87feb /boot        ext4                     1 2

UUID=ba894dab-f6f1-4840-93d0-0a126119b7bc /home            ext4    noauto,auto        1 2

UUID=51fb268f-4b81-4232-ac4c-f3dc3b4efd9d swap              swap    defaults        0 0
2.2.4 /etc/fstab 故障实际练习4:硬盘分区的UUID变化导致系统引导失败

图片

这个图,提示了系统启动顺序.挂载分区的过程.

发现卡在 880f 这里.发现实际上我们没有UUID以 880f结尾的分区.

图片

这是系统最终停在了救援用的命令行界面,输入root的密码,可以使用有限的命令功能, 使用journalctl -xb 查看系统错误日志记录。

图片

通过lsblk -f 结果显示的实际分区UUID变成了b7bc结尾的UUID。

与 /etc/fstab内的UUID对比,可以发现 /etc/fstab 原来的 UUID 880f 结尾的 是/home对应分区的,要改成现在实际的UUID(以lsblk -f 结果为准).

图片

修改后的 /etc/fstab 内容:

图片

现在重启系统看下效果,启动正常。到此,硬盘分区的UUID变化导致系统引导失败 故障也解决好了。

图片

2.3 分区维护命令,特别是LVM分区方式。

略。

2.4 强制断电引起的无法引导修复。

只需要知道fsck 命令的用法就可以了(不适合于文件系统是xfs 的情况,xfs文件系统有其他专门修复命令):

fsck /dev/设备路径。对于执行修复中提示的 fix it ? 的提问,一般都输入y,以确认修复。因为ext4是日志文件系统,数据一致性一般都可以保证。

当然,为防止 意外,建议fsck 修复重要数据分区的之前,不能挂载这个分区,且养成先用dd命令 先备份 该分区到其他硬盘上。然后再做fsck 修复。

3 进入救援模式讲解

3.1 grub >命令模式 ,

该模式的功能非常有限,无法修复/boot分区内文件被删的问题。需要shell的 rescue模式才能修复 /boot被删的问题

如何进入 grub> 命令模式:grub菜单选择界面,按c进入:

图片

3.2 shell 救援模式

重启系统,在grub选择菜单那里 进入rescue (命令行)模式:

图片

进入rescue模式后,也需要root用户密码登录,登录后得到 命令行界面。多用户模式。

图片

命令行具备常用命令,包括mount fsck等。实例操作可参照上文:(/etc/fstab 文件丢失 情况1)

3.3 RHEL 7/ Centos7 的grub配置文件及排错, 恢复grub启动文件

不需要手动修改/boot/grub2/grub.cfg 文件。因为它是产物,不是来源。

grub的来源配置文件在 /etc/default/grub

确保该文件内容正确,然后用 grub2-mkconfig 命令就可以产生 /boot/grub2/grub.cfg 文件

具体命令为:

grub2-mkconfig -o /boot/grub2/grub.cfg

4 shell故障:

4.1 丢失bash文件(文件缺失、依赖库文件破坏)

/bin/sh 是到 /bin/bash 的链接, /bin 目录是到 /usr/bin 的软链接。所以删掉 /usr/bin/bash 系统所有的 shell 都不能用了。也影响了 其他系统chroot 到硬盘Linux系统(会提示 /bin/bash 不可用的错误)

从光盘引导进入光盘救援系统,可以从 centos7的 系统iso镜像挂载后,Packages目录里面找到 bash-4.2.x.x.rpm 文件,

rpm2cpio  bash.rpm包名  | cpio -idv

就会在 当前目录下的看到目录层级 usr/bin/bash 的可执行文件,复制到 /usr/bin/bash ,注意要chmod +x /usr/bin/bash,给与可执行权限。

bash 软件包涉及到的文件有:其中/usr/bin/ 目录下的文件都是必须的。其他文件即使没有,也不影响bash运行。如果/bin/bash 都没了,那就需要手动安装回来。

# rpm -ql bash

/etc/skel/.bash_logout

/etc/skel/.bash_profile

/etc/skel/.bashrc

/usr/bin/alias

/usr/bin/bash

/usr/bin/read

/usr/bin/sh

其他文件省略……

怎么找回 bash :

进入rescue 模式下,

如果有网络的情况下,可直接用yum 命令安装bash软件:

#yum install bash

如果没有网络,就找到安装光盘iso文件,挂载iso文件到 /media/cdrom/ 目录  (互联网搜索关键词:ISO镜像文件作为centos 软件源 )

# mkdir /media/cdrom;

# mount /path/to/centos7-iso-filename.iso /media/cdrom

由于Centos 7 默认有个 /etc/yum.repos.d/CentOS-Media.repo

[c7-media]
name=CentOS-$releasever - Media
baseurl=file:///media/CentOS/
        file:///media/cdrom/
        file:///media/cdrecorder/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

文件,里面指定了使用目录路径的文件,作为软件安装来源,而centos 7 iso 文件里具有软件仓库,包括bash软件包。

修改enabled=0 为 enabled=1,

然后就可以 在没有网络的情况下,使用 yum install --force bash 方式安装上 bash。

也可以从光盘中 找到 bash的 rpm包,运行 rpm -ivh --force bash-xxxxx.rpm 强行重装 相同版本的 bash 软件包。

4.2 bash 依赖的库文件缺失

库文件缺失就往往是大问题了。

先看下 /usr/bin/bash 软件依赖哪些库文件:ldd 命令,是查看 某可执行文件依赖哪些其他二进制动态库 文件的

[root@osboxes ~]# ldd /usr//bin/bash
        linux-vdso.so.1 =>  (0x00007fff193f0000)
        libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007fe048320000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007fe048118000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fe047d48000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fe048550000)

所以,如果这里

/lib64/libtinfo.so.5     /lib64/libdl.so.2    /lib64/libc.so.6

当中任何一个文件丢失,都会对系统造成重大影响。不仅bash无法使用,可能大部分软件都无法正常启动了。

这是后就要想办法修复这些底层文件。很快可能仅仅是因为某个文件系统没挂载成功导致的。

库损坏的实际解决,往往涉及到多方面知识,下面是一个实战记录(libdl相关的文件丢失导致bash和系统崩溃):

某次系统无法启动,并且没有打印错误信息到屏幕上,怎么找到线索: 

开始时进入 硬盘自带的救援模式,进不去,一样是没显示任何错误,因为救援模式基于的系统 崩溃了。

然后 用 centos 7(7.4)的 光盘引导机器,进入光盘救援模式,chroot /mnt/sysimage ,出现重要线索: 

chroot  /mnt/sysimage 失败错误信息:/bin/bash 找不到依赖库文件 /lib64/libdl.so.2 ,无法运行。

【经网络搜索知道 /lib64/libdl.so.2 是 glibc包提供的,也可以在其他centos下用 sudo  yum  provides  /lib64/libdl.so.2 查询 由哪个包提供了 这个文件】 。

 这时候以为可以复制 centos 7(7.4)的iso镜像Packages目录里的 libclibdl.so.2  和 /lib64/libdl-2.17.so 文件到 /mnt/sysimage/lib64/目录下 可以解决。

 结果重启后,仍然无法启动,仍然屏幕一片黑,没有打印线索。

由于损坏的系统的版本是 centos 7.9 (2009),所以考虑是否 7.9 跟 7.4的 glibc 库有了升级,如果很多系统软件依赖的是7.9 的 glibc的函数功能,

那么7.4就不能满足 这些软件的运行要求,这些软件就仍然无法工作(毕竟libdl是非常基础的库,dl:dynamic  link 顾名思义 它负责动态链接库功能 ) 。

  所以找到 centos 7.9的 iso ,得到里的 glibc的 libdl-2.17.so 和 libdl.so.2 用 `cp`  -p 命令方式复制到 /mnt/sysimage/lib64目录下。重启,问题解决。

注意:复制是在 光盘救援模式的【3 人工 shell 】模式操作的。因为chroot /mnt/sysimage失败,只能选择3。

4.3 环境变量相关的配置文件,及其导致的shell故障

# env | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

环境变量,其中指定了默认可执行文件的所在目录,如果/usr/bin/ 没在PATH路径范围,那么bash 就无法被直接使用。所以修正

/etc/profile 文件 的PATH环境变量,可以解决无法找到 bash的问题。

5 MBR和GPT

#MBR与 GPT分区表的区别:

MBR分区方式是传统分区方式,只支持最多4个主分区和多个逻辑分区。单个分区最大2TB。

GPT的单个分区可超过2TB,分区个数不只4个。

可能出现的问题有 MBR与GPT、误克隆覆盖、fdisk 误操作从MBR变为GPT 等。

5.1 修复分区表丢失

用gdisk 软件修复,大部分 linux发行版都带有这个工具。gdisk比fdisk 更高级,能支持GPT/MBR 分区表的硬盘。fdisk不支持GPT分区表。

gdisk 启动后,显示当前硬盘的分区表类型,下面显示说 属于 MBR分区。

# gdisk /dev/sdb

GPT fdisk (gdisk) version 1.0.3

Partition table scan:
  MBR: MBR only
  BSD: not present
  APM: not present
  GPT: not present
***************************************************************

Found invalid GPT and valid MBR; converting MBR to GPT format

in memory. THIS OPERATION IS POTENTIALLY DESTRUCTIVE! Exit by

typing 'q' if you don't want to convert your MBR partitions

to GPT format!

***************************************************************

Command (? for help):

这里准备第二块硬盘作为演示

上面有3个分区:

/dev/sdb1  是boot分区 /boot
/dev/sdb2是 系统分区  /
/dev/sdb3 是 swap分区  swap

分区布局情况如下:

图片

5.1.1 模拟 过去曾备份过分区表:

gdisk 备份 分区表:

图片

5.1.2 模拟误删 分区表(分区MBR转换为GPT,导致分区表丢失)

图片

输入w,让删除分区表生效。

图片

5.1.3 用备份的分区表恢复 分区信息:

图片

5.2 修复 /boot分区下文件被删的问题:

[root@osboxes ~]# mount | grep /boot
/dev/sda1 on /boot type ext4 (rw,relatime,seclabel,data=ordered)
[root@osboxes ~]# grep /boot   /etc/fstab
UUID=a2828f1e-dfa7-4cc8-b6e5-6ec203d87feb /boot              ext4    defaults        1 2
5.2.1 恢复 /boot 下的vmlinuz (内核可执行文件) initramfs (系统启动时的内存临时根文件系统)文件:

(适合于/boot/ 目录下文件丢失的情况)

# mkinitrd   /boot/initramfs-`uname -r`.img    `uname -r`

# 需确保 /lib/modules/目录下有对应版本的内核库、驱动文件(也就是 kernel-x.x.x..rpm包有安装过),用于生成 initramfs img文件系统镜像。结果/boot下只生成了 initramfs-xxxx.img 文件,没有vmlinuz-xxxx 内核二进制文件。系统这时候重启,是否无法引导的。

# rpm  -ivh   --force     kernel-3.10.0-693.el7.x86_64.rpm

# 安装 得到 /boot目录下的vmlinuz-x.x.x 文件 。rpm包可以从光盘里面找 kernel-xxxx.rpm包,版本要跟mkinitramfs 生成的 initramfs 文件系统镜像的版本一致。

# 注意:从光盘 安装 kernel rpm包,由于光盘内只有一个版本,所以最好用 mkinitrd 命令产生initramfs-x.x.x.img文件的时候 也用这个版本号。而不是uname -r 指定的版本。因为有时候当前运行的内核版本是系统安装后更新过的,但网络环境不通,或者无法yum获得对应版本的 kernel-x.x.x.rpm 。而通过光盘安装就不存在这种困难。所以作为救援,建议从光盘里的rpm安装。

5.2.2 恢复 /boot下的grub2相关文件: (适合于/boot/ 目录下文件丢失的情况)

# grub2-install /dev/sda (就是 /boot分区所在的磁盘) #这时候生成了/boot/grub2下的大部分grub引导用到的文件。但没有/boot/grub2/grub.cfg 文件。

# grub2-mkconfig  -o  /boot/grub2/grub.cfg

# 注意:先 grub2-install 生成基本文件,然后 grub2-mkconfig,因为后者需要使用前者生成的一些基础文件(如/boot/grub2/ 目录下的 fonts grub.cfg grubenv i386-pc locale 等文件)。

#注意:如果 /boot下的 内核vmlinuz 和 initramfs 也被删了,那在做grub2-mkconfig -o /boot/grub2/grub.cfg 之前,要先做 5.2.1 生成 vmlinuz 和 initramfs文件,然后grub2-mkconfig 才能根据内核文件生成 grub引导菜单。

5.3 /lib/modules/XXX 内核(开发用的)模块文件被删****,

可导致 编译安装一些新驱动的时候,提示找不到 /lib/modules/xxxxx 内核文件的错误,同样也会影响 /boot/initramfs-xxxx.img 文件的生成。

解决方式可以 通过yum或者 rpm方式 重新安装 :

yum  install   kernel-`uname  -r`
rpm   -ivh  --force   kernel-`uname  -r`.rpm

来恢复/lib/modules/XXX 目录。

5.4 误删数据文件恢复原理。

5.5 linux下两种数据恢复软件****(extundelete,testdisk)实操。

testdisk软件的安装:

#注意:如果文件误删的分区是当前系统分区,建议不要安装新软件,不要写入数据,以免进一步造成破坏。可以在u盘 光盘linux引导后在live系统模式下安装testdisk,进行文件救援。

testdisk 适合于 搜索分区表丢失的情况(误格式化硬盘)。可根据选择的被扫描出的原分区表进行分区恢复。

extundelete 适合于 误删文件。

两个软件都要求在分区 umount状态的时候对分区修复。

yum install epel-release
yum update
yum install testdisk

extundelete的参数:可以指定要恢复哪个目录的文件,这样节省了时间。

extundelete 的演示效果不确定,大部分时候都没恢复文件。

# #centos下安装extundelete:
# yum install epel-release
# yum -y install e2fsprogs e2fsprogs-libs e2fsprogs-devel
# extundelete --help

Usage: extundelete [options] [--] device-file

Options:

  --version, -[vV]       Print version and exit successfully.

  --help,                Print this help and exit successfully.

  --superblock           Print contents of superblock in addition to the rest.

                         If no action is specified then this option is implied.

  --journal              Show content of journal.

  --after dtime          Only process entries deleted on or after 'dtime'.

  --before dtime         Only process entries deleted before 'dtime'.

Actions:

  --inode ino            Show info on inode 'ino'.

  --block blk            Show info on block 'blk'.

  --restore-inode ino[,ino,...]

                         Restore the file(s) with known inode number 'ino'.

                         The restored files are created in ./RECOVERED_FILES

                         with their inode number as extension (ie, file.12345).

  --restore-file 'path'  Will restore file 'path'. 'path' is relative to root

                         of the partition and does not start with a '/'

                         The restored file is created in the current

                         directory as 'RECOVERED_FILES/path'.

  --restore-files 'path' Will restore files which are listed in the file 'path'.

                         Each filename should be in the same format as an option

                         to --restore-file, and there should be one per line.

  --restore-directory 'path'

                         Will restore directory 'path'. 'path' is relative to the

                         root directory of the file system.  The restored

                         directory is created in the output directory as 'path'.

  --restore-all          Attempts to restore everything.

  -j journal             Reads an external journal from the named file.

  -b blocknumber         Uses the backup superblock at blocknumber when opening

                         the file system.

  -B blocksize           Uses blocksize as the block size when opening the file

                         system.  The number should be the number of bytes.

  --log 0                Make the program silent.

  --log filename         Logs all messages to filename.

--log D1=0,D2=filename   Custom control of log messages with comma-separated

   Examples below:       list of options.  Dn must be one of info, warn, or

   --log info,error      error.  Omission of the '=name' results in messages

   --log warn=0          with the specified level to be logged to the console.

   --log error=filename  If the parameter is '=0', logging for the specified

                         level will be turned off.  If the parameter is

                         '=filename', messages with that level will be written

                         to filename.

   -o directory          Save the recovered files to the named directory.

                         The restored files are created in a directory

                         named 'RECOVERED_FILES/' by default.

6. 库文件缺失导致软件/系统无法正常运行/centos/RHEL系统的yum 命令运行报错:

6.1 当在 CentOS 7 上使用 yum 命令时,如果 Python 依赖关系损坏,可能会出现以下错误提示信息之一:

1. ImportError: No module named 'urlgrabber':这个错误提示表明 urlgrabber 模块没有被正确安装或已经损坏。

2. ImportError: No module named 'yum':这个错误提示表明 yum 模块没有被正确安装或已经损坏。

3. ImportError: No module named 'rpm':这个错误提示表明 rpm 模块没有被正确安装或已经损坏。

4. ImportError: No module named 'sqlitecachec': 这个错误提示表明 sqlitecachec 模块没有被正确安装或已经损坏。

这些错误提示表明 Python 模块没有被正确加载,可能是由于依赖关系损坏导致的。解决方法通常是重新安装相应的 Python 模块或者重新安装整个 Python 环境。

解决方法:

由于当前系统的yum已无法使用,可在其他linux 系统的docker环境的相同版本的linux系统中,运行 yum install --downloadonly…… 命令,在线获取 yum包相关的软件rpm文件。完整命令示例如下(最终下载到的yum包 和依赖的包都在 /root目录内):

yum install --downloadonly --downloaddir=目录   包名
例如:yum intall --downloadonly --downloaddir=/root yum

然后复制这些rpm 到待修复的系统内,通过 rpm -ivh --force *.rpm ,将所有rpm包安装上(--force 为强制安装) ,就把之前故障的yum包和依赖关系都修复了。