QEMU (日本語) - ArchWiki

# QEMU (日本語)

関連記事

- KVM
- Libvirt
- VirtualBox
- Xen
- VMware

QEMU ホームページ より:

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

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

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

## QEMU のインストール

公式リポジトリから qemu をインストールしてください。

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

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

- virt-manager (libvirt に含まれています)
- gnome-boxes
- qemu-launcher
- qtemu

AUR より:

- aqemu-git
- qemulator[broken link: package not found]

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

Tip: Arch Linux を仮想化する場合、既存の Arch Linux システム上に直接ディスクイメージを作成することができます、詳しくは Creating Arch Linux disk image#Install Arch Linux in a disk image without the installation media を見て下さい。

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

Tip: 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 ディスクを作成できます。

Note: raw イメージは `dd` や `fallocate` を使って必要なサイズのファイルを作成するだけでも作れます。
Warning: ハードディスクイメージを 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 イメージのパスが変更された場合、修正が必要になります。

Warning: 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

#### イメージのリサイズ

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

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

    $ qemu-img resize disk_image +10G

Tip: NTFS ブートファイルシステムを含んでいるイメージをリサイズする方法 (この例では qcow2 フォーマットのイメージを使っていますが他のフォーマットでも方法は同じです):

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

イメージを 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

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

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

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

Tip: If using an optical disk, it is a good idea to first dump the media to a file because this both improves performance and does not require you to have direct access to the devices (that is, you can run QEMU as a regular user without having to change access permissions on the media's device file). For example, if the CD-ROM device node is named `/dev/cdrom`, you can dump it to a file with the command:

    $ dd if=/dev/cdrom of=cd_image.iso

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

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

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

    $ qemu-system-i386 -cdrom iso_image -boot order=d qemu_image

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

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

Tip:

- デフォルトではマシンに割り当てられるメモリは 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-i386` や `qemu-system-x86_64` など、エミュレートするアーキテクチャによって異なります) を使って仮想化システムを実行します。使用方法は:

    $ qemu-system-i386 options disk_image

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

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

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

### KVM を有効にする

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

QEMU を KVM モードで起動するには、起動オプションに `-enable-kvm` を追加してください。

Note: GUI ツールを使って VM を起動した時にパフォーマンスが出ない場合、KVM サポートを確認してください。QEMU がソフトウェアエミュレーションにフォールバックしている可能性があります。

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

### ネットワーク

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

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

### QEMU の内蔵 SMB サーバー

QEMU のドキュメントには "内蔵の" SMB サーバーがあると書かれていますが、実際は自動的に生成された設定ファイルで 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` を開きます。

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

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

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

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

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

    # 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` パラメータを設定してロードしてください。

Tip: You can put an entry in `/etc/modprobe.d` to load the loop module with `max_part=15` every time, or you can put `loop.max_part=15` on the kernel command-line, depending on whether you have the `loop.ko` module built into your kernel or not.

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

    # losetup -f disk_image

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

    # mount /dev/loop0p1 mountpoint

#### kpartx を使う

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

    # kpartx -a /dev/loop0

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

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

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

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

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

Warning:

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

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

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

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

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

Note: In this example, it is the host's images that are being used, not the guest's. If you wish to use the guest's images, either mount `/dev/sda3` read-only (to protect the file system from the host) and specify the `/full/path/to/images` or use some kexec hackery in the guest to reload the guest's kernel (extends boot time).

    $ 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

Let us assume the resulting device is `/dev/loop0`, because we would not already have been using other loopbacks. Next step is to create the "merged" MBR + `/dev/hdaN` disk image using software RAID:

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

The resulting `/dev/md0` is what you will use as a QEMU raw disk image (do not forget to set the permissions so that the emulator can access it). The last (and somewhat tricky) step is to set the disk configuration (disk geometry and partitions table) so that the primary partition start point in the MBR matches the one of `/dev/hdaN` inside `/dev/md0` (an offset of exactly 16 * 512 = 16384 bytes in this example). Do this using `fdisk` on the host machine, not in the emulator: the default raw disc detection routine from QEMU often results in non-kilobyte-roundable offsets (such as 31.5 KB, as in the previous section) that cannot be managed by the software RAID code. Hence, from the the host:

    # fdisk /dev/md0

Press `X` to enter the expert menu. Set number of 's'ectors per track so that the size of one cylinder matches the size of your MBR file. For two heads and a sector size of 512, the number of sectors per track should be 16, so we get cylinders of size 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 ドライバーのインストール を参照。

### Link-level address caveat

By giving the `-net nic` argument to QEMU, it will, by default, assign a virtual machine a network interface with the link-level address `52:54:00:12:34:56`. However, when using bridged networking with multiple virtual machines, it is essential that each virtual machine has a unique link-level (MAC) address on the virtual machine side of the tap device. Otherwise, the bridge will not work correctly, because it will receive packets from multiple sources that have the same link-level address. This problem occurs even if the tap devices themselves have unique link-level addresses because the source link-level address is not rewritten as packets pass through the tap device.

Make sure that each virtual machine has a unique link-level address, but it should always start with `52:54:`. Use the following option, replace X with arbitrary hexadecimal digit:

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

Generating unique link-level addresses can be done in several ways:

1. Manually specify unique link-level address for each NIC. The benefit is that the DHCP server will assign the same IP address each time the virtual machine is run, but it is unusable for large number of virtual machines.

2. Generate random link-level address each time the virtual machine is run. Practically zero probability of collisions, but the downside is that the DHCP server will assign a different IP address each time. You can use the following command in a script to generate random link-level address in a `macaddr` variable:

    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. Use the following script `qemu-mac-hasher.py` to generate the link-level address from the virtual machine name using a hashing function. Given that the names of virtual machines are unique, this method combines the benefits of the aforementioned methods: it generates the same link-level address each time the script is run, yet it preserves the practically zero probability of collisions.

    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 マスカレードを通して物理ホストのネットワークにアクセスできるようになります。

Warning: 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 上の他のマシンが仮想マシンに通信できるようにしたい場合に価値があります。

Warning: 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 などの他の仮想化ソフトウェアではホストオンリーネットワークと呼ばれています。

Tip:

- If you want to set up IP masquerading, e.g. NAT for virtual machines, see the Internet sharing#Enable NAT page.
- You may want to have a DHCP server running on the bridge interface to service the virtual network. For example, to use the `172.20.0.1/16` subnet with dnsmasq as the DHCP server:

    # 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 を使用するブリッジネットワーク

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

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

Tip: ブリッジの作成に関する情報は Bridge with 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 [...]

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

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

The following describes how to bridge a virtual machine to a host interface such as `eth0`, which is probably the most common configuration. This configuration makes it appear that the virtual machine is located directly on the external network, on the same Ethernet segment as the physical host machine.

We will replace the normal Ethernet adapter with a bridge adapter and bind the normal Ethernet adapter to it. See http://en.gentoo-wiki.com/wiki/KVM#Networking_2[dead link 2013-07-23].

- ブリッジを制御するための `brctl` が入っている bridge-utils をインストール。

- IPv4 フォワーディングを有効にする:

    # sysctl net.ipv4.ip_forward=1

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

- `tun` モジュールをロードして起動時にロードするように設定してください。詳しくはカーネルモジュールを参照。

- ブリッジを作成します。詳しくは Bridge with netctl を見て下さい。ブリッジの名前を `br0` にするか、下のスクリプトを使用するブリッジの名前に忘れずに変更してください。

- Create the script that QEMU uses to bring up the tap adapter with `root:kvm` 750 permissions:

    /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

Then to launch a VM, do something like this

    $ run-qemu -hda myvm.img -m 512 -vga std

Tip: ホストで DHCP アドレスが取得できない場合、おそらくブリッジで iptables がデフォルトで立ち上がっているのが原因です。

- パフォーマンスとセキュリティ上の理由でブリッジのファイアウォールは無効化するのが推奨されています:

    /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 wiki や Fedora bug 512206 を参照。起動中にファイルが存在しないというエラーが起こるときは、起動時に `bridge` モジュールをロードするようにしてください。カーネルモジュール#ロード を参照。

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

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

### VDE2 によるネットワーク

#### VDE とは?

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

The idea is to create virtual switches, which are basically sockets, and to "plug" both physical and virtual machines in them. The configuration we show here is quite simple; However, VDE is much more powerful than this, it can plug virtual switches together, run them on different hosts and monitor the traffic in the switches. You are invited to read the documentation of the project.

The advantage of this method is you do not have to add sudo privileges to your users. Regular users should not be allowed to run modprobe.

#### 基本

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

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

    # modprobe tun

仮想スイッチを作成:

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

This line creates the switch, creates `tap0`, "plugs" it, and allows the users of the group `users` to use it.

The interface is plugged in but not configured yet. To configure it, run this command:

    # ip addr add 192.168.100.254/24 dev tap0

Now, you just have to run KVM with these `-net` options as a normal user:

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

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

Tip: You might want to set up NAT on tap device to access the internet from the virtual machine. See Internet sharing#Enable NAT for more information.

#### 起動スクリプト

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

Based on quickhowto: qemu networking using vde, tun/tap, and bridge graphic. Any virtual machine connected to vde is externally exposed. For example, each virtual machine can receive DHCP configuration directly from your ADSL router.

#### 基本

`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`, `cirrus`, `vmware`, `qxl`, `none`。

### std

`-vga std` では 2560 x 1600 ピクセルまでの解像度を得ることができます。

### vmware

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

### qxl

QXL は 2D サポートのある準仮想化グラフィックドライバーです。使用するには以下の条件を満たす必要があります:

- ホストシステムで Spice を有効にしなければなりません。
- ゲストにドライバーをインストールします (例: AUR の xf86-video-qxl)。
- `-vga qxl` スイッチを使って仮想マシンを起動します。

### 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-vnc の `gvncviewer` を使うことです。libvirt のメーリングリストに投稿された この メッセージも参照してください。

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

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

- virtio ブロックデバイスにはシンプルな `-hd*` の代わりに `-drive` オプションと `if=virtio` が必要です:

    $ qemu-system-i386 -boot order=c -drive file=disk_image,if=virtio

Note: `-boot order=c` is absolutely necessary when you want to boot from it. There is no auto-detection as with `-hd*`.

- ネットワークでもほぼ同じです:

    $ qemu-system-i386 -net nic,model=virtio

Note: This will only work if the guest machine has drivers for virtio devices. Linux does, and the required drivers are included in Arch Linux, but there is no guarantee that virtio devices will work with other operating systems.

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

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

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

    /etc/mkinitcpio.conf

    MODULES="virtio virtio_blk virtio_pci virtio_net"

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

Tip: When referencing to disks by UUID in both `/etc/fstab` and bootloader, nothing has to be done.

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

### 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

Note: ブルースクリーンになってしまう場合は、`-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

Note: `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_id` と `product_id` がわかります。

Note: 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 を参照。

Tip: KSM が問題なく動いているか確かめる簡単な方法として、ディレクトリのファイルの中身を全て表示する方法があります:

    $ grep . /sys/kernel/mm/ksm/*

### Spice サポート

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

公式の qemu パッケージは Spice サポートを付けてビルドされています。

VM を次のように起動することができます:

    $ qemu-system-i386 -vga qxl -spice port=5930,disable-ticketing

それから spice クライアントで接続してください:

    $ spicec -h 127.0.0.1 -p 5930

Tip:

- Spice のゲストドライバーは こちら の Guest セクションからダウンロードできます。
- 取られたマウスとキーボードを開放するキーコンビネーションは設定可能です、デフォルトは `Shift+F12` になります:

      $ spicec --hotkeys release-cursor=ctrl+alt

- virt-manager には Spice クライアントが入っています。

### コピーアンドペースト

ホストとゲスト間のコピーアンドペーストを行うには 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 8 まで全てのバージョンの Windows を動かすことができます。

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

#### Remote Desktop Protocol

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

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

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

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

## トラブルシューティング

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

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

    $ export SDL_VIDEO_X11_DGAMOUSE=0

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

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

キーの一部が動かなかったり間違ったキーが押されてしまう (特に矢印キー) ときは、おそらくキーボードレイアウトをオプションとして指定する必要があります。キーボードレイアウトは `/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

- 複数の仮想マシンを同時に動かしていて、全て同じオペレーティングシステムをインストールしている場合、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

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

## 参照

- 公式 QEMU ウェブサイト
- 公式 KVM ウェブサイト
- QEMU エミュレーターユーザードキュメント
- QEMU Wikibook
- Hardware virtualization with QEMU by AlienBOB
- Building a Virtual Army by Falconindy
- QEMU, KVM, Xen & libvirt by Robert Warnke and Thomas Ritzau
- Networking QEMU Virtual BSD Systems

Categories:

- Emulators (日本語)
- Virtualization (日本語)