第10章 ゲスト仮想マシンデバイスの設定

Red Hat Enterprise Linux 6 は、ゲスト仮想マシンの以下の 3 つのクラスのデバイスに対応します。
  • エミュレートされたデバイス は、実際のハードウェアを模倣する純粋の仮想デバイスです。変更されていないゲストオペレーティングシステムは標準のインボックスドライバーを使ってこれらのデバイスと動作できるようになります。Red Hat Enterprise Linux 6 は、最高 216 の virtio デバイスに対応します。
  • Virtio デバイス は、仮想マシン内で最適に動作するように設計された純粋の仮想デバイスです。Virtio デバイスは、エミュレートされたデバイスと似ていますが、Linux 以外の仮想マシンにはこれらのデバイスが必要とするドライバーがデフォルトで含まれていません。仮想マシンマネージャー (virt-manager) や Red Hat Enterprise Virtualization Hypervisor といった仮想化管理ソフトウェアは、対応する Linux 以外のゲストオペレーティングシステムにこれらのドライバーを自動的にインストールします。Red Hat Enterprise Linux 6 は最高 700 の scsi ディスクに対応します。
  • 割り当てデバイス は、仮想マシンに公開されている物理デバイスです。この方法は、パススルーとも呼ばれます。デバイス割り当てにより、仮想マシンによる幅広いタスクでの PCI デバイスへの排他アクセスが可能になり、PCI デバイスをゲストオペレーティングシステムに物理的にアタッチされているかのように表示させ、動作させることが可能になります。Red Hat Enterprise Linux 6 は、仮想マシン 1 台あたり最高 32 の割り当てデバイスに対応します。
デバイス割り当ては、一部のグラフィックスデバイスを含め PCIe デバイス上でサポートされています。Nvidia K シリーズ Quadro、GRID、および Tesla グラフィックスカード GPU 機能が Red Hat Enterprise Linux 6 のデバイス割り当てでサポートされるようになりました。パラレル PCI デバイスは割り当てデバイスとしてサポートされますが、セキュリティーとシステム設定の競合により厳しい制限があります。

注記

仮想マシンにアタッチできるデバイス数は、いくつかの要素に左右されます。そのうちの 1 つは、QEMU プロセス (/etc/security/limits.conf で設定。/etc/libvirt/qemu.conf によるオーバーライドが可能) が開くファイル数です。この他には、仮想バスで利用可能なスロット数や sysctl で設定されたシステム全体でのオープンファイルの制限があります。
特定デバイスの詳細および制限の詳細は、「デバイス」 を参照してください。
Red Hat Enterprise Linux 6 は、仮想マシンへの単一機能のスロットとして公開されるデバイスの PCI ホットプラグをサポートします。単一機能のホットデバイスとマルチ機能のホットデバイスの個別の機能は、このサポートを有効にするように設定できます。デバイスを仮想マシンへのマルチ機能の PCI スロットとして公開する設定は、ノンホットプラグアプリケーションに推奨されます。

注記

割り込み再マッピングのプラットフォームサポートは、割り当てデバイスを持つゲストをホストから完全に分離するために必要です。このサポートがない場合、ホストは悪意のあるゲストからの割り込み挿入攻撃に対して脆弱になる可能性があります。ゲストが信頼される環境では、管理者は vfio_iommu_type1 モジュールに対して allow_unsafe_interrupts オプションを使用する PCI デバイス割り当て許可を選択できます。これは、以下を含む .conf ファイル (例: local.conf) を /etc/modprobe.d に追加することで永続的に実行できます。
options vfio_iommu_type1 allow_unsafe_interrupts=1
または、sysfs エントリーを動的に使用することも同じことが実行できます。
# echo 1 > /sys/module/vfio_iommu_type1/parameters/allow_unsafe_interrupts

10.1. PCI デバイス

PCI デバイス割り当ては、Intel VT-d または AMD IOMMU 対応のハードウェアプラットフォーム上でのみ利用可能です。PCI デバイス割り当てが機能するには、Intel VT-d または AMD IOMMU の仕様が BIOS で有効化されている必要があります。

手順10.1 Intel システムでの PCI デバイス割り当て準備

  1. Intel VT-d 仕様の有効化

    Intel VT-d 仕様は、物理デバイスを直接仮想マシンに割り当てるためのハードウェアサポートを提供します。この仕様は、Red Hat Enterprise Linux で PCI デバイス割り当てを使用するために必要なものです。
    Intel VT-d 仕様は、BIOS で有効化されている必要があります。システムメーカーの中には、この仕様をデフォルトで無効としているところもあります。この仕様に使う用語はメーカーによって異なります。使用されている用語に関しては、システムメーカーの資料を参照してください。
  2. カーネル内で Intel VT-d をアクティブ化する

    カーネル内で Intel VT-d をアクティブ化するには、intel_iommu=on パラメーターを /etc/sysconfig/grub ファイルの GRUB_CMDLINX_LINUX 行の終わりの引用符の内側に追加します。
    以下の修正例は、grub ファイルで Intel VT-d がアクティブ化されたものです。
    GRUB_CMDLINE_LINUX="rd.lvm.lv=vg_VolGroup00/LogVol01 
    vconsole.font=latarcyrheb-sun16 rd.lvm.lv=vg_VolGroup_1/root 
    vconsole.keymap=us $([ -x /usr/sbin/rhcrashkernel-param ] && /usr/sbin/
    rhcrashkernel-param || :) rhgb quiet intel_iommu=on"
  3. config file の再生成

    以下を実行して /boot/grub2/grub.cfg を再生成します。
    grub2-mkconfig -o /boot/grub2/grub.cfg
  4. 準備完了

    システムを再起動して、変更を有効にします。これでシステムは、PCI デバイス割り当てに対応します。

手順10.2 AMD システムでの PCI デバイス割り当て準備

  1. AMD IOMMU 仕様の有効化

    AMD IOMMU 仕様は、Red Hat Enterprise Linux で PCI デバイス割り当てを使用するために必要なものです。この仕様は、BIOS で有効化されている必要があります。システムメーカーのなかには、この仕様をデフォルトで無効としているところもあります。
  2. IOMMU カーネルサポートの有効化

    amd_iommu=on/etc/sysconfig/grub の GRUB_CMDLINX_LINUX 行の終わりの引用符の内側に追加し、AMD IOMMU 仕様が起動時に有効にされるようにします。
  3. config file の再生成

    以下を実行して /boot/grub2/grub.cfg を再生成します。
    grub2-mkconfig -o /boot/grub2/grub.cfg
  4. 準備完了

    システムを再起動して、変更を有効にします。これでシステムは、PCI デバイス割り当てに対応します。

10.1.1. virsh を使用した PCI デバイスの割り当て

このステップでは、KVM ハイパーバイザー上の仮想マシンに PCI デバイスを割り当てる方法を説明します。
以下の例では、PCI 識別子コード pci_0000_01_00_0 の PCIe ネットワークコントローラーと guest1-rhel6-64 という名前の完全仮想化ゲストマシンを使います。

手順10.3 virsh を使用した PCI デバイスのゲスト仮想マシンへの割り当て

  1. デバイスの特定

    最初に、仮想マシンへのデバイス割り当てに指定されているPCI デバイスを特定します。lspci コマンドを使用して利用可能な PCI デバイスを一覧表示します。lspci の出力は grep で絞り込むことができます。
    この例では、以下の出力で強調表示されているイーサネットコントローラーを使用します。
    # lspci | grep Ethernet
    00:19.0 Ethernet controller: Intel Corporation 82567LM-2 Gigabit Network Connection
    01:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
    01:00.1 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
    このイーサネットコントローラーは 00:19.0 の短い識別子で表示されています。この PCI デバイスを仮想マシンに割り当てるには、virsh が使用する詳細な識別子を見つける必要があります。
    これを実行するには、virsh nodedev-list コマンドを使用して、ホストマシンにアタッチされている特定の種類 (pci) のデバイスをすべて一覧表示します。次に、使用するデバイスの短い識別子にマップされている文字列の出力を探します。
    この例では、短い識別子 00:19.0 でイーサネットコントローラーにマップする文字列を強調表示しています。詳細な識別子では、:. の文字がアンダースコアに置き換えられています。
    # virsh nodedev-list --cap pci
    pci_0000_00_00_0
    pci_0000_00_01_0
    pci_0000_00_03_0
    pci_0000_00_07_0
    pci_0000_00_10_0
    pci_0000_00_10_1
    pci_0000_00_14_0
    pci_0000_00_14_1
    pci_0000_00_14_2
    pci_0000_00_14_3
    pci_0000_00_19_0
    pci_0000_00_1a_0
    pci_0000_00_1a_1
    pci_0000_00_1a_2
    pci_0000_00_1a_7
    pci_0000_00_1b_0
    pci_0000_00_1c_0
    pci_0000_00_1c_1
    pci_0000_00_1c_4
    pci_0000_00_1d_0
    pci_0000_00_1d_1
    pci_0000_00_1d_2
    pci_0000_00_1d_7
    pci_0000_00_1e_0
    pci_0000_00_1f_0
    pci_0000_00_1f_2
    pci_0000_00_1f_3
    pci_0000_01_00_0
    pci_0000_01_00_1
    pci_0000_02_00_0
    pci_0000_02_00_1
    pci_0000_06_00_0
    pci_0000_07_02_0
    pci_0000_07_03_0
    使用するデバイスを呼び出す PCI デバイス番号は他のステップで必要になるので、その番号を書き留めます。
  2. デバイス情報の確認

    ドメインやバスおよび情報については、virsh nodedev-dumpxml コマンドからの出力を参照することができます。
    virsh nodedev-dumpxml pci_0000_00_19_0
    <device>
      <name>pci_0000_00_19_0</name>
      <parent>computer</parent>
      <driver>
        <name>e1000e</name>
      </driver>
      <capability type='pci'>
        <domain>0</domain>
        <bus>0</bus>
        <slot>25</slot>
        <function>0</function>
        <product id='0x1502'>82579LM Gigabit Network Connection</product>
        <vendor id='0x8086'>Intel Corporation</vendor>
        <iommuGroup number='7'>
          <address domain='0x0000' bus='0x00' slot='0x19' function='0x0'/>
        </iommuGroup>
      </capability>
    </device>

    注記

    IOMMU グループは、IOMMU から見たデバイスの可視性と分離度に基づいて決定されます。それぞれの IOMMU グループには、1 つ以上のデバイスが含まれる可能性があります。複数のデバイスが表示される場合、IOMMU グループ内のすべてのエンドポイントが、ゲストに割り当てられるグループ内のすべてのデバイスに対して要求される必要があります。これは、追加のエンドポイントをゲストに割り当てるか、または virsh nodedev-detach を使用してそれらをホストから分離させるかのいずれかの方法で実行できます。単一グループに含まれるデバイスは、複数のゲスト間で分割したり、ホストとゲストの間で分割したりすることができないことがあります。PCIe ルートポート、スイッチポート、およびブリッジなどのノンエンドポイントのデバイスはホストドライバーから切り離せず、これらはエンドポイントの割り当てを妨げることはありません。
    IOMMU グループ内のデバイスは、virsh nodedev-dumpxml 出力の iommuGroup セクションを使用して判別できます。グループの各メンバーは、別個の「アドレス」フィールドで指定されます。この情報は、以下を使用して sysfs 内に見つけることもできます。
    $ ls /sys/bus/pci/devices/0000:01:00.0/iommu_group/devices/
    この出力の一例を示します。
    0000:01:00.0  0000:01:00.1
    0000.01.00.0 のみをゲストに割り当てるには、ゲストを起動する前に、使用されていないエンドポイントをホストから切り離す必要があります。
    $ virsh nodedev-detach pci_0000_01_00_1
  3. 必要な設定詳細の決定

    設定ファイルで必要な値については、virsh nodedev-dumpxml pci_0000_00_19_0 コマンドの出力を参照します。
    サンプルのデバイスでは、以下の値が使用されています。bus = 0、slot = 25、function = 0。10 進法の設定では、これらの値を使用します。
    bus='0'
    slot='25'
    function='0'
  4. 設定詳細の追加

    仮想マシン名を特定して virsh edit を実行し、<source> セクションにデバイスエントリーを追加し、PCI デバイスをゲスト仮想マシンに割り当てます。
    # virsh edit guest1-rhel6-64
    <hostdev mode='subsystem' type='pci' managed='yes'>
      <source>
         <address domain='0' bus='0' slot='25' function='0'/>
      </source>
    </hostdev>
    または、仮想マシン名とゲストの XML ファイルを特定して virsh attach-device を実行します。
    virsh attach-device guest1-rhel6-64 file.xml
  5. 仮想マシンの開始

    # virsh start guest1-rhel6-64
これで PCI デバイスは正しく仮想マシンに割り当てられ、ゲストオペレーティングシステムにアクセスできます。

10.1.2. virt-manager を使用した PCI デバイスの割り当て

PCI デバイスは、グラフィカルな virt-manager ツールを使ってゲスト仮想マシンに追加することができます。以下の手順では、Gigabit イーサネットコントローラーをゲスト仮想マシンに追加します。

手順10.4 virt-manager を使用した PCI デバイスのゲスト仮想マシンへの割り当て

  1. ハードウェア設定を開く

    ゲスト仮想マシンを開き、ハードウェアを追加 ボタンをクリックして新規デバイスを仮想マシンに追加します。
    The virtual machine hardware window with the Information button selected on the top taskbar and Overview selected on the left menu pane.

    図10.1 仮想マシンのハードウェア情報ウィンドウ

  2. PCI デバイスの選択

    左側の ハードウェア リストから PCI Host Device を選択します。
    未使用の PCI デバイスを選択します。別のゲストが使用している PCI デバイスを選択する場合、エラーが発生する可能性があります。以下の例では、予備の 82576 ネットワークデバイスが使用されます。完了 をクリックしてセットアップを終了します。
    The Add new virtual hardware wizard with PCI Host Device selected on the left menu pane, showing a list of host devices for selection in the right menu pane.

    図10.2 新たな仮想ハードウェア追加ウィザード

  3. 新規デバイスの追加

    セットアップが完了し、ゲスト仮想マシンはこれで PCI デバイスに直接アクセスできます。
    The virtual machine hardware window with the Information button selected on the top taskbar and Overview selected on the left menu pane, displaying the newly added PCI Device in the list of virtual machine devices in the left menu pane.

    図10.3 仮想マシンのハードウェア情報ウィンドウ

注記

デバイスの割り当てに失敗する場合、ホストに依然としてアタッチされている他のエンドポイントが同じ IOMMU グループ内にある可能性があります。virt-manager を使用してグループ情報を検索する方法はありませんが、virsh コマンドを使用して、IOMMU グループの範囲を分析し、必要な場合はデバイスを分離することができます。
IOMMU グループについての詳細および virsh を使用したエンドポイントデバイスを切り離す方法については、「virsh を使用した PCI デバイスの割り当て」注記 を参照してください。

10.1.3. virt-install を使用した PCI デバイスの割り当て

virt-install を使用して PCI デバイスを割り当てるには、--host-device パラメーターを使います。

手順10.5 virt-install を使用したゲスト仮想マシンへのPCI デバイス割り当て

  1. デバイスの特定

    ゲスト仮想マシンへのデバイス割り当てに指定されているPCI デバイスを特定します。
    # lspci | grep Ethernet
    00:19.0 Ethernet controller: Intel Corporation 82567LM-2 Gigabit Network Connection
    01:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
    01:00.1 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
    virsh nodedev-list コマンドがシステムにアタッチされている全デバイスを一覧表示し、各 PCI デバイスを文字列で特定します。出力を PCI デバイスに限定するには、以下のコマンドを実行します。
    # virsh nodedev-list --cap pci
    pci_0000_00_00_0
    pci_0000_00_01_0
    pci_0000_00_03_0
    pci_0000_00_07_0
    pci_0000_00_10_0
    pci_0000_00_10_1
    pci_0000_00_14_0
    pci_0000_00_14_1
    pci_0000_00_14_2
    pci_0000_00_14_3
    pci_0000_00_19_0
    pci_0000_00_1a_0
    pci_0000_00_1a_1
    pci_0000_00_1a_2
    pci_0000_00_1a_7
    pci_0000_00_1b_0
    pci_0000_00_1c_0
    pci_0000_00_1c_1
    pci_0000_00_1c_4
    pci_0000_00_1d_0
    pci_0000_00_1d_1
    pci_0000_00_1d_2
    pci_0000_00_1d_7
    pci_0000_00_1e_0
    pci_0000_00_1f_0
    pci_0000_00_1f_2
    pci_0000_00_1f_3
    pci_0000_01_00_0
    pci_0000_01_00_1
    pci_0000_02_00_0
    pci_0000_02_00_1
    pci_0000_06_00_0
    pci_0000_07_02_0
    pci_0000_07_03_0
    PCI デバイス番号は他のステップで必要になるので、その番号を書き留めます。
    ドメインやバスおよび機能の情報は、virsh nodedev-dumpxml コマンドからの出力を参照することができます。
    # virsh nodedev-dumpxml pci_0000_01_00_0
    <device>
      <name>pci_0000_01_00_0</name>
      <parent>pci_0000_00_01_0</parent>
      <driver>
        <name>igb</name>
      </driver>
      <capability type='pci'>
        <domain>0</domain>
        <bus>1</bus>
        <slot>0</slot>
        <function>0</function>
        <product id='0x10c9'>82576 Gigabit Network Connection</product>
        <vendor id='0x8086'>Intel Corporation</vendor>
        <iommuGroup number='7'>
          <address domain='0x0000' bus='0x00' slot='0x19' function='0x0'/>
        </iommuGroup>
      </capability>
    </device>

    注記

    IOMMU グループに複数のエンドポイントがあり、それらのすべてがゲストに割り当てられている訳ではない場合、ゲストを起動する前に以下のコマンドを実行して、他のエンドポイントをホストから手動で切り離す必要があります。
    $ virsh nodedev-detach pci_0000_00_19_1
    IOMMU グループの詳細は、「virsh を使用した PCI デバイスの割り当て」注記 を参照してください。
  2. デバイスの追加

    virsh nodedev コマンドからの PCI 識別子の出力を --host-device パラメーターの値として使います。
    virt-install \
    --name=guest1-rhel6-64 \
    --disk path=/var/lib/libvirt/images/guest1-rhel6-64.img,size=8 \
    --nonsparse --graphics spice \
    --vcpus=2 --ram=2048 \
    --location=http://example1.com/installation_tree/RHEL6.0-Server-x86_64/os \
    --nonetworks \
    --os-type=linux \
    --os-variant=rhel6
    --host-device=pci_0000_01_00_0
  3. インストールの完了

    これでゲストインストールが完了しました。PCI デバイスはゲストに割り当てられています。

10.1.4. 割り当てた PCI デバイスの切り離し

ホストの PCI デバイスがゲストマシンに割り当てられると、ホストはこのデバイスを使用できなくなります。このセクションでは、virsh または virt-manager を使ってデバイスをゲストから切り離す方法を説明します。これによって、ホストがデバイスを使えるようになります。

手順10.6 virsh を使用した PCI デバイスのゲストからの切り離し

  1. デバイスの切り離し

    以下のコマンドを使ってゲストの XML ファイル内から PCI デバイスを削除することで、ゲストから PCI デバイスを切り離します。
    # virsh detach-device name_of_guest file.xml
  2. デバイスのホストへの再割り当て (オプション)

    デバイスが managed モードの場合は、このステップを飛ばします。デバイスは自動的にホストに戻ります。
    デバイスが managed モードでない場合は、以下のコマンドを使用して PCI デバイスをホストマシンに再度割り当てます。
    # virsh nodedev-reattach device
    たとえば、pci_0000_01_00_0 デバイスをホストに再度割り当てるには、以下のようにします。
    virsh nodedev-reattach pci_0000_01_00_0
    これでこのデバイスはホストで使用できます。

手順10.7 virt-manager を使用した PCI デバイスのゲストからの切り離し

  1. 仮想ハードウェアの詳細ウィンドウを開く

    virt-manager で、対象のデバイスを含む仮想マシンをダブルクリックします。仮想ハードウェアの詳細表示 ボタンを選択し、仮想ハードウェアのリストを表示させます。
    The Show virtual hardware details button.

    図10.4 仮想ハードウェア詳細ボタン

  2. デバイスの選択および削除

    左パネルの仮想デバイスリストから切り離す PCI デバイスを選択します。
    The PCI device details and the Remove button.

    図10.5 切り離す PCI デバイスの選択

    削除 ボタンをクリックします。これでデバイスがホストで使用可能になります。

10.1.5. PCI ブリッジの作成

PCI (Peripheral Component Interconnect) ブリッジは、ネットワークカード、モデムおよび音声カードなどのデバイスに割り当てるために使用されます。物理デバイスと同様に、仮想デバイスも PCI ブリッジに割り当てることができます。かつてゲスト仮想マシンに追加できる PCI デバイスの数は 31 のみでした。現在では、31 番目の PCI デバイスが追加されると、PCI ブリッジが自動的に 31 番目のスロットに配置され、追加の PCI デバイスはその PCI ブリッジに移行します。それぞれの PCI ブリッジには、追加の 31 デバイスに対応する 31 のスロットがあり、それらすべてをブリッジにすることができます。この方法で、900 を超えるデバイスをゲスト仮想マシンで利用可能にすることができます。

注記

このアクションは、ゲスト仮想マシンが実行中の場合は実行することができません。シャットダウンされているゲスト仮想マシンに PCI デバイスを追加する必要があります。

10.1.6. PCI パススルー

PCI ネットワーク (<source> 要素で指定される) は、汎用デバイスの パススルー を使用してゲストに直接割り当てられます。これは、最初にオプションとしてデバイスの MAC アドレスを設定済みの値に設定し、デバイスをオプションで指定した <virtualport> 要素を使用して 802.1Qbh 対応スイッチに関連付けた後に行なわれます (上記の type='direct' ネットワークデバイスに指定された virtualport の例を参照)。標準の単一ポート PCI イーサネットカードドライバーの設計上の制限により、この方法で割り当てられるのは、SR-IOV (シングルルート I/O 仮想化) の仮想機能 (VF) デバイスのみになります。標準の単一ポート PCI または PCIe イーサネットカードをゲストに割り当てるには、従来の <hostdev> デバイスの定義を使用します。
従来のレガシーの KVM デバイス割り当てではなく、VFIO デバイス割り当てを使用するには (VFIO は、UEFI Secure Boot と互換性のあるデバイス割り当ての新しい方法です)、<type='hostdev'> インターフェースに、name 属性を「vfio」に設定してオプションの driver サブ要素を持たせることができます (または、<driver='kvm'> が現在デフォルトになっているため、<driver> 要素を単純に省略することもできます)。

注記

ネットワークデバイスのインテリジェントパススルーは、標準の <hostdev> デバイスと非常によく似ています。違いは、この方法では パススルーデバイスの MAC アドレスと <virtualport> を指定できる点にあります。これらの機能が不要な場合で、標準の単一ポート PCI、PCIe、または SR-IOV をサポートしない (それゆえゲストドメインへの割り当て後のリセット時に設定済み MAC アドレスが失われる) USB ネットワークがあるか、または 0.9.11 より古いバージョンの libvirt を使用している場合は、デバイスをゲストに割り当てるのに、<interface type='hostdev'/> の代わりに標準の <hostdev> を使用する必要があります。

     <devices>
    <interface type='hostdev'>
      <driver name='vfio'/>
      <source>
        <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
      </source>
      <mac address='52:54:00:6d:90:02'>
      <virtualport type='802.1Qbh'>
        <parameters profileid='finance'/>
      </virtualport>
    </interface>
  </devices>

図10.6 PCI デバイス割り当ての XML サンプル

10.1.7. SR-IOV デバイスの場合の PCI 割り当て (パススルー) の設定

このセクションは、SR-IOV デバイスのみを対象とします。SR-IOV ネットワークカードは、複数の 仮想機能 (VF) を提供します。これらの仮想機能は、それぞれ PCI デバイス割り当てを使用してゲスト仮想マシンに割り当てることができます。いったん割り当てられると、それぞれの仮想機能は完全物理ネットワークデバイスのように機能します。これにより、多くのゲスト仮想マシンが、ホスト物理マシン上で単一スロットのみを使用していても、直接の PCI デバイス割り当てによるパフォーマンス上の利点を得られます。
これらの仮想機能 (VF) は、要素 <hostdev> を使用して従来の方法によりゲスト仮想マシンに割り当てられますが、SR-IOV VF ネットワークデバイスには永続的な固有の MAC アドレスがないため、ホスト物理マシンが再起動されるたびにゲスト仮想マシンのネットワーク設定を再設定する必要があるという問題が生じます。この問題を修復するには、VF をホスト物理マシンに割り当てる前に MAC アドレスを設定する必要があり、この設定はゲスト仮想マシンの起動時に毎回行う必要があります。他のオプションと同様にこの MAC アドレスを割り当てるには、以下で説明されている手順を参照してください: 手順10.8「SR-IOV での PCI デバイス割り当てのための MAC アドレス、vLAN、および仮想ポートの設定」

手順10.8 SR-IOV での PCI デバイス割り当てのための MAC アドレス、vLAN、および仮想ポートの設定

まず、<hostdev> 要素は、MAC アドレス割り当て、vLAN タグ ID 割り当て、または仮想ポートの割り当てなどの機能固有のアイテムに使用することはできないことに留意してください。その理由は、<mac><vlan>、および <virtualport> 要素は <hostdev> の有効な子ではないからです。それらは <interface> で有効であるため、新規インターフェースタイプのサポートが追加されました (<interface type='hostdev'>)。この新規インターフェースのデバイスタイプは <interface><hostdev> のハイブリッドとして機能します。そのため、PCI デバイスをゲスト仮想マシンに割り当てる前に、libvirt は、ゲスト仮想マシンの XML 設定ファイルに示されるネットワーク固有のハードウェアまたはスイッチ (MAC アドレスの設定、vLAN タグの設定、および/または 802.1Qbh スイッチとの関連付け) を初期化します。vLAN タグの設定についての情報は、「vLAN タグの設定」 を参照してください。
  1. ゲスト仮想マシンをシャットダウンします。

    virsh shutdown コマンド (「ゲスト仮想マシンのシャットダウン」 を参照) を使用して、guestVM という名前のゲスト仮想マシンをシャットダウンします。
    # virsh shutdown guestVM
  2. 情報を収集します。

    <interface type='hostdev'> を使用するには、SR-IOV 対応ネットワークカード、また Intel VT-d または AMD IOMMU 拡張のいずれかをサポートするホスト物理マシンハードウェアが必要であり、割り当てる VF の PCI アドレスを知っておく必要があります。
  3. XML ファイルを開いて編集します。

    編集する XML ファイルを開くには、# virsh save-image-edit コマンドを実行します (詳細は、「ドメイン XML 設定ファイルの編集」 を参照してください)。ゲスト仮想マシンを以前の実行状態に戻したい場合は、--running を使用できます。この例の設定ファイルの名前は、ゲスト仮想マシンの名前が guestVM なので guestVM.xml になります。
     # virsh save-image-edit guestVM.xml --running 
    ユーザーのデフォルトエディターで guestVM.xml が開かれます。
  4. XML ファイルを編集します。

    以下のような <devices> エントリーを持たせるように設定ファイル (guestVM.xml) を更新します。
    
     <devices>
       ...
       <interface type='hostdev' managed='yes'>
         <source>
           <address type='pci' domain='0x0' bus='0x00' slot='0x07' function='0x0'/> <!--these values can be decimal as well-->
         </source>
         <mac address='52:54:00:6d:90:02'/>                                         <!--sets the mac address-->
         <virtualport type='802.1Qbh'>                                              <!--sets the virtual port for the 802.1Qbh switch-->
           <parameters profileid='finance'/>
         </virtualport>
         <vlan>                                                                     <!--sets the vlan tag-->
          <tag id='42'/>
         </vlan>
       </interface>
       ...
     </devices>

    図10.7 hostdev interface type のドメイン XML のサンプル

    MAC アドレスを指定しない場合、それ以外のタイプのインターフェースデバイスと同様に、そのアドレスは自動的に生成されます。さらに、<virtualport> 要素は、802.11Qgh ハードウェアスイッチ (802.11Qbg (別名「VEPA」) に接続される場合にのみ使用されます。これらのスイッチは現在サポートされていません。
  5. ゲスト仮想マシンを再起動します。

    最初のステップでシャットダウンしたゲスト仮想マシンを再開するために virsh start コマンドを実行します (例では、ゲスト仮想マシンのドメイン名として guestVM を使用しています)。詳細は、「定義されたドメインの起動」 を参照してください。
     # virsh start guestVM 
    ゲスト仮想マシンが起動すると、設定済みの MAC アドレスと共に、物理ホストマシンのアダプターによって指定されたネットワークデバイスが表示されます。この MAC アドレスは、ゲスト仮想マシンと物理ホストマシンの起動時に変更されることはありません。

10.1.8. SR-IOV 仮想機能のプールから PCI デバイス割り当てを設定する

特定の 仮想機能 (VF) の PCI アドレスをゲストの設定にハードコーディングする上で、2 つの重大な制限があります。
  • 指定した VF は、ゲスト仮想マシンの起動時にはいつでも利用可能な状態でなければなりません。つまり、これは管理者が単一のゲスト仮想マシンに対してそれぞれの VF を永久的に割り当てなければならないことを意味しています (またはそれぞれのゲスト仮想マシンの起動時に、現在使用されていない VF の PCI アドレスを指定するためにすべてのゲスト仮想マシンの設定ファイルを修正する必要があります)。
  • ゲスト仮想マシンが別のホスト物理マシンに移行する場合、そのホスト物理マシンには、PCI バス上の同じ場所に全く全く同じハードウェアがなければなりません (または、ここでも起動前にゲスト仮想マシンの設定を変更する必要があります)。
これらの問題は、いずれも SR-IOV デバイスのすべての VF を含むデバイスプールと共に libvirt ネットワークを作成することによって回避することができます。いったんこれが実行されると、このネットワークを参照するようにゲスト仮想マシンを設定できます。ゲストが起動するたびに、単一の VF がプールからゲスト仮想マシンに割り当てられます。ゲスト仮想マシンが停止すると、VF は別のゲスト仮想マシンが使用できるようにのプールに戻ります。

手順10.9 デバイスプールの作成

  1. ゲスト仮想マシンをシャットダウンします。

    virsh shutdown コマンド (「ゲスト仮想マシンのシャットダウン、再起動および強制終了」 を参照) を使用して、guestVM という名前のゲスト仮想マシンをシャットダウンします。
    # virsh shutdown guestVM
  2. 設定ファイルの作成

    任意のエディターを使用して、/tmp ディレクトリーに XML ファイル (例:passthrough.xml という名前のファイル) を作成します。pf dev='eth3' は、各自の SR-IOV デバイスの物理機能 (PF) に置き換えるようにしてください。
    以下は、物理機能 (PF) がホスト物理マシンの「eth3」に設定された、SR-IOV アダプターのすべての VF のプールを利用可能にするネットワーク定義のサンプルです。
                
    <network>
       <name>passthrough</name>                                                <!--This is the name of the file you created-->
       <forward mode='hostdev' managed='yes'>
         <pf dev='myNetDevName'/>                                              <!--Use the netdev name of your SR-IOV devices PF here-->
       </forward>
    </network>
    

    図10.8 ネットワーク定義ドメインの サンプル XML

  3. 新しい XML ファイルをロードします。

    /tmp/passthrough.xml を直前のステップで作成した XML ファイルの名前と場所に置き換え、以下のコマンドを実行します。
    # virsh net-define /tmp/passthrough.xml
  4. ゲストの再起動

    passthrough.xml を直前のステップで作成した XML ファイルの名前に置き換え、以下を実行します。
     # virsh net-autostart passthrough # virsh net-start passthrough 
  5. ゲスト仮想マシンを再起動します。

    最初のステップでシャットダウンしたゲスト仮想マシンを再開するために virsh start コマンドを実行します (例では、ゲスト仮想マシンのドメイン名として guestVM を使用しています)。詳細は、「定義されたドメインの起動」 を参照してください。
     # virsh start guestVM 
  6. デバイスのパススルーの開始

    単一デバイスのみが表示されていますが、libvirt は、ゲスト仮想マシンの初回起動時に、PF に関連付けられたすべての VF の一覧を自動的に派生させます。この起動には、以下のようなドメイン XML 内のインターフェース定義が使用されます。
             
    <interface type='network'>
       <source network='passthrough'>
    </interface>
    

    図10.9 インターフェースネットワーク定義のサンプルドメイン XML

  7. 検証

    検証は、ネットワークを使用する最初のゲストの起動後に virsh net-dumpxml passthrough コマンドで実行できます。以下のような出力が得られます。
          
    <network connections='1'>
       <name>passthrough</name>
       <uuid>a6b49429-d353-d7ad-3185-4451cc786437</uuid>
       <forward mode='hostdev' managed='yes'>
         <pf dev='eth3'/>
         <address type='pci' domain='0x0000' bus='0x02' slot='0x10' function='0x1'/>
         <address type='pci' domain='0x0000' bus='0x02' slot='0x10' function='0x3'/>
         <address type='pci' domain='0x0000' bus='0x02' slot='0x10' function='0x5'/>
         <address type='pci' domain='0x0000' bus='0x02' slot='0x10' function='0x7'/>
         <address type='pci' domain='0x0000' bus='0x02' slot='0x11' function='0x1'/>
         <address type='pci' domain='0x0000' bus='0x02' slot='0x11' function='0x3'/>
         <address type='pci' domain='0x0000' bus='0x02' slot='0x11' function='0x5'/>
       </forward>
    </network>
    

    図10.10 XML ダンプファイル passthrough の内容