QEMU

提供: ArchWiki
2019年1月27日 (日) 03:32時点におけるKusakata.bot (トーク | 投稿記録)による版 (Pkg/AUR テンプレートの更新)
ナビゲーションに移動 検索に移動

関連記事

QEMU ホームページ より:

QEMU は汎用なオープンソースのマシンエミュレータ・バーチャライザーです。

マシンエミュレータとして使う場合、QEMU はあるマシン (例: ARM ボード) 用に作られた OS やプログラムを他のマシン (例: x86 PC) で動かすことができます。動的変換を利用することによって、素晴らしいパフォーマンスを実現します。

XenKVM など他のハイパーバイザを使うことで QEMU は仮想化のための CPU 拡張命令を利用することができます。バーチャライザーとして使う場合、ゲストコードをホスト CPU で直接実行することにより QEMU はネイティブに近いパフォーマンスを得ることができます。

目次

インストール

qemu パッケージ (または GUI が必要ない場合は qemu-headless) をインストールしてください。また、任意で以下のパッケージもインストールしてください:

QEMU のグラフィカルフロントエンド

VirtualBoxVMware など他の仮想化プログラムと違って、QEMU は仮想マシンを管理するための GUI を提供しません (仮想マシンを動かすときに表示されるウィンドウは別です)。また、保存された設定を使って永続的な仮想マシンを作成する方法も提供していません。仮想マシンを起動するためのカスタムスクリプトを作成しないかぎり、仮想マシンを起動するための全てのパラメータは起動する度にコマンドラインに指定する必要があります。ただし、QEMU の GUI フロントエンドは複数存在します:

新しい仮想化システムの作成

ヒント: Arch Linux を仮想化する場合、既存の Arch Linux システム上に直接ディスクイメージを作成することができます、詳しくはインストールガイドを見て下さい。

ハードディスクイメージの作成

ヒント: QEMU イメージに関する詳細は QEMU Wikibook を参照。

CD-ROM やネットワークからライブシステムを起動するのでない (そしてオペレーティングシステムをハードディスクイメージにインストールしない) 限り、QEMU を実行するにはハードディスクイメージが必要になります。ハードディスクイメージはエミュレートするハードディスクの内容を保存するファイルです。

ハードディスクイメージを raw にすると、ゲストからは文字通りバイト単位で等しいようになり、ホスト上のゲストハードドライブをフルに使用することになります。この方法は I/O のオーバーヘッドを最小に抑えられますが、ゲストで使用していない領域もホストは使えないため、大量の容量を消費するのが欠点です。

また、ハードディスクイメージを qcow2 などのフォーマットにすることもできます。ゲストオペレーティングシステムが実際に仮想ハードディスク上のセクタに書き込んだ時にイメージファイルに容量を割り当てます。ホストシステムで占める容量はかなり少なくて済み、ゲストオペレーションにはフルサイズのイメージとして見えます。QEMU のスナップショット機能にも対応しています (詳しくは#モニタコンソールを使ってスナップショットを作成・管理を参照)。こちらの形式では raw と違ってパフォーマンスに多少影響を与えます。

QEMU にはハードディスクイメージを作成するための qemu-img コマンドがあります。例えば raw フォーマットで 4GB イメージを作成するには:

$ qemu-img create -f raw image_file 4G

-f qcow2 を使うことで qcow2 ディスクを作成できます。

ノート: raw イメージは ddfallocate を使って必要なサイズのファイルを作成するだけでも作れます。
警告: ハードディスクイメージを Btrfs ファイルシステム上に保存する場合、イメージを作成する前にディレクトリの Copy-on-Write を無効にするべきでしょう。

オーバーレイストレージイメージ

一度ストレージメディアを作成してから ('backing' イメージ)、QEMU にイメージへの変更を overlay イメージとして維持させることができます。これによってストレージメディアを前の状態に戻すことが可能になります。戻りたい時点で、オリジナルの backing イメージを元に新しい overlay イメージを作成することで戻すことができます。

overlay イメージを作成するには、次のようにコマンドを実行してください:

$ qemu-img create -o backing_file=img1.raw,backing_fmt=raw -f qcow2 img1.cow

その後通常通り QEMU VM を起動することができます (仮想化システムを実行するを参照):

$ qemu-system-x86_64 img1.cow

backing イメージには変更が加えられず、ストレージへの追記は overlay イメージファイルに保存されるようになります。

backing イメージのパスが変更された場合、修正が必要になります。

警告: backing イメージの絶対ファイルシステムパスは (バイナリの) overlay イメージファイルに保存されます。backing イメージのパスを変更するのは大変です。

オリジナルの backing イメージのパスからこのイメージに繋がるようにしてください。必要ならば、オリジナルのパスに新しいパスへのシンボリックリンクを作成します。次のようなコマンドを実行してください:

$ qemu-img rebase -b /new/img1.raw /new/img1.cow

あなたの判断で、backing イメージの古いパスがチェックされない'危険な' rebase を実行することもできます:

$ qemu-img rebase -u -b /new/img1.raw /new/img1.cow

イメージのリサイズ

警告: NTFS ブートファイルシステムを含んでいるイメージをリサイズするとそこにインストールされている VM が起動できなくなってしまう可能性があります。詳しい説明や回避方法は ここ を見て下さい。

qemu-img 実行可能ファイルには resize オプションがあり、ハードドライブイメージの簡単なリサイズができます。このコマンドは rawqcow2 の両方で使えます。例えば、イメージ容量を 10GB 増やすには、次を実行してください:

$ qemu-img resize disk_image +10G
ヒント: NTFS ブートファイルシステムを含んでいるイメージをリサイズする方法 (この例では qcow2 フォーマットのイメージを使っていますが他のフォーマットでも方法は同じです):

重要: イメージを使用している VM はあらかじめ全てシャットダウンしてください。

リサイズするのに qcow2 から raw にイメージを変換する必要はありません (ただしイメージが NTFS で VM ゲストをそこから起動している場合は別です)。直接 qemu-img resize コマンドを使って下さい。その後、ゲストの仮想マシンを起動してディスクに新しい場所を再配置してください。

そして適当なツールを使ってパーティションのサイズを変更 (例えば Windows Vista 以降なら、Windows を起動して初めから入っている Disk Management ユーティリティ を使うことができます)。

イメージが起動する NTFS の場合、qcow2 ファイルを以下のようにして変換する必要があります:

イメージを raw フォーマットに変換して末尾に空きスペースを追加します (オリジナルのイメージはバックアップとして残しておく):

$ qemu-img convert -f qcow2 -O raw myimg.qcow2 myimg.raw
$ truncate -s +4G myimg.raw
$ mv myimg.qcow2 myimg.qcow2.bak

大きくしたイメージを qcow2 に戻して、raw は削除:

$ qemu-img convert -f raw -O qcow2 myimg.raw myimg.qcow2 
$ rm myimg.raw 

オリジナルのイメージのパーミッションと合わせる:

$ chown --reference=myimg.qcow2.bak myimg.qcow2
$ chmod --reference=myimg.qcow2.bak myimg.qcow2

インストールメディアを準備する

ディスクイメージにオペレーティングシステムをインストールするには、オペレーティングシステムのインストールメディア (例: オプティカルディスク、USB ドライブ、ISO イメージ) が必要です。QEMU はメディアに直接アクセスできないのでインストールメディアをマウントしてはいけません。

ヒント: 光ディスクを使う場合、最初に中身をファイルに移動させると良いでしょう。パフォーマンスが発揮されるようになり、デバイスに直接アクセスする必要がなくなります (従って、メディアのデバイスファイルのアクセス権限を変えることなく QEMU を通常ユーザーで起動することが可能になります)。 CD-ROM デバイスノードの名前が /dev/cdrom なら、次のコマンドでファイルに dump することが出来ます: $ dd if=/dev/cdrom of=cd_image.iso

オペレーティングシステムのインストール

ここで初めてエミュレータを起動することになります。ディスクイメージにオペレーティングをインストールするには、ディスクイメージとインストールメディアの両方を仮想マシンに結びつけて、インストールメディアから起動するようにする必要があります。

例えば x86_64 環境で、CD-ROM と raw ディスクイメージのブータブル ISO ファイルからインストールするには:

$ qemu-system-x86_64 -cdrom iso_image -boot order=d -drive file=disk_image,format=raw

フロッピーやディスクイメージ、物理ドライブなどの他のメディアタイプをロードする方法は qemu(1) を見てください。

オペレーティングシステムのインストールが終了したら、直接 QEMU イメージを起動することができます (仮想化システムを実行するを参照)。

警告: デフォルトではマシンに割り当てられるメモリは 128 MB だけです。メモリの量は -m スイッチで調整することができます、例えば -m 512M-m 2G
ヒント:
  • -boot order=x を指定する代わりに、ブートメニューを使う方を好むユーザーもいるかもしれません: -boot menu=on、設定や実験をしている時は便利です。
  • インストールプロセスでフロッピーや CD を替える必要がある場合、QEMU マシンモニター (仮想マシンのウィンドウで Ctrl+Alt+2 を押す) を使って仮想マシンからストレージデバイスを取り外したりアタッチすることができます。ブロックデバイスを見るには info block を、デバイスをスワップアウトするには change コマンドを使って下さい。Ctrl+Alt+1 を押せば仮想マシンに戻ります。

仮想化システムを実行する

qemu-system-* バイナリ (例えば qemu-system-i386qemu-system-x86_64 など、エミュレートするアーキテクチャによって異なります) を使って仮想化システムを実行します。使用方法は:

$ qemu-system-x86_64 options disk_image

全ての qemu-system-* バイナリでオプションは共通です、全てのオプションのドキュメントは qemu(1) を見て下さい。

デフォルトで、QEMU は仮想マシンのビデオ出力をウィンドウに表示します。注意: QEMU ウィンドウの中をクリックすると、マウスポインタが取り込まれます。ポインタを戻すには、Ctrl+Alt+g を押して下さい。

警告: QEMU を root で実行しないでください。スクリプト内で root で実行する必要があるときは、-runas オプションを使って QEMU の root 特権を外して下さい。

KVM を有効にする

使用しているプロセッサとカーネルが KVM をサポートしている必要があります。また、必要なカーネルモジュールがロードされてなければなりません。詳しくは KVM を見て下さい。

QEMU を KVM モードで起動するには、起動オプションに -enable-kvm を追加してください。実行中の仮想マシンで KVM が有効になっているかどうか確認するには、Ctrl+Alt+Shift+2 を使って QEMU Monitor に入り、info kvm と入力してください。

ノート:
  • GUI ツールを使って VM を起動した時にパフォーマンスが出ない場合、KVM サポートを確認してください。QEMU がソフトウェアエミュレーションにフォールバックしている可能性があります。
  • ブルースクリーンを出さずに Windows 7 や Windows 8 を正しく起動するには KVM を有効にする必要があります。

IOMMU (Intel VT-d/AMD-Vi) サポートを有効にする

IOMMU を使うことで PCI パススルーやメモリの保護などの機能が利用できます。Wikipedia:ja:IOMMU#利点Memory Management (computer programming): Could you explain IOMMU in plain English? を見てください。

IOMMU を有効化するには:

  1. CPU によって AMD-Vi/Intel VT-d がサポートされていること、BIOS の設定で有効になっていることを確認してください。
  2. Intel の CPU を使っている場合は intel_iommu=on、AMD の CPU を使っている場合は amd_iommu=onカーネルパラメータに追加してください。
  3. PCI パススルーのためだけに IOMMU が必要な場合、iommu=pt パラメータも追加してください。Linux がパススルーするデバイスの IOMMU だけを有効化できるようになり、システムの他のデバイスへのパフォーマンスの影響を避けられます。CPU メーカー別のパラメータ (上記) も on にする必要があります。
  4. 再起動して dmesgDMAR があることを確認して IOMMU が有効になっていることをチェックしてください: [0.000000] DMAR: IOMMU enabled
  5. -device intel-iommu を追加して IOMMU デバイスを作成してください:
$ qemu-system-x86_64 -enable-kvm -machine q35,accel=kvm -device intel-iommu -cpu host,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time ..
ノート: Intel の CPU が搭載されている場合、-device intel-iommu を使って QEMU ゲストに IOMMU デバイスを作成すると PCI パススルーが無効化されて以下のようなエラーが表示されることがあります:
Device at bus pcie.0 addr 09.0 requires iommu notifier which is currently not supported by intel-iommu emulation
(vfio-pci による PCI パススルーなど) IO をリマップするには intel_iommu=on カーネルパラメータの追加が必要ですが、PCI パススルーを使う場合は -device intel-iommu は設定してはいけません。

ホスト・ゲスト OS 間でデータを移動する

ネットワーク

ファイルを転送できるネットワークプロトコルであれば NFS, SMB, NBD, HTTP, FTP, SSH など何でも使ってホストとゲスト OS 間でデータを共有することができます、ただしネットワークを適切に設定して適切なサービスを有効にする必要があります。

デフォルトのユーザーモードネットワークは IP アドレス 10.0.2.2 でゲストがホスト OS にアクセスするのを許可します。ホスト OS で動作する全てのサーバー、SSH サーバーや SMB サーバーなどは、この IP アドレスでアクセスすることが可能になります。そしてゲストでは、SMBNFS でホストのディレクトリをマウントしたり、ホストの HTTP サーバーなどにアクセスすることが可能です。 ゲスト OS で動作しているサーバーにホスト OS がアクセスすることはできませんが、他のネットワーク設定を使えば不可能ではありません (#QEMU の Tap ネットワーク を参照)。

QEMU の内蔵 SMB サーバー

QEMU のドキュメントには "内蔵の" SMB サーバーがあると書かれていますが、実際は自動的に生成された設定ファイル (/tmp/qemu-smb.pid-0/smb.conf) で Samba を起動して別の IP アドレス (デフォルトでは 10.0.2.4) でゲストにアクセスできるようにするだけです。この機能はユーザーネットワークでしか動作せず、また、共有を設定していればホストの通常の Samba サービスにゲストがアクセスすることもできるので、必ずしも便利な機能とは言えません。

この機能を有効にするには、次のようなコマンドで QEMU を起動します:

$ qemu-system-x86_64 disk_image -net nic -net user,smb=shared_dir_path

shared_dir_path はゲストとホストで共有したいディレクトリに置き換えてください。

これで、ゲストから、ホスト 10.0.2.4 の共有ディレクトリに共有名 "qemu" でアクセスすることができるようになります。例えば、Windows エクスプローラーなら \\10.0.2.4\qemu を開きます。

ノート:
  • -net user,smb=shared_dir_path1 -net user,smb=shared_dir_path2-net user,smb=shared_dir_path1,smb=shared_dir_path2 のように共有オプションを複数回使用した場合、最後に定義したものだけが共有されます。
  • ゲストシステムが Windows で共有フォルダにアクセスできない場合、NetBIOS プロトコルが有効になっているかどうか そして NetBIOS プロトコルによって使用されている ポート がファイアウォールでブロックされてないか確認してください。

raw ディスクイメージの中にパーティションをマウントする

仮想マシンが動作していないときに、raw ディスクイメージファイル内のパーティションをループバックデバイスとして設定することでマウントすることが可能です。これは qcow2 などの特別なフォーマットのディスクイメージでは動作しませんが、qemu-nbd を使ってマウントすることはできます。

警告: 仮想マシンをまた実行する前にパーティションをアンマウントしていることを必ず確認してください。パーティションを読み取り専用以外でマウントしていた場合、データが喪失する可能性があります。

手動でバイトオフセットを指定する

ディスクイメージのパーティションをマウントする一つの方法として、次のようなコマンドを使って特定のオフセットでディスクイメージをマウントする方法があります:

# mount -o loop,offset=32256 disk_image mountpoint

offset=32256 オプションは losetup プログラムにわたされて、ファイルのバイトオフセット 32256 から最後まで続くループバックデバイスが設定され、それからこのループバックデバイスがマウントされます。sizelimit オプションを使ってパーティションの実際のサイズを指定することもできますが、これは基本的に必要ありません。

ディスクイメージによって、必要なパーティションがオフセット 32256 から始まってない可能性があります。fdisk -l disk_image を実行してイメージ内のパーティションを見て下さい。fdisk は512バイトセクタ単位で起点と終点を表示するので、512 を掛けて適当なオフセットを mount で指定してください。

loop モジュールでパーティションを自動検出する

Linux の loop ドライバーはループバックデバイスのパーティションをサポートしていますが、デフォルトでは無効にされています。有効にするには、以下を行なって下さい:

  • 全てのループバックデバイスを取り除いて下さい (マウントされているイメージを全てアンコメントするなど)。
  • loop モジュールを一度アンロードしてから、max_part=15 パラメータを設定してロードしてください。また、ループデバイスの最大数は max_loop パラメータで決めることができます。
ヒント: loop.ko モジュールをカーネルに組み込んでいるかどうかにあわせて、/etc/modprobe.d にエントリを記述して毎回 max_part=15 で loop モジュールをロードするか、カーネルコマンドラインに loop.max_part=15 と書きます。

あなたのイメージをループバックデバイスとして設定:

# losetup -f -P disk_image

これで、デバイスが /dev/loop0 の場合、追加のデバイス /dev/loop0pX が自動的に作成されます。X はパーティションの番号です。これらのパーティションのループバックデバイスは直接マウントすることができます。例:

# mount /dev/loop0p1 mountpoint

udisksctl でディスクイメージをマウントする方法は Udisks#ISO イメージのマウントを見てください。

kpartx を使う

AURmultipath-tools パッケージに入っている kpartx はデバイスのパーティションテーブルを読み込んでパーティションごとに新しいデバイスを作成することができます。例えば:

# kpartx -a disk_image

上記のコマンドで、ループバックデバイスがセットアップされ /dev/mapper/ に必要なパーティションデバイスが作成されます。

qcow2 イメージの中にパーティションをマウントする

qcow2 イメージの中のパーティションは qemu-nbd を使ってマウントできます。Wikibooks を見て下さい。

実際のパーティションをハードディスクイメージのシングルプライマリパーティションとして使う

場合によって、QEMU の中からシステムパーティションのどれかを使いたくなることもあるでしょう。仮想マシンでの raw パーティションの使用は、読み書きの操作が物理ホストのファイルシステムレイヤーを通過しないため、パフォーマンスが高くなります。そのようなパーティションをホストとゲストでのデータの共有手段として使うこともできます。

Arch Linux では、raw パーティションのデバイスファイルは、デフォルトで、rootdisk グループが所有者です。root 以外のユーザーで raw パーティションに読み書きできるようにしたい場合は、パーティションのデバイスファイルの所有者をそのユーザーに変える必要があります。

警告:
  • 仮想マシンにホストシステムのクリティカルなデータ (root パーティションなど) を変更する許可を与えるのは可能ではありますが、推奨はされません。
  • ホストとゲストの両方で同時にパーティションのファイルシステムを読み書き可能でマウントしてはいけません。そうすると、データが破壊される可能性があります。

その後、パーティションを QEMU の仮想マシンに仮想ディスクとしてアタッチできます。

ただし、仮想マシン全体をパーティションに収めたいときは、自体は多少複雑になります。そのような場合、実際に仮想マシンを起動するディスクイメージファイルがないために、MBR でパーティション分けされたデバイスではなくファイルシステムとしてフォーマットされたパーティションにブートローダーをインストールすることができません。このような仮想マシンはカーネルinitrd を手動で指定するか、リニア RAID を使って MBR のディスクをシミュレートすることで起動できます。

カーネルと initrd を手動で指定する

QEMU は GRUB などのブートローダーを迂回して、Linux カーネルinit ramdisk を直接ロードすることをサポートしています。それから root ファイルシステムを含んでいる物理パーティションで、パーティションされていない仮想ディスクとして起動することができます。以下のようなコマンドを実行することで行います:

ノート: この例で使用するのはゲストのイメージではなく、ホストのイメージです。ゲストのイメージを使いたい場合は、(ホストからファイルシステムを保護するために) /dev/sda3 を読み取り専用でマウントして /full/path/to/images と指定するか、ゲストで kexec を使ってゲストのカーネルをリロードしてください (起動時間を拡張します)。
$ qemu-system-x86_64 -kernel /boot/vmlinuz-linux -initrd /boot/initramfs-linux.img -append root=/dev/sda /dev/sda3

上の例では、ゲストの root ファイルシステムに使われている物理パーティションはホストの /dev/sda3 で、ゲストでは /dev/sda として表示されます。

もちろん、Arch Linux で使われているものとは違うカーネルや initrd を自由に指定することができます。

複数のカーネルパラメータ-append オプションで指定するときは、クォートを使って囲む必要があります。例:

... -append 'root=/dev/sda1 console=ttyS0'

リニア RAID を使って MBR で仮想ディスクをシミュレート

ファイルシステムでフォーマットされたパーティションを維持しながらゲストのパーティションをまるでディスクであるかのようなパーティションにしないで、仮想マシンで物理パーティションを使用するもっと複雑な方法として、MBR をシミュレートして GRUB などのブートローダーを使って起動できるようにする方法があります。

リニアモードのソフトウェア RAID (linear.ko カーネルドライバーが必要) とループバックデバイスを使えばこれが可能です: 方策としては QEMU の raw ディスクイメーに埋め込みたい物理パーティションに動的にマスターブートレコード (MBR) を先頭に付け加えます。

QEMU ディスクイメージの一部にしたいファイルシステムがあるプレーンな、マウントされていない /dev/hdaN パーティションがあるとします。まず最初に、MBR を入れるための小さなファイルを作成:

$ dd if=/dev/zero of=/path/to/mbr count=32

これで 16 KB (32 * 512 バイト) のファイルが作成されます。(MBR は512バイトのブロックしか必要としませんが) あまり小さくしすぎないことが重要です。なぜならファイルを小さくすればするほど、ソフトウェア RAID デバイスのチャンクサイズも小さくしなくてはならなくなり、パフォーマンスに影響を与えるからです。次に、MBR ファイルのループバックデバイスを設定します:

# losetup -f /path/to/mbr

他にループバックを使っていないために、作成されるデバイスは /dev/loop0 になるとします。次のステップはソフトウェア RAID を使って "merged" MBR + /dev/hdaN ディスクイメージを作成することです:

# modprobe linear
# mdadm --build --verbose /dev/md0 --chunk=16 --level=linear --raid-devices=2 /dev/loop0 /dev/hdaN

作成した /dev/md0 は QEMU の raw ディスクイメージとして使用します (エミュレータがアクセスできるようにパーミッションを設定するのを忘れないでください)。最後にプライマリパーティションの開始位置が /dev/md0/dev/hdaN に一致するようにディスクの設定 (ディスクのジオメトリとパーティションテーブルの設定) を行います (上の例では 16 * 512 = 16384 バイトのオフセットです)。ホストマシンで fdisk を使って行ってください。エミュレータの中で行ってはいけません: QEMU のデフォルトのディスク認識ルーチンによってキロバイトで割り切れないオフセットが生まれるとソフトウェア RAID コードで管理できなくなります。ホストから以下を実行してください:

# fdisk /dev/md0

X を押してエキスパートメニューを開きます。トラック毎のセクタ数を設定してシリンダーの容量が MBR ファイルの容量に一致するようにしてください。ヘッダが2つでセクタサイズが512の場合、1トラックあたりのセクタ数は16となり、シリンダのサイズは 2x16x512=16k になります。

R を押してメインメニューに戻って下さい。

P を押してシリンダーのサイズが 16k になってることを確認します。

/dev/hdaN にあわせてシングルプライマリパーティションを作成してください。パーティションの開始位置はシリンダー2で終了位置はディスクの末尾になります (シリンダーの数は fdisk に入力したときの値で変わります)。

最後に、結果をファイルに書き出してください ('w')。これでホストから直接パーティションをディスクイメージとしてマウントすることができます:

$ qemu-system-x86_64 -hdc /dev/md0 [...]

もちろん、元のパーティション /dev/hdaN に必要ツールが含まれていれば、QEMU を使ってディスクイメージにブートローダーを設定できます。

nbd-server を使う

リニア RAID を使う代わりに、(nbd パッケージに含まれている) nbd-server を使って QEMU の MBR ラッパーを作成する方法もあります。

上記のように MBR ラッパーファイルを設定したら、wrapper.img.0 に名前を変更してください。そして同じディレクトリに wrapper.img.1 という名前のシンボリックリンクを作成して、パーティションにリンクするようにしてください。また、同じディレクトリに以下のスクリプトを作成します:

#!/bin/sh
dir="$(realpath "$(dirname "$0")")"
cat >wrapper.conf <<EOF
[generic]
allowlist = true
listenaddr = 127.713705
port = 10809

[wrap]
exportname = $dir/wrapper.img
multifile = true
EOF

nbd-server \
    -C wrapper.conf \
    -p wrapper.pid \
    "$@"

.0.1 という拡張子が重要です。他は変えてもかまいません。上記のスクリプトを実行後 (nbd-server がパーティションにアクセスできるように root で実行してください)、以下のコマンドで QEMU を起動できます:

$ qemu-system-x86_64 -drive file=nbd:127.713705:10809:exportname=wrap [...]

ネットワーク

仮想ネットワークのパフォーマンスはユーザーモードネットワークまたは vde によるよりも tap デバイスやブリッジを用いる方が良いでしょう。tap デバイスやブリッジはカーネル内で実装されているからです。

加えて、デフォルトの e1000 NIC のエミュレーションではなく virtio ネットワークデバイスを仮想マシンに指定することでネットワークのパフォーマンスを向上させることができます。詳しくは #virtio ドライバーのインストール を参照。

リンク層アドレス

QEMU に -net nic 引数を与えると、デフォルトで、仮想マシンにリンク層アドレス 52:54:00:12:34:56 のネットワークインターフェイスが割り当てられます。しかしながら、ブリッジネットワークで複数の仮想マシンを使用する場合、個別の仮想マシンにはタップデバイスの仮想マシン側からそれぞれ固有のリンク層 (MAC) アドレスを設定しなくてはなりません。設定を行わないと、ブリッジが上手く動きません。同一のリンク層アドレスを持つ複数のソースからパケットを受け取ることになるからです。たとえタップデバイス自体に固有のリンク層アドレスを設定していたとしても、ソースのリンク層アドレスはタップデバイスを通過するときに書き換えられないため、問題が発生します。

個々の仮想マシンに固有のリンク層アドレスを設定、それも、どのアドレスも 52:54: で始まるように設定してください。以下のオプションを使って下さい (X は任意の16進数の数字に置き換えてください):

$ qemu-system-x86_64 -net nic,macaddr=52:54:XX:XX:XX:XX -net vde disk_image

固有のリンク層アドレスの生成は複数の方法で行うことができます:

1. NIC ごとに固有のリンク層アドレスを手動で指定する。仮想マシンを起動するたびに同じ IP アドレスが DHCP サーバーによって割り当てられるという利点がありますが、仮想マシンが大量にある場合は現実的ではありません。

2. 仮想マシンを起動するたびにランダムなリンク層アドレスを生成する。衝突する可能性はほとんどゼロですが、DHCP サーバーによって割り当てられる IP アドレスが毎回異なるのが欠点です。以下のコマンドをスクリプトで使うことで macaddr 変数にランダムなリンク層アドレスを生成できます:

printf -v macaddr "52:54:%02x:%02x:%02x:%02x" $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff )) $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff ))
qemu-system-x86_64 -net nic,macaddr="$macaddr" -net vde disk_image

3. 以下のスクリプト qemu-mac-hasher.py を使ってハッシュ関数を利用し仮想マシンの名前からリンク層アドレスを生成する。仮想マシンの名前を一意なものとして、上記の方法の良いところを組み合わせています。スクリプトが実行されるたびに同一のリンク層アドレスが生成される上、衝突する可能性はほとんどありません。

qemu-mac-hasher.py
#!/usr/bin/env python

import sys
import zlib

if len(sys.argv) != 2:
    print("usage: %s <VM Name>" % sys.argv[0])
    sys.exit(1)

crc = zlib.crc32(sys.argv[1].encode("utf-8")) & 0xffffffff
crc = str(hex(crc))[2:]
print("52:54:%s%s:%s%s:%s%s:%s%s" % tuple(crc))

以下のように使うことができます:

vm_name="VM Name"
qemu-system-x86_64 -name "$vm_name" -net nic,macaddr=$(qemu-mac-hasher.py "$vm_name") -net vde disk_image

ユーザーモードネットワーク

デフォルトで、-netdev 引数をつけていないと、QEMU は DHCP サーバーが内蔵されたユーザーモードネットワークを使用します。DHCP クライアントを実行したときに仮想マシンには IP アドレスが与えられ、QEMU による IP マスカレードを通して物理ホストのネットワークにアクセスできるようになります。

警告: TCP と UDP プロトコルでしか動作しないので、ping を含む ICMP は動作しません。ping を使ってネットワーク接続をテストしても無駄です。

ホストがインターネットに接続されていれば、このデフォルトの設定で簡単に仮想マシンをインターネットにアクセスさせることができますが、外部ネットワークからは仮想マシンは直接は見えず、また、複数の仮想マシンを同時に起動していても仮想マシン同士が通信することはできません。

QEMU のユーザーモードネットワークには内蔵の TFTP や SMB サーバー、ゲストを VLAN に追加してゲストの通信を可能にするなどの機能があります。詳しくは -net user フラグの QEMU ドキュメントを参照してください。

ただし、ユーザーモードネットワークには有用性とパフォーマンスの両方で制約があります。より高度なネットワーク設定をするには tap デバイスや他の方法を使って下さい。

ノート: ホスト環境が systemd-networkd を使用している場合、systemd-networkd#必要なサービスと設定に書かれているように /etc/resolv.conf ファイルのシンボリックリンクを作成してください。作成しないとゲスト環境で DNS ルックアップができなくなります。

QEMU の Tap ネットワーク

Tap デバイスは Linux カーネルの機能で、本当のネットワークインターフェイスのように見える仮想ネットワークインターフェイスを作成することができます。tap インターフェイスに送られたパケットは、そのインターフェイスに bind された、QEMU などのユーザースペースプログラムに送信されます。

QEMU は仮想マシンで tap ネットワークを利用して、tap インターフェイスに送られたパケットを仮想マシンに送信することで仮想マシンのネットワークインターフェイス (通常は Ethernet インターフェイス) から受け取ったように見せることが可能です。逆に、仮想マシンがネットワークインターフェイスを通して送信したものは全て tap インターフェイスが受け取ります。

Tap デバイスは Linux の bridge ドライバーによってサポートされているため、tap デバイスを互いに、または eth0 といったホストのインターフェイスとブリッジすることができます。これは、仮想マシンを互いに通信できるようにしたい場合や、LAN 上の他のマシンが仮想マシンに通信できるようにしたい場合に価値があります。

警告: tap デバイスとホストのインターフェイス (eth0 など) をブリッジすると、仮想マシンは外部ネットワークから直接認識されるようになり、攻撃を受ける可能性が出てきます。仮想マシンからアクセスできるリソースに応じて、通常のコンピュータと同じような対策を施して仮想マシンを防護するようにしてください。仮想マシンのリソースがほとんどなかったり複数の仮想マシンを立ち上げるなど危険性が高すぎる場合、ホストオンリーネットワークを使って NAT を設定するほうが良いでしょう。その場合、ゲストごとにファイアウォールを設定する必要はなく、ホストだけにファイアウォールを設定すれば十分です。

ホストオンリーネットワーク

ブリッジに IP アドレスが与えられていてそこへのトラフィックが許可されていながら、本当のインターフェイス (例: eth0) がブリッジに接続されていない場合、仮想マシンは互いに通信したりホストシステムと通信することができるようになります。しかしながら、物理ホストで IP マスカレードを設定しないかぎり外部ネットワークとは一切通信することができません。この設定は VirtualBox などの他の仮想化ソフトウェアではホストオンリーネットワークと呼ばれています。

ヒント:
  • IP マスカレードを設定したい場合、インターネット共有#NAT の有効化ページを見てください。
  • ブリッジインターフェイスで DHCP サーバーを実行して仮想ネットワークを構築することもできます。例えば 172.20.0.1/16 サブネットで DHCP サーバーとして dnsmasq を使うには:
# ip addr add 172.20.0.1/16 dev br0
# ip link set br0 up
# dnsmasq --interface=br0 --bind-interfaces --dhcp-range=172.20.0.2,172.20.255.254

内部ネットワーク

ブリッジに IP アドレスを与えずにブリッジへの全てのトラフィックを INPUT チェインで drop する iptables ルールを追加した場合、仮想マシンは互いに通信することはできても、物理ホストや外側のネットワークに接続できなくなります。この設定は VirtualBox などの他の仮想化ソフトウェアでは内部ネットワークと呼ばれています。仮想マシンに固定 IP アドレスを割り当てるかマシンのどれか一つで DHCP サーバーを実行する必要があります。

デフォルトで iptables はブリッジネットワークのパケットを拒否します。ブリッジネットワークのパケットを許可する iptables のツールを使用する必要があります:

# iptables -I FORWARD -m physdev --physdev-is-bridged -j ACCEPT

qemu-bridge-helper を使用するブリッジネットワーク

ノート: この方法は QEMU 1.1 から使うことができます、http://wiki.qemu.org/Features/HelperNetworking を参照。

この方法にはスタートアップスクリプトが必要なく、すぐに複数の tap やブリッジに対応することができます。既存のブリッジに tap デバイスを作成できるようにする、/usr/lib/qemu/qemu-bridge-helper バイナリを使用します。

ヒント: ブリッジの作成に関する情報は netctl でブリッジ接続を参照。

まず、/etc/qemu/bridge.conf.sample/etc/qemu/bridge.conf にコピーします。そして /etc/qemu/bridge.conf を編集して QEMU で使用するブリッジの名前を全て記述します:

/etc/qemu/bridge.conf
allow bridge0
allow bridge1
...

設定したら VM を起動して下さい。一番基本的な使い方は:

$ qemu-system-x86_64 -net nic -net bridge,br=bridge0 [...]

tap が複数の場合、追加の NIC 全てに VLAN を指定する必要があります:

$ qemu-system-x86_64 -net nic -net bridge,br=bridge0 -net nic,vlan=1 -net bridge,vlan=1,br=bridge1 [...]

ブリッジを手動で作成する

ヒント: QEMU 1.1 から、スクリプトを追加することなく network bridge helper で tun/tap を設定することができます。#qemu-bridge-helper を使用するブリッジネットワーク を参照。

以下では仮想マシンを eth0 などのホストインターフェイスにブリッジする方法を説明しています。おそらく一番よく使われている設定です。この設定では、物理的なホストマシンと同一の Ethernet セグメントに、直接外部ネットワークに仮想マシンが位置するようになります。

通常の Ethernet アダプタをブリッジアダプタで置き換えて、通常の Ethernet アダプタをブリッジアダプタに bind することにします。

  • ブリッジを制御するための brctl が入っている bridge-utils をインストール。
  • IPv4 フォワーディングを有効にする:
# sysctl net.ipv4.ip_forward=1

変更を永続的にするために、/etc/sysctl.d/99-sysctl.confnet.ipv4.ip_forward = 0net.ipv4.ip_forward = 1 に変えます。

  • tun モジュールをロードして起動時にロードするように設定してください。詳しくはカーネルモジュールを参照。
  • ブリッジを作成します。詳しくは netctl でブリッジ接続を見て下さい。ブリッジの名前を br0 にするか、下のスクリプトを使用するブリッジの名前に忘れずに変更してください。
  • QEMU 用に root:kvm 750 パーミッションで tap アダプタを立ち上げるスクリプトを作成:
/etc/qemu-ifup
#!/bin/sh
  
echo "Executing /etc/qemu-ifup"
echo "Bringing up $1 for bridged mode..."
sudo /usr/bin/ip link set $1 up promisc on
echo "Adding $1 to br0..."
sudo /usr/bin/brctl addif br0 $1
sleep 2
  • QEMU 用に root:kvm 750 パーミッションで /etc/qemu-ifdown の tap アダプタを落とすスクリプトを作成:
/etc/qemu-ifdown
#!/bin/sh
 
echo "Executing /etc/qemu-ifdown"
sudo /usr/bin/ip link set $1 down
sudo /usr/bin/brctl delif br0 $1
sudo /usr/bin/ip link delete dev $1
  • visudo を使って sudoers ファイルに以下を追加します:
Cmnd_Alias      QEMU=/usr/bin/ip,/usr/bin/modprobe,/usr/bin/brctl
%kvm     ALL=NOPASSWD: QEMU
  • 以下の run-qemu スクリプトを使って QEMU を起動します:
run-qemu
#!/bin/bash
USERID=$(whoami)

# Get name of newly created TAP device; see https://bbs.archlinux.org/viewtopic.php?pid=1285079#p1285079
precreationg=$(/usr/bin/ip tuntap list | /usr/bin/cut -d: -f1 | /usr/bin/sort)
sudo /usr/bin/ip tuntap add user $USERID mode tap
postcreation=$(/usr/bin/ip tuntap list | /usr/bin/cut -d: -f1 | /usr/bin/sort)
IFACE=$(comm -13 <(echo "$precreationg") <(echo "$postcreation"))

# This line creates a random MAC address. The downside is the DHCP server will assign a different IP address each time
printf -v macaddr "52:54:%02x:%02x:%02x:%02x" $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff )) $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff ))
# Instead, uncomment and edit this line to set a static MAC address. The benefit is that the DHCP server will assign the same IP address.
# macaddr='52:54:be:36:42:a9'
  
qemu-system-x86_64 -net nic,macaddr=$macaddr -net tap,ifname="$IFACE" $*
  
sudo ip link set dev $IFACE down &> /dev/null
sudo ip tuntap del $IFACE mode tap &> /dev/null 

それから VM を起動するために、以下のようにコマンドを実行して下さい:

$ run-qemu -hda myvm.img -m 512 -vga std
ヒント: ホストで DHCP アドレスが取得できない場合、おそらくブリッジで iptables がデフォルトで立ち上がっているのが原因です。
  • パフォーマンスとセキュリティ上の理由でブリッジのファイアウォールは無効化するのが推奨されています [1]:
/etc/sysctl.d/10-disable-firewall-on-bridge.conf
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0

すぐに変更を適用するには sysctl -p /etc/sysctl.d/10-disable-firewall-on-bridge.conf を実行してください。

libvirt wikiFedora bug 512206 を参照。起動中にファイルが存在しないというエラーが起こるときは、起動時に bridge モジュールをロードするようにしてください。カーネルモジュール#ロード を参照。

または、次のようにルールを追加することで全てのトラフィックをブリッジで通すように iptables を設定することができます:

-I FORWARD -m physdev --physdev-is-bridged -j ACCEPT

VDE2 によるネットワーク

VDE とは?

VDE は Virtual Distributed Ethernet の略です。uml_switch の拡張として始まりました。仮想ネットワークを管理するためのツールボックスです。

基本的にはソケットである仮想スイッチを作成して、物理マシンと仮想マシンを両方ともスイッチに"接続"するという考えになります。以下で説明する設定はとてもシンプルです。ただし、VDE はさらに強力な力を持っており、仮想スイッチ同士を接続したり、別のホストでスイッチを動作させスイッチのトラフィックを監視することなどができます。プロジェクトのドキュメント を読むことを推奨。

この方法の利点はユーザーに sudo 権限を与える必要がないということです。通常ユーザーに modprobe の実行を許可する必要はありません。

基本

VDE サポートは vde2 パッケージでインストールできます。

この設定では、tun/tap を使ってホストに仮想インターフェイスを作成します。tun モジュールをロード (詳しくはカーネルモジュールを参照):

# modprobe tun

仮想スイッチを作成:

# vde_switch -tap tap0 -daemon -mod 660 -group users

上記のコマンドでスイッチと tap0 が作成され、接続され、そして users グループのユーザーがスイッチを使えるようにします。

インターフェイスは接続されてもまだ設定がされていません。設定するには、次のコマンドを実行:

# ip addr add 192.168.100.254/24 dev tap0

そして、通常ユーザーで -net オプションを使って KVM を実行してください:

$ qemu-system-x86_64 -net nic -net vde -hda [...]

物理ネットワークでやるのと同じようにゲストのネットワークを設定してください。

ヒント: 仮想マシンからインターネットにアクセスするためにタップデバイスに NAT を設定することができます。詳しくはインターネット共有#NAT の有効化を見て下さい。

起動スクリプト

VDE を起動するメインスクリプトの例:

/etc/systemd/scripts/qemu-network-env
#!/bin/sh
# QEMU/VDE network environment preparation script

# The IP configuration for the tap device that will be used for
# the virtual machine network:

TAP_DEV=tap0
TAP_IP=192.168.100.254
TAP_MASK=24
TAP_NETWORK=192.168.100.0

# Host interface
NIC=eth0

case "$1" in
  start)
        echo -n "Starting VDE network for QEMU: "

        # If you want tun kernel module to be loaded by script uncomment here 
	#modprobe tun 2>/dev/null
	## Wait for the module to be loaded
 	#while ! lsmod | grep -q "^tun"; do echo "Waiting for tun device"; sleep 1; done

        # Start tap switch
        vde_switch -tap "$TAP_DEV" -daemon -mod 660 -group users

        # Bring tap interface up
        ip address add "$TAP_IP"/"$TAP_MASK" dev "$TAP_DEV"
        ip link set "$TAP_DEV" up

        # Start IP Forwarding
        echo "1" > /proc/sys/net/ipv4/ip_forward
        iptables -t nat -A POSTROUTING -s "$TAP_NETWORK"/"$TAP_MASK" -o "$NIC" -j MASQUERADE
        ;;
  stop)
        echo -n "Stopping VDE network for QEMU: "
        # Delete the NAT rules
        iptables -t nat -D POSTROUTING "$TAP_NETWORK"/"$TAP_MASK" -o "$NIC" -j MASQUERADE

        # Bring tap interface down
        ip link set "$TAP_DEV" down

        # Kill VDE switch
        pgrep -f vde_switch | xargs kill -TERM 
        ;;
  restart|reload)
        $0 stop
        sleep 1
        $0 start
        ;;
  *)
        echo "Usage: $0 {start|stop|restart|reload}"
        exit 1
esac
exit 0

上のスクリプトを使う systemd サービスの例:

/etc/systemd/system/qemu-network-env.service
[Unit]
Description=Manage VDE Switch

[Service]
Type=oneshot
ExecStart=/etc/systemd/scripts/qemu-network-env start
ExecStop=/etc/systemd/scripts/qemu-network-env stop
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

qemu-network-env が実行できるようにパーミッションを変更:

# chmod u+x /etc/systemd/scripts/qemu-network-env

通常の方法で起動することができます (詳しくは systemd#ユニットを使う を参照):

# systemctl start qemu-network-env

他の方法

上の方法が動作しない場合やカーネル設定, TUN, dnsmasq, iptables を変えたくない場合は以下のコマンドで同じ結果になります。

# vde_switch -daemon -mod 660 -group users
# slirpvde --dhcp --daemon

ホストのネットワークの接続を使って VM を起動するには:

$ qemu-system-x86_64 -net nic,macaddr=52:54:00:00:EE:03 -net vde disk_image

VDE2 Bridge

quickhowto: qemu networking using vde, tun/tap, and bridge に基づいています。vde に接続された仮想マシンは外部から参照出来る状態になります。例えば、ADSL ルーターから直接 DHCP の設定を個々の仮想マシンが受け取ることが可能です。

基本

tun モジュールと bridge-utils パッケージが必要です。

vde2/tap デバイスを作成:

# vde_switch -tap tap0 -daemon -mod 660 -group users
# ip link set tap0 up

ブリッジを作成:

# brctl addbr br0

デバイスを追加:

# brctl addif br0 eth0
# brctl addif br0 tap0

ブリッジインターフェイスを設定:

# dhcpcd br0

起動スクリプト

全てのデバイスを設定する必要があります。ブリッジに必要なのは IP アドレスだけです。ブリッジの物理デバイスは (例: eth0)、netctl でカスタム Ethernet プロファイルを使います:

/etc/netctl/ethernet-noip
Description='A more versatile static Ethernet connection'
Interface=eth0
Connection=ethernet
IP=no

以下のカスタム systemd サービスを使うことで users ユーザーグループで使用する VDE2 tap インターフェイスを作成することができます。

/etc/systemd/system/vde2@.service
[Unit]
Description=Network Connectivity for %i
Wants=network.target
Before=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/vde_switch -tap %i -daemon -mod 660 -group users
ExecStart=/usr/bin/ip link set dev %i up
ExecStop=/usr/bin/ip addr flush dev %i
ExecStop=/usr/bin/ip link set dev %i down

[Install]
WantedBy=multi-user.target

そして最後に、netctl でブリッジネットワークを作成することが可能です。

グラフィック

QEMU は様々なグラフィック出力を使うことができます: std, qxl, vmware, virtio, cirrus, none

std

-vga std では 2560 x 1600 ピクセルまでの解像度を得ることができます。QEMU 2.2 からデフォルトとなっています。

qxl

QXL は 2D サポートのある準仮想化グラフィックドライバーです。使用するには -vga qxl オプションを使用してゲストにドライバーをインストールしてください。QXL を使用する場合 SPICE を使うことでグラフィックの性能を向上させることができます。

Linux ゲストでは、パフォーマンスを得るために qxlbochs_drm カーネルモジュールをロードしてください。

SPICE

Spice プロジェクト は仮想化されたデスクトップデバイスを操作するための完全な、オープンソースのソリューションを提供することを目的としています。主として QEMU 仮想マシンへの高品質なリモートアクセスを提供することに力を注いでいます。

グラフィック出力に QXL を使用している場合にのみ SPICE を利用できます。

リモートデスクトッププロトコルとして SPICE を使用して起動するコマンドの例:

$ qemu-system-x86_64 -vga qxl -spice port=5930,disable-ticketing -device virtio-serial-pci -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 -chardev spicevmc,id=spicechannel0,name=vdagent

-device virtio-serial-pci オプションは virtio-serial デバイスを追加し、-device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 は spice vdagent のためにデバイスのポートを開いて -chardev spicevmc,id=spicechannel0,name=vdagent はポートに spicevmc chardev を追加します。virtserialport デバイスの chardev= オプションは chardev オプションに指定する id= オプションと一致している必要があります (上記の例では spicechannel0)。また、ポートの名前はゲストの vdagent が使用する名前空間である com.redhat.spice.0 でなければなりません。最後に name=vdagent を指定することで spice はチャンネルの利用目的を使用することができます。

ヒント: SPICE モードの QEMU はリモートデスクトップサーバーのように振る舞うため、-daemonize パラメータを付けて QEMU をデーモンモードで起動するとより便利です。

それから SPICE クライアントでゲストに接続してください。プロトコルの開発者は SPICE クライアントとして virt-viewer を推奨しています:

$ remote-viewer spice://127.0.0.1:5930

リファレンス・テスト実装である spice-gtk3[リンク切れ: 置換パッケージ: spice-gtk] を使うこともできおます:

$ spicy -h 127.0.0.1 -p 5930

クライアントは他にも存在します [2]

TCP ポートの代わりに Unix ソケットを使用することで、パフォーマンスが向上するという報告があります [3]。例:

$ qemu-system-x86_64 -vga qxl -device virtio-serial-pci -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 -chardev spicevmc,id=spicechannel0,name=vdagent -spice unix,addr=/tmp/vm_spice.socket,disable-ticketing

接続するには:

$ remote-viewer spice+unix:///tmp/vm_spice.socket

または:

$ spicy --uri="spice+unix:///tmp/vm_spice.socket"

マルチモニターやクリップボードの共有などのサポートが必要な場合、以下のパッケージをゲスト側でインストールしてください:

インストールしたら spice-vdagentd.service を有効にしてください。

SPICE によるパスワード認証

SPICE のパスワード認証を有効にしたい場合、-spice 引数から disable-ticketing を外して password=yourpassword を追加してください。例:

$ qemu-system-x86_64 -vga qxl -spice port=5900,password=yourpassword -device virtio-serial-pci -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 -chardev spicevmc,id=spicechannel0,name=vdagent

SPICE サーバーに接続する際に SPICE クライアントがパスワードを要求するようになります。

TLS 暗号化

SPICE サーバーとの通信を TLS で暗号化するよう設定することもできます。まず、以下のファイルが含まれたディレクトリが必要です (ファイルの名前は完全に一致している必要があります):

  • ca-cert.pem: CA マスター証明書。
  • server-cert.pem: ca-cert.pem で署名されたサーバー証明書。
  • server-key.pem: サーバー秘密鍵。

サーバー自身の CA で自己署名証明書を生成する方法は Spice User Manual に例が載っています。

証明書を用意したら -spice 引数を使って SPICE で QEMU を起動してください: -spice tls-port=5901,password=yourpassword,x509-dir=/path/to/pki_certs (/path/to/pki_certs は証明書が含まれているディレクトリのパスに置き換えてください)。

起動したら virt-viewer を使ってサーバーに接続することが可能です:

$ remote-viewer spice://hostname?tls-port=5901 --spice-ca-file=/path/to/ca-cert.pem --spice-host-subject="C=XX,L=city,O=organization,CN=hostname" --spice-secure-channels=all

--spice-host-subject パラメータは server-cert.pem のサブジェクトにあわせて設定する必要があります。また、サーバー証明書を検証するために ca-cert.pem をクライアントにコピーしてください。

ヒント: --spice-host-subject に指定するサーバー証明書のサブジェクトは以下のコマンドで確認することができます:
$ openssl x509 -noout -subject -in server-cert.pem | cut -d' ' -f2- | sed 's/\///' | sed 's/\//,/g'

spice-gtk3[リンク切れ: 置換パッケージ: spice-gtk] を使用する場合:

$ spicy -h hostname -s 5901 --spice-ca-file=ca-cert.pem --spice-host-subject="C=XX,L=city,O=organization,CN=hostname" --spice-secure-channels=all

vmware

多少バグが存在しますが、std や cirrus よりもパフォーマンスが上です。ゲストに、VMware ドライバーをインストールしてください (Arch Linux ゲストなら xf86-video-vmwarexf86-input-vmmouse)。

virtio

virtio-vga / virtio-gpuvirgl がベースの順仮想化 3D グラフィックドライバーです。発展途上であり、カーネルバージョンが新しい (4.4 以上) Linux ゲストで --with-gallium-drivers=virgl オプションを付けてコンパイルされた mesa (>=11.2) でしか動作しません。

ゲスト環境で 3D アクセラレーションを有効にするには -vga virtio を使って vga を選択して -display sdl,gl=on (sdl ディスプレイ出力) または -display gtk,gl=on (gtk ディスプレイ出力) を使用してディスプレイデバイスで opengl コンテキストを有効にしてください。ゲスト側のカーネルログを見ることで設定が問題ないか確認できます:

$ dmesg | grep drm 
[drm] pci: virtio-vga detected
[drm] virgl 3d acceleration enabled

2016年9月現在、spice プロトコルのサポートは開発中で、spice (>= 0.13.2) の開発版をインストールして qemu を再コンパイルすることでテストできます。

詳しくは kraxel のブログ を見てください。

cirrus

cirrus グラフィカルアダプタは 2.2 以前まではデフォルト でした。新しいシステムでは 使用しないほうがよい とされています。

none

これは VGA カードが全くない PC と同じようになります。-vnc オプションを使ってもアクセスすることはできません。また、QEMU に VGA カードをエミュレートさせ SDL ディスプレイを無効にする -nographic オプションとは異なります。

vnc

-nographic オプションを使っている場合、-vnc display オプションを追加することで QEMU に display を listen させて VGA ディスプレイを VNC セッションにリダイレクトさせることができます。#ブート時に QEMU 仮想マシンを起動する セクションの設定例にこれのサンプルがあります。

$ qemu-system-x86_64 -vga std -nographic -vnc :0
$ gvncviewer :0

VNC を使う際、ここで示されているようなキーボードの問題が発生するかもしれません。解決方法は、QEMU で -k オプションを使わないことと、gtk-vncgvncviewer を使うことです。libvirt のメーリングリストに投稿された この メッセージも参照してください。

オーディオ

ホスト

QEMU で使用するオーディオドライバーは QEMU_AUDIO_DRV 環境変数で設定できます:

$ export QEMU_AUDIO_DRV=pa

以下のコマンドを実行すると PulseAudio に関する QEMU の設定オプションが表示されます:

$ qemu-system-x86_64 -audio-help | awk '/Name: pa/' RS=

表示されたオプションは以下のように環境変数としてエクスポートできます:

$ export QEMU_PA_SINK=alsa_output.pci-0000_04_01.0.analog-stereo.monitor
$ export QEMU_PA_SOURCE=input

ゲスト

使用できるエミュレーションオーディオドライバーのリストを表示するには:

$ qemu-system-x86_64 -soundhw help

例えば、ゲストで hda ドライバーを使用するには -soundhw hda を使ってください。

ノート: ゲストマシンのエミュレートされたビデオグラフィックカードドライバーによって問題が起こることがあります。ドライバーをそれぞれ試してみてください。qemu-system-x86_64 -h | grep vga で利用可能なオプションを確認できます。

virtio ドライバーのインストール

QEMU にで virtio ドライバーを使って準仮想化ブロックとネットワークデバイスをゲストが利用できるようにすることができ、より良いパフォーマンス・少ないオーバーヘッドを実現します。

  • virtio ブロックデバイスにはシンプルな -hd* の代わりに -drive オプションと if=virtio が必要です:
$ qemu-system-x86_64 -boot order=c -drive file=disk_image,if=virtio
ノート: 起動するには -boot order=c が絶対に必要です。-hd* では自動で検出されません。
  • ネットワークでもほぼ同じです:
$ qemu-system-x86_64 -net nic,model=virtio
ノート: ゲストマシンに virtio デバイスのドライバーが存在する場合にのみ機能します。Arch Linux を含む Linux には必要なドライバーが入っていますが、他のオペレーティングシステムで virtio デバイスが使える保証はありません。

(Arch) Linux ゲストを用意する

Arch Linux ゲストをインストールした後 virtio デバイスを使うには、次のモジュールをゲストでロードする必要があります: virtio, virtio_pci, virtio_blk, virtio_net, virtio_ring。32ビットのゲストの場合、特定の "virtio" モジュールは必要ありません。

virtio ディスクから起動したい場合、イニシャル RAM ディスクに必要なモジュールを含ませなければなりません。デフォルトでは、mkinitcpioautodetect フックによって管理されています。もしくは /etc/mkinitcpio.confMODULES 行を使って必要なモジュールを含めてイニシャル RAM ディスクをリビルドしてください。

/etc/mkinitcpio.conf
MODULES="virtio virtio_blk virtio_pci virtio_net"

Virtio ディスクは前に v が付いて認識されます (例: vda, vdb など)。なので、virtio ディスクから起動する際は /etc/fstab/boot/grub/grub.cfg などに変更を加える必要があります。

ヒント: /etc/fstab とブートローダーの両方で UUID を使ってディスクを指定している場合、何もする必要はありません。

KVM による準仮想化に関する詳細は こちら で読むことができます。

qemu-guest-agent をインストールすることでハイパーバイザの管理機能を拡張する QMP コマンドのサポートを得ることができます。パッケージをインストールしたら qemu-ga.service を起動・有効化してください。

Windows ゲストを用意する

ノート: Windows 8.1 ゲストを Windows 10 にアップグレードするには、一時的に CPU を core2duo,nx にしてインストールするしかありません [4]。インストール後は他の CPU 設定に戻して大丈夫です。

ブロックデバイスドライバー

Windows の新規インストール

Windows には virtio ドライバーが付属していません。そのため、インストール時にロードする必要があります。基本的には2つの方法が存在します: フロッピーディスクを使用するか ISO ファイルを使用するかです。どちらのイメージも Fedora のリポジトリ からダウンロードできます。

フロッピーディスクを使う方法は QEMU の電源を入れた最初のときに F6 (新しい Windows では Shift-F6) を押さなければいけないため難易度が高くなります。VNC コンソールウィンドウに接続するのに時間が必要であるためです。起動シーケンスに遅延時間を追加することができます。起動時に遅延を適用する方法は qemu(1) を参照してください。

ISO を使ってドライバーをロードする方法は Windows Vista あるいは Windows Server 2008 以降でないと使用できません。virtio ドライバーでイメージをロードして、それから最初のディスクデバイスで cdrom デバイスと Windows インストーラーをロードします:

$ qemu-system-x86_64 ... \
-drive file=/path/to/primary/disk.img,index=0,media=disk,if=virtio \
-drive file=/path/to/installer.iso,index=2,media=cdrom \
-drive file=/path/to/virtio.iso,index=3,media=cdrom \
...

インストール時に Windows インストーラーはプロダクトキーを要求してチェックを行います。"Where do you want to install Windows?" 画面では、ディスクが見つけられないという警告が表示されます。以下の手順に従ってください (アップデート適用済みの Windows Server 2012 R2 がベース):

  • Load Drivers オプションを選択。
  • "Hide drivers that aren't compatible with this computer's hardware" のチェックを外す。
  • Browse ボタンをクリックして virtio iso の CDROM を開く (通常は "virtio-win-XX" という名前になります)。
  • E:\viostor\[your-os]\amd64 を選択して OK を押す。
  • Next をクリック。

これで virtio ディスクが表示されるので、選択して、フォーマット・インストールすることができます。

virtio を使用するように既存の Windows 仮想マシンを変更

virtio ディスクから起動するように Windows ゲストを用意するのはやや面倒です。

Fedora のリポジトリ から virtio ディスクドライバーをダウンロードすることができます。

そして Windows がドライバーを検索するように、新しいディスクイメージを作成する必要があります。例:

$ qemu-img create -f qcow2 fake.qcow2 1G

(virtio モードの) フェイクディスクと CD-ROM とドライバーで元の Windows ゲストを起動 (ブートディスクを IDE モードで使う):

$ qemu-system-x86_64 -m 512 -vga std -drive file=windows_disk_image,if=ide -drive file=fake.qcow2,if=virtio -cdrom virtio-win-0.1-81.iso

Windows はフェイクディスクを検出してそのドライバーを検索します。ドライバーが見つからない場合は、Device Manager を開いて、エクスクラメーションマークのアイコンが付いた SCSI ドライブを探して (開いて下さい)、Update driver をクリックして仮想 CD-ROM を選択してください。ディレクトリを再帰的に検索すると書かれたチェックボックスを選択するのを忘れずに。

インストールが成功したら、仮想マシンを止めて virtio モードのブートディスクで再起動することができます:

$ qemu-system-x86_64 -m 512 -vga std -drive file=windows_disk_image,if=virtio
ノート: ブルースクリーンになってしまう場合は、-m パラメータを忘れていないこと、ドライバーをインストールする前にシステムドライブを ide ではなく virtio を使って起動していないことを確認してください。

ネットワークドライバー

virtio ネットワークドライバーのインストールはもう少し簡単で、上記に -net 引数を追加します:

$ qemu-system-x86_64 -m 512 -vga std -drive file=windows_disk_image,if=virtio -net nic,model=virtio -cdrom virtio-win-0.1-74.iso

Windows はネットワークアダプタを検出してそのドライバーを検索します。ドライバーが見つからない場合は、Device Manager を開いて、エクスクラメーションマークのアイコンが付いたネットワークアダプタを探して (開いて下さい)、Update driver をクリックして仮想 CD-ROM を選択してください。ディレクトリを再帰的に検索すると書かれたチェックボックスを選択するのを忘れずに。

バルーンドライバー

(virsh コマンドの dommemstat を使うなどして) ゲストのメモリ状態を監視したりメモリの容量を実行中に変えたい場合、ゲストバルーンドライバーをインストールする必要があります。

Device Manager を開いて System devicesPCI standard RAM Controller (あるいは Other devices の unrecognized PCI controller) から Update driver を選択してください。ウィンドウが開いたら Browse my computer... を選んで CD-ROM を選択してください (必ず Include subdirectories チェックボックスにチェックを入れてください)。インストールしたら再起動してください。ドライバーがインストールされてバルーンを膨張させることができるようになります (例えば hmp の balloon memory_size コマンドでバルーンができるかぎり多くのメモリを取得してゲストの利用可能なメモリ容量を memory_size まで縮小します)。ただしゲストのメモリ状態を監視するには、さらに Balloon サービスをインストールする必要があります。管理者としてコマンドラインを開いて CD-ROM から Balloon ディレクトリの奥に入ってください。amd64 (x86) ディレクトリまで入ったら blnsrv.exe -i を実行することでインストールが実行されます。その後 virshdommemstat コマンドでサポートされている値が出力されるはずです。

FreeBSD ゲストを用意する

FreeBSD 8.3 以降を使っている場合は emulators/virtio-kmod port をインストールしてください、10.0-CURRENT ではカーネルに含まれています。インストール後、/boot/loader.conf ファイルに以下を追加します:

virtio_loader="YES"
virtio_pci_load="YES"
virtio_blk_load="YES"
if_vtnet_load="YES"
virtio_balloon_load="YES"

そして次を実行して /etc/fstab を修正してください:

sed -i bak "s/ada/vtbd/g" /etc/fstab

それから /etc/fstab が問題ないか確認してください。何かがおかしい場合、レスキュー CD で起動して /etc/fstab.bak/etc/fstab にコピーします。

QEMU モニタ

QEMU の実行中、仮想マシンを操作するためのモニタコンソールが表示されます。QEMU モニタには仮想マシンの情報を取得したりデバイスをホットプラグしたり、仮想マシンの状態を保存するスナップショットを作成するなどの機能があります。利用可能なコマンドのリストは QEMU モニタコンソールで help または ? を実行したり、QEMU 公式ドキュメント で確認できます。

モニタコンソールにアクセス

デフォルトグラフィックオプションの std を使用している場合、QEMU ウィンドウで Ctrl+Alt+2 を押すか View > compatmonitor0 をクリックすることで QEMU モニタにアクセスできます。仮想マシンのグラフィックビューに戻るには Ctrl+Alt+1 を押すか View > VGA をクリックします。

ただし、モニタにアクセスする標準の方法は QEMU がサポートしている全てのグラフィック出力で使えるわけではありません。モニタにアクセスする別の方法として以下の方法があります:

  • telnet: -monitor telnet:127.0.0.1:port,server,nowait パラメータを付けて QEMU を起動してください。仮想マシンが起動したら telnet 経由でモニタにアクセスできます:
$ telnet 127.0.0.1 port
ノート: listen する IP として 127.0.0.1 を指定した場合、QEMU が動作している同一ホストからのみモニタに接続できるようになります。リモートホストから接続したい場合、QEMU が 0.0.0.0 を listen するように指定する必要があります: -monitor telnet:0.0.0.0:port,server,nowait。接続は暗号化されず認証も不要であるため、ファイアウォールが設定されていてローカルネットワークが信頼できる場合のみこの方法を使ってください。
  • UNIX ソケット: -monitor unix:socketfile,server,nowait パラメータを付けて QEMU を起動してください。socat または openbsd-netcat を使って接続することができます。

例えば QEMU を以下のコマンドで起動した場合:

$ qemu-system-x86_64 [...] -monitor unix:/tmp/monitor.sock,server,nowait [...]

以下のコマンドでモニタに接続できます:

$ socat - UNIX-CONNECT:/tmp/monitor.sock

または:

$ nc -U /tmp/monitor.sock
  • TCP: -monitor tcp:127.0.0.1:port,server,nowait パラメータを付けることで TCP 経由でモニタにアクセスできます。openbsd-netcat または gnu-netcat をインストールして netcat で接続してください:
$ nc 127.0.0.1 port
ノート: QEMU が動作しているホスト以外のデバイスから tcp ソケットに接続したい場合、telnet と同じように 0.0.0.0 を使うようにしてください。
  • 標準 I/O: -monitor stdio 引数を付けて起動することで同じターミナルから自動的にモニタにアクセスすることができます。

モニタコンソールを使って仮想マシンにキーボードの押下を送信

設定によっては仮想マシン上で一部のキーの組み合わせがホストによって邪魔されて使えない場合があります (tty を切り替える Ctrl+Alt+F* など)。特定のキーの組み合わせについてはモニタコンソールを使ってキーを送信することで問題を解決できます。モニタに切り替えてから sendkey コマンドを使って仮想マシンにキーの押下を送信してください。例:

(qemu) sendkey ctrl-alt-f2

モニタコンソールを使ってスナップショットを作成・管理

ノート: スナップショット機能は仮想マシンのディスクイメージが qcow2 形式の場合にのみ利用できます。raw イメージでは使用できません。

ときには仮想マシンの現在の状態を保存して何か問題が発生したときに仮想マシンの状態を元に戻したいということもあるでしょう。QEMU のモニタコンソールにはスナップショットを作成・管理してマシンの状態をリバートするのに必要なユーティリティが備わっています。

  • savevm name を使うことで name という名前のスナップショットが作成されます。
  • loadvm name をしよすうると仮想マシンがスナップショット name の状態に戻ります。
  • delvm namename という名前のスナップショットが削除されます。
  • 保存済みのスナップショットのリストは info snapshots で確認できます。スナップショットは自動付与される ID 番号とユーザーがスナップショットを作成するときに付けた名前で識別できます。

immutable モードで仮想マシンを起動

-snapshot パラメータを付けて QEMU を起動することで仮想マシンを凍った状態で実行することができ、仮想マシンの電源が来られたときに全ての変更は破棄されます。ゲストによるディスクイメージの書き込みがあったときは、/tmp の一時ファイルに変更が保存され QEMU が停止したときに消去されます。

ただしマシンが frozen モードで実行中のとき、モニタコンソールを使って以下のコマンドを実行することで変更をディスクイメージに保存することが可能です:

(qemu) commit

frozen モードで実行中にスナップショットが作成されると同じようにディスクに変更をコミットしないかぎり QEMU の終了時に破棄されます。

モニタコンソールによる一時停止と電源オプション

モニタコマンドを使って物理マシンの操作を QEMU でエミュレートできます:

  • system_powerdown は仮想マシンに ACPI シャットダウンリクエストを送信します。物理マシンの電源ボタンを押したときと同じような動きになります。
  • system_reset は物理マシンのリセットボタンと同じように仮想マシンをリセットします。仮想マシンが正常に再起動されないためデータが消失したりファイルシステムが破損する可能性があります。
  • stop は仮想マシンを停止します。
  • cont は仮想マシンを停止した状態から復帰します。

仮想マシンのスクリーンショットの取得

モニタコンソールで以下のコマンドを実行することで PPM 形式で仮想マシンのグラフィックディスプレイのスクリーンショットを取得できます:

(qemu) screendump file.ppm

ヒントとテクニック

ブート時に QEMU 仮想マシンを起動する

libvirt を使う

libvirt を使って仮想マシンをセットアップした場合、virsh autostart や virt-manager の GUI を通して、仮想マシンの Boot Options から "Start virtual machine on host boot up" を選択することでホストの起動時に仮想マシンを起動するように設定することができます。

カスタムスクリプト

起動時に QEMU VM を実行するように、以下の systemd ユニットと設定を使うことができます。

/etc/systemd/system/qemu@.service
[Unit]
Description=QEMU virtual machine

[Service]
Environment="type=system-x86_64" "haltcmd=kill -INT $MAINPID"
EnvironmentFile=/etc/conf.d/qemu.d/%i
PIDFile=/tmp/%i.pid
ExecStart=/usr/bin/env qemu-${type} -name %i -nographic -pidfile /tmp/%i.pid $args
ExecStop=/bin/sh -c ${haltcmd}
TimeoutStopSec=30
KillMode=none

[Install]
WantedBy=multi-user.target
ノート:
  • systemd.service(5)systemd.kill(5) の man ページによれば、KillMode=none オプションの使用が必須です。このオプションがないと ExecStop コマンド (一行 echo するだけ) が終了した後にすぐにメインの qemu プロセスがキルされることになり、システムを正しくシャットダウンできなくなってしまいます。
  • PIDFile オプションを使用しないと systemd は qemu のメインプロセスが終了したかどうか通知できず、システムが正しくシャットダウンできなくなります。ホスト環境でシャットダウンしても仮想マシンのシャットダウンを待機しなくなってしまいます。

VM ごとに、/etc/conf.d/qemu.d/vm_name という名前の設定ファイルを作成して、以下の変数を設定します:

type
実行する QEMU バイナリ。指定すれば、/usr/bin/qemu- が前に付けられて VM を起動するのにそのバイナリが使われます。例えば type="system-arm"qemu-system-arm イメージが起動できます。
args
起動するときの QEMU コマンドライン。-name ${vm} -nographic はいつも前に付けます。
haltcmd
VM を安全にシャットダウンするためのコマンド。例えば -monitor telnet:.. を使ってモニターに system_powerdown を送信して ACPI で VM の電源を切ります。SSH やその他の方法が使えます。

設定例:

/etc/conf.d/qemu.d/one
type="system-x86_64"

args="-enable-kvm -m 512 -hda /dev/mapper/vg0-vm1 -net nic,macaddr=DE:AD:BE:EF:E0:00 \
 -net tap,ifname=tap0 -serial telnet:localhost:7000,server,nowait,nodelay \
 -monitor telnet:localhost:7100,server,nowait,nodelay -vnc :0"

haltcmd="echo 'system_powerdown' | nc localhost 7100" # or netcat/ncat

# You can use other ways to shut down your VM correctly
#haltcmd="ssh powermanager@vm1 sudo poweroff"
/etc/conf.d/qemu.d/two
args="-enable-kvm -m 512 -hda /srv/kvm/vm2.img -net nic,macaddr=DE:AD:BE:EF:E0:01 \
 -net tap,ifname=tap1 -serial telnet:localhost:7001,server,nowait,nodelay \
 -monitor telnet:localhost:7101,server,nowait,nodelay -vnc :1"

haltcmd="echo 'system_powerdown' | nc localhost 7101"

以下のコマンドを使って、ブート時にそれぞれの仮想マシンが起動するように設定します:

# systemctl enable qemu@vm_name
# systemctl disable qemu@vm_name

シームレスなマウス

ゲストのオペレーティングシステムのウィンドウをクリックしたときにマウスが取り込まれないようにするには、-usb -device usb-tablet オプションを追加します。これによって QEMU はマウスを取り込むことなくマウスの位置を伝えることができるようになります。また、このコマンドは有効化されている場合 PS/2 マウスエミュレーションを上書きします。例:

$ qemu-system-x86_64 -hda disk_image -m 512 -vga std -usb -device usb-tablet

上のコマンドで動作しない場合は、#マウスカーソルが敏感すぎたり迷走する を参照してみて下さい。

ホスト USB デバイスのパススルー

VM からホストに接続された物理 USB デバイスにアクセスするために、以下のオプションを使って QEMU を起動することができます:

$ qemu-system-x86_64 -usbdevice host:vendor_id:product_id disk_image

lsusb コマンドでデバイスの vendor_idproduct_id がわかります。

デフォルトで qemu によってエミュレートされる I440FX チップセットはシングル UHCI コントローラ (USB 1) のため、-usbdevice オプションは物理デバイスを USB 1 にアタッチしますが新しいデバイスでは場合によっては問題が発生することがあります。-machine type=q35 オプションを使って12個までのデバイスをサポートする EHCI コントローラを提供する ICH9 チップセットをエミュレートさせることで解決します。

-device usb-ehci,id=ehci-device nec-usb-xhci,id=xhci オプションを使って EHCI (USB 2) または XHCI (USB 3) コントローラをエミュレートして以下のように -device usb-host,.. オプションを使って物理デバイスにアタッチするという方法もあります:

-device usb-host,bus=controller_id.0,vendorid=0xvendor_id,productid=0xproduct_id

...,port=<n> 設定を追加することで仮想コントローラの物理ポートを指定することができます。複数の USB デバイスを VM に追加したい場合に有用です。

ノート: QEMU の実行時にパーミッションエラーが起こる場合は、Udev#udev ルールを記述する のデバイスのパーミッションの設定方法を見て下さい。

SPICE による USB リダイレクト

SPICE を使用しているのであれば、QEMU コマンドで指定しなくてもクライアントから仮想マシンに USB デバイスをリダイレクトすることが可能です。USB スロットの数を設定することができます (スロットの数によって同時にリダイレクトできるデバイスの最大数が決まります)。-usbdevice を使用する方法と違って SPICE でリダイレクトする場合は仮想マシンを起動した後に USB デバイスをホットスワップすることができ、リダイレクトから USB デバイスを削除・追加するのに仮想マシンを停止する必要がありません。また、ネットワーク経由でクライアントからサーバーに USB デバイスをリダイレクトすることもできます。QEMU 仮想マシンで USB デバイスを最大限に活用することが可能です。

使用するには USB リダイレクトスロットにそれぞれ EHCI/UHCI コントローラーと SPICE リダイレクトチャンネルを追加する必要があります。例えば、3つの USB スロットをリダイレクトで使用できるように SPICE モードで仮想マシンを起動するには QEMU コマンドに以下の引数を追加します:

-device ich9-usb-ehci1,id=usb \
-device ich9-usb-uhci1,masterbus=usb.0,firstport=0,multifunction=on \
-device ich9-usb-uhci2,masterbus=usb.0,firstport=2 \
-device ich9-usb-uhci3,masterbus=usb.0,firstport=4 \
-chardev spicevmc,name=usbredir,id=usbredirchardev1 \
-device usb-redir,chardev=usbredirchardev1,id=usbredirdev1 \
-chardev spicevmc,name=usbredir,id=usbredirchardev2 \
-device usb-redir,chardev=usbredirchardev2,id=usbredirdev2 \
-chardev spicevmc,name=usbredir,id=usbredirchardev3 \
-device usb-redir,chardev=usbredirchardev3,id=usbredirdev3

spice-gtk3[リンク切れ: 置換パッケージ: spice-gtk]spicy (Input > Select USB Devices for redirection) と virt-viewerremote-viewer (File > USB device selection) の両方ともリダイレクト機能をサポートしています。期待通りに動作させるには仮想マシンに SPICE ゲストツールをインストールする必要があります (詳しくは #SPICE セクションを参照してください)。

警告: クライアントから USB デバイスをリダイレクトしている間は、リダイレクトを停止するまでクライアントのオペレーティングシステムからデバイスを使うことはできなくなるので注意してください。特に入力デバイス (マウスやキーボード) をリダイレクトするときは注意しないと、SPICE のクライアントメニューから戻すことができなくなってしまいます。仮想マシンに入力デバイスをリダイレクトするとクライアントが入力デバイスに反応しなくなるためです。

KSM を有効にする

Kernel Samepage Merging (KSM) はアプリケーションがページをマージするように登録した他のプロセスとページをマージするようにカーネルに登録できるようにする Linux カーネルの機能です。この KSM 機構によってゲストの仮想マシンは互いにページを共有することが可能になります。同じようなゲストオペレーティングシステムが多数動作する環境では、メモリの使用量を著しく節約することができます。

KSM を有効にするには、次を実行してください:

# echo 1 > /sys/kernel/mm/ksm/run

systemd の一時ファイルを使って KSM を永続的に有効にできます:

/etc/tmpfiles.d/ksm.conf
w /sys/kernel/mm/ksm/run - - - - 1

KSM が動作しているとき、マージされるページが存在するために (つまり少なくとも2つの同じような VM が動いている)、/sys/kernel/mm/ksm/pages_shared はゼロになりません。詳しくは https://www.kernel.org/doc/Documentation/vm/ksm.txt を参照。

ヒント: KSM が問題なく動いているか確かめる簡単な方法として、ディレクトリのファイルの中身を全て表示する方法があります:
$ grep . /sys/kernel/mm/ksm/*

マルチモニターのサポート

Linux QXL ドライバーはデフォルトで4台までのマルチモニター (仮想スクリーン) をサポートしています。qxl.heads=N カーネルパラメータで変更することができます。

QXL デバイスのデフォルトの VGA メモリサイズは 16M です (VRAM のサイズは 64M です)。1920x1200 のモニターを2台使用しようとすると 2 × 1920 × 4 (色深度) × 1200 = 17.6 MiB の VGA メモリが必要になるためメモリが不足します。-vga qxl-vga none -device qxl-vga,vgamem_mb=32 に置き換えることでメモリ容量を変更できます。vgamem_mb を 64M 以上に増やした場合、vram_size_mb オプションも増やす必要があります。

コピーアンドペースト

ホストとゲスト間のコピーアンドペーストを行うには spice エージェント通信チャンネルを有効にする必要があります。それには virtio-serial デバイスをゲストに追加して、spice vdagent のためにポートを開かなければなりません。また、ゲストへの spice vdagent のインストールも必須です (Arch ゲストの場合は spice-vdagent、Windows ゲストの場合は Windows ゲストツール)。エージェントが動いていること (さらに、今後のために、自動で起動すること) を確認してください。QEMU で SPICE プロトコルを使う方法は #SPICE を参照してください。

Windows 特有のノート

QEMU は Windows 95 から Windows 10 まで全てのバージョンの Windows を動かすことができます。

QEMU で Windows PE を実行することも可能です。

高速スタートアップ

ノート: 電源設定を変更するには管理者権限が必要です。

Windows 8 (あるいはそれ移行) をゲストにする場合、コントロールパネルの電源オプションから"高速スタートアップ"を無効にしないと、起動時にゲストがフリーズすることがあります。

-smp オプションを正しく適用するために高速スタートアップを無効化しなくてはならないこともあります。

Remote Desktop Protocol

MS Windows ゲストを使っている場合、RDP を使ってゲスト VM に接続する方法もあります。VLAN を使用してしてゲストが同じネットワークにない場合、次を使って下さい:

$ qemu-system-x86_64 -nographic -net user,hostfwd=tcp::5555-:3389

そして Rdesktopfreerdp を使ってゲストに接続してください。例えば:

$ xfreerdp -g 2048x1152 localhost:5555 -z -x lan

トラブルシューティング

仮想マシンの動作が遅すぎる

仮想マシンのパフォーマンスを向上させることができる多数のテクニックがあります。例えば:

  • -cpu host オプションを使うことで QEMU にホストの CPU を正確にエミュレートさせることができます。このオプションを使わない場合、もっと一般的な CPU がエミュレートされます。
  • Windows ゲストの場合、Hyper-V enlightenments を有効にしてください: -cpu host,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time
  • ホストマシンに CPU が複数ある場合は、-smp オプションを使ってゲストにもっと多くの CPU を割り当てて下さい。
  • 仮想マシンに十分なメモリを割り当てているか確認してください。デフォルトでは、QEMU はそれぞれの仮想マシンに 128 MiB のメモリしか割り当てません。-m オプションを使って多めのメモリを割り当てて下さい。例えば、-m 1024 で仮想マシンは 1024 MiB のメモリを使って動作します。
  • 可能な限り KVM を使って下さい: QEMU の起動コマンドに -machine type=pc,accel=kvm を追加します。
  • ゲストのオペレーティングシステムのドライバーによってサポートされているときは、ネットワークやブロックデバイスに virtio を使って下さい。例えば:
$ qemu-system-x86_64 -net nic,model=virtio -net tap,if=tap0,script=no -drive file=disk_image,media=disk,if=virtio
  • ユーザーモードネットワークの代わりに TAP デバイスを使って下さい。#QEMU の Tap ネットワーク を参照。
  • ゲスト OS がディスクへの書き込みを頻繁に行う場合、ホストのファイルシステムで特定のマウントオプションを使うと良いかもしれません。例えば、ext4 ファイルシステムbarrier=0 オプションでマウントすることが考えられます。ファイルシステムのパフォーマンスを向上させるオプションは、場合によってデータの保全性を犠牲にする可能性があるので、変更するオプションのドキュメントを読んでおいたほうが無難です。
  • raw ディスクイメージを使っている場合、キャッシュを無効にする:
$ qemu-system-x86_64 -drive file=disk_image,if=virtio,cache=none
  • ネイティブの Linux AIO を使用する:
$ qemu-system-x86_64 -drive file=disk_image,if=virtio,aio=native,cache.direct=on
  • qcow2 ディスクイメージを使用している場合、十分な容量の L2 キャッシュを割り当てることで I/O の性能が著しく改善することがあります。L2 キャッシュを計算するときの 公式 は: l2_cache_size = disk_size * 8 / cluster_size です。デフォルトのクラスタサイズ 64K で、容量 8 GB の qcow2 イメージを作成した場合、最適な L2 キャッシュは 1 MB となります。QEMU はデフォルトでは 1 MB しか L2 キャッシュを使用しません。QEMU のコマンドラインでキャッシュの容量を指定することができます。例えば使用するキャッシュを 4 MB にするには:
$ qemu-system-x86_64 -drive file=disk_image,format=qcow2,l2-cache-size=4M
  • 複数の仮想マシンを同時に動かしていて、全て同じオペレーティングシステムをインストールしている場合、kernel same-page merging を有効にすることでメモリを節約できます。#KSM を有効にするを見てください。
  • 場合によっては、ゲストのオペレーティングシステムでメモリバルーニングドライバーを実行して QEMU を -balloon virtio オプションで起動することで、実行中の仮想マシンからメモリを回収することができます。

詳しくは http://www.linux-kvm.org/page/Tuning_KVM を参照してください。

マウスカーソルが敏感すぎたり迷走する

カーソルが画面を飛び回って手に負えない場合、QEMU を起動する前にターミナルに次を入力することで直るかもしれません:

$ export SDL_VIDEO_X11_DGAMOUSE=0

このコマンドで直ったら、~/.bashrc ファイルにコマンドを追加することができます。

カーソルが表示されない

マウスカーソルを表示するには -show-cursor を QEMU のオプションに追加してください。

オプションを追加しても表示されない場合、ディスプレイデバイスが正しく設定されているか確認してください。例: -vga qxl

カーソルが移動・アタッチできない

QEMU オプションの -usbdevice tablet-usb に置き換えてください。

キーボードが壊れているまたは矢印キーが動作しない

キーの一部が動かなかったり間違ったキーが押されてしまう (特に矢印キー) ときは、おそらくキーボードレイアウトをオプションとして指定する必要があります。キーボードレイアウトは /usr/share/qemu/keymaps で探すことができます。

$ qemu-system-x86_64 -k keymap disk_image

ウィンドウのリサイズでゲストのディスプレイが引き伸ばされる

デフォルトのウィンドウサイズに戻すには、Ctrl+Alt+u を押して下さい。

ioctl(KVM_CREATE_VM) failed: 16 Device or resource busy

-enable-kvm オプションを使って QEMU を起動した時に以下のようなエラーメッセージが表示される場合:

ioctl(KVM_CREATE_VM) failed: 16 Device or resource busy
failed to initialize KVM: Device or resource busy

他のハイパーバイザが動作しています。同時に複数のハイパーバイザを動かすのは推奨されていません、もしくは不可能です。

libgfapi エラーメッセージ

起動時に以下のエラーメッセージが表示される場合:

Failed to open module: libgfapi.so.0: cannot open shared object file: No such file or directory

任意の依存パッケージである GlusterFS が存在しないというだけなので無視して問題ありません。glusterfs パッケージをインストールすれば消えます。

ライブ環境でカーネルパニックが発生する

ライブ環境を起動した場合に以下が発生する場合:

[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown block(0,0)

-m VALUE スイッチを付けて適当な量の RAM を指定して VM を起動してみてください。RAM が足りなくなると上記のような問題が発生することがあります。

Windows 7 ゲストの音質が酷い

Windows 7 ゲストで hda オーディオドライバーを使用すると音質に問題が発生することがあります。QEMU の引数に -soundhw ac97 を指定してオーディオドライバーを ac97 に変更し、ゲストに Realtek AC'97 Audio Codecs の ac97 ドライバーをインストールすることで問題は解決します。詳しくは Red Hat Bugzilla – Bug 1176761 を参照してください。

Could not access KVM kernel module: Permission denied

以下のエラーが表示される場合:

libvirtError: internal error: process exited while connecting to monitor: Could not access KVM kernel module: Permission denied failed to initialize KVM: Permission denied

Systemd によって kvm グループに動的 id が割り当てられていることが原因です (FS#54943 を参照)。エラーを解決するには /etc/libvirt/qemu.conf ファイルを編集して以下の行を:

group = "78"

以下のように変更してください:

group = "kvm"

Windows の仮想マシンを起動したときに "System Thread Exception Not Handled"

Windows 8 や Windows 10 ゲストが起動時に "System Thread Exception Not Handled" という例外を発生させることがあります。実機で古いドライバーの動作がおかしいことが原因です。KVM では CPU のモデルを core2duo に設定することで解決します。

特定の Windows のゲームやアプリケーションでクラッシュやブルスクリーンが発生する

ときどき、物理マシンでは問題なく動作するのに、仮想マシンでアプリケーションを実行するとクラッシュが発生することがあります。dmesg -wH を実行したときに MSR というエラーが表示される場合、クラッシュの原因はゲストがサポートされていない Model-specific registers (MSR) にアクセスしようとしたときに KVM が General protection fault (GPF) を起こすためです。ゲームの最適化などの機能が機能しない場合、KVM モジュールに ignore_msrs=1 オプションを指定して実装されていない MSR へのアクセスを無視することで問題は解決します:

/etc/modprobe.d/kvm.conf
...
options kvm ignore_msrs=1
...

上記のオプションが役に立つのは以下のような場合です:

  • GeForce Experience でサポートされたいない PCU が存在するとエラーが表示される。
  • StarCraft 2 や L.A. Noire で KMODE_EXCEPTION_NOT_HANDLED が発生して Windows 10 がブルースクリーンになる。
警告: 未知の MSR のアクセスを無視すると、VM 内の他のソフトウェアや他の VM が動作しなくなる可能性があります。

参照