如何修复 libvirt/kvm 的已损坏的调整大小的 qcow2 磁盘映像?

如何修复 libvirt/kvm 的已损坏的调整大小的 qcow2 磁盘映像?

今天我想增加虚拟机的大小,所以我做了我一直在做的事情(以前做过):

qemu-img resize diskimage.qcow2 +22GB

然后文件损坏,虚拟机无法再启动。我尝试从 CD 启动虚拟机来调整分区,但系统不再读取磁盘:

qemu-img check -r all diskimage.qcow2
tcmalloc: large alloc 389841715200 bytes == (nil) @  0x7fdb4ea66bf3 0x7fdb4ea88488 0x7fdb4e5674a6 0x7fdb50236a37 0x7fdb50236bc8 0x7fdb50237011 0x7fdb5023941e 0x7fdb5023d891 0x7fdb5027848b 0x7fdb5027c196 0x7fdb491efb35 0x7fdb5021ee4d (nil)
No errors were found on the image.

没有错误?听起来不错,但virsh start vm不起作用,日志显示:

2017-05-21T10:02:30.755824Z qemu-system-x86_64: -drive file=/.../diskimage.qcow2,format=qcow2,if=none,id=drive-virtio-disk0: could not open disk image /.../diskimage.qcow2: qcow2: Image is corrupt; cannot be opened read/write

我尝试转换为原始但转换失败(退出 1):

qemu-img convert -f qcow2 diskimage.qcow2 -O raw diskimage.raw
qcow2: Image is corrupt: L2 table offset 0x2d623039326500 unaligned (L1 index: 0); further non-fatal corruption events will be suppressed
qemu-img: error while reading block status of sector 0: Input/output error

该过程创建了一个 354334801920 字节的文件(比 +22GB 应有的大小大得多),但它显然无法使用 - 当我尝试将其转换回 qcow2 时,我得到了一个 200kB 的文件。

nbd有没有办法从 qcow2 文件中提取数据,或者即使有损坏也能以某种方式将其挂载为读写文件?我的机器上没有内核模块。

答案1

当 QEMU 进程仍在运行且同一磁盘打开时,您是否运行了“qemu-img resize diskimage.qcow2 +22GB”?如果是这样,那肯定可以解释数据损坏,因为您可能会有 2 个进程同时写入 qcow2 文件,并且如果两个写入都需要 qcow2 元数据分配,这可能会损坏内部文件数据结构。

“qemu-img 检查”结果看起来非常虚假。特别是 tcmalloc 抱怨它无法分配 360 GB 的内存块。看起来 qemu-img 将此错误误解为成功,打印虚假消息“未发现错误”。这是一个您肯定应该向 QEMU 报告的错误。

“转换”错误看起来只是 tcmalloc 遇到的相同错误的后续。

不幸的是,我没有任何建议来修复这个问题 - 我只是建议使用“check -r”来尝试修复它。你唯一可能的机会就是给 qemu-devel 发邮件,看看 qcow2 维护者是否有建议。

答案2

将 qcow2 损坏视为具有坏块的硬盘。

关闭该虚拟机。

然后做:

modprobe nbd
qemu-nbd --connect=/dev/nbd0 diskimage.qcow2
ddrescue /dev/nbd0 new_diskimage.raw
qemu-nbd --disconnect /dev/nbd0
qemu-img convert -O qcow2 new_diskimage.raw new_diskimage.qcow2

现在尝试启动并祈祷,希望它能让您进入救援模式,您可以在该磁盘上运行 fsck。

相关内容