0

我最近发现,从 VM 外部在 VMWare中挂载虚拟磁盘(*.VMDK文件)可能很危险。

场景描述: 我创建了一个新的虚拟机(我们称之为VM B ),我从包含从此类虚拟磁盘读取的映像工具(例如Parted Magic )的 ISO 映像引导(属于不同的虚拟机器,名为VM A ),以便将内容写入不同的外部物理磁盘。该虚拟磁盘文件仅被挂载,我没有对其结构进行任何更改。

在此处输入图像描述

问题: 在我关闭VM B并尝试启动另一个VM A后,令我惊讶的是它不再启动。查看机器的日志文件 (vmware.log),我在VM A的日志中发现“内容 ID 不匹配”错误。

发生了什么?我怎样才能解决这个问题?

4

1 回答 1

1

以下是一些背景信息(所提供的信息对VMWare Workstation 9有效。如果您使用的是其他版本,则不能保证它完全适用):

VMWare 为每个快照创建一个新的 VMDK 文件。在这些文件中,有一个称为磁盘描述符的结构,如下所示:

# Disk DescriptorFile
version=1
CID=acd1cf11
parentCID=ffffffff
createType="vmfs"

当访问此类 VMDK 文件时,VMWare 会创建一个新的唯一文件CID并将其存储在其中。每个 VMDK 文件都有一个 parentCID,第一个用 标记ffffffff,它告诉 VMWare,没有进一步的父存在。每个后续都parentID引用一个较早创建的父级,因此它正在以这种方式构建一个链表

我遇到的问题是,如果您将属于不同虚拟机的 VMDK 文件添加到另一个虚拟机,并且已挂载,则会创建一个新的 CID,并且链表 可能会中断。

在这种情况下,此 VMDK 文件所属的虚拟机不再启动,您就会遇到问题。

例子:

---------- C:\DATA\VMWARE\VMWINDOWS7X64.VMDK
CID=acd1cf11
!OK! parentCID=ffffffff

---------- C:\DATA\VMWARE\VMWINDOWS7X64-000003.VMDK
CID=e54a0beb
!OK! parentCID=627c6ec2

---------- C:\DATA\VMWARE\VMWINDOWS7X64-000002.VMDK
CID=627c6ec2
?NOTFOUND? parentCID=b43e1a6f

---------- C:\DATA\VMWARE\VMWINDOWS7X64-000006.VMDK
CID=0454e2f0
!OK! parentCID=8f139197

---------- C:\DATA\VMWARE\VMWINDOWS7X64-000001.VMDK
CID=92718e8b
?NOTFOUND? parentCID=ad44b86e

[...]

你可以看到,我在哪里添加了!OK!在 parentCID 行中,存在具有有效 CID 的父 VMDK。但在完整的真实案例中,总共找不到 2 个(在此示例中标记为?NOTFOUND? )。VMWare 上有一篇文章描述了这个问题( “父虚拟磁盘已在子虚拟磁盘创建后被修改”错误 (1007969))。我曾尝试挂载较早版本的 VMDK 文件,但没有成功,因为链中的第一个文件 VMWINDOWS7X64.VMDK 不再被任何其他文件引用。

使用文本编辑器按照上面提到的 VMWare 文章的建议编辑这些文件不是一种选择,因为

  1. 我不会用文本编辑器触摸二进制文件
  2. 我还没有找到可以在 Windows 中处理如此大文件的编辑器。

我在 Stackoverflow 中看到一些文章要求在 C# 中查找和替换代码,但还没有找到令人满意的答案。然后我找到了一个可以为 Windows 处理大型二进制文件的十六进制编辑器,它的名字是HxD。它可免费用于商业和非商业用途。

使用此编辑器,您可以找到上述问题中提到的结构,修补 CID 并修复损坏的链,例如:

VMDK示例

行动:

  • 备份整个虚拟机。在副本上工作。
  • 使用之前创建的 CID 和父 CID 列表(如问题中所示)
  • 更新它,以便每个 parentCID 指向适当的 CID(快照文件的编号可能在这里有所帮助,但在我的情况下,我发现快照编号并不总是升序。parentFilenameHint如果顺序,首先将包含在 VMDK 文件中仍然不清楚在资源管理器中按日期时间降序对 VMDK 文件进行排序 - 最旧的是根文件(parentCID=ffffffff)。事实证明,这几乎是您查看CID链表时得到的顺序)。
  • 使用编辑器修补每个 VMDK 文件,但只修补那些不适合的 CID/parentCID
  • 尝试启动虚拟机。如果它成功了,你很幸运并且已经修复了它。如果它没有启动,请移除虚拟磁盘并尝试使用链中的另一个磁盘。就我而言,经过一些尝试,它接受了文件VMWINDOWS7X64-000003.VMDK并正确启动。这意味着并非所有快照都已恢复,但机器又可以正常工作了。另请参阅下面的注释,我终于能够完全修复它。

最终起作用的修复是(用 标记的更改!FIX!):

---------- C:\DATA\VMWARE\VMWINDOWS7X64-000003.VMDK
CID=e54a0beb
!OK! parentCID=627c6ec2

---------- C:\DATA\VMWARE\VMWINDOWS7X64-000002.VMDK

CID=627c6ec2
!FIX! parentCID=92718e8b

---------- C:\DATA\VMWARE\VMWINDOWS7X64-000001.VMDK
CID=92718e8b
!FIX! parentCID=acd1cf11

---------- C:\DATA\VMWARE\VMWINDOWS7X64.VMDK
CID=acd1cf11
!OK! parentCID=ffffffff

笔记:

  • 无法保证修补 CID 会使 VM 恢复工作状态。
  • 该方案假定您尚未写入快照所依赖的 VMDK。
  • 可能是您找到了几种方法来恢复 CID 的链接列表 - 将它们全部写下来然后尝试它们(记住:您有备份!),如果您幸运的话,您找到了正确的,然后您就可以完全恢复一切。就我而言,有两种可能的方法来重新创建链接列表。一个让我部分恢复,另一个最终恢复了问题发生之前的一切。
  • 我建议在成功修复后,您应该在新目录中从虚拟机的当前状态创建完整克隆。这为您提供了干净、一致的文件。
于 2012-11-13T12:33:06.630 回答