QEMU

提供: ArchWiki
2017年1月29日 (日) 00:36時点におけるKusakata (トーク | 投稿記録)による版 (文字列「[[zh-CN:」を「[[zh-hans:」に置換)
ナビゲーションに移動 検索に移動

関連記事

QEMU ホームページ より:

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

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

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

目次

インストール

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

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

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

AUR より:

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

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

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

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

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

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

また、ハードディスクイメージを qcow2 などのフォーマットにすることもできます。ゲストオペレーティングシステムが実際に仮想ハードディスク上のセクタに書き込んだ時にイメージファイルに容量を割り当てます。ホストシステムで占める容量はかなり少なくて済み、ゲストオペレーションにはフルサイズのイメージとして見えます。こちらの形式では 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-i386 img1.cow

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

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

警告: The backing image's absolute filesystem path is stored in the (binary) overlay image file. Changing the backing image's path requires some effort.

オリジナルの 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

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

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

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

$ qemu-system-i386 -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-i386 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. 再起動して dmesgDMAR があることを確認して IOMMU が有効になっていることをチェックしてください: [0.000000] DMAR: IOMMU enabled
  4. -machine に応じて iommu=on または q35,iommu=on をオプションとして追加してください。

ホスト・ゲスト 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-i386 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-toolsAUR パッケージに入っている 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-i386 -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 になってることを確認します。

Now, create a single primary partition corresponding to /dev/hdaN. It should start at cylinder 2 and end at the end of the disk (note that the number of cylinders now differs from what it was when you entered fdisk.

Finally, 'w'rite the result to the file: you are done. You now have a partition you can mount directly from your host, as well as part of a QEMU disk image:

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

You can, of course, safely set any bootloader on this disk image using QEMU, provided the original /dev/hdaN partition contains the necessary tools.

ネットワーク

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

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

リンク層アドレス

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

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

$ qemu-system-i386 -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-i386 -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))

In a script, you can use for example:

vm_name="VM Name"
qemu-system-i386 -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 デバイスや他の方法を使って下さい。

QEMU の Tap ネットワーク

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

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

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

警告: If you bridge together tap device and some host interface, such as eth0, your virtual machines will appear directly on the external network, which will expose them to possible attack. Depending on what resources your virtual machines have access to, you may need to take all the precautions you normally would take in securing a computer to secure your virtual machines. If the risk is too great, virtual machines have little resources or you set up multiple virtual machines, a better solution might be to use host-only networking and set up NAT. In this case you only need one firewall on the host instead of multiple firewalls for each guest.

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

ブリッジに 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-i386 -net nic -net bridge,br=bridge0 [...]

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

$ qemu-system-i386 -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
  • Create the script that QEMU uses to bring down the tap adapter in /etc/qemu-ifdown with root:kvm 750 permissions:
/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-i386 -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-i386 -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-i386 -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-i386 -vga qxl -spice port=5930,disable-ticketing -chardev spicevm

それから SPICE クライアントでゲストに接続してください。現在は spice-gtk3 が推奨されていますが、他のクライアントも利用できます [2]:

$ spicy -h 127.0.0.1 -p 5930

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,playback-compression=off
$ spicy --uri="spice+unix:///tmp/vm_spice.socket"

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

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-i386 -vga std -nographic -vnc :0
$ gvncviewer :0

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

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

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

  • virtio ブロックデバイスにはシンプルな -hd* の代わりに -drive オプションと if=virtio が必要です:
$ qemu-system-i386 -boot order=c -drive file=disk_image,if=virtio
ノート: 起動するには -boot order=c が絶対に必要です。-hd* では自動で検出されません。
  • ネットワークでもほぼ同じです:
$ qemu-system-i386 -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 ゲストを用意する

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

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

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

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

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

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

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

ネットワークドライバー

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

$ qemu-system-i386 -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 を選択してください。ディレクトリを再帰的に検索すると書かれたチェックボックスを選択するのを忘れずに。

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 にコピーします。

Tips and tricks

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

libvirt を使う

libvirt を使って仮想マシンをセットアップした場合、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
ExecStart=/usr/bin/env qemu-${type} -name %i -nographic $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 プロセスがキルされることになり、システムを正しくシャットダウンできなくなってしまいます。

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

シームレスなマウス

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

$ qemu-system-i386 -hda disk_image -m 512 -vga std -usbdevice tablet

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

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

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

$ qemu-system-i386 -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 ルールを記述する のデバイスのパーミッションの設定方法を見て下さい。

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 を次のオプションを使って起動します:

$ qemu-system-i386 -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 を追加します。

chardev オプションの id= オプションと、virtserialport デバイスの chardev= オプションは一致していなければなりません (この例では spicechannel0)。ポートの名前が com.redhat.spice.0 であることも重要です、これが vdagent がゲストで探す名前空間だからです。そして、name=vdagent を指定することで spice がこのチャンネルが何のためなのか知ることができます。

Windows 特有のノート

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

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

高速スタートアップ

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

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

Remote Desktop Protocol

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

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

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

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

トラブルシューティング

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

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

$ export SDL_VIDEO_X11_DGAMOUSE=0

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

カーソルが表示されない

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

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

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

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

$ qemu-system-i386 -k keymap disk_image

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

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

  • -cpu host オプションを使うことで QEMU にホストの CPU を正確にエミュレートさせることができます。このオプションを使わない場合、もっと一般的な CPU がエミュレートされます。
  • ホストマシンに CPU が複数ある場合は、-smp オプションを使ってゲストにもっと多くの CPU を割り当てて下さい。
  • 仮想マシンに十分なメモリを割り当てているか確認してください。デフォルトでは、QEMU はそれぞれの仮想マシンに 128 MiB のメモリしか割り当てません。-m オプションを使って多めのメモリを割り当てて下さい。例えば、-m 1024 で仮想マシンは 1024 MiB のメモリを使って動作します。
  • 可能な限り KVM を使って下さい: QEMU の起動コマンドに -machine type=pc,accel=kvm を追加します。
  • ゲストのオペレーティングシステムのドライバーによってサポートされているときは、ネットワークやブロックデバイスに virtio を使って下さい。例えば:
$ qemu-system-i386 -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-i386 -drive file=disk_image,if=virtio,cache=none
  • ネイティブの Linux AIO を使用する:
$ qemu-system-i386 -drive file=disk_image,if=virtio,aio=native
  • 複数の仮想マシンを同時に動かしていて、全て同じオペレーティングシステムをインストールしている場合、kernel same-page merging を有効にすることでメモリを節約できます:
# echo 1 > /sys/kernel/mm/ksm/run
  • 場合によっては、ゲストのオペレーティングシステムでメモリバルーニングドライバーを実行して QEMU を -balloon virtio オプションで起動することで、実行中の仮想マシンからメモリを回収することができます。

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

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

デフォルトのウィンドウサイズに戻すには、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 の任意の依存パッケージが存在しないというだけなので問題ありません。

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

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

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

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

参照