13.2. SR-IOV の使用

このセクションでは、SR-IOV 対応のマルチポイントネットワークカードの仮想機能をネットワークデバイスとして仮想マシンに割り当てる、PCI パススルーの使い方を説明します。
virsh edit または virsh attach-device コマンドで <hostdev> 内のデバイスエントリーを追加することにより、SR-IOV 仮想機能を仮想マシンに割り当てられます。しかし、通常のネットワークデバイスと違って SR-IOV VF は永久的な固有の MAC アドレスを持たず、ホストが再起動するたびに新たな MAC アドレスを割り当てられるので、これは問題となります。このため、再起動後にゲストに同じ仮想機能が割り当てられても、ホストが再起動すると、ゲストは新規の MAC アドレスを持つための新たなネットワークアダプターを決定します。その結果、ゲストは毎回新たなハードウェアが接続されたと考え、通常、ゲストのネットワークの再設定を要求することになります。
libvirt-0.9.10 およびそれ以降には、<interface type='hostdev'> インタフェースデバイスが含まれています。このインタフェースデバイスを使って、libvirt は指定されたネットワーク特定のハードウェア/スイッチの初期化をまず行います (MAC アドレスや VLAN タグ、802.1Qbh virtualport パラメーターの設定など)。その後に、ゲストへの PCI デバイス割り当てを実行します。
<interface type='hostdev'> インタフェースデバイスの使用には、以下が必要です。
  • SR-IOV 対応ネットワークカード
  • Intel VT-d または AMD IOMMU 拡張をサポートするホストハードウェア
  • 割り当てられる仮想機能の PCI アドレス

重要

SR-IOV デバイスを仮想マシンに割り当てるには、ホストハードウェアが Intel VT-d または AMD IOMMU 仕様に対応している必要があります。
SR-IOV ネットワークデバイスを Intel または AMD システムにアタッチするには、以下の手順にしたがいます。

手順13.1 SR-IOV ネットワークデバイスを Intel または AMD システムにアタッチする

  1. Intel VT-d または AMD IOMMU 仕様を BIOS およびカーネル内で有効にする

    Intel システムでは、Intel VT-d が有効化されていない場合、BIOS でこれを有効にします。BIOS およびカーネル内での Intel VT-d の有効化に関しては、手順12.1「Intel システムでの PCI デバイス割り当て準備」 を参照してください。
    Intel VT-d が有効化され、機能している場合は、このステップを飛ばしてください。
    AMD システムでは、AMD IOMMU 仕様が有効化されていない場合、BIOS でこれを有効にします。BIOS での IOMMU の有効化に関しては、手順12.2「AMD システムでの PCI デバイス割り当て準備」 を参照してください。
  2. サポートの確認

    SR-IOV 対応の PCI デバイスが検出されるかどうかを確認します。この例では、SR-IOV 対応の Intel 82576 ネットワークインタフェースカードがリストされています。lspci コマンドを使ってデバイスが検出されたかどうかを確認します。
    # lspci
    03:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
    03:00.1 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
    出力が変更されて、他のデバイスがすべて削除されたことに注意してください。
  3. SR-IOV カーネルモジュールの開始

    デバイスが対応していれば、ドライバーカーネルモジュールがカーネルによって自動的にロードされます。オプションのパラメーターは、modprobe コマンドを使ってモジュールに送信できます。Intel 82576 ネットワークインタフェースカードは、igb ドライバーカーネルモジュールを使用します。
    # modprobe igb [<option>=<VAL1>,<VAL2>,]
    # lsmod |grep igb
    igb    87592  0
    dca    6708    1 igb
  4. 仮想機能のアクティブ化

    igb モジュールの max_vfs パラメーターは、最大数の仮想機能を割り当てます。max_vfs パラメーターにより、ドライバーは最大パラメーターの値までの仮想機能を発生させます。このカードでは、有効な範囲は 0 から 7 です。
    モジュールを削除して、変数を変更します。
    # modprobe -r igb
    max_vfs7 またはご使用のデバイスがサポートする最大数の仮想機能数に設定し、モジュールを再起動します。
    # modprobe igb max_vfs=7
  5. 仮想機能に一貫性を持たせる

    /etc/modprobe.d にあるすべてのファイルに options igb max_vfs=7 の行を追加し、仮想機能に一貫性を持たせます。たとえば、以下のようになります。
    # echo "options igb max_vfs=7" >>/etc/modprobe.d/igb.conf
  6. 新たな仮想機能の検証

    lspci コマンドを使用して、Intel 82576 ネットワークデバイスにアタッチされ、新たに追加された仮想機能をリストします (別の方法では、grep を使って Virtual Function、または Virtual Function をサポートするデバイスを検索します。)。
    # lspci | grep 82576
    0b:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
    0b:00.1 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection(rev 01)
    0b:10.0 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:10.1 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:10.2 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:10.3 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:10.4 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:10.5 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:10.6 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:10.7 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:11.0 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:11.1 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:11.2 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:11.3 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:11.4 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:11.5 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    PCI デバイスの識別子は、lspci コマンドの -n パラメーターで見つけます。物理機能は、0b:00.0 および 0b:00.1 に対応しています。仮想機能にはすべて Virtual Function と記されています。
  7. virsh を使用してデバイスの有無を確認する

    デバイスを仮想マシンに追加する前に、libvirt サービスはそのデバイスを認識する必要があります。libvirt は、lspci の出力に類似した表示を使用します。lspci の出力では、すべての句読点とセミコロン (;) およびピリオド (.) は、アンダースコア (_) に変換されます。
    virsh nodedev-list コマンドと grep コマンドを使って、利用可能なホストデバイスのリストから Intel 82576 ネットワークデバイスを選び出します。この例の 0b は、Intel 82576 ネットワークデバイスのフィルターです。これはお使いのシステムによっても異なり、結果的にデバイスがさらに加わる場合もあります。
    # virsh nodedev-list | grep 0b
    pci_0000_0b_00_0
    pci_0000_0b_00_1
    pci_0000_0b_10_0
    pci_0000_0b_10_1
    pci_0000_0b_10_2
    pci_0000_0b_10_3
    pci_0000_0b_10_4
    pci_0000_0b_10_5
    pci_0000_0b_10_6
    pci_0000_0b_11_7
    pci_0000_0b_11_1
    pci_0000_0b_11_2
    pci_0000_0b_11_3
    pci_0000_0b_11_4
    pci_0000_0b_11_5
    リストには、仮想機能と物理機能のシリアル番号が表示されます。
  8. virsh を使用してデバイスの詳細を確認する

    pci_0000_0b_00_0 は物理機能の 1 つで、pci_0000_0b_10_0 はこの物理機能に対応する最初の仮想機能です。virsh nodedev-dumpxml コマンドを使って、両方のデバイスの詳細な出力を表示します。
    # virsh nodedev-dumpxml pci_0000_0b_00_0
    <device>
       <name>pci_0000_0b_00_0</name>
       <parent>pci_0000_00_01_0</parent>
       <driver>
          <name>igb</name>
       </driver>
       <capability type='pci'>
          <domain>0</domain>
          <bus>11</bus>
          <slot>0</slot>
          <function>0</function>
          <product id='0x10c9'>82576 Gigabit Network Connection</product>
          <vendor id='0x8086'>Intel Corporation</vendor>
       </capability>
    </device>
    # virsh nodedev-dumpxml pci_0000_0b_10_0
    <device>
       <name>pci_0000_0b_10_0</name>
       <parent>pci_0000_00_01_0</parent>
       <driver>
          <name>igbvf</name>
       </driver>
       <capability type='pci'>
          <domain>0</domain>
          <bus>11</bus>
          <slot>16</slot>
          <function>0</function>
          <product id='0x10ca'>82576 Virtual Function</product>
          <vendor id='0x8086'>Intel Corporation</vendor>
       </capability>
    </device>
    この例では、仮想機能 pci_0000_0b_10_0ステップ 9 の仮想マシンに追加します。仮想機能の busslotfunction パラメーターは、デバイスを追加するのに必要になります。
    /tmp/new-interface.xml などの一時 XML ファイルにこれらのパラメーターをコピーします。
       <interface type='hostdev' managed='yes'>
         <source>
           <address type='pci' domain='0' bus='11' slot='16' function='0'/>
         </source>
       </interface>

    注記

    MAC アドレスは、指定されない場合は自動生成されます。<virtualport> 要素は、802.11Qbh ハードウェアスウィッチに接続する場合のみ使用されます。<vlan> 要素は、Red Hat Enterprise Linux 6.4 で初めて導入されたもので、ゲストのデバイスを 42 にタグ付けされた VLAN 上に透過的に配置します。
    仮想マシンは、物理アダプターが提供し、MAC アドレスが設定されたタイプのネットワークデバイスをスタート時に認識します。このMAC アドレスは、ホストおよびゲストが再起動しても変化しません。
    以下の <interface> の例では、<mac address><virtualport><vlan> 要素オプションの構文を表示しています。実際には、<vlan> または <virtualport> を、例のように両方同時にではなく、どちらかを使用します。
    ...
     <devices>
       ...
       <interface type='hostdev' managed='yes'>
         <source>
           <address type='pci' domain='0' bus='11' slot='16' function='0'/>
         </source>
         <mac address='52:54:00:6d:90:02'>
         <vlan>
            <tag id='42'/>
         </vlan>
         <virtualport type='802.1Qbh'>
           <parameters profileid='finance'/>
         </virtualport>
       </interface>
       ...
     </devices>
  9. 仮想機能を仮想マシンに追加する

    上記のステップで作成された一時ファイルで以下のコマンドを使用して、仮想機能を仮想マシンに追加します。これで新規デバイスは即座にアタッチされ、これ以降のゲスト再スタートにも保存されます。
    virsh attach-device MyGuest /tmp/new-interface.xml  --config
    --config オプションを使用すると、これ以降のゲスト再スタート後も新規デバイスが確実に利用可能になります。
仮想マシンが新規ネットワークインタフェースカードを検出します。この新規カードが、SR-IOV デバイスの仮想機能です。