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

Ned*_*d64 8 corruption libvirt qemu qcow2 kvm-virtualization

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

qemu-img resize diskimage.qcow2 +22GB
Run Code Online (Sandbox Code Playgroud)

然后文件损坏了,VM 不再启动。我尝试从 CD 启动 VM 以调整分区,但系统将不再读取磁盘:

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.
Run Code Online (Sandbox Code Playgroud)

没有错误?听起来不错,但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
Run Code Online (Sandbox Code Playgroud)

我尝试转换为 raw 但转换失败(退出 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
Run Code Online (Sandbox Code Playgroud)

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

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

Dan*_*elB 4

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

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

“convert”错误看起来只是 tcmalloc 遇到的同一错误的后续。

不幸的是,我没有任何建议来解决这个问题 - 我只是建议“check -r”来尝试修复它。您唯一可能剩下的机会是邮寄 qemu-devel 并查看 qcow2 维护者是否有建议。