20.40. ゲスト仮想マシンの CPU モデルの設定

20.40.1. はじめに

それぞれのハイパーバイザーには、ゲスト仮想マシンにデフォルトで表示する CPU 情報に関して独自のポリシーがあります。ゲスト仮想マシンで使用できるホスト物理マシンの CPU 機能をハイパーバイザー側で決めるものもあれば、QEMU/KVM ではゲスト仮想マシンには qemu32 または qemu64 という汎用モデルを表示します。こうしたハイパーバイザーでは、より高度なフィルター機能を備え、すべての物理 CPU をいくつかのグループに分類して、ゲスト仮想マシンに対して表示するベースライン CPU モデルを各グループに 1 つずつ用意します。これにより、同じグループに分類される物理 CPU が使用される場合、ホスト物理マシン間でのゲスト仮想マシンの安全な移行が可能になります。libvirt では一般的にはポリシー自体の強制は行わず、より高い層が独自の必要なポリシーを定義するメカニズムを提供します。CPU のモデル情報を取得し、ゲスト仮想マシンに適した CPU モデルを定義する方法を理解することは、ホスト物理マシン間でゲスト仮想マシンを正常に移行する上で非常に重要となります。ハイパーバイザーは認識できる機能しかエミュレートできないため、そのハイパーバイザーのリリース後に作成された機能についてはエミュレートできません。

20.40.2. ホスト物理マシン CPU モデルに関する認識

virsh capabilities コマンドは、ハイパーバイザーの接続とホスト物理マシンの機能を記述する XML ドキュメントを表示します。表示される XML スキーマは、ホスト物理マシンの CPU モデルの情報を提供するように拡張されています。CPU モデルの記述において大きな課題となるものの1 つは、すべてのアーキテクチャーがそれぞれの機能の公開に対して異なるアプローチを取っていることです。QEMU/KVM および libvirt は、CPU モデル名の文字列を命名されたフラグ一式と合わせるスキームを使用します。
既知の CPU モデルすべてを一覧表示するデータベースを取得することは実際的ではありません。そのため、libvirt はベースライン CPU モデル名の小規模な一覧を維持します。この一覧は、実際のホスト物理マシン CPU と最大数の CPUID ビットを共有するものを選択して、残りの部分は名前付きの機能として一覧表示します。libvirt は、ベースライン CPU に含まれる機能は表示しないことに注意してください。これは、一見すると不具合のように思われる可能性がありますが、このセクションで後述されるように、この情報について知る必要はありません。

20.40.3. VFIO IOMMU デバイスのサポートの判別

virsh domcapabilities コマンドを使用して VFIO のサポートを判別します。以下の出力例を参照してください。

# virsh domcapabilities

[...output truncated...]

<enum name='pciBackend'>
        <value>default</value>
        <value>vfio</value>

[...output truncated...]

図20.3 VFUI のサポートの判別

20.40.4. ホスト物理マシンのプールに適合する互換性のある CPU モデルの決定

1 つのホスト物理マシンが持つ CPU 機能を認識することができるようになったら、次のステップは、どの CPU 機能をそのゲスト仮想マシンに公開するのが最適であるかを決定することです。ゲスト仮想マシンを別のホスト物理マシンに移行する必要が全くないことが判明している場合、そのホスト物理マシンの CPU モデルは修正なしに単純に渡されます。一部の仮想化データセンターには、すべてのサーバーが 100% 同一の CPU を保持していることを保証する設定のセットが含まれる場合があります。そのような場合も、ホスト物理マシンの CPU モデルは修正なしに単純に渡されます。しかし、さらに一般的なケースとしては、ホスト物理マシン間に CPU のバリエーションが存在することがあります。このような CPU の混在環境では、妥協できる共通の CPU を決定する必要があります。これは単純な手順ではないため、libvirt はこのタスクに適格な API を提供します。libvirt が、それぞれホスト物理マシン用の CPU モデルを記述している XML 文書の一覧を受け取ると、内部でこれらを CPUID マスクに変換し、それらの接点を算出して、CPUID マスクの結果を XML CPU 記述に変換し直します。
以下は、virsh capabilities が実行される際に、libvirt が基本ワークステーションの機能として報告する内容についての例です。

<capabilities>
  <host>
    <cpu>
      <arch>i686</arch>
      <model>pentium3</model>
      <topology sockets='1' cores='2' threads='1'/>
      <feature name='lahf_lm'/>
      <feature name='lm'/>
      <feature name='xtpr'/>
      <feature name='cx16'/>
      <feature name='ssse3'/>
      <feature name='tm2'/>
      <feature name='est'/>
      <feature name='vmx'/>
      <feature name='ds_cpl'/>
      <feature name='monitor'/>
      <feature name='pni'/>
      <feature name='pbe'/>
      <feature name='tm'/>
      <feature name='ht'/>
      <feature name='ss'/>
      <feature name='sse2'/>
      <feature name='acpi'/>
      <feature name='ds'/>
      <feature name='clflush'/>
      <feature name='apic'/>
    </cpu>
 </host>
</capabilities>

図20.4 ホスト物理マシンの CPU モデル情報のプル

ここで、同じ virsh capabilities コマンドを使ってこれを別のサーバーと比較します。

<capabilities>
  <host>
    <cpu>
      <arch>x86_64</arch>
      <model>phenom</model>
      <topology sockets='2' cores='4' threads='1'/>
      <feature name='osvw'/>
      <feature name='3dnowprefetch'/>
      <feature name='misalignsse'/>
      <feature name='sse4a'/>
      <feature name='abm'/>
      <feature name='cr8legacy'/>
      <feature name='extapic'/>
      <feature name='cmp_legacy'/>
      <feature name='lahf_lm'/>
      <feature name='rdtscp'/>
      <feature name='pdpe1gb'/>
      <feature name='popcnt'/>
      <feature name='cx16'/>
      <feature name='ht'/>
      <feature name='vme'/>
    </cpu>
    ...snip...

図20.5 ランダムサーバーからの CPU 記述の生成

この CPU 記述に直前のワークステーションの CPU 記述との互換性があるかを判別するには、virsh cpu-compare コマンドを使用します。
この縮小されたコンテンツは virsh-caps-workstation-cpu-only.xml という名前のファイル内に格納されて、このファイルに virsh cpu-compare コマンドを実行することができます。
# virsh cpu-compare virsh-caps-workstation-cpu-only.xml
Host physical machine CPU is a superset of CPU described in virsh-caps-workstation-cpu-only.xml
以上の出力から分かるように、サーバー CPU 内のいくつかの機能がクライアント CPU 内に見つからないため、libvirt は CPU には厳密には互換性がないことを正しく報告しています。クライアントとサーバー間の移行を可能にするには、XML ファイルを開いていくつかの機能をコメントアウトする必要があります。どの機能を削除するかを決定するには、両方のマシンの CPU 情報が含まれる virsh cpu-baselineboth-cpus.xml コマンドを実行します。# virsh cpu-baseline both-cpus.xml を実行すると、次のような結果になります。

<cpu match='exact'>
  <model>pentium3</model>
  <feature policy='require' name='lahf_lm'/>
  <feature policy='require' name='lm'/>
  <feature policy='require' name='cx16'/>
  <feature policy='require' name='monitor'/>
  <feature policy='require' name='pni'/>
  <feature policy='require' name='ht'/>
  <feature policy='require' name='sse2'/>
  <feature policy='require' name='clflush'/>
  <feature policy='require' name='apic'/>
</cpu>

図20.6 複合 CPU ベースライン

この複合ファイルは共通の要素を示します。共通でない要素はすべてコメントアウトされます。