16.2. SR-IOV デバイスを使用した PCI デバイスの割り当て
<source>
要素によりドメイン XML で指定) は、直接デバイス割り当て (passthrough と呼ばれることもあります) を使用して、ゲストに直接接続できます。 標準的なシングルポートの PCI イーサネットカードドライバー設計の制限により、この方法で割り当てることができるのは Single Root I/O Virtualization (SR-IOV) virtual function (VF) デバイスのみとなります。標準的なシングルポートの PCI または PCIe イーサネットカードをゲストに割り当てる場合は、従来の <hostdev>
デバイス定義を使用します。
図16.9 PCI デバイスの割り当ての XML 例
<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>
図16.10 SR-IOV の仕組み
- Physical Function (PF) は、SR-IOV 機能を含む完全な PCIe デバイスです。物理機能は、検出、管理、および通常の PCI デバイスとして設定されます。物理機能は、仮想機能を割り当てることにより、SR-IOV 機能を設定および管理します。
- 仮想機能 (VF) は、I/O のみを処理する単純な PCIe 機能です。各仮想機能は、物理機能から派生しています。デバイスに含まれる仮想機能の数は、デバイスのハードウェアにより制限されます。単一のイーサネットポートである物理デバイスは、仮想マシンで共有できる多くの仮想機能にマップできます。
16.2.1. SR-IOV の利点
16.2.2. SR-IOV の使用
<hostdev>
にデバイスエントリーを追加することで、仮想マシンに割り当てることができます。ただし、これは通常のネットワークデバイスとは異なり、SR-IOV VF ネットワークデバイスには永続的な一意の MAC アドレスがなく、ホストを再起動するたびに新しい MAC アドレスが割り当てられるため、問題になることがあります。このため、システムの再起動後にゲストに同じ VF が割り当てられた場合でも、ホストの再起動時に、ゲストのネットワークアダプターが新しい MAC アドレスを持つと判断します。その結果、ゲストは毎回新しいハードウェアが接続されていると考え、通常はゲストのネットワーク設定を再設定する必要があります。
<interface type='hostdev'>
インターフェイスデバイスが含まれます。このインターフェイスデバイスを使用すると、libvirt は、最初に、示されたネットワーク固有のハードウェアおよびスイッチの初期化 (MAC アドレス、VLAN タグ、802.1Qbh 仮想ポートパラメーターの設定など) を実行し、次にゲストに PCI デバイスを割り当てます。
<interface type='hostdev'>
インターフェイスを使用するには、以下が必要です。
- SR-IOV 対応のネットワークカード、
- Intel VT-d 拡張機能または AMD IOMMU 拡張機能のいずれかに対応するホストハードウェア
- 割り当てる VF の PCI アドレス。
手順16.8 Intel または AMD システムでの SR-IOV ネットワークデバイスの接続
BIOS およびカーネルで、Intel VT-d または AMD IOMMU の仕様を有効にします。
Intel システムでは、BIOS で Intel VT-d が有効になっていない場合は有効にします。BIOS およびカーネルで Intel VT-d を有効にする場合は、手順16.1「PCI デバイス割り当てのための Intel システムの準備」 を参照してください。Intel VT-d がすでに有効で機能している場合は、この手順をスキップしてください。AMD システムでは、BIOS で AMD IOMMU 仕様が有効になっていない場合は有効にします。BIOS で IOMMU を有効にする方法は、手順16.2「PCI デバイス割り当て用の AMD システムの準備」 を参照してください。サポートの確認
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)
この出力は、その他のデバイスをすべて削除するように変更されていることに注意してください。仮想機能のアクティブ化
以下のコマンドを実行します。# echo ${num_vfs} > /sys/class/net/enp14s0f0/device/sriov_numvfs
仮想機能を永続化します。
再起動後も仮想機能を永続化するには、選択したエディターを使用して、以下のような udev ルールを作成します。ここでは、ネットワークインターフェイスカードでサポートされている制限まで、予定している数の VF (この例では2
) を指定します。以下の例では、enp14s0f0 を PF ネットワークデバイス名に置き換え、ENV{ID_NET_DRIVER}
の値を、使用中のドライバーに合わせて調整します。# vim /etc/udev/rules.d/enp14s0f0.rules
ACTION=="add", SUBSYSTEM=="net", ENV{ID_NET_DRIVER}=="ixgbe", ATTR{device/sriov_numvfs}="2"
これにより、システムの起動時に機能が有効になります。新しい仮想機能の検査
lspci コマンドを使用して、Intel 82576 ネットワークデバイスに追加した仮想機能のリストを表示します。(もしくは、grep を使用して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
が記載されています。デバイスが 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仮想機能と物理機能の PCI アドレスがリストに含まれている必要があります。virsh でデバイスの詳細を取得する
pci_0000_0b_00_0
は、物理機能のいずれかで、pci_0000_0b_10_0
は、その物理機能に対応する最初の仮想機能です。virsh nodedev-dumpxml を実行すると、両方のデバイスの情報が表示されます。# virsh nodedev-dumpxml pci_0000_03_00_0 <device> <name>pci_0000_03_00_0</name> <path>/sys/devices/pci0000:00/0000:00:01.0/0000:03:00.0</path> <parent>pci_0000_00_01_0</parent> <driver> <name>igb</name> </driver> <capability type='pci'> <domain>0</domain> <bus>3</bus> <slot>0</slot> <function>0</function> <product id='0x10c9'>82576 Gigabit Network Connection</product> <vendor id='0x8086'>Intel Corporation</vendor> <capability type='virt_functions'> <address domain='0x0000' bus='0x03' slot='0x10' function='0x0'/> <address domain='0x0000' bus='0x03' slot='0x10' function='0x2'/> <address domain='0x0000' bus='0x03' slot='0x10' function='0x4'/> <address domain='0x0000' bus='0x03' slot='0x10' function='0x6'/> <address domain='0x0000' bus='0x03' slot='0x11' function='0x0'/> <address domain='0x0000' bus='0x03' slot='0x11' function='0x2'/> <address domain='0x0000' bus='0x03' slot='0x11' function='0x4'/> </capability> <iommuGroup number='14'> <address domain='0x0000' bus='0x03' slot='0x00' function='0x0'/> <address domain='0x0000' bus='0x03' slot='0x00' function='0x1'/> </iommuGroup> </capability> </device>
# virsh nodedev-dumpxml pci_0000_03_11_5 <device> <name>pci_0000_03_11_5</name> <path>/sys/devices/pci0000:00/0000:00:01.0/0000:03:11.5</path> <parent>pci_0000_00_01_0</parent> <driver> <name>igbvf</name> </driver> <capability type='pci'> <domain>0</domain> <bus>3</bus> <slot>17</slot> <function>5</function> <product id='0x10ca'>82576 Virtual Function</product> <vendor id='0x8086'>Intel Corporation</vendor> <capability type='phys_function'> <address domain='0x0000' bus='0x03' slot='0x00' function='0x1'/> </capability> <iommuGroup number='35'> <address domain='0x0000' bus='0x03' slot='0x11' function='0x5'/> </iommuGroup> </capability> </device>
この例では、手順 8 で作成した仮想マシンに、仮想機能pci_0000_03_10_2
を追加します。仮想機能のbus
、slot
、およびfunction
パラメーターは、デバイスを追加するために必要です。このパラメーターは、/tmp/new-interface.xml
などの一時 XML ファイルにコピーします。<interface type='hostdev' managed='yes'> <source> <address type='pci' domain='0x0000' bus='0x03' slot='0x10' function='0x2'/> </source> </interface>
注記仮想マシンが起動すると、物理アダプターが提供するタイプのネットワークデバイスと、設定された 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>
MAC アドレスを指定しないと、MAC アドレスが自動的に生成されます。<virtualport>
要素は、802.11Qbh ハードウェアスイッチに接続する場合にのみ使用されます。<vlan>
要素は、VLAN タグ付けされた42
に、ゲストのデバイスを透過的に配置します。仮想マシンへの仮想機能の追加
上の手順で作成した一時ファイルを使用し、次のコマンドを実行して仮想マシンに仮想機能を追加します。これにより、新しいデバイスがすぐに接続され、以降のゲストの再起動のために保存されます。virsh attach-device MyGuest
/tmp/new-interface.xml
--live --configvirsh attach-device で--live
を指定すると、新しいデバイスが実行中のゲストに接続されます。--config
オプションを使用すると、今後ゲストを再起動しても新しいデバイスを使用できるようになります。注記--live
オプションは、ゲストが実行中の場合にのみ受け入れられます。実行されていないゲストで--live
オプションが使用されると、virsh はエラーを返します。
16.2.3. SR-IOV デバイスを使用した PCI 割り当ての設定
<hostdev>
要素を使用してゲスト仮想マシンに割り当てることができます。ただし、SR-IOV VF ネットワークデバイスには永続的な一意の MAC アドレスがないため、ホストの物理マシンを再起動するたびにゲスト仮想マシンのネットワーク設定を再設定する必要があるという問題が発生します。これを修正するには、ゲスト仮想マシンを起動するたびに、ホストの物理マシンに VF を割り当てる前に MAC アドレスを設定する必要があります。この MAC アドレスやその他のオプションを割り当てるには、以下の手順を参照してください。
手順16.9 SR-IOV で PCI デバイスを割り当てる MAC アドレス、vLAN、および仮想ポートの設定
<hostdev>
要素は、MAC アドレスの割り当て、vLAN タグ ID の割り当て、仮想ポートの割り当てなどの機能固有の項目には使用できません。これは、<mac>
要素、<vlan>
要素、および <virtualport>
要素が <hostdev>
の有効な子ではないためです。代わりに、この要素は hostdev インターフェイスタイプ <interface type='hostdev'>
と一緒に使用できます。このデバイスタイプは、<インタフェース>
と <hostdev>
を組み合わせたものとして動作します。そのため、libvirt は、ゲスト仮想マシンに PCI デバイスを割り当てる前に、ゲスト仮想マシンの XML 設定ファイルに示されているネットワーク固有のハードウェア/スイッチを初期化します (MAC アドレスの設定、vLAN タグの設定、802.1Qbh スイッチへの関連付けなど)。vLAN タグの設定方法は、「vLAN タグの設定」 を参照してください。
情報の収集
<interface type='hostdev'>
を使用するには、SR-IOV 対応のネットワークカード、Intel VT-d 拡張機能または AMD IOMMU 拡張機能に対応するホストの物理マシンハードウェアが必要で、割り当てる VF の PCI アドレスを把握している必要があります。ゲスト仮想マシンのシャットダウン
virsh shutdown コマンドを使用して、ゲスト仮想マシンをシャットダウンします (ここでは guestVM という名前)。# virsh shutdown guestVM
編集する XML ファイルを開く
# virsh edit guestVM.xml
オプション: virsh save コマンドで作成された XML 設定ファイルの場合、次を実行します。# virsh save-image-edit guestVM.xml
--running
設定ファイル (この例では guestVM.xml) がデフォルトのエディターで開きます。詳細は、「ゲスト仮想マシンの設定の編集」 を参照してください。XML ファイルの編集
設定ファイル (guestVM.xml) を更新して、以下のような<devices>
エントリーが表示されるようにします。図16.11 hostdev インターフェイスタイプのサンプルドメイン 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>
注記MAC アドレスを指定しないと、その他のタイプのインターフェイスデバイスと同様に、MAC アドレスが自動的に生成されます。また、<virtualport>
要素は、802.11Qgh ハードウェアスイッチに接続する場合にのみ使用されます。802.11 Qbg (VEPA としても知られている) スイッチには現在対応していません。ゲスト仮想マシンを再起動します。
virsh start コマンドを実行して、手順 2 でシャットダウンしたゲスト仮想マシンを再起動します。詳細は、「仮想マシンの起動、再開、および復元」 を参照してください。# virsh start guestVM
ゲスト仮想マシンは起動時に、設定された MAC アドレスを持つ、物理ホストマシンのアダプターにより提供されたネットワークデバイスを認識します。この MAC アドレスは、ゲスト仮想マシンやホストの物理マシンを再起動しても変更されません。
16.2.4. SR-IOV 仮想機能のプールからの PCI デバイス割り当ての設定
- ゲスト仮想マシンを起動する場合は、常に指定した VF を使用できる状態にしておく必要があります。そのため、管理者は、各 VF を 1 つのゲスト仮想マシンに永続的に割り当てる必要があります (または、各ゲスト仮想マシンの設定ファイルを変更して、ゲスト仮想マシンが起動するたびに現在使用されていない VF の PCI アドレスを指定します)。
- ゲスト仮想マシンを別のホスト物理マシンに移動する場合は、そのホスト物理マシンのハードウェアが PCI バス上の同じ場所にある必要があります (または、ゲスト仮想マシンの設定を起動前に変更する必要があります)。
手順16.10 デバイスプールの作成
ゲスト仮想マシンのシャットダウン
virsh shutdown コマンドを使用して、ゲスト仮想マシンをシャットダウンします (ここでは guestVM という名前)。# virsh shutdown guestVM
設定ファイルの作成
任意のエディターを使用して、/tmp
ディレクトリーに XML ファイル (名前は passthrough.xml など) を作成します。pf dev='eth3'
は、独自の SR-IOV デバイスーの Physical Function (PF) の netdev 名称に置き換えてください。以下は、ホスト物理マシンの "eth3' にある PF を持つ SR-IOV アダプターのすべての VF のプールを使用できるようにするネットワーク定義の例です。図16.12 サンプルのネットワーク定義ドメイン XML
<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>
新しい XML ファイルの読み込み
/tmp/passthrough.xml を、前の手順で作成した XML ファイルの名前と場所に置き換え、次のコマンドを入力します。# virsh net-define /tmp/passthrough.xml
ゲストの再起動
passthrough.xml を、前の手順で作成した XML ファイルの名前に置き換えて、次のコマンドを実行します。# virsh net-autostart passthrough # virsh net-start passthrough
ゲスト仮想マシンの再起動
virsh start コマンドを実行して、最初の手順でシャットダウンしたゲスト仮想マシンを再起動します (例では、ゲスト仮想マシンのドメイン名として guestVM を使用します)。詳細は、「仮想マシンの起動、再開、および復元」 を参照してください。# virsh start guestVM
デバイスのパススルーの開始
表示されているデバイスは 1 つだけですが、libvirt は、ゲスト仮想マシンが次のようなドメイン XML のインターフェイス定義で初めて起動されたときに、その PF に関連付けられているすべての VF のリストを自動的に取得します。図16.13 インターフェイスネットワーク定義のサンプルドメイン XML
<interface type='network'> <source network='passthrough'> </interface>
検証
ネットワークを使用する最初のゲストを起動したら、virsh net-dumpxml passthrough コマンドを実行し、これを確認できます。以下のような出力が得られます。図16.14 XML ダンプファイルの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>
16.2.5. SR-IOV の制限
- Intel® 82576NS ギガビットイーサネットコントローラー (igb ドライバー)
- Intel® 82576EB ギガビットイーサネットコントローラー (igb ドライバー)
- Intel® 82599ES 10 ギガビットイーサネットコントローラー (ixgbe ドライバー)
- Intel® 82599EB 10 ギガビットイーサネットコントローラー (ixgbe ドライバー)