概要
仮想マシン(VM)を別の環境に移行したとき、「前は動いていたのに、なぜか起動しない」という経験をしたことはないでしょうか。
私のようにイメージファイルをそのままコピーして、ホストサーバに食わせてやれば動くだろう、VMなんだからという安易な考え方をしている場合はこの壁にぶち当たるでしょう。
今回はまさにそのケースで、QEMU環境からProxmoxへVMのディスクイメージを移したところ、FreeBSDが起動直後にクラッシュするという問題が発生しました。原因はとてもシンプルなものでしたが、初見では気づきにくいポイントがあったので、記録として残しておきます。
何が起きたか
Proxmoxの管理画面からVMのコンソールを開くと、こんなメッセージが表示されて止まっていました。

「kernel mode」でエラー、「general protection fault(一般保護違反)」。OSが起動しようとした瞬間にクラッシュしています。スタックトレース(エラーの足跡)を見ると、mca_init という関数で止まっていました。これはCPUのハードウェア機能を初期化する処理です。
最初に試したこと
- ホストサーバのVMの設定を見ると、OS種別が「Linux 6.x」になっていました。
- 起動予定のVMはFreeBSDなのにLinux扱いになっています。
- これは明らかにおかしいので other に修正しました。
- 更に仮想マシンのCPUタイプを汎用的な kvm64 に変更しました。
- これはよくある解決策なのですが、今回はこれでも直りませんでした。
本当の原因
元のQEMU環境の設定を確認したところ、CPUモデルが Nehalem に設定されていました。

「Nehalem」はIntelの特定のCPUアーキテクチャの名前です。FreeBSDのカーネルはこの設定を前提に動作していたため、Proxmoxで別のCPUモデル(kvm64)で起動しようとすると、CPU固有の機能にアクセスしようとした瞬間に「そんな機能ない」となってクラッシュしていたのです。
解決方法
ホストサーバのVMの設定編集して、CPUモデルを元と同じ Nehalem に変更するだけでした。FreeBSDが正常に立ち上がりました。
なぜこうなるのか(やさしく解説)
仮想マシンは「本物のコンピューターのふりをするソフトウェア」です。その中で動くOSは、「自分はこういうCPUの上で動いている」という前提で動作します。
引っ越し前の環境では Nehalem というCPUのふりをしていたので、FreeBSDも「Nehalemがあるはず」という前提でCPUの機能を使おうとします。ところが引っ越し後は kvm64 という別のCPUのふりをしていたため、「あるはずの機能がない」という状態になり、起動直後にクラッシュしてしまったわけです。
まとめ
VMを移行するときに確認すること
CPUモデル元環境と同じモデルを指定するOS種別FreeBSDなら other に設定RTCの設定FreeBSDではUTC(既定)を使う。
仮想マシンの引っ越しは「ディスクイメージをコピーすれば終わり」ではなく、元の環境の設定も一緒に引き継ぐ必要があります。特にCPUモデルは見落としやすいので、移行前に必ず確認するようにしましょう。


