虚拟机文件系统损坏

发布时间 2023-04-25 10:27:51作者: XU-NING

1. 问题描述

在操作系统使用过程中,经常会遇到因掉电引起文件系统损坏导致系统无法启动的问题

1.1. linux

  • 因计算节点重启过 rbd lock 未释放

rbdlock

  • 操作系统文件系统损坏

xfsbroken

xfsbroken1

1.2. windows

  • 操作系统系统启动引导文件损坏

windowsmbr

2. 问题原因

  • 因计算节点重启过 rbd lock 未释放,当第二次 qemu 进程在计算节点启动之后连接
    rbd image 时由于上次 image 被 lock 了,所以无法进行io操作
  • 因存储数据有损坏或者虚拟机进行不当操作,引起操作系统文件系统损坏

3. 问题影响

  • 虚拟机系统无法启动
  • 虚拟机 io 操作异常

4. 问题解决

4.1. 问题确认

  • 关闭虚拟机查看是否有 rbd lock (J版)或者 rbd watcher(L版),通过如下命令查看
rbd lock ls vms/8a918810-33ac-410d-8b5e-2b7342202a51_disk
rbd status vms/8a918810-33ac-410d-8b5e-2b7342202a51_disk
  • 如果关闭虚拟机一分钟之后有 watcher 或者 lock 则手动去掉 lock watcher启动虚拟机即可
rbd lock ls   vms/f0f6e6ae-6a3f-49c6-bc23-0b7bda049783
There is 1 exclusive lock on this image.
Locker          ID                   Address
client.39864782 auto 140568776689264 10.85.44.162:0/387540111
rbd status vms/f0f6e6ae-6a3f-49c6-bc23-0b7bda049783_disk
Watchers:
  watcher=10.85.44.162:0/387540111 client.39864782 cookie=140568776689264
  • 释放 rbd lock
rbd lock remove  vms/f0f6e6ae-6a3f-49c6-bc23-0b7bda049783 \
"auto 140568776689264" client.39864782
  • 将该watcher加入黑名单
ceph osd blacklist add 10.85.44.162:0/387540111
  • 如果都没有则关闭虚拟机,下载虚拟机磁盘到本地 进行本地修复

4.2. 修复虚拟机磁盘

以uuid为f0f6e6ae-6a3f-49c6-bc23-0b7bda049783的虚拟机为例

  • 下载虚拟机磁盘到计算节点

    确保要操作的计算节点有足够的cpu 内存 磁盘空间

    • 创建修复目录
    mkdir /var/lib/nova/workers
    
    • 下载虚拟机镜像到修复目录
    rbd export vms/f0f6e6ae-6a3f-49c6-bc23-0b7bda049783_disk \
    /var/lib/nova/workers/f0f6e6ae-6a3f-49c6-bc23-0b7bda049783_disk
    

4.2.1. linux 操作系统修复

4.2.1.1. 准备修复镜像

linux 操作系统文件系统格式一般为 xfs ext4 仅需一台可以挂载虚拟机磁
盘的 ISO或者 可启动的磁盘镜像

  • linux 为了方便可以直接下载 Openstack 平台的linux镜像
# 找到故障虚拟机对应操作系统的镜像uuid
glance image-list
# 下载镜像磁盘到本地
# 例如镜像uuid为afed05de-ad6b-4ef4-aa29-04138b688838
rbd export images/afed05de-ad6b-4ef4-aa29-04138b688838 \
/var/lib/nova/workers/linuximg
  • 亦可到官网下载 对应版本的ISO 进入救援模式修复

4.2.1.2. 通过下载的镜像/磁盘镜像启动新的kvm虚拟机,将故障虚拟机磁盘挂载到系统进行修复

如果虚拟机操作系统为 LVM 且操作系统 VG 还包括
另一块云硬盘,则需要把这块云硬盘也下载到本地,挂载成 vdc

  • 上传 files/fkk-vm.xml/var/lib/nova/workers/
  • 修改 fkk-vm.xml
<emulator>/usr/libexec/qemu-kvm</emulator>
<!-->以可启动镜像文件启动<-->
<disk type='file' device='disk'>
  <driver name='qemu' type='qcow2'/>
  <source file='/var/lib/nova/workers/linuximg'/>
  <target dev='vda' bus='virtio'/>
</disk>
<!-->将要修复的虚拟机磁盘作为vdb挂载<-->
<disk type='file' device='disk'>
  <driver name='qemu' type='raw'/>
  <source file=' /var/lib/nova/workers/f0f6e6ae-6a3f-49c6-bc23-0b7bda049783_disk'/>
  <target dev='vdb' bus='virtio'/>
</disk>

4.2.1.3. 启动虚拟机,进行修复

virsh create fkk-vm.xml
  • 进入新启动的虚拟机系统修复

  • PC 端下载 vnc viewer

  • 查看新建的虚拟机 vnc 端口

virsh vncdisplay fkk-vm
# 输出如
:18

以上输出则 vnc 端口为 5918

  • 通过 vnc viewer 连接,进入系统修复

    分区类型主要两种 标准分区 lvm
    文件系统类型主要有两种 ext4 xfs

    • 标准分区-xfs
    # 查看要要修复得分区
    lsblk
    # 例如 /dev/vdb1 修复
    # 检查
    xfs_repair -n /dev/vdb1
    # 无损修复
    xfs_repair /dev/vdb1
    # 如无损修复失败则有损修复
    xfs_repair -L /dev/vdb1
    
    • 标准分区-ext4
    # 查看要要修复得分区
    lsblk
    # 例如 /dev/vdb1 修复
    fsck /dev/vdb1
    
    • lvm分区-xfs修复
    # 找到想要修复的虚拟机系统分区挂载的lv和vg
    lvscan
    vgscan
    # 检查
    xfs_repair -n  /dev/Volgroup/centos-root
    # 无损修复
    xfs_repair /dev/Volgroup/centos-root
    # 如无损修复失败则有损修复
    xfs_repair -L /dev/Volgroup/centos-root
    

    至此linux修复完毕

  • 关闭启动的修复虚拟机

    • 可以在系统内执行 init 0
    • 亦可使用 virsh destroy fkk-vm 来操作

4.2.1.4. 验证

  • 以修复后的虚拟机磁盘来启动虚拟机

修改 fkk-vm

如果虚拟机操作系统为 LVM 且操作系统 VG 还包括
另一块云硬盘,则需要把这块云硬盘也下载到本地,挂载成 vdb

<emulator>/usr/libexec/qemu-kvm</emulator>
<!--以可启动镜像文件启动-->
<!--
<disk type='file' device='disk'>
  <driver name='qemu' type='qcow2'/>
  <source file='/var/lib/nova/workers/linuximg'/>
  <target dev='vda' bus='virtio'/>
</disk>
-->
<!--将要修复的虚拟机磁盘作为vdb挂载-->
<disk type='file' device='disk'>
  <driver name='qemu' type='raw'/>
  <source file=' /var/lib/nova/workers/f0f6e6ae-6a3f-49c6-bc23-0b7bda049783_disk'/>
  <target dev='vda' bus='virtio'/>
</disk>

正常启动系统则修复成功!

4.2.1.5. 使用 ISO 修复需注意

需要设置 xml 文件以 cdrom 启动

<disk type='file' device='cdrom'>
  <driver name='qemu' type='raw'/>
  <source file='/var/lib/nova/workers/en_windows_server_2016_x64_dvd_9718492.iso'/>
  <target dev='hdc' bus='ide'/>
  <readonly/>
  <address type='drive' controller='0' bus='1' unit='0'/>
</disk>
<os>
  <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>
  <boot dev='hd'/>
  <boot dev='cdrom'/>
  <smbios mode='sysinfo'/>
</os>

4.2.2. windows 操作系统修复

windows 可操作性相对linux低的多,暂时只实践了通过ISO启动修复

4.2.2.1. 下载windows iso 镜像

下载镜像上传至 /var/lib/nova/workers/windows2016server standerd 为例

en_windows_server_2016_x64_dvd_9718492.iso

4.2.2.2. 从镜像启动kvm虚拟机

windows 占用资源比较大,这里使用8核16G的配置,如需调整修改
<memory unit='GB'>16</memory>
<vcpu placement='static'>8</vcpu>

  • 修改 fkk-cd.xmlcdrom 启动

注意虚拟机磁盘的驱动是 ide 盘符是 sda
使用 scsi virtio 均不能被识别 (如需标准的ISO可以识别这些驱动需要
在ISO中注入对应驱动,操作耗时耗力)

<disk type='file' device='disk'>
  <driver name='qemu' type='raw'/>
  <source file='/var/lib/nova/workers/59f01c98-a050-4ef3-994d-4f0c7da7e7d0_disk'/>
  <target dev='sda' bus='ide'/>
</disk>
<disk type='file' device='cdrom'>
  <driver name='qemu' type='raw'/>
  <source file='/var/lib/nova/workers/en_windows_server_2016_x64_dvd_9718492.iso'/>
  <target dev='hdc' bus='ide'/>
  <readonly/>
  <address type='drive' controller='0' bus='1' unit='0'/>
</disk>
  • 启动虚拟机
virsh create fkk-cd.xml
  • 连接虚拟机部分同 linux

4.2.2.3. 修复windows虚拟机

  • 选择修复已有系统
  • 启动系统之后选择 troubleshooting 选择 command prompt

winrepair1

  • 检查虚拟机磁盘是否被识别

如果不识别说明驱动不被支持,List volume 只会有一行

Diskpart
List volume
List disk
List partition
  • 修复
Bootrec /FixMbr
Bootrec /FIxBoot
Bootrec /ScanOs
Bootrec /RebuildBcd

如果前面都能执行成功 Bootrec /RebuildBcd 失败
报错如下

winrepair2

执行

Diskpart
List volume
# 或者
List disk
# 找到 scanos找到的系统分区
# 具体select 那个需要看scanos出来的是那个 例如是分区3
select partition 3
# 激活
active
退出
exit

再进行修复即可

Bootrec /RebuildBcd
Y

看到如下图,修复成功

winrepair3

正常启动系统则修复成功!

4.3. 使用修复过得虚拟机磁盘文件替换ceph上面的rbd image

  • 删除 ceph 上面的虚拟机磁盘文件
rbd remove vms/f0f6e6ae-6a3f-49c6-bc23-0b7bda049783_disk
  • 上传修改过的虚拟机磁盘镜像到 ceph
rbd import f0f6e6ae-6a3f-49c6-bc23-0b7bda049783_disk \
vms/f0f6e6ae-6a3f-49c6-bc23-0b7bda049783_disk
  • 启动虚拟机

5. 验证

启动虚拟机可以正常使用则修复完毕