Jump to contentJump to page navigation: previous page [access key p]/next page [access key n]
コンテンツコンテンツ
仮想化ガイド
  1. 前書き
  2. I 概要
    1. 1 仮想化技術
    2. 2 仮想化シナリオ
    3. 3 Xen 仮想化の紹介
    4. 4 KVM 仮想化の紹介
    5. 5 仮想化ツール
    6. 6 仮想化コンポーネントのインストール
  3. II libvirt を利用した仮想マシンの管理
    1. 7 libvirt デーモン
    2. 8 VM ホストサーバ の準備
    3. 9 ゲストのインストール
    4. 10 基本的な VM ゲスト の管理
    5. 11 接続と認可
    6. 12 高度なストレージ設定
    7. 13 仮想マシンマネージャ を利用した仮想マシンの設定
    8. 14 virsh を利用した仮想マシンの設定
    9. 15 AMD SEV-SNP による仮想マシンのセキュリティ強化
    10. 16 VM ゲスト の移行
    11. 17 Xen から KVM への移行ガイド
  4. III 全ハイパーバイザ共通の機能
    1. 18 ディスクのキャッシュモード
    2. 19 VM ゲスト の時刻設定
    3. 20 libguestfs
    4. 21 QEMU ゲストエージェント
    5. 22 ソフトウエア TPM エミュレータ
    6. 23 VM ゲスト に対するクラッシュダンプの作成
  5. IV Xen を利用した仮想マシンの管理
    1. 24 仮想マシンホストの設定
    2. 25 仮想ネットワーク
    3. 26 仮想環境の管理
    4. 27 Xen 内でのブロックデバイス
    5. 28 仮想化: オプション設定
    6. 29 管理作業
    7. 30 XenStore: ドメイン間で共有される設定データベース
    8. 31 Xen の高可用性仮想化ホストとしての使用
    9. 32 Xen: 準仮想化 (PV) ゲストから完全仮想化 (FV/HVM) ゲストへの変換
  6. V QEMU を利用した仮想マシンの管理
    1. 33 QEMU の概要
    2. 34 KVM VM ホストサーバ の構築
    3. 35 ゲストのインストール
    4. 36 qemu-system-ARCH を利用した仮想マシンの実行
    5. 37 QEMU モニタを利用した仮想マシンの管理
  7. VI トラブルシューティング
    1. 38 内蔵ヘルプとパッケージのドキュメンテーション
    2. 39 システム情報とログの収集
  8. 用語集
  9. A NVIDIA カードに対する GPU パススルー の設定
  10. B GNU ライセンス
ナビゲーション
適用先 openSUSE Leap 15.7

14 virsh を利用した仮想マシンの設定 Edit source

概要

VM ゲスト を設定するにあたっては、 仮想マシンマネージャ だけでなく virsh も使用することができます。 virsh は仮想マシン (VM) を管理するためのコマンドラインツールで、これを利用することで、 VM の状態の制御や設定の編集、他のホストへの移行などを行うことができます。下記の章では、 virsh を利用した管理の方法について説明しています。

14.1 VM の設定変更 Edit source

仮想マシンの設定ファイルは /etc/libvirt/qemu/ 内に XML 形式で保存されていて、下記のような内容になっているはずです:

例 14.1: XML 設定ファイルの例
<domain type='kvm'>
  <name>sles15</name>
  <uuid>ab953e2f-9d16-4955-bb43-1178230ee625</uuid>
  <memory unit='KiB'>2097152</memory>
  <currentMemory unit='KiB'>2097152</currentMemory>
  <vcpu placement='static'>2</vcpu>
  <os>
    <type arch='x86_64' machine='pc-q35-2.0'>hvm</type>
  </os>
  <features>...</features>
  <cpu mode='custom' match='exact' check='partial'>
    <model fallback='allow'>Skylake-Client-IBRS</model>
  </cpu>
  <clock>...</clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <pm>
    <suspend-to-mem enabled='no'/>
    <suspend-to-disk enabled='no'/>
  </pm>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type='file' device='disk'>...</disk>
  </devices>
  ...
</domain>

VM ゲスト の設定を変更する場合は、まずシャットオフ状態になっているかどうかを確認します:

> sudo virsh list --inactive

上記のコマンドの実行結果に編集対象の VM ゲスト が現れている場合は、そのまま設定を変更してかまいません:

> sudo virsh edit VM_名

なお設定の保存時には、 virsh が RelaxNG スキーマを利用して設定内容のチェックを行います。

14.2 マシンの種類の変更 Edit source

virt-install ツールを利用してインストールを行った場合、 VM ゲスト のマシンの種類は、既定で pc-q35 になります。マシンの種類も VM ゲスト の設定ファイル内に含まれていて、 type というタグ要素内に書かれています:

<type arch='x86_64' machine='pc-q35-2.3'>hvm</type>

下記の手順では、例としてマシンの種類を q35 に変更します。 q35 という値は Intel* 社のチップセットを表す文字列で、 PCIe が含まれているほか、最大で 12 個までの USB ポートに対応し、 SATAIOMMU にも対応しています。

手順 14.1: マシンの種類の変更
  1. まずは VM ゲスト が停止していることを確認します:

    > sudo virsh list --inactive
    Id    名前                           状態
    ----------------------------------------------------
    -     sles15                         シャットオフ
  2. この VM ゲスト に対する設定を編集します:

    > sudo virsh edit sles15
  3. タグ内の machine という属性の値を、 pc-q35-2.0 に変更します:

    <type arch='x86_64' machine='pc-q35-2.0'>hvm</type>
  4. VM ゲスト を起動し直します:

    > sudo virsh start sles15
  5. マシンの種類が変更されていることを確認します。 VM ゲスト を起動してログインし、下記のコマンドを実行します:

    > sudo dmidecode | grep Product
    Product Name: Standard PC (Q35 + ICH9, 2009)
ヒント
ヒント: マシンの種類を更新した際の推奨事項について

ホストシステム側の QEMU のバージョンをアップグレードした場合 (たとえば VM ホストサーバ のディストリビューションのバージョンをアップグレードした場合など) 、 VM ゲスト 側のマシンの種類についても、利用可能な最新版にアップグレードするようにしてください。どのような種類を指定できるのかを知りたい場合は、 VM ホストサーバ 側で qemu-system-x86_64 -M help を実行してください。

また、既定で使用されるマシン種類 (pc-i440fx) なども、定期的に更新が行われます。お使いの VM ゲスト が今も pc-i440fx-1.X のマシン種類で動作している場合は、 pc-i440fx-2.X にアップグレードすることを強くお勧めします。これにより、最新の更新内容を受けることができることになり、不具合の修正や将来の互換性維持に役立つことになります。

14.3 ハイパーバイザ機能の設定 Edit source

libvirt はほとんどの状況下において適切なハイパーバイザ設定を行うよう自動設定されていますが、必要に応じて特定の機能を有効化したり無効化したりすることができます。たとえば Xen の既定では PCI パススルーが有効化されていませんが、 passthrough を設定することで有効化することができます。ハイパーバイザの機能は virsh を利用して、 VM ゲスト の設定ファイル内に <features> 要素を指定して設定します。たとえば Xen での PCI パススルー機能を有効化するには、下記のように設定します:

> sudo virsh edit sle15sp1
 <features>
    <xen>
      <passthrough/>
    </xen>
 </features>

あとは設定を保存して VM ゲスト を再起動してください。

詳しくは https://libvirt.org/formatdomain.html#elementsFeatures (英語) にある libvirt の Domain XML format 内の Hypervisor features の章をお読みください。

14.4 CPU の設定 Edit source

virsh を利用することで、 VM ゲスト に対して提供される様々な仮想 CPU の設定を変更することができます。 VM ゲスト に割り当てる CPU 数の現在値や最大値のほか、 CPU のモデルや機能セットなども設定することができます。下記の章では、 VM ゲスト で一般的な CPU 設定を変更する方法を説明しています。

14.4.1 CPU 数の設定 Edit source

VM ゲスト の CPU の割当数は、 /etc/libvirt/qemu/ にある XML 設定ファイル内の vcpu タグ内に書かれています:

<vcpu placement='static'>1</vcpu>

上記の例では、 VM ゲスト 側には CPU を 1 つだけ割り当てていることになります。下記の手順では、 VM ゲスト 側への CPU の割当数の変更方法を説明しています:

  1. まずは VM ゲスト が停止していることを確認します:

    > sudo virsh list --inactive
    Id    名前                           状態
    ----------------------------------------------------
    -     sles15                         シャットオフ
  2. 既存の VM ゲスト に対する設定を編集します:

    > sudo virsh edit sles15
  3. CPU の割当数を変更して保存します:

    <vcpu placement='static'>2</vcpu>
  4. VM ゲスト を起動し直します:

    > sudo virsh start sles15
  5. VM に対して割り当てられている CPU 数が変更されていることを確認します:

    > sudo virsh vcpuinfo sled15
    VCPU:           0
    CPU:            N/A
    State:          N/A
    CPU time        N/A
    CPU Affinity:   yy
    
    VCPU:           1
    CPU:            N/A
    State:          N/A
    CPU time        N/A
    CPU Affinity:   yy

VM ゲスト が動作中の場合であっても、c CPU 数を変更することができます。ただし、 VM ゲスト の起動時に設定した最大数までしかホットプラグ (活性接続) することができませんし、逆に減らす場合の最小数は 1 であることにも注意してください。下記の例では、現在の CPU 数である 2 を、あらかじめ設定しておいた最大値 4 に変更する手順を説明しています。

  1. まずは現時点での CPU 数を確認します:

    > sudo virsh vcpucount sles15 | grep live
    maximum      live           4
    current      live           2
  2. CPU 数の現在値 (使用可能な CPU 数) を 4 に変更します:

    > sudo virsh setvcpus sles15 --count 4 --live
  3. 最後に vcpu 数が 4 になっていることを確認します:

    > sudo virsh vcpucount sles15 | grep live
    maximum      live           4
    current      live           4
重要
重要: 255 個以上の CPU を設定する場合について

KVM を利用する場合、 255 個以上の CPU を VM ゲスト に設定することができます。ただし、 VM ゲスト の起動時に追加の設定を行っておく必要があります。具体的には ioapic の機能を調整し、 IOMMU デバイスを VM ゲスト に追加する必要があります。下記は 288 個の CPU を設定した場合の例です。

<domain>
 <vcpu placement='static'>288</vcpu>
 <features>
  <ioapic driver='qemu'/>
 </features>
 <devices>
  <iommu model='intel'>
   <driver intremap='on' eim='on'/>
  </iommu>
 </devices>
</domain>

14.4.2 CPU モデルの設定 Edit source

VM ゲスト に対して提示される CPU モデルの設定は、その中で動作する処理に影響します。既定の CPU モデルは host-model という設定値で、ホスト側の CPU モデルをそのまま VM ゲスト に提示する設定になります。

<cpu mode='host-model'/>

CPU モデルとして host-model を指定して VM ゲスト を起動すると、 libvirt はホストの CPU モデルをそのままコピーして VM ゲスト 側に対して提供するようになります。 VM ゲスト 側の定義にコピーされた CPU モデルと機能については、 virsh capabilities コマンドの出力で確認することができます。

それ以外にも、 host-passthrough という値を設定することもできます。

<cpu mode='host-passthrough'/>

CPU モデルとして host-passthrough を指定した場合は、 VM ゲスト に提供される CPU は VM ホストサーバ と全く同一になります。これは、 単純化された host-model CPU では提供されていない特別な機能を必要とする VM ゲスト を動作させる際には便利な設定です。ただし、この host-passthrough モデルの場合は、移行の柔軟性が低くなることに注意してください。具体的には、全く同一のハードウエア構成の VM ホストサーバ 間でのみ移行が可能となります。

このほか、 host-passthrough の CPU モデルを指定した場合で、特定の不要な機能のみを無効化したいような場合は、下記のように設定することもできます。下記の例では、ホスト側の CPU と全く同一のモデルでありながら、 vmx 機能のみを無効化しています。

<cpu mode='host-passthrough'>
  <feature policy='disable' name='vmx'/>
  </cpu>

また、 custom CPU モデルを指定することで、 CPU モデルを標準化し、クラスタ内にある異なる CPU 構成のホスト間の移行を可能にすることができます。たとえばクラスタ内に Nehalem, IvyBridge, SandyBridge の各 CPU モデルが混在しているような場合、 VM ゲスト で custom CPU モデルを指定することで、 VM ゲスト の CPU モデルを Nehalem に統一することができます。

<cpu mode='custom' match='exact'>
  <model fallback='allow'>Nehalem</model>
  <feature policy='require' name='vme'/>
  <feature policy='require' name='ds'/>
  <feature policy='require' name='acpi'/>
  <feature policy='require' name='ss'/>
  <feature policy='require' name='ht'/>
  <feature policy='require' name='tm'/>
  <feature policy='require' name='pbe'/>
  <feature policy='require' name='dtes64'/>
  <feature policy='require' name='monitor'/>
  <feature policy='require' name='ds_cpl'/>
  <feature policy='require' name='vmx'/>
  <feature policy='require' name='est'/>
  <feature policy='require' name='tm2'/>
  <feature policy='require' name='xtpr'/>
  <feature policy='require' name='pdcm'/>
  <feature policy='require' name='dca'/>
  <feature policy='require' name='rdtscp'/>
  <feature policy='require' name='invtsc'/>
  </cpu>

libvirt の CPU モデルとトポロジのオプションについて、詳しくは https://libvirt.org/formatdomain.html#cpu-model-and-topology (英語) にある CPU model and topology のドキュメンテーションをお読みください。

14.5 起動オプションの変更 Edit source

VM ゲスト の起動メニューの設定は os 要素内に含まれ、下記のような内容になっています:

<os>
  <type>hvm</type>
  <loader>readonly='yes' secure='no' type='rom'/>/usr/lib/xen/boot/hvmloader</loader>
  <nvram template='/usr/share/OVMF/OVMF_VARS.fd'/>/var/lib/libvirt/nvram/guest_VARS.fd</nvram>
  <boot dev='hd'/>
  <boot dev='cdrom'/>
  <bootmenu enable='yes' timeout='3000'/>
  <smbios mode='sysinfo'/>
  <bios useserial='yes' rebootTimeout='0'/>
  </os>

上記の例では、 hdcdrom という 2 つのデバイスが有効化されています。設定の順序は実際の起動順序にも影響し、上記の例では cdrom よりも前に hd の起動が試されることになります。

14.5.1 起動順序の変更 Edit source

VM ゲスト の起動順序は、 XML 設定ファイル内での出現順序で表されます。つまり、デバイスのタグを入れ替えることで起動順序を変更できることになります。

  1. VM ゲスト の XML 設定ファイルを開きます。

    > sudo virsh edit sles15
  2. デバイスの順序を入れ替えます。

    ...
    <boot dev='cdrom'/>
    <boot dev='hd'/>
    ...
  3. VM ゲスト の BIOS 設定内の起動メニューを確認して、起動順序が変更されていることを確認します。

14.5.2 直接カーネル起動の使用 Edit source

直接カーネル起動を使用することで、ホスト内に保存されているカーネルと initrd を利用して起動を行うことができます。この場合は、 kernelinitrd のタグを追加してファイルを指定します:

<os>
    ...
  <kernel>/root/f8-i386-vmlinuz</kernel>
  <initrd>/root/f8-i386-initrd</initrd>
    ...
<os>

直接カーネル起動を有効化するには、下記の手順を実施します:

  1. VM ゲスト の XML 設定を開きます:

    > sudo virsh edit sles15
  2. os タグ内に kernel タグを追加し、ホスト側でのカーネルファイルのパスを指定します:

    ...
    <kernel>/root/f8-i386-vmlinuz</kernel>
    ...
  3. 同様に initrd タグを追加し、ホスト内での initrd ファイルのパスを指定します:

    ...
    <initrd>/root/f8-i386-initrd</initrd>
    ...
  4. あとは VM を起動すると、新しいカーネルでの起動が行われます:

    > sudo virsh start sles15

14.6 メモリ割り当ての設定 Edit source

VM ゲスト に対するメモリ割当量の設定変更は、 virsh でも行うことができます。メモリ割当量は memory 要素内に書かれていて、この中に VM ゲスト の起動時の最大メモリ割当量を設定します。また currentMemory という任意指定の要素を指定することで、 VM ゲスト に割り当てる実際のメモリ量を指定することもできます。なお、 currentMemory の値を memory よりも少なくしておくことで、 VM ゲスト の動作中にメモリ量を増やす (バルーン と呼びます) ことができます。また、 currentMemory の指定を省略すると、 memory と同じ値を指定したものと見なされます。

なお、 VM ゲスト の設定を編集することで、メモリ設定を変更することができますが、変更した内容は次回の起動時まで反映されないことに注意してください。下記の手順では、 VM ゲスト に対して起動時に 4GB のメモリを割り当て、あとから 8GB まで増やす場合の例を示しています:

  1. VM ゲスト の XML 設定を開きます:

    > sudo virsh edit sles15
  2. memory タグを検索して、メモリの割当量を 8GB に変更します:

    ...
    <memory unit='KiB'>8388608</memory>
    ...
  3. currentMemory 要素が存在していない場合は memory 要素内に currentMemory 要素を追加します。既に存在している場合は、値のみを変更します:

    [...]
    <memory unit='KiB'>8388608</memory>
    <currentMemory unit='KiB'>4194304</currentMemory>
    [...]

VM ゲスト の動作中にメモリ割当量を変更したい場合は、 setmem サブコマンドを使用します。下記の手順では、メモリの割り当てを 8GB まで増やしています:

  1. 現時点での VM ゲスト のメモリ設定を表示します:

    > sudo virsh dominfo sles15 | grep memory
    Max memory:     8388608 KiB
    Used memory:    4194608 KiB
  2. 8GB までメモリ量を増やします:

    > sudo virsh setmem sles15 8388608
  3. 変更が反映されたことを確認します:

    > sudo virsh dominfo sles15 | grep memory
    Max memory:     8388608 KiB
    Used memory:    8388608 KiB
重要
重要: 巨大なメモリを使用する VM ゲスト の場合について

4TB 以上のメモリを必要とする VM ゲスト を動作させる場合、現時点では host-passthrough CPU モードを使用するか、 host-model または custom CPU モードを使用する場合は仮想 CPU アドレスサイズを明示的に指定しなければなりません。これは、後者 2 つの CPU モードの場合、既定の仮想 CPU アドレスサイズでは 4TB 以上のメモリに対して不適切な設定になってしまっているためです。下記の例では、 host-model CPU モードを使用する際の VM ホストサーバ の物理 CPU アドレスサイズの設定方法を示しています。

[...]
<cpu mode='host-model' check='partial'>
<maxphysaddr mode='passthrough'>
</cpu>
[...]

仮想 CPU アドレスサイズに関する詳細は、 https://libvirt.org/formatdomain.html#cpu-model-and-topology (英語) にある CPU model and topology (CPU モデルとトポロジ) 内の maxphysaddr オプションの説明をお読みください。

14.7 PCI デバイスの追加 Edit source

virsh を利用して VM ゲスト に対して PCI デバイスを追加するには、下記の手順を実施します:

  1. まずは VM ゲスト に割り当てるホスト側の PCI デバイスを識別します。下記の例では、 DEC 社のネットワークカードをゲストに割り当てようとしています:

    > sudo lspci -nn
    [...]
    03:07.0 Ethernet controller [0200]: Digital Equipment Corporation DECchip \
    21140 [FasterNet] [1011:0009] (rev 22)
    [...]

    デバイス ID (上記の例では 03:07.0) をメモしておきます。

  2. virsh nodedev-dumpxml ID を実行して、デバイスに関する詳細情報を取得します。ここで ID にはデバイス ID (この例では 03:07.0 ) を指定しますが、コロン (:) とピリオド (.) をアンダースコア (_) に置き換え、かつ pci_0000_ という前置きを置いた値 (この例では pci_0000_03_07_0 になります) を指定して実行します:

    > sudo virsh nodedev-dumpxml pci_0000_03_07_0
    <device>
      <name>pci_0000_03_07_0</name>
      <path>/sys/devices/pci0000:00/0000:00:14.4/0000:03:07.0</path>
      <parent>pci_0000_00_14_4</parent>
      <driver>
        <name>tulip</name>
      </driver>
      <capability type='pci'>
        <domain>0</domain>
        <bus>3</bus>
        <slot>7</slot>
        <function>0</function>
        <product id='0x0009'>DECchip 21140 [FasterNet]</product>
        <vendor id='0x1011'>Digital Equipment Corporation</vendor>
        <numa node='0'/>
      </capability>
    </device>

    出力された値の中から、 domain, bus, function の値 (上記太字部分) をメモしておきます。

  3. VM ゲスト に対して割り当てを行う前に、 VM ホストサーバ 側からの切り離しを行います:

    > sudo virsh nodedev-detach pci_0000_03_07_0
      Device pci_0000_03_07_0 detached
    ヒント
    ヒント: 多機能型 PCI デバイスについて

    FLR (Function Level Reset; 機能レベルリセット) や PM (Power Management; 電源管理) リセットに対応していない多機能型の PCI デバイスを使用している場合、 VM ゲスト 側に割り当てるには、 VM ホストサーバ 側で全ての機能を切り離す必要があります。また、セキュリティ上の理由から、デバイス全体をリセットする必要があります。 libvirt では、 VM ホストサーバ 側もしくは他の VM ゲスト 側で機能の一部が使用されている場合、その割り当てを拒否するようになっています。

  4. domain, bus, slot, function の各値を 16 進数に変換します。上記の例では、 domain = 0, bus = 3, slot = 7, function = 0 ですので、下記のようなコマンドを実行して変換を行います。なお、指定の順序を間違えないようにしてください:

    > printf "<address domain='0x%x' bus='0x%x' slot='0x%x' function='0x%x'/>
    " 0 3 7 0

    上記を実行すると、下記のように出力されるはずです:

    <address domain='0x0' bus='0x3' slot='0x7' function='0x0'/>
  5. あとは対象の VM ゲスト の設定ファイルを virsh edit で編集して、上記の手順の出力結果を <devices> タグ内に貼り付けます:

    <hostdev mode='subsystem' type='pci' managed='yes'>
      <source>
        <address domain='0x0' bus='0x03' slot='0x07' function='0x0'/>
      </source>
    </hostdev>
    ヒント
    ヒント: managedunmanaged の違いについて

    libvirt では、 PCI デバイスの処理方法を 2 種類 (managedunmanaged) 用意しています。 managed の場合、 libvirt は必要に応じて既存のドライバからデバイスを切り離す処理からデバイスのリセット、仮想マシンを起動する前の vfio-pci への接続など、全ての詳細処理を制御するようになります。また、仮想マシンが終了した場合や仮想マシンからデバイスを切り離した場合、 libvirtvfio-pci への接続を解除して元のドライバに再接続する処理までを行うようになります。逆に unmanaged の場合、 libvirt はそれらの処理を行わず、仮想マシンにハードウエアを割り当てる際と、仮想マシンからハードウエアを切り離す際には、それらの処理をユーザ側で行わなければなりません。

    上記の例では managed='yes' を指定しているため、 managed を選択していることになります。 unmanaged に切り替えたい場合は、これを managed='no' に変更してください。なお、この場合は virsh nodedev-detachvirsh nodedev-reattach のコマンドを利用して、対応するドライバに対する処理を行う必要があります。具体的には、 VM ゲスト を起動する前に virsh nodedev-detach pci_0000_03_07_0 を実行してホスト側から切り離し、終了後には virsh nodedev-reattach pci_0000_03_07_0 を実行して、ホスト側で認識できるように再設定する必要があります。

  6. ホスト側で SELinux が動作している場合は、 VM ゲスト をシャットダウンして SELinux を無効化します。

    > sudo setsebool -P virt_use_sysfs 1
  7. VM ゲスト を起動すると、 VM ゲスト から割り当てられた PCI デバイスにアクセスできるようになります:

    > sudo virsh start sles15
重要
重要: SLES11 SP4 の KVM ゲストについて

新しい QEMU マシンタイプ (pc-i440fx-2.0 もしくはそれ以降) を設定した SLES 11 SP4 KVM ゲストの場合、ゲスト内では既定で acpiphp モジュールが読み込まれません。このモジュールはディスクやネットワークデバイスのホットプラグ (活性接続) を行うために読み込んでおかなければならないモジュールですので、必要であれば modprobe acpiphp コマンドを実行して読み込んでください。なお、 /etc/modprobe.conf.local ファイル内に install acpiphp /bin/true の行を追加すると、システムの起動時に自動読み込みを行うことができます。

重要
重要: QEMU Q35 マシンタイプを使用する KVM ゲストについて

QEMU Q35 マシンタイプを使用する KVM マシンの場合、 1 つの pcie-root コントローラと 7 つの pcie-root-port コントローラからなる PCI トポロジを構成します。 pcie-root コントローラはホットプラグ (活性接続) には対応しませんが、 pcie-root-port コントローラはそれぞれ 1 つの PCIe デバイスのホットプラグに対応します。 PCI コントローラ自身はホットプラグに対応していませんので、 7 つ以上の PCIe デバイスのホットプラグが必要となる場合、あらかじめ pcie-root-port コントローラを追加しておくようにしてください。また pcie-to-pci-bridge コントローラを追加することで、古い PCI デバイスのホットプラグを実現することもできます。 QEMU のマシンタイプ別の PCI トポロジの詳細について、詳しくは https://libvirt.org/pci-hotplug.html (英語) をお読みください。

14.7.1 IBM Z 向けの PCI パススルー Edit source

IBM Z をサポートするため、 QEMU は追加の属性を設定するために PCI 表記を拡張しています。具体的には uidfid という 2 種類の属性が libvirt 仕様内の <zpci/> に追加されています。 uid はユーザ定義の識別値を、 fid の PCI 機能の識別値をそれぞれ設定します。これらの属性はいずれも任意指定で、何も指定しない場合は矛盾の無い値を自動的に生成します。

ドメイン設定内に zPCI 属性を含めたい場合は、下記の例を参考にしてください:

<controller type='pci' index='0' model='pci-root'/>
<controller type='pci' index='1' model='pci-bridge'>
  <model name='pci-bridge'/>
  <target chassisNr='1'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'>
    <zpci uid='0x0001' fid='0x00000000'/>
  </address>
</controller>
<interface type='bridge'>
  <source bridge='virbr0'/>
  <model type='virtio'/>
  <address type='pci' domain='0x0000' bus='0x01' slot='0x01' function='0x0'>
    <zpci uid='0x0007' fid='0x00000003'/>
  </address>
</interface>

14.8 USB デバイスの追加 Edit source

USB デバイスを VM ゲスト に割り当てるには、 virsh を使用して下記のように実施します:

  1. VM ゲスト に接続されている USB デバイスを識別します:

    > sudo lsusb
    [...]
    Bus 001 Device 003: ID 0557:2221 ATEN International Co., Ltd Winbond Hermon
    [...]

    出力された ID をメモしておきます。上記の例では、製造元 ID が 0557 、製品 ID が 2221 となります。

  2. 仮想マシンに対して virsh edit を実行し、下記の内容を <devices> タグ内に追加します。このとき、 vendor と product の箇所にそれぞれメモした値を指定します:

    <hostdev mode='subsystem' type='usb'>
      <source startupPolicy='optional'>
       <vendor id='0557'/>
       <product id='2221'/>
      </source>
    </hostdev>
    ヒント
    ヒント: 製造元 (vendor) と製品 (product) の指定ではなく、デバイスのアドレス (address) を設定する方法について

    <vendor/> および <product/> の ID を指定する方法のほかにも、 14.7項 「PCI デバイスの追加」 で PCI デバイスを割り当てる際の説明と同様に、 <address/> タグを利用して割り当てる方法もあります。

  3. ホスト内で SELinux が動作している場合は、 VM ゲスト をシャットダウンして SELinux を無効化します。

    > sudo setsebool -P virt_use_sysfs 1
  4. VM ゲスト を起動すると、 VM ゲスト から割り当てられた PCI デバイスにアクセスできるようになります:

    > sudo virsh start sles15

14.9 SR-IOV デバイスの追加 Edit source

Single Root I/O Virtualization ( SR-IOV ) に対応した PCIe デバイスは、リソースを複製することができるため、複数のデバイスとして振る舞うことができます。複製されたリソースは 擬似デバイス として、 VM ゲスト への割り当てを行うことができます。

SR-IOV は Peripheral Component Interconnect Special Interest Group (PCI-SIG) が作成した工業仕様で、物理機能 (Physical Functions (PF)) と仮想機能 (Virtual Functions (VF)) を提供しています。 PF はデバイスを管理したり設定したりするための完全な PCIe 機能で、データの移動も行うことができます。それに対して VF 側には管理部分が提供されておらず、データの移動と設定機能の一部のみが提供されています。 VF は全ての PCIe 機能を持っているわけではないので、ホスト側のオペレーティングシステムもしくは ハイパーバイザSR-IOV に対応し、 VF へのアクセスと初期化を行わなければなりません。論理上の VF の最大数は、 1 デバイスあたり 256 個まで (たとえば 2 ポートのイーサネットカードであれば 512 個) になります。実際には各 VF がリソースを消費してしまうことから、この最大値はもっとずっと小さくなります。

14.9.1 要件 Edit source

SR-IOV を使用するには、下記の要件を全て満たさなければなりません:

  • SR-IOV に対応したネットワークカードを用意すること (openSUSE Leap ではネットワークカードのみに対応しています) 。

  • AMD64/Intel 64 でハードウエア仮想化 (AMD-V もしくは Intel VT-x) に対応していること。

  • デバイスの割り当て (AMD-Vi もしくは Intel VT-d) に対応したチップセットであること。

  • libvirt 0.9.10 もしくはそれ以降が存在すること。

  • ホストシステム内で SR-IOV ドライバが読み込まれ、設定されていること。

  • ホスト側の設定が 重要: VFIO および SR-IOV の要件について に示されている要件を満たしていること。

  • VM ゲスト に割り当てる予定の VF の PCI アドレスの一覧を用意していること。

ヒント
ヒント: デバイスが SR-IOV に対応しているかどうかの確認方法

デバイスが SR-IOV に対応しているかどうかは、 lspci -v を実行して表示される情報から判断することができます。 SR-IOV に対応するデバイスである場合、下記のような表示が現れるはずです:

Capabilities: [160 v1] Single Root I/O Virtualization (SR-IOV)
注記
注記: VM ゲスト の作成時における SR-IOV デバイスの追加について

初期設定時に VM ゲスト に SR-IOV デバイスを追加する場合は、あらかじめ 14.9.2項 「SR-IOV ホストドライバの読み込みと設定」 で説明している手順で設定を済ませておく必要があります。

14.9.2 SR-IOV ホストドライバの読み込みと設定 Edit source

VF にアクセスして準備を行うには、 SR-IOV 対応のドライバをホスト側のシステムに読み込んでおく必要があります。

  1. ドライバを読み込む前に、まずは lspci を実行して、カードが正しく検出されていることを確認します。下記の例では、 lspci がデュアルポートの Intel 82576NS ネットワークカードを検出しています:

    > sudo /sbin/lspci | grep 82576
    01:00.0 Ethernet controller: Intel Corporation 82576NS Gigabit Network Connection (rev 01)
    01:00.1 Ethernet controller: Intel Corporation 82576NS Gigabit Network Connection (rev 01)
    04:00.0 Ethernet controller: Intel Corporation 82576NS Gigabit Network Connection (rev 01)
    04:00.1 Ethernet controller: Intel Corporation 82576NS Gigabit Network Connection (rev 01)

    カードが検出されていない場合、 BIOS/EFI の設定でハードウエア仮想化の設定が有効化されていないことが考えられます。ハードウエア仮想化機能が有効化されているか同化を調べるには、ホスト側の BIOS 設定をご確認ください。

  2. 次に lsmod を実行して、 SR-IOV ドライバが読み込まれているかどうかを確認します。下記の例では igb ドライバ (Intel 82576NS ネットワークカード向けのドライバです) が読み込まれているかどうかの確認になります。下記のように表示されれば、ドライバが既に読み込まれていることになります。何も出力を返さない場合は、ドライバが読み込まれていないことになります。

    > sudo /sbin/lsmod | egrep "^igb "
    igb                   185649  0
  3. ドライバが既に読み込まれている場合は、この手順を飛ばしてください。 SR-IOV ドライバが読み込まれていない場合は、あらかじめ SR-IOV 非対応のドライバの読み込みを解除する必要があります。読み込みを解除するには、 rmmod コマンドをお使いください。下記の例では、 Intel 82576NS ネットワークカード向けの SR-IOV 非対応ドライバの読み込みを解除しています:

    > sudo /sbin/rmmod igbvf
  4. あとは modprobe を利用して、 SR-IOV 対応のドライバを読み込みます。このとき、 VF パラメータ ( max_vfs ) を必ず指定してください:

    > sudo /sbin/modprobe igb max_vfs=8

代わりの方法として、 SYSFS を介してドライバを読み込む方法もあります:

  1. イーサネットデバイスの一覧を表示して、物理 NIC の PCI ID を確認します:

    > sudo lspci | grep Eth
    06:00.0 Ethernet controller: Emulex Corporation OneConnect NIC (Skyhawk) (rev 10)
    06:00.1 Ethernet controller: Emulex Corporation OneConnect NIC (Skyhawk) (rev 10)
  2. VF を有効化するには、 sriov_numvfs パラメータに対して必要な VF 数を書き込みます:

    > sudo echo 1 > /sys/bus/pci/devices/0000:06:00.1/sriov_numvfs
  3. VF NIC が読み込まれたことを確認します:

    > sudo lspci | grep Eth
    06:00.0 Ethernet controller: Emulex Corporation OneConnect NIC (Skyhawk) (rev 10)
    06:00.1 Ethernet controller: Emulex Corporation OneConnect NIC (Skyhawk) (rev 10)
    06:08.0 Ethernet controller: Emulex Corporation OneConnect NIC (Skyhawk) (rev 10)
  4. 設定可能な VF の最大数を知りたい場合は、下記のようなコマンドを入力して実行します:

    > sudo lspci -vvv -s 06:00.1 | grep 'Initial VFs'
                           Initial VFs: 32, Total VFs: 32, Number of VFs: 0,
    Function Dependency Link: 01
  5. /etc/systemd/system/before.service ファイルを作成して、システムの起動時に SYSFS 経由で VF を自動設定するように設定します:

    [Unit]
    Before=
    [Service]
    Type=oneshot
    RemainAfterExit=true
    ExecStart=/bin/bash -c "echo 1 > /sys/bus/pci/devices/0000:06:00.1/sriov_numvfs"
    # 注意: 実行ファイルはシェル経由ではなく、直接実行されます。詳しい書式については、
    # systemd.service と systemd.unit のマニュアルページをお読みください
    [Install]
    # このサービスを開始するターゲットの指定
    WantedBy=multi-user.target
    #WantedBy=graphical.target
  6. また VM を起動する前に、もう 1 つのサービスファイル ( after-local.service ) を作成し、 NIC の切り離しを行うスクリプト /etc/init.d/after.local を実行するように設定します。これを行わないと、 VM の起動が失敗するようになってしまいます:

    [Unit]
    Description=/etc/init.d/after.local Compatibility
    After=libvirtd.service
    Requires=libvirtd.service
    [Service]
    Type=oneshot
    ExecStart=/etc/init.d/after.local
    RemainAfterExit=true
    
    [Install]
    WantedBy=multi-user.target
  7. 上記の内容を /etc/systemd/system にコピーします。

    #! /bin/sh
    # ...
    virsh nodedev-detach pci_0000_06_08_0

    上記の内容を /etc/init.d/after.local に保存します。

  8. マシンを再起動したあと、手順の冒頭で実行した lspci コマンドを実行しなおし、 SR-IOV ドライバが読み込まれていることを確認します。 SR-IOV ドライバが正しく読み込まれていれば、下記のように VF 向けの追加の行が現れているはずです:

    01:00.0 Ethernet controller: Intel Corporation 82576NS Gigabit Network Connection (rev 01)
    01:00.1 Ethernet controller: Intel Corporation 82576NS Gigabit Network Connection (rev 01)
    01:10.0 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    01:10.1 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    01:10.2 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    [...]
    04:00.0 Ethernet controller: Intel Corporation 82576NS Gigabit Network Connection (rev 01)
    04:00.1 Ethernet controller: Intel Corporation 82576NS Gigabit Network Connection (rev 01)
    04:10.0 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    04:10.1 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    04:10.2 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    [...]

14.9.3 VM ゲスト に対する VF ネットワークデバイスの追加 Edit source

SR-IOV 対応のハードウエアの設定を VM ホストサーバ 内で正しく実施したあとは、 VM ゲスト に対して VF を追加していきます。これを行うには、まずいくつかのデータを収集しておく必要があります。

手順 14.2: 既存の VM ゲスト に対する VF ネットワークデバイスの追加

下記に示す手順は構成例となります。お使いの環境に合わせて各種のデータを変更して実行してください。

  1. virsh nodedev-list コマンドを実行して、割り当てる VF と対応する PF の PCI アドレスを取得します。 lspci の出力は 14.9.2項 「SR-IOV ホストドライバの読み込みと設定」 のようになります (たとえば 01:00.004:00.1 など) 。このアドレス情報のコロン (:) やドット (.) をアンダースコア (_) に変換し、冒頭に "pci_0000_" を付けたものが virsh で使用するアドレスとなります。たとえば lspci コマンドで "04:00.0" と出力された場合、 virsh のアドレスは "pci_0000_04_00_0" になります。下記の例では、 Intel 82576NS デュアルポートイーサネットカードでの PCI ID を取得しています:

    > sudo virsh nodedev-list | grep 0000_04_
    pci_0000_04_00_0
    pci_0000_04_00_1
    pci_0000_04_10_0
    pci_0000_04_10_1
    pci_0000_04_10_2
    pci_0000_04_10_3
    pci_0000_04_10_4
    pci_0000_04_10_5
    pci_0000_04_10_6
    pci_0000_04_10_7
    pci_0000_04_11_0
    pci_0000_04_11_1
    pci_0000_04_11_2
    pci_0000_04_11_3
    pci_0000_04_11_4
    pci_0000_04_11_5

    最初の 2 つの項目が PF を、残りの項目が VF を表しています。

  2. あとは virsh nodedev-dumpxml を実行して、追加したい VF の PCI ID を取得します:

    > sudo virsh nodedev-dumpxml pci_0000_04_10_0
    <device>
      <name>pci_0000_04_10_0</name>
      <parent>pci_0000_00_02_0</parent>
      <capability type='pci'>
        <domain>0</domain>
        <bus>4</bus>
        <slot>16</slot>
        <function>0</function>
        <product id='0x10ca'>82576 Virtual Function</product>
        <vendor id='0x8086'>Intel Corporation</vendor>
        <capability type='phys_function'>
          <address domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
        </capability>
      </capability>
    </device>

    次の手順では、下記のデータが必要となります:

    • <domain>0</domain>

    • <bus>4</bus>

    • <slot>16</slot>

    • <function>0</function>

  3. あとは一時的な XML ファイル (たとえば /tmp/vf-interface.xml) を作成して、既存の VM ゲスト に VF ネットワークデバイスを追加するのに必要なデータを記述していきます。このファイルを最も短く作成すると、下記のようになります:

    <interface type='hostdev'>1
     <source>
      <address type='pci' domain='0' bus='11' slot='16' function='0'2/>2
     </source>
    </interface>

    1

    VF は固定の MAC アドレスを取得しません。ホストが再起動されるたびに MAC アドレスが変更される形になります。この場合、 hostdev従来の方法を利用して ネットワークデバイスを追加すると、ホスト側の再起動が発生するたびに MAC アドレスが変わってしまうため、 VM ゲスト 側のネットワークデバイスを再設定する必要が生じてしまいます。このような問題を回避するため、 libvirt では hostdev という値が提供されるようになり、これによってデバイスの割り当て にネットワーク固有のデータを設定できるようになっています。

    2

    以前の手順で取得したデータを指定します。

  4. デバイスが既にホスト側に割り当てられてしまっている場合、 VM ゲスト に対して割り当てることができなくなります。ゲストに対して割り当てたい場合は、下記のようにしてホスト側から切り離しを行ってください:

    > sudo virsh nodedev-detach pci_0000_04_10_0
  5. あとは既存の VM ゲスト に VF インターフェイスを追加します:

    > sudo virsh attach-device 仮想マシン名 /tmp/vf-interface.xml --オプション

    仮想マシン名 の箇所には VM ゲスト の名前のほか、 ID や UUID を指定することもできます。また、 --オプション の部分には下記を指定することができます:

    --persistent

    仮想マシンの XML 設定ファイルに対してデバイスを追加します。これに加えて、仮想マシンが動作中である場合、ホットプラグで接続することもできます。

    --config

    仮想マシンの XML 設定ファイルに対してデバイスを追加します。仮想マシンが動作中の場合、ホットプラグは行われず、次回の再起動以降に現れるようになります。

    --live

    仮想マシンの動作中の状態にのみ適用します。仮想マシンが動作中ではない場合、この操作は失敗します。 XML ファイル内には保存されませんので、 VM ゲスト の再起動を行うとデバイスが消えてしまいます。

    --current

    仮想マシンの現在の状態に反映させます。仮想マシンが動作中ではない場合、デバイスを XML 設定ファイル内に追加し、次回の起動時に現れるようになります。仮想マシンが動作中である場合、デバイスはホットプラグで追加されますが、 XML 設定ファイルには追加されないようになります。

  6. VF インターフェイスを切り離すには、 virsh detach-device コマンドを使用します。オプション類は上記と同じです。

14.9.4 プールからの動的な VF の割り当て Edit source

14.9.3項 「VM ゲスト に対する VF ネットワークデバイスの追加」 の手順に従って VM ゲスト の設定内に VF の PCI アドレスを指定してしまうと、他のホストへの移行が難しくなってしまいます。移行先のホストで移行元と同じ PCI バスに同じハードウエアが搭載されていれば問題はありませんが、そうでない場合は VM ゲスト の設定を変更しなければならなくなってしまいます。

このような場合は、 SR-IOV の全ての VF を含むデバイスプールを設定し、 libvirt 側から使用できるようにする方法があります。 VM ゲスト では起動時にこのプールを参照し、空いているいずれかのデバイスを動的に使用することができます。 VM ゲスト を停止すると VF はプール内に戻されますので、他のゲストから使用できるようになります。

14.9.4.1 VM ホストサーバ 内の VF プールを利用したネットワークの定義 Edit source

下記の例では、ホスト側で eth0 のネットワークインターフェイスが割り当てられている PF に対して、それに結びつく全ての SR-IOV デバイスである VF のプールを作成しています:

<network>
  <name>passthrough</name>
    <forward mode='hostdev' managed='yes'>
      <pf dev='eth0'/>
    </forward>
  </network>

このネットワークインターフェイスをホスト側で使用する場合は、上記のコードをファイルに保存 (例: /tmp/passthrough.xml) したあと、下記のコマンドを実行してください。なお、上記の eth0 の箇所はお使いの環境内の SR-IOV デバイスの PF に置き換えてください:

> sudo virsh net-define /tmp/passthrough.xml
> sudo virsh net-autostart passthrough
> sudo virsh net-start passthrough

14.9.4.2 プールから VF を使用するための VM ゲスト 側の設定 Edit source

下記の VM ゲスト のデバイスインターフェイス定義は、 14.9.4.1項 「VM ホストサーバ 内の VF プールを利用したネットワークの定義」 で作成したプールから SR-IOV デバイスの VF を使用する設定です。 libvirt では、最初のゲストの起動時に、 PF に結びつけられた VF の一覧を自動的に取得します。

<interface type='network'>
  <source network='passthrough'>
</interface>

VF のプールからネットワークインターフェイスを使用するように設定した VM ゲスト を起動したあとは、 VF が正しく使用されていることを確認します。これを行うには、ホスト側で virsh net-dumpxml passthrough を実行します:

<network connections='1'>
  <name>passthrough</name>
  <uuid>a6a26429-d483-d4ed-3465-4436ac786437</uuid>
  <forward mode='hostdev' managed='yes'>
    <pf dev='eth0'/>
    <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>

14.10 接続されているデバイスの一覧表示 Edit source

virsh には VM ゲスト に接続されている全ての VM ホストサーバ のデバイスを一覧表示する機能はありませんが、指定した VM ゲスト に接続されているデバイスを一覧表示することはできます。具体的には下記のようなコマンドを入力して実行します:

virsh dumpxml VM_ゲスト名 | xpath -e /domain/devices/hostdev

たとえば下記のようになります:

> sudo virsh dumpxml sles12 | -e xpath /domain/devices/hostdev
Found 2 nodes:
-- NODE --
<hostdev mode="subsystem" type="pci" managed="yes">
  <driver name="xen" />
  <source>
    <address domain="0x0000" bus="0x0a" slot="0x10" function="0x1" />
  </source>
  <address type="pci" domain="0x0000" bus="0x00" slot="0x0a" function="0x0" />
  </hostdev>
-- NODE --
<hostdev mode="subsystem" type="pci" managed="yes">
  <driver name="xen" />
  <source>
    <address domain="0x0000" bus="0x0a" slot="0x10" function="0x2" />
  </source>
  <address type="pci" domain="0x0000" bus="0x00" slot="0x0b" function="0x0" />
</hostdev>
ヒント
ヒント: <interface type='hostdev'> で接続されている SR-IOV デバイスの一覧表示について

<interface type='hostdev'> を利用して VM ホストサーバ のデバイスに接続している SR-IOV デバイスの場合は、上記とは異なる XPath クエリを指定する必要があります:

virsh dumpxml VM_ゲスト名 | xpath -e /domain/devices/interface/@type

14.11 ストレージデバイスの設定 Edit source

ストレージデバイスは disk 内に記述します。通常、 disk タグには複数の属性を指定します。そのうち、下記に示す 2 つの属性が最も重要です:

  • type 属性: 仮想ディスクデバイスのソースを指定するための属性です。 file , block , dir , network , volume のいずれかを指定します。

  • device 属性: ディスクを VM ゲスト 側の OS に示す際の方法を指定する属性です。 floppy (フロッピィディスク), disk (ハードディスク), cdrom (CD-ROM) などがあります。

子要素として最も重要なものは下記のとおりです:

  • driver にはドライバとバスに関する情報を指定します。ここには VM ゲスト 側での処理方法などを指定します。

  • target には VM ゲスト 内でのデバイス名の設定が含まれます。ここには任意指定の bus 属性 (接続されているストレージバスに関する情報) を含むことができます。

VM ゲスト にストレージデバイスを追加するには、下記の手順を実施します:

  1. 既存の VM ゲスト に対する設定を編集します:

    > sudo virsh edit sles15
  2. devices 要素内に disk 要素を追加し、その中に typedevice の属性を追加します。

    <disk type='file' device='disk'>
  3. driver タグでは下記のような既定値を指定します:

    <driver name='qemu' type='qcow2'/>
  4. 新しい仮想ディスクデバイスのソースとなるディスクイメージを作成します:

    > sudo qemu-img create -f qcow2 /var/lib/libvirt/images/sles15.qcow2 32G
  5. あとは source タグでソースを指定します:

    <source file='/var/lib/libvirt/images/sles15.qcow2'/>
  6. VM ゲスト 内でのデバイス名を表す target タグを追加します。このとき、接続先を表す bus 属性も設定しておきます:

    <target dev='vda' bus='virtio'/>
  7. あとは仮想マシンを再起動します:

    > sudo virsh start sles15

これで、 VM ゲスト の OS 内から新しいストレージデバイスにアクセスできるようになります。

14.12 コントローラデバイスの設定 Edit source

libvirt では一般に、 VM ゲスト が使用する仮想デバイスの種類に応じて、自動的にコントローラを管理することができます。たとえば VM ゲスト 内に PCI デバイスや SCSI デバイスが存在する場合、 PCI や SCSI のコントローラは自動的に作成され管理されます。このほか、 libvirt ではハイパーバイザ固有のコントローラ、たとえば KVM の VM ゲスト であれば virtio-serial 、 Xen の VM ゲスト であれば xenbus を作成することができます。通常は既定のコントローラとそれに付随する設定で問題なく動作しますが、必要に応じてコントローラやその設定を調整することもできます。たとえば virtio-serial でより多くのポートが必要となっている場合や、 xenbus コントローラに対してより多くのメモリを割り当てたり、割り込みを多く割り当てたりするような場合がそれに該当します。

xenbus コントローラは、全ての Xen 準仮想化デバイスに対するコントローラとして動作する点でユニークなものであると言えます。また、 VM ゲスト に数多くのディスクやネットワークデバイスが接続されるような場合には、コントローラに対してもメモリを多く割り当てる必要があるかもしれません。 Xen の max_grant_frames 属性は許可するフレームの数、もしくは共有メモリのブロック数を指定しますが、これはそれぞれの VM ゲスト に対する xenbus コントローラに対して割り当てられます。

既定値は 32 で、ほとんどの環境において十分な値ではありますが、 I/O デバイスの多い VM ゲスト や I/O 負荷の高いシステムでは、フレームの枯渇によって性能が落ちることがあります。このような場合、 xen-diag コマンドを利用して dom0 およびお使いの VM ゲスト の max_grant_frames の現在値および最大値を確認してください。なお、ゲストは動作中でなければなりません:

> sudo virsh list
 Id   Name             State
--------------------------------
 0    Domain-0         running
 3    sle15sp1         running

 > sudo xen-diag gnttab_query_size 0
domid=0: nr_frames=1, max_nr_frames=256

> sudo xen-diag gnttab_query_size 3
domid=3: nr_frames=3, max_nr_frames=32

上記では、 sle15sp1 のゲストは 32 フレームのうちの 3 フレームしか使用していません。性能面で何らかの問題がある場合や、フレーム数が不足している旨のログが記録されているような場合は、 virsh でフレーム数を増やしてください。具体的には、ゲスト側の設定ファイル内にある <controller type='xenbus' という行を探して、 maxGrantFrames という制御要素を追加します:

> sudo virsh edit sle15sp1
 <controller type='xenbus' index='0' maxGrantFrames='40'/>

設定を保存してゲストを再起動してください。これで設定が反映されます:

> sudo xen-diag gnttab_query_size 3
domid=3: nr_frames=3, max_nr_frames=40

maxGrantFrames と同様に、 xenbus コントローラには maxEventChannels という設定値も用意されています。それぞれのチャンネルは準仮想化された割り込みのような動作をするもので、許可するフレーム数と同時に、準仮想化ドライバ向けのデータ転送構造を構築するためのものです。仮想 CPU 数の多い VM ゲスト や多数の準仮想化デバイスが接続されている VM ゲスト の場合は、既定値である 1023 よりも大きい値を設定する必要があるかもしれません。 maxEventChannels は maxGrantFrames と同じように変更することができます:

> sudo virsh edit sle15sp1
 <controller type='xenbus' index='0' maxGrantFrames='128' maxEventChannels='2047'/>

詳しくは https://libvirt.org/formatdomain.html#elementsControllers (英語) にある libvirt Domain XML format マニュアルの中にある、 Controllers 章をお読みください。

14.13 ビデオデバイスの設定 Edit source

仮想マシンマネージャを利用した場合、ビデオデバイスのモデルのみを設定することができます。 VRAM の割り当てや 2D/3D のアクセラレーションの設定については、 XML の設定を編集することでしか設定することができません。

14.13.1 VRAM の割当量の変更 Edit source

  1. 既存の VM ゲスト に対する設定を編集します:

    > sudo virsh edit sles15
  2. VRAM に割り当てるサイズを変更するには、下記のように設定します:

    <video>
    <model type='vga' vram='65535' heads='1'>
    ...
    </model>
    </video>
  3. あとは仮想マシンマネージャを開いて、仮想マシン側に割り当てられた VRAM のサイズを確認してください。

14.13.2 2D/3D アクセラレーションの設定変更 Edit source

  1. 既存の VM ゲスト に対する設定を編集します:

    > sudo virsh edit sles15
  2. 2D/3D アクセラレーション機能を有効化/無効化するには、それぞれ accel3d もしくは accel2d の設定を変更します:

    <video>
     <model>
      <acceleration accel3d='yes' accel2d='no'>
     </model>
    </video>
ヒント
ヒント: 2D/3D アクセラレーションの有効化について

2D/3D アクセラレーション機能を使用するには、 virtio もしくは vbox ビデオデバイスを使用する必要があります。それ以外のビデオデバイスである場合は、機能を有効化することができません。

14.14 ネットワークデバイスの設定 Edit source

本章では、 virsh を利用して仮想ネットワークデバイスを設定するための方法について説明しています。

libvirt のネットワークインターフェイス仕様について、詳しくは https://libvirt.org/formatdomain.html#elementsDriverBackendOptions をお読みください。

14.14.1 マルチキュー型の virtio-net によるネットワーク性能の強化 Edit source

マルチキュー型の virtio-net 機能を使用することで、 VM ゲスト の仮想 CPU を複数個同時に使用することができるようになります。これにより、ネットワークの性能を改善することができるようになります。一般的な情報については 34.3.3項 「マルチキュー型 virtio-net を利用したネットワーク性能の強化」 をお読みください。

特定の VM ゲスト に対して virtio-net のマルチキュー設定を行うには、 14.1項 「VM の設定変更」 で示している手順で XML ファイルを編集します。具体的には、下記の箇所を修正します:

<interface type='network'>
 [...]
 <model type='virtio'/>
 <driver name='vhost' queues='キュー数'/>
</interface>

14.15 VM ホストサーバ のネットワークインターフェイスを共有するための macvtap の使用 Edit source

macvtap は VM ゲスト の仮想インターフェイスをホストのネットワークインターフェイスに直接結びつけるための方法です。 macvtap ベースのインターフェイスは VM ホストサーバ のネットワークインターフェイスを拡張するための仕組みで、同じイーサネットセグメント内で別の MAC アドレスを使用します。通常は VM ゲスト と VM ホストサーバ をそれぞれ同じスイッチに接続する形になります。

注記
注記: Linux ブリッジでは macvtap を使用することができない問題について

macvtap は対象のインターフェイスが Linux ブリッジに接続されている場合、使用することができません。 macvtap インターフェイスを作成する前に、ブリッジからインターフェイスを削除しておく必要があります。

注記
注記: macvtap を利用した VM ゲスト と VM ホストサーバ の通信

macvtap を使用すると、 VM ゲスト 同士のほか、ネットワーク内の他のホストとも通信を行うことができるようになります。ただし、 VM ゲスト が動作している VM ホストサーバ との間は、通信を行うことができません。これは macvtap の意図的な動作によるもので、 VM ホストサーバ の物理イーサネットが macvtap ブリッジに割り当てられているためです。 VM ゲスト からブリッジへのトラフィックはそのまま物理インターフェイスに送信され、 VM ホストサーバ の IP スタックに戻ることができないようになっています。これと同様に、 VM ホストサーバ の IP スタックからのトラフィックも物理インターフェイスにそのまま送信され、 VM ゲスト の macvtap に戻ることができなくなっています。

macvtap ベースの仮想ネットワークインターフェイスは libvirt でサポートされていて、インターフェイスの種類 (type) を direct にすることによって実現することができます。たとえば下記のようになります:

<interface type='direct'>
   <mac address='aa:bb:cc:dd:ee:ff'/>
   <source dev='eth0' mode='bridge'/>
   <model type='virtio'/>
   </interface>

macvtap の操作モードは、 mode 属性を設定することで制御することができます。下記の一覧には、設定可能な値とそれらの説明を示しています:

  • vepa : 全ての VM ゲスト パケットを外部ブリッジに送信します。同じ VM ホストサーバ 内の VM ゲスト を宛先とするパケットは、 VEPA 対応ブリッジによって VM ホストサーバ 側に戻される動作になります (現在のブリッジは一般に VEPA 対応ではありません) 。

  • bridge : 同じ VM ホストサーバ を宛先とするパケットは、ターゲットの macvtap デバイスに直接配信されるようになります。送信元と送信先のデバイスは、直接配送に対応する bridge モードである必要があります。いずれかのモードが vepa である場合は、 VEPA 対応ブリッジが必要になります。

  • private : 全てのパケットを外部ブリッジに送信し、外部のルータやゲートウエイから送信されたパケットは同じ VM ホストサーバ 内のターゲットの VM ゲスト にのみ配信されるようになります。この処理は送信元と送信先のいずれかがプライベートモードである場合の動作になります。

  • passthrough : ネットワークインターフェイスに対してさらなる力を与えるための特殊なモードです。全てのパケットはインターフェイスに転送され、 virtio VM ゲスト では MAC アドレスの変更やプロミスキャスモードに対応することで、インターフェイスのブリッジや VLAN インターフェイスの作成に対応するようになります。ただし、 passthrough モードではネットワークインターフェイスを共有することはできません。 VM ゲスト にインターフェイスを割り当てると、 VM ホストサーバ 側からは切り離されます。このような理由から、 SR-IOV 仮想機能は VM ゲスト の passthrough モードと比較されます。

14.16 メモリバルーンデバイスの無効化 Edit source

メモリバルーン機能は KVM では既定のオプションになっています。 VM ゲスト 側には明示的にデバイスが割り当てられるようになっていますので、 VM ゲスト の XML 設定ファイルには、メモリバルーンのタグを追加する必要はありません。何らかの理由で VM ゲスト のメモリバルーン機能を無効化したい場合は、下記のようにして model='none' を指定する必要があります:

<devices>
   <memballoon model='none'/>
</device>

14.17 マルチモニタ (デュアルヘッド) の設定 Edit source

libvirt では、 VM ゲスト に対して複数のモニタを接続してそれぞれにビデオ出力を行うことのできる、デュアルヘッド設定に対応しています。

重要
重要: Xen がサポート対象外である点について

Xen ハイパーバイザは、デュアルヘッド設定に対応していません。

手順 14.3: デュアルヘッドの設定
  1. 仮想マシンを動作させた状態で、 VM ゲスト 内に xf86-video-qxl パッケージがインストールされていることを確認します:

    > rpm -q xf86-video-qxl
  2. VM ゲスト をシャットダウンして、 14.1項 「VM の設定変更」 で示している手順で XML ファイルを変更します。

  3. このとき、仮想グラフィックカードの型式 (モデル) を 'qxl' にしてください:

    <video>
     <model type='qxl' ... />
  4. グラフィックカードの設定内にある heads パラメータを増やして、デュアルヘッドの設定を行います。たとえば既定値の 1 から 2 に増やします:

    <video>
     <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='2' primary='yes'/>
     <alias name='video0'/>
     <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
    </video>
  5. VNC ではなく、 Spice ディスプレイを使用するように仮想マシンを設定します:

    <graphics type='spice' port='5916' autoport='yes' listen='0.0.0.0'>
     <listen type='address' address='0.0.0.0'/>
    </graphics>
  6. 仮想マシンを起動して、 virt-viewer 経由でディスプレイに接続します。たとえば下記のように入力して実行します:

    > virt-viewer --connect qemu+ssh://ユーザ名@ホスト名/system
  7. VM の一覧の中から設定を変更した仮想マシンを選択して、 接続 を押します。

  8. VM ゲスト 内でグラフィカルサブシステム (Xorg) が読み込まれたら、 表示 › ディスプレイ › ディスプレイ 2 を選択すると、 2 つめのモニタの出力を表示することができるようになります。

14.18 IBM Z における KVM ゲストへの暗号化アダプタのパススルー Edit source

14.18.1 概要 Edit source

IBM Z には、乱数生成やデジタル署名の検証、暗号化などの便利な機能を提供する暗号化ハードウエアが含まれています。 KVM では、これらの暗号化ハードウエアをゲストに占有させることで、パススルーデバイスとして使用することができます。このパススルー機能を設定した場合、ゲストとデバイスとの間の通信をハイパーバイザから監視することはできなくなります。

14.18.2 カバーされる範囲 Edit source

ここでは、 IBM Z ハードウエアで KVM ゲストに対する暗号化アダプタの占有方法を説明しています。手順は下記のような流れになっています:

  • まずはホスト側で暗号化アダプタとドメインを既定のドライバからマスクします。

  • vfio-ap ドライバを読み込みます。

  • vfio-ap ドライバに対して、暗号化アダプタとドメインを割り当てます。

  • あとは暗号化アダプタを使用するようゲスト側を設定します。

14.18.3 要件 Edit source

  • QEMU / libvirt の仮想化環境を正しくインストールしておき、問題なく動作できるようにしておく必要があります。

  • ホスト側のオペレーティングシステムで、 vfio_apvfio_mdev の各モジュールを用意しておきます。

14.18.4 KVM ホスト側での暗号化ドライバの占有設定 Edit source

  1. まずはホスト側で vfio_apvfio_mdev のカーネルモジュールが読み込まれていることを確認します:

    > lsmod | grep vfio_

    どちらか 1 つでも読み込まれていない場合は、下記のようにして手作業で読み込みを行います:

    > sudo modprobe vfio_mdev
  2. ホスト内で新しい MDEV デバイスを作成し、それが追加されていることを確認します:

    uuid=$(uuidgen)
    $ echo ${uuid} | sudo tee /sys/devices/vfio_ap/matrix/mdev_supported_types/vfio_ap-passthrough/create
    dmesg | tail
    [...]
    [272197.818811] iommu: Adding device 24f952b3-03d1-4df2-9967-0d5f7d63d5f2 to group 0
    [272197.818815] vfio_mdev 24f952b3-03d1-4df2-9967-0d5f7d63d5f2: MDEV: group_id = 0
  3. 次に KVM ゲストに占有させるホスト側の論理パーティション内のデバイスを識別します:

    > ls -l /sys/bus/ap/devices/
    [...]
    lrwxrwxrwx 1 root root 0 Nov 23 03:29 00.0016 -> ../../../devices/ap/card00/00.0016/
    lrwxrwxrwx 1 root root 0 Nov 23 03:29 card00 -> ../../../devices/ap/card00/

    上記の例では、カードとキューがそれぞれ 016 になっていることがわかります。 Hardware Management Console (HMC) の設定とあわせるため、 16 進数表記 16 を 10 進数表記 22 に変換してください。

  4. 対称のアダプタを zcrypt から使用されないようにマスクします:

    > lszcrypt
    CARD.DOMAIN TYPE MODE STATUS REQUEST_CNT
    -------------------------------------------------
    00 CEX5C CCA-Coproc online 5
    00.0016 CEX5C CCA-Coproc online 5

    アダプタをマスクします:

    > cat /sys/bus/ap/apmask
    0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
    echo -0x0 | sudo tee /sys/bus/ap/apmask
    0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

    ドメインをマスクします:

    > cat /sys/bus/ap/aqmask
    0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
    echo -0x0 | sudo tee /sys/bus/ap/aqmask
    0xfffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  5. アダプタ 0, ドメイン 16 (10 進数で 22) を vfio-ap に割り当てます:

    > sudo echo +0x0 > /sys/devices/vfio_ap/matrix/${uuid}/assign_adapter
    > echo +0x16 | sudo tee /sys/devices/vfio_ap/matrix/${uuid}/assign_domain
    > echo +0x16 | sudo tee /sys/devices/vfio_ap/matrix/${uuid}/assign_control_domain
  6. 設定した matrix を確認します:

    > cat /sys/devices/vfio_ap/matrix/${uuid}/matrix
    00.0016
  7. あとは新しい VM を作成 (詳しくは 第9章 「ゲストのインストール をお読みください) して準備が完了するまで待つか、既存の VM に設定を行います。いずれの場合にしても、 VM はシャットダウンしておく必要があります。

  8. MDEV デバイスを使用するよう設定を変更します:

    > sudo virsh edit VM_NAME
    [...]
    <hostdev mode='subsystem' type='mdev' model='vfio-ap'>
     <source>
      <address uuid='24f952b3-03d1-4df2-9967-0d5f7d63d5f2'/>
     </source>
    </hostdev>
    [...]
  9. あとは仮想マシンを再起動します:

    > sudo virsh reboot VM_名
  10. ゲストにログインして、アダプタが存在していることを確認します:

    > lszcrypt
    CARD.DOMAIN TYPE MODE STATUS REQUEST_CNT
    -------------------------------------------------
    00 CEX5C CCA-Coproc online 1
    00.0016 CEX5C CCA-Coproc online 1

14.18.5 さらに詳しい情報 Edit source