1. 記事一覧 >
  2. ブログ記事
category logo

VMware仮想マシンのディスクが壊れて起動しなかった→データだけ救い出した話

(更新) (公開)

はじめに

ある日、VMware の仮想マシンを起動しようとしたら、エラーになって起動しませんでした。


エラー内容:
親仮想ディスクは、子ディスクが作成された後に変更されています。親仮想ディスクのコンテンツ ID は、子の対応する親コンテンツ ID と一致しません。
ディスク「C:\VMWARE\CentOS7.6.1810\xxxxx-000027.vmdk」、またはこのディスクが依存するスナップショット ディスクを開くことができません。
モジュール Disk のパワーオンに失敗しました。
仮想マシンの起動に失敗しました。

親仮想ディスクは、子ディスクが作成された後に変更されています。


・スナップショットにも戻せない。
・バックアップした仮想マシンも同じ状況のままバックアップしていた。
となり、詰みました。


Node.js(Next.js)と Strapi のプログラム構成(詳細:StrapiとNext.jsを使って静的ウェブサイトを構築)で、ソースコードは有るので、Strapi のデータさえ救い出せれば、良い状況です。Strapi のデータをごにょごにょしていて、その部分がどこにも正確に記録されていないのが問題でした。
あきらめずに頑張った結果、この状況から、回復することに成功しました。正確には、エラーになった仮想マシンが元に戻る事は無かったのですが、Node.js(Next.js)と Strapi のプログラム構成は、別のマシンの元で、完全復旧しました。
どうやって復旧したかの手順を書いていきたいと思います。

データのサルベージができただけで、仮想マシン自体は復旧しませんでした。

【検証環境】

Windows 10 Pro x64

 VMware Workstation 16 Pro

  CentOS7.6.1810


エラー状況

仮想マシンを起動すると、
ファイルが見つかりません: C:\VMWARE\CentOS7.6.1810\xxxxx-000004.vmdk
このファイルは仮想マシンをパワーオンするのに必要です。このファイルを移動した場合は、新しい格納場所を指定してください。
とエラーになりました。

ファイルが見つかりません:


参照ボタンで xxxxx-000004.vmdk を選択すると、
親仮想ディスクは、子ディスクが作成された後に変更されています。親仮想ディスクのコンテンツ ID は、子の対応する親コンテンツ ID と一致しません。
ディスク「C:\VMWARE\CentOS7.6.1810\xxxxx-000027.vmdk」、またはこのディスクが依存するスナップショット ディスクを開くことができません。
モジュール Disk のパワーオンに失敗しました。
仮想マシンの起動に失敗しました。
とエラーになります。

親仮想ディスクは、子ディスクが作成された後に変更されています。


スナップショットを選択すると、
スナップショットに戻している最中にエラーが発生しました:この仮想マシンのディスクの 1 つが、すでに他の仮想マシンかスナップショットで使用されています。
とエラーになり、スナップショットにも戻せません。

スナップショットに戻している最中にエラーが発生しました:


復旧準備

該当の VMware をいったん、閉じます。(VMware WorkStation の場合、タブの × ボタンで閉じます。)
Unix コマンドで復旧したいため、Git for Windows をインストールします。※復旧手順の方で説明しますが、必須ではありません。
仮想マシン全体をバックアップします。
今回、C:\VMWARE\CentOS7.6.1810\*.vmx で起動し、C:\VMWARE\CentOS7.6.1810\*.vmdk がある状況のため、C:\VMWARE\CentOS7.6.1810 フォルダごとコピーして、C:\VMWARE\CentOS7.6.1810-bak とバックアップします。
復旧作業は、C:\VMWARE\CentOS7.6.1810 で行います。


復旧手順

Step1

エラーになったディスクを特定するため、ログを見ます。
C:\VMWARE\CentOS7.6.1810\vmware.log
C:\VMWARE\CentOS7.6.1810\vmware-0.log
C:\VMWARE\CentOS7.6.1810\vmware-1.log
といったログのどこかに、以下のようなエラーがあると思います。


検索キーワードの例:
DISKLIB-LINK : DiskLinkIsAttachPossible: Content ID mismatch
failed to open (The parent virtual disk

2021-11-10T22:14:05.311+09:00| vmx| I005: DISKLIB-DSCPTR: Opened [0]: "xxxxx-000006.vmdk" (0xe)
2021-11-10T22:14:05.311+09:00| vmx| I005: DISKLIB-LINK  : Opened 'C:\VMWARE\CentOS7.6.1810\xxxxx-000006.vmdk' (0xe): monolithicSparse, 167772160 sectors / 80 GB.
2021-11-10T22:14:05.319+09:00| vmx| I005: DISKLIB-DSCPTR: Opened [0]: "xxxxx-000004.vmdk" (0xe)
2021-11-10T22:14:05.319+09:00| vmx| I005: DISKLIB-LINK  : Opened 'C:\VMWARE\CentOS7.6.1810\xxxxx-000004.vmdk' (0xe): monolithicSparse, 167772160 sectors / 80 GB.
2021-11-10T22:14:05.319+09:00| vmx| I005: DISKLIB-LINK  : DiskLinkIsAttachPossible: Content ID mismatch (parentCID 7826d11f != 8636ce6f) C:\VMWARE\CentOS7.6.1810\xxxxx-000006.vmdk C:\VMWARE\CentOS7.6.1810\xxxxx-000004.vmdk.
2021-11-10T22:14:05.319+09:00| vmx| I005: DISKLIB-CHAIN : "C:\VMWARE\CentOS7.6.1810\xxxxx-000004.vmdk" : failed to open (The parent virtual disk has been modified since the child was created. The content ID of the parent virtual disk does not match the corresponding parent content ID in the child).
2021-11-10T22:14:05.323+09:00| vmx| I005: DISKLIB-LIB   : Failed to open 'C:\VMWARE\CentOS7.6.1810\xxxxx-000024.vmdk' with flags 0xa The parent virtual disk has been modified since the child was created. The content ID of the parent virtual disk does not match the corresponding parent content ID in the child (18).
2021-11-10T22:14:05.323+09:00| vmx| I005: DISK: Cannot open disk 'C:\VMWARE\CentOS7.6.1810\xxxxx-000024.vmdk': The parent virtual disk has been modified since the child was created. The content ID of the parent virtual disk does not match the corresponding parent content ID in the child (18).
2021-11-10T22:14:05.323+09:00| vmx| I005: DISK: Opening disks took 144 ms.
2021-11-10T22:14:05.323+09:00| vmx| I005: Module 'Disk' power on failed.

Step2

Content ID mismatch (parentCID 7826d11f != 8636ce6f)の行に、xxxxx-000004.vmdk、xxxxx-000006.vmdk が載っていますので、調査対象は、xxxxx-000004.vmdk、xxxxx-000006.vmdk です。
ファイルの上の方に、ID が書かれているため、それを見ます。
Unix コマンドを使いたかったため、Git Bash を使う前提になります。他の手段でも構いません。

$ head xxxxx-000004.vmdk
# Disk DescriptorFile
version=1
encoding="Shift_JIS"
CID=8636ce6f
parentCID=144f9ca4
createType="monolithicSparse"
parentFileNameHint="xxxxx-000003.vmdk"

※実際は、以下のように文字化けした部分がありますが、省略しています。

head 文字化けした部分

$ head xxxxx-000006.vmdk
# Disk DescriptorFile
version=1
encoding="Shift_JIS"
CID=a80e212c
parentCID=7826d11f
createType="monolithicSparse"
parentFileNameHint="xxxxx-000004.vmdk"

parentFileNameHint="xxxxx-000004.vmdk"
から
xxxxx-000006.vmdk の親が xxxxx-000004.vmdk
と分かります。
また、xxxxx-000006.vmdk の親の番号は、
parentCID=7826d11f
となっているのに対し、
xxxxx-000004.vmdk は、
CID=8636ce6f
となっていて、一致していません。
Content ID mismatch (parentCID 7826d11f != 8636ce6f)
はこのことを言っています。

xxxxx-000004.vmdk をCID=7826d11fに修正が必要です。

000004などの.vmdkの前の数字は必ずしも番号順ではありません。


Step3

xxxxx-000004.vmdk をそのまま vi で開きたいですが、サイズが大きすぎて、メモリが足りません。
そこで、まず vmdk を分割します。
Unix コマンドを使いたかったため、Git Bash を使っています。分割ソフトで分割して編集できるくらい小さくするなど、他の手段でも構いません。
ファイルの上の方の ID を編集するため、編集対象部分だけ切り出して小さくします。最初から小さい場合は、必要ありません。

$ cp -p xxxxx-000004.vmdk xxxxx-000004.vmdk.bak
$ head -c 1024 xxxxx-000004.vmdk > xxxxx-000004.vmdk.1
$ tail -c +1025 xxxxx-000004.vmdk > xxxxx-000004.vmdk.2

head -c 1024 [元ファイル] > [先頭 1024 バイト切り出したファイル]
tail -c +1025 [元ファイル] > [先頭 1025 バイト目から末尾までを切り出したファイル]
になります。


Step4

CID=8636ce6fCID=7826d11fと書き換えます。文字化けして見える部分は、無視して、ID 部分だけ編集して上書きします。

$ vi xxxxx-000004.vmdk.1

vi xxxxx-000004.vmdk.1

Git Bash の vi の場合は、問題無かったですが、Windows の一般的なエディタの場合、保存時に書き換えたところ以外も書き換わるかもしれません。バイナリエディタで編集した方が良いかもしれません。


Step5

分割した vmdk をつなぎ合わせます。

$ cat xxxxx-000004.vmdk.1 xxxxx-000004.vmdk.2 > xxxxx-000004.vmdk

コマンドプロンプト(cmd.exe)でcopy /b xxxxx-000004.vmdk.1 + xxxxx-000004.vmdk.2 xxxxx-000004.vmdkでも同じ意味です。


復旧後

ここから先は、状況次第だと思います。下記の通りいかないかもしれません。

該当仮想マシンを起動します。
すると、また、「ファイルが見つかりません:」となります。

ファイルが見つかりません:

(ここであきらめかけましたが・・・)
参照ボタンから、xxxxx-000004.vmdk を選択すると、状況が変わり、起動してきます。

状況が変わり、起動してきます。

しかし、
この CPU はゲスト OS によって無効にされています。仮想マシンをパワーオフまたはリセットしてください。
となり、起動の途中で止まります。

この CPU はゲスト OS によって無効にされています。


OK をクリックした後、再起動します。

OK をクリックした後、再起動


エラーが表示されて、止まった後、エンターキーを押すと、root のパスワード入力待ちになりますので、root のパスワードを入力します。

root のパスワードを入力


コマンドが入力できて、復旧したように見えますが、ネットワークが回復していません。scp で退避したくてもできない状況です。
一旦、rebootで再起動してみます。

ネットワークが回復していません


またエラーが大量に表示されるため、エンターキーを押します。

エラーが大量に表示


すると、今度は、localhost login:となります。

localhost login:


root でログインできました!
ネットワークも使えます。

root でログインできました


ネットワークも使えます。


・・・この状態から目的のファイルを tar.gz で固めて、scp できました。・・・・


実は、tar コマンド中 node_modules 配下で数ファイルエラーになりましたが、node_modules は、後で入れなおせば良いため、助かりました。


ヨシ!

loading...