「QEMU」の版間の差分
(→QEMU の内蔵 SMB サーバー: https://wiki.archlinux.org/index.php?title=QEMU&oldid=740338 2022-08-07T02:35:49 版に同期) |
(→ファイルシステムパススルーと VirtFS を使う: https://wiki.archlinux.org/index.php?title=QEMU&oldid=740338 2022-08-07T02:35:49 版に同期) |
||
326行目: | 326行目: | ||
この共有はゲスト上で {{ic|\\10.0.2.4\''myshare''}} として利用可能になります。 |
この共有はゲスト上で {{ic|\\10.0.2.4\''myshare''}} として利用可能になります。 |
||
+ | |||
+ | === ファイルシステムパススルーと VirtFS を使う === |
||
+ | |||
+ | https://wiki.qemu.org/Documentation/9psetup QEMU ドキュメント] を参照してください。 |
||
=== raw ディスクイメージの中にパーティションをマウントする === |
=== raw ディスクイメージの中にパーティションをマウントする === |
2022年8月8日 (月) 00:37時点における版
QEMU ホームページ より:
- QEMU は汎用なオープンソースのマシンエミュレータ・バーチャライザーです。
マシンエミュレータとして使う場合、QEMU はあるマシン (例: ARM ボード) 用に作られた OS やプログラムを他のマシン (例: x86 PC) で動かすことができます。動的変換を利用することによって、素晴らしいパフォーマンスを実現します。
Xen や KVM など他のハイパーバイザを使うことで QEMU は仮想化のための CPU 拡張命令を利用することができます。バーチャライザーとして使う場合、ゲストコードをホスト CPU で直接実行することにより QEMU はネイティブに近いパフォーマンスを得ることができます。
目次
- 1 インストール
- 2 QEMUのグラフィカルフロントエンド
- 3 新しい仮想化システムの作成
- 4 仮想化システムを実行する
- 5 ホスト・ゲスト OS 間でデータを移動する
- 6 ネットワーク
- 7 グラフィック
- 8 オーディオ
- 9 virtio ドライバーのインストール
- 10 QEMU モニタ
- 11 ヒントとテクニック
- 12 トラブルシューティング
- 12.1 仮想マシンの動作が遅すぎる
- 12.2 マウスカーソルが敏感すぎたり迷走する
- 12.3 カーソルが表示されない
- 12.4 カーソルが移動・アタッチできない
- 12.5 キーボードが壊れているまたは矢印キーが動作しない
- 12.6 ウィンドウのリサイズでゲストのディスプレイが引き伸ばされる
- 12.7 ioctl(KVM_CREATE_VM) failed: 16 Device or resource busy
- 12.8 libgfapi エラーメッセージ
- 12.9 ライブ環境でカーネルパニックが発生する
- 12.10 Windows 7 ゲストの音質が酷い
- 12.11 Could not access KVM kernel module: Permission denied
- 12.12 Windows の仮想マシンを起動したときに "System Thread Exception Not Handled"
- 12.13 特定の Windows のゲームやアプリケーションでクラッシュやブルスクリーンが発生する
- 13 参照
インストール
qemu-full パッケージ (または GUI が必要ない場合は qemu-base) をインストールしてください。また、任意で以下のパッケージもインストールしてください:
- qemu-block-gluster - GlusterFS ブロックのサポート
- qemu-block-iscsi - iSCSI ブロックのサポート
- qemu-block-rbd - RBD ブロックのサポート
- samba - SMB/CIFS サーバーのサポート
あるいは、usermode と static のバリアントとして qemu-user-staticAUR が存在します。
QEMU バリアンツ
QEMUには、さまざまなユースケースに適したいくつかのバリアンツが用意されています。
最初の分類として、QEMUにはフルシステムエミュレーションモードとユーザーモードエミュレーションモードの2種類が提供されています。
- フルシステムエミュレーション
- このモードでは、QEMUは1つまたは複数のプロセッサとさまざまな周辺機器を含むフルシステムをエミュレートします。より正確ですが速度は遅く、エミュレートするOSはLinuxである必要がありません。
- フルシステムエミュレーション用のQEMUコマンドは
qemu-system-target_architecture
という名前が付けられています。例えば インテル64ビットCPUのエミュレーション用のqemu-system-x86_64
、インテル32ビットCPU用のqemu-system-i386
、 ARM(32ビット)用のqemu-system-arm
、 ARM64用のqemu-system-aarch64
などです。 - ターゲットアーキテクチャがホスト CPU と一致する場合、このモードでも KVM や Xen のようなハイパーバイザーを使うことで大幅なスピードアップの恩恵を受けられるかもしれません。
- ユーザーモードエミュレーション
- このモードでは、QEMUはホストシステムのリソースを利用することで、(潜在的に)異なるアーキテクチャ用にコンパイルされた Linux 実行ファイルを呼び出すことができます。互換性の問題がある場合があります。例えば、一部の機能が実装されていない、動的リンクされた実行ファイルがそのままでは動作しない(これについては#x86_64 から arm/arm64 環境への Chrootingを参照)、そして Linux のみがサポートされています(ただし Windows 実行ファイルの実行には Wine が使用できる場合があります)。
- ユーザーモードエミュレーション用のQEMUコマンドには
qemu-target_architecture
という名前が付けられており、例えばintel 64ビットCPUのエミュレーション用はqemu-x86_64
になります。
QEMU には動的リンク型と静的リンク型のバリアンツが提供されています。
- 動的リンク型(デフォルト)
qemu-*
コマンドはホストOSのライブラリに依存し、このため実行ファイルのサイズが小さくなっています。- 静的リンク型
qemu-*
コマンドは同じアーキテクチャの Linux システムにコピーすることができます。
Arch Linux の場合、フルシステムエミュレーションは以下のように提供されます:
- 非ヘッドレス (デフォルト)
- このバリアントでは、追加の依存関係(SDL や GTK など)を必要とする GUI 機能を使用できます。
- ヘッドレス
- GUI を必要としないスリムなバリアントです(サーバなどに適しています)。
ヘッドレス版と非ヘッドレス版は同じ名前のコマンド(例: qemu-system-x86_64
)をインストールするため、両方を同時にインストールすることはできないことに注意してください。
Arch Linux で利用可能なパッケージの詳細
- qemu-desktop パッケージはフルシステムエミュレーション用の
x86_64
アーキテクチャエミュレータを提供します(qemu-system-x86_64
)。 qemu-emulators-full パッケージは、x86_64
ユーザモード版 (qemu-x86_64
) を提供し、サポートされている他のアーキテクチャについても、フルシステム版と ユーザモード版の両方(例:qemu-system-arm
およびqemu-arm
)が含まれています。 - これらのパッケージのヘッドレスバージョン (フルシステムエミュレーションにのみ適用可能) は、 qemu-base (
x86_64
-のみ) および qemu-emulators-full (その他のアーキテクチャ) です。 - フルシステムエミュレーションは、別のパッケージに含まれるいくつかの QEMU モジュールを使用して拡張することができます: qemu-block-gluster, qemu-block-iscsi, qemu-block-rbd, qemu-guest-agent.
- 非公式の AUR パッケージ qemu-user-staticAUR は QEMU がサポートする全てのターゲットアーキテクチャにユーザーモードと静的バリアントを提供します。このパッケージのプリコンパイルバージョンが存在します: qemu-user-static-binAUR} 。インストールされる QEMU コマンドは
qemu-target_architecture-static
という名前で、例えば intel 64-bit CPU 用はqemu-x86_64-static
です。 - 非公式の AUR パッケージ qemu-loongarch64-gitAUR は(qemu-system-loongarch64-gitAUR と qemu-loongarch64-static-gitAUR とともに) LoongArch アーキテクチャ用の QEMU で、version 7.1 から公式にサポートされています。
QEMUのグラフィカルフロントエンド
VirtualBox や VMware などの他の仮想化プログラムと違って、QEMUは仮想マシンを管理するためのGUI (仮想マシン実行時に表示されるウィンドウを除く)を提供せず、保存された設定を使って永続的な仮想マシンを作成する方法も提供しません。仮想マシンを起動するためのカスタムスクリプトを作成していない限り、仮想マシンを実行するためのすべてのパラメータは、起動のたびにコマンドラインで指定する必要があります。
Libvirt は、QEMU 仮想マシンを管理するための便利な方法を提供します。利用可能なフロントエンドについては、libvirtクライアントの一覧 を参照してください。
その他の QEMU 用 GUI フロントエンド:
- AQEMU — Qt5で書かれたQEMU GUI。
新しい仮想化システムの作成
ハードディスクイメージの作成
CD-ROM やネットワークからライブシステムを起動するのでない (そしてオペレーティングシステムをハードディスクイメージにインストールしない) 限り、QEMU を実行するにはハードディスクイメージが必要になります。ハードディスクイメージはエミュレートするハードディスクの内容を保存するファイルです。
ハードディスクイメージを raw にすると、ゲストからは文字通りバイト単位で等しいようになり、ホスト上のゲストハードドライブをフルに使用することになります。この方法は I/O のオーバーヘッドを最小に抑えられますが、ゲストで使用していない領域もホストは使えないため、大量の容量を消費するのが欠点です。
また、ハードディスクイメージを qcow2 などのフォーマットにすることもできます。ゲストオペレーティングシステムが実際に仮想ハードディスク上のセクタに書き込んだ時にイメージファイルに容量を割り当てます。ホストシステムで占める容量はかなり少なくて済み、ゲストオペレーションにはフルサイズのイメージとして見えます。QEMU のスナップショット機能にも対応しています (詳しくは#モニタコンソールを使ってスナップショットを作成・管理を参照)。こちらの形式では raw と違ってパフォーマンスに多少影響を与えます。
QEMU にはハードディスクイメージを作成するための qemu-img
コマンドがあります。例えば raw フォーマットで 4GiB イメージを作成するには:
$ qemu-img create -f raw image_file 4G
-f qcow2
を使うことで qcow2 ディスクを作成できます。
オーバーレイストレージイメージ
一度ストレージメディアを作成してから ('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 イメージのパスからこのイメージに繋がるようにしてください。必要ならば、オリジナルのパスに新しいパスへのシンボリックリンクを作成します。次のようなコマンドを実行してください:
$ qemu-img rebase -b /new/img1.raw /new/img1.cow
あなたの判断で、backing イメージの古いパスがチェックされない'危険な' rebase を実行することもできます:
$ qemu-img rebase -u -b /new/img1.raw /new/img1.cow
イメージのリサイズ
qemu-img
実行可能ファイルには resize
オプションがあり、ハードドライブイメージの簡単なリサイズができます。このコマンドは raw と qcow2 の両方で使えます。例えば、イメージ容量を 10GB 増やすには、次を実行してください:
$ qemu-img resize disk_image +10G
ディスクイメージを拡大した後、仮想マシン内でファイルシステムおよびパーティションツールを使用して、新しいスペースを実際に使い始める必要があります。ディスクイメージを縮小する場合、仮想マシン内のファイルシステムおよびパーティションツールを使用して まず割り当てられたファイル・システムとパーティション・サイズを縮小 し、それに応じてディスクイメージを縮小する必要があります。Windows ゲストの場合、"ハードディスクパーティションの作成とフォーマット" コントロールパネルを開きます。
インストールメディアを準備する
ディスクイメージにオペレーティングシステムをインストールするには、オペレーティングシステムのインストールメディア (例: オプティカルディスク、USB ドライブ、ISO イメージ) が必要です。QEMU はメディアに直接アクセスできないのでインストールメディアをマウントしてはいけません。
オペレーティングシステムのインストール
ここで初めてエミュレータを起動することになります。ディスクイメージにオペレーティングをインストールするには、ディスクイメージとインストールメディアの両方を仮想マシンに結びつけて、インストールメディアから起動するようにする必要があります。
例えば i386 ゲストで、CD-ROM としてのブータブル ISO ファイルと raw ディスクイメージからインストールするには:
$ qemu-system-x86_64 -cdrom iso_image -boot order=d -drive file=disk_image,format=raw
他のメディアタイプ(フロッピー、ディスクイメージ、物理ドライブなど)の読み込みについては qemu(1) を、その他の便利なオプションについては #仮想化システムを実行する を見て下さい。
オペレーティングシステムのインストールが終了したら、直接 QEMU イメージを起動することができます( #仮想化システムを実行する を参照)。
{注意|デフォルトではマシンに割り当てられるメモリは 128MiB だけです。メモリの量は -m
スイッチで調整できます。例えば -m 512M
や -m 2G
。}
仮想化システムを実行する
qemu-system-*
バイナリ (例えば qemu-system-i386
や qemu-system-x86_64
など、エミュレートするアーキテクチャによって異なります) を使って仮想化システムを実行します。使用方法は:
$ qemu-system-x86_64 options disk_image
全ての qemu-system-*
バイナリでオプションは共通です、全てのオプションのドキュメントは qemu(1) を見て下さい。
デフォルトで、QEMU は仮想マシンのビデオ出力をウィンドウに表示します。注意: QEMU ウィンドウの中をクリックすると、マウスポインタが取り込まれます。ポインタを戻すには、Ctrl+Alt+g
を押して下さい。
KVM を有効にする
使用しているプロセッサとカーネルが KVM をサポートしている必要があります。また、必要なカーネルモジュールがロードされてなければなりません。詳しくは KVM を見て下さい。
QEMU を KVM モードで起動するには、起動オプションに -enable-kvm
を追加してください。実行中の仮想マシンで KVM が有効になっているかどうか確認するには、Ctrl+Alt+Shift+2
を使って QEMU Monitor に入り、info kvm
と入力してください。
IOMMU (Intel VT-d/AMD-Vi) サポートを有効にする
IOMMU を使うことで PCI パススルーやメモリの保護などの機能が利用できます。Wikipedia:ja:IOMMU#利点 や Memory Management (computer programming): Could you explain IOMMU in plain English? を見てください。
IOMMU を有効化するには:
- CPU によって AMD-Vi/Intel VT-d がサポートされていること、BIOS の設定で有効になっていることを確認してください。
- Intel の CPU を使っている場合は
intel_iommu=on
、AMD の CPU を使っている場合はamd_iommu=on
をカーネルパラメータに追加してください。 - PCI パススルーのためだけに IOMMU が必要な場合、
iommu=pt
パラメータも追加してください。Linux がパススルーするデバイスの IOMMU だけを有効化できるようになり、システムの他のデバイスへのパフォーマンスの影響を避けられます。CPU メーカー別のパラメータ (上記) もon
にする必要があります。 - 再起動して
dmesg
にDMAR
があることを確認して IOMMU が有効になっていることをチェックしてください:[0.000000] DMAR: IOMMU enabled
。 -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 ..
UEFIモードでの起動
QEMU が使用するデフォルトのファームウェアは SeaBIOS で、これはレガシー BIOS の実装です。QEMU はデフォルトの読み取り専用(ROM)イメージとして /usr/share/qemu/bios-256k.bin
(seabios で提供される) を使用します。他のファームウェアファイルを選択するには -bios
引数を使用します。しかし、UEFI が正しく動作するためには書き込み可能なメモリが必要であるため、代わりに PC システムフラッシュ をエミュレートする必要があります。
OVMF は仮想マシンの UEFI サポートを有効にするための TianoCore プロジェクトです。 edk2-ovmf パッケージで インストール することができます。
OVMF をファームウェアとして使うには 2 つの方法があります。一つは /usr/share/edk2-ovmf/x64/OVMF.fd
をコピーして書き込み可能にし、pflashドライブとして利用する方法です:
-drive if=pflash,format=raw,file=/copy/of/OVMF.fd.
UEFI 設定への全ての変更はこのファイルに直接保存されます。
もう一つのより好ましい方法は OVMF を二つのファイルに分割することです。最初のファイルは読み込み専用でファームウェアの実行ファイルを保存し、2番目のファイルは書き込み可能な変数ストアとして使われます。利点はファームウェアファイルをコピーせずに直接使うことができ、 pacman によって自動的にアップデートされることです。
/usr/share/edk2-ovmf/x64/OVMF_CODE.fd
を最初のリードオンリーな pflash ドライブとして使用します。/usr/share/edk2-ovmf/x64/OVMF_VARS.fd
をコピーして書き込み可能にし、2台目の書き込み可能な pflash ドライブとして使用します:
-drive if=pflash,format=raw,readonly=on,file=/usr/share/edk2-ovmf/x64/OVMF_CODE.fd \ -drive if=pflash,format=raw,file=/copy/of/OVMF_VARS.fd
Trusted Platform Module のエミュレーション
QEMUは、Windows 11などの一部のシステムで必要とされるTrusted Platform Module をエミュレートすることができます。
ソフトウェア TPM の実装を提供する swtpm パッケージをインストール します。 TPM のデータを格納するディレクトリを作成します(/path/to/mytpm
を例として使用します)。以下のコマンドを実行し、エミュレータを起動します:
$ swtpm socket --tpm2 --tpmstate dir=/path/to/mytpm --ctrl type=unixio,path=/path/to/mytpm/swtpm-sock
/path/to/mytpm/swtpm-sock
は swtpm が作成します: これはQEMUが接続するUNIXソケットです。どのディレクトリに置いてもかまいません。
デフォルトでは、swtpm は TPM バージョン 1.2 エミュレータを起動します。 --tpm2
オプションを指定すると、TPM 2.0 のエミュレーションが有効になります。
最後に、QEMU に以下のオプションを追加します:
-chardev socket,id=chrtpm,path=/path/to/mytpm/swtpm-sock \ -tpmdev emulator,id=tpm0,chardev=chrtpm \ -device tpm-tis,tpmdev=tpm0
すると、VM 内で TPM が使用できるようになります。VM をシャットダウンすると、swtpmは自動的に終了します。
詳しくは the QEMU documentation を参照してください。
ホスト・ゲスト 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のポートフォワーディング
QEMUのポートフォワーディングはIPv4のみです。
QEMUはホストからゲストへポートを転送し、例えばホストからゲスト上で動作しているSSHサーバーへの接続を可能にします。
例えば、ホストのポート 60022 とゲストのポート 22(SSH) をバインドするには、次のようなコマンドでQEMUを起動します:
$ qemu-system-x86_64 disk_image -nic user,hostfwd=tcp::60022-:22
ゲストで sshd が動いていることを確認し、接続します:
$ ssh guest-user@127.0.0.1 -p 60022
SSHFS を使って共有読み込みと書き込みのためにゲストのファイルシステムをホストにマウントできます。
複数のポートを転送するには、hostfwd
を -nic
引数で繰り返すだけです、例えば VNC のポートは次のようになります:
$ qemu-system-x86_64 disk_image -nic user,hostfwd=tcp::60022-:22,hostfwd=tcp::5900-:5900
QEMUの内蔵SMBサーバ
QEMUのドキュメントには "内蔵の" SMBサーバーがあると書かれていますが、実際は tmp/qemu-smb.random_string
にある自動生成の smb=
で共有設定できるのは1つのディレクトリだけですが、QEMUがシンボリックリンクに従うようにSMBを設定すれば、(仮想マシン実行中でも)共有ディレクトリにシンボリックリンクを作成するだけで簡単に他のディレクトリを追加することが可能です。このようなことをすることはありませんが、実行中のSMBサーバーの設定を後述のように変更することができます。
ホスト上にSambaがインストールされている必要があります。この機能を有効にするには、次のようなコマンドでQEMUを起動します。
$ qemu-system-x86_64 -nic user,id=nic0,smb=shared_dir_path disk_image
shared_dir_path
はゲストとホストで共有したいディレクトリです。
これで、ゲストから、ホスト 10.0.2.4 上の共有ディレクトリに 共有名 "qemu" でアクセスできるようになります。例えば、Windowsエクスプローラで \\10.0.2.4\qemu
に移動します。
複数のディレクトリを共有し、仮想マシンの実行中にディレクトリの追加や削除を行う方法として、空のディレクトリを共有し、共有ディレクトリ内のディレクトリへのシンボリックリンクを作成/削除する方法があります。これを機能させるには、実行中のSMBサーバーの設定を以下のスクリプトで変更します。これは、ホスト側で実行可能に設定されていないファイルのゲスト側での実行も許可します。
#!/bin/sh eval $(ps h -C smbd -o pid,args | grep /tmp/qemu-smb | gawk '{print "pid="$1";conf="$6}') echo "[global] allow insecure wide links = yes [qemu] follow symlinks = yes wide links = yes acl allow execute always = yes" >> "$conf" # in case the change is not detected automatically: smbcontrol --configfile="$conf" "$pid" reload-config
これはゲストが初めてネットワークドライブに接続した後にのみ、qemuによって起動された実行中のサーバーに適用することができます。この代わりに、次のように設定ファイルに追加の共有を追加する方法があります:
echo "[myshare]
path=another_path read only=no guest OK=yes force user=username" >> $conf
この共有はゲスト上で \\10.0.2.4\myshare
として利用可能になります。
ファイルシステムパススルーと VirtFS を使う
https://wiki.qemu.org/Documentation/9psetup QEMU ドキュメント] を参照してください。
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
パラメータで決めることができます。
あなたのイメージをループバックデバイスとして設定:
# losetup -f -P disk_image
これで、デバイスが /dev/loop0
の場合、追加のデバイス /dev/loop0pX
が自動的に作成されます。X はパーティションの番号です。これらのパーティションのループバックデバイスは直接マウントすることができます。例:
# mount /dev/loop0p1 mountpoint
udisksctl でディスクイメージをマウントする方法は Udisks#ISO イメージのマウントを見てください。
kpartx を使う
AUR の multipath-tools パッケージに入っている kpartx はデバイスのパーティションテーブルを読み込んでパーティションごとに新しいデバイスを作成することができます。例えば:
# kpartx -a disk_image
上記のコマンドで、ループバックデバイスがセットアップされ /dev/mapper/
に必要なパーティションデバイスが作成されます。
qcow2 イメージの中にパーティションをマウントする
qcow2 イメージの中のパーティションは qemu-nbd
を使ってマウントできます。Wikibooks を見て下さい。
実際のパーティションをハードディスクイメージのシングルプライマリパーティションとして使う
場合によって、QEMU の中からシステムパーティションのどれかを使いたくなることもあるでしょう。仮想マシンでの raw パーティションの使用は、読み書きの操作が物理ホストのファイルシステムレイヤーを通過しないため、パフォーマンスが高くなります。そのようなパーティションをホストとゲストでのデータの共有手段として使うこともできます。
Arch Linux では、raw パーティションのデバイスファイルは、デフォルトで、root と disk グループが所有者です。root 以外のユーザーで raw パーティションに読み書きできるようにしたい場合は、パーティションのデバイスファイルの所有者をそのユーザーに変える必要があります。
その後、パーティションを QEMU の仮想マシンに仮想ディスクとしてアタッチできます。
ただし、仮想マシン全体をパーティションに収めたいときは、自体は多少複雑になります。そのような場合、実際に仮想マシンを起動するディスクイメージファイルがないために、MBR でパーティション分けされたデバイスではなくファイルシステムとしてフォーマットされたパーティションにブートローダーをインストールすることができません。このような仮想マシンはカーネルと initrd を手動で指定するか、リニア RAID を使って MBR のディスクをシミュレートすることで起動できます。
カーネルと initrd を手動で指定する
QEMU は GRUB などのブートローダーを迂回して、Linux カーネルと init ramdisk を直接ロードすることをサポートしています。それから root ファイルシステムを含んでいる物理パーティションで、パーティションされていない仮想ディスクとして起動することができます。以下のようなコマンドを実行することで行います:
$ 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 マスカレードを通して物理ホストのネットワークにアクセスできるようになります。
ホストがインターネットに接続されていれば、このデフォルトの設定で簡単に仮想マシンをインターネットにアクセスさせることができますが、外部ネットワークからは仮想マシンは直接は見えず、また、複数の仮想マシンを同時に起動していても仮想マシン同士が通信することはできません。
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 上の他のマシンが仮想マシンに通信できるようにしたい場合に価値があります。
ホストオンリーネットワーク
ブリッジに IP アドレスが与えられていてそこへのトラフィックが許可されていながら、本当のインターフェイス (例: eth0
) がブリッジに接続されていない場合、仮想マシンは互いに通信したりホストシステムと通信することができるようになります。しかしながら、物理ホストで IP マスカレードを設定しないかぎり外部ネットワークとは一切通信することができません。この設定は VirtualBox などの他の仮想化ソフトウェアではホストオンリーネットワークと呼ばれています。
内部ネットワーク
ブリッジに IP アドレスを与えずにブリッジへの全てのトラフィックを INPUT チェインで drop する iptables ルールを追加した場合、仮想マシンは互いに通信することはできても、物理ホストや外側のネットワークに接続できなくなります。この設定は VirtualBox などの他の仮想化ソフトウェアでは内部ネットワークと呼ばれています。仮想マシンに固定 IP アドレスを割り当てるかマシンのどれか一つで DHCP サーバーを実行する必要があります。
デフォルトで iptables はブリッジネットワークのパケットを拒否します。ブリッジネットワークのパケットを許可する iptables のツールを使用する必要があります:
# iptables -I FORWARD -m physdev --physdev-is-bridged -j ACCEPT
qemu-bridge-helper を使用するブリッジネットワーク
この方法にはスタートアップスクリプトが必要なく、すぐに複数の tap やブリッジに対応することができます。既存のブリッジに tap デバイスを作成できるようにする、/usr/lib/qemu/qemu-bridge-helper
バイナリを使用します。
まず、/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 [...]
ブリッジを手動で作成する
以下では仮想マシンを eth0
などのホストインターフェイスにブリッジする方法を説明しています。おそらく一番よく使われている設定です。この設定では、物理的なホストマシンと同一の Ethernet セグメントに、直接外部ネットワークに仮想マシンが位置するようになります。
通常の Ethernet アダプタをブリッジアダプタで置き換えて、通常の Ethernet アダプタをブリッジアダプタに bind することにします。
- ブリッジを制御するための
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
モジュールをロードして起動時にロードするように設定してください。詳しくはカーネルモジュールを参照。
- ブリッジを作成します。詳しくは 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
- パフォーマンスとセキュリティ上の理由でブリッジのファイアウォールは無効化するのが推奨されています [2]:
/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 の拡張として始まりました。仮想ネットワークを管理するためのツールボックスです。
基本的にはソケットである仮想スイッチを作成して、物理マシンと仮想マシンを両方ともスイッチに"接続"するという考えになります。以下で説明する設定はとてもシンプルです。ただし、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 [...]
物理ネットワークでやるのと同じようにゲストのネットワークを設定してください。
起動スクリプト
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 ゲストでは、パフォーマンスを得るために qxl
と bochs_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 クライアントでゲストに接続してください。プロトコルの開発者は SPICE クライアントとして virt-viewer を推奨しています:
$ remote-viewer spice://127.0.0.1:5930
リファレンス・テスト実装である spice-gtk3[リンク切れ: 置換パッケージ: spice-gtk] を使うこともできおます:
$ spicy -h 127.0.0.1 -p 5930
クライアントは他にも存在します [3]。
TCP ポートの代わりに Unix ソケットを使用することで、パフォーマンスが向上するという報告があります [4]。例:
$ 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-vdagent: クライアントと X セッションの間でコピーアンドペーストを可能にする Spice エージェント
- xf86-video-qxl xf86-video-qxl-gitAUR: Xorg の X11 qxl ビデオドライバー
- 他のオペレーティングシステムの場合、SPICE-Space ダウンロード ページのゲストセクションを見てください。
インストールしたら 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-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-vmware と xf86-input-vmmouse)。
virtio
virtio-vga
/ virtio-gpu
は virgl がベースの順仮想化 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-vnc の gvncviewer
を使うことです。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
を使ってください。
virtio ドライバーのインストール
QEMU にで virtio ドライバーを使って準仮想化ブロックとネットワークデバイスをゲストが利用できるようにすることができ、より良いパフォーマンス・少ないオーバーヘッドを実現します。
- virtio ブロックデバイスにはシンプルな
-hd*
の代わりに-drive
オプションとif=virtio
が必要です:
$ qemu-system-x86_64 -boot order=c -drive file=disk_image,if=virtio
- ネットワークでもほぼ同じです:
$ qemu-system-x86_64 -net nic,model=virtio
(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
などに変更を加える必要があります。
KVM による準仮想化に関する詳細は こちら で読むことができます。
qemu-guest-agent をインストールすることでハイパーバイザの管理機能を拡張する QMP コマンドのサポートを得ることができます。パッケージをインストールしたら qemu-ga.service
を起動・有効化してください。
Windows ゲストを用意する
ブロックデバイスドライバー
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
ネットワークドライバー
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 devices の PCI 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
を実行することでインストールが実行されます。その後 virsh
の dommemstat
コマンドでサポートされている値が出力されるはずです。
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
- 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
- 標準 I/O:
-monitor stdio
引数を付けて起動することで同じターミナルから自動的にモニタにアクセスすることができます。
モニタコンソールを使って仮想マシンにキーボードの押下を送信
設定によっては仮想マシン上で一部のキーの組み合わせがホストによって邪魔されて使えない場合があります (tty を切り替える Ctrl+Alt+F*
など)。特定のキーの組み合わせについてはモニタコンソールを使ってキーを送信することで問題を解決できます。モニタに切り替えてから sendkey
コマンドを使って仮想マシンにキーの押下を送信してください。例:
(qemu) sendkey ctrl-alt-f2
モニタコンソールを使ってスナップショットを作成・管理
ときには仮想マシンの現在の状態を保存して何か問題が発生したときに仮想マシンの状態を元に戻したいということもあるでしょう。QEMU のモニタコンソールにはスナップショットを作成・管理してマシンの状態をリバートするのに必要なユーティリティが備わっています。
savevm name
を使うことで name という名前のスナップショットが作成されます。loadvm name
をしよすうると仮想マシンがスナップショット name の状態に戻ります。delvm name
で name という名前のスナップショットが削除されます。- 保存済みのスナップショットのリストは
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
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_id
と product_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 に追加したい場合に有用です。
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-viewer の remote-viewer
(File > USB device selection) の両方ともリダイレクト機能をサポートしています。期待通りに動作させるには仮想マシンに SPICE ゲストツールをインストールする必要があります (詳しくは #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 を参照。
マルチモニターのサポート
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
そして Rdesktop か freerdp を使ってゲストに接続してください。例えば:
$ 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 がブルースクリーンになる。
参照
- QEMU 公式ウェブサイト
- KVM 公式ウェブサイト
- QEMU エミュレータユーザードキュメント
- QEMU Wikibook
- Hardware virtualization with QEMU by AlienBOB
- Building a Virtual Army by Falconindy
- 最新ドキュメント
- QEMU on Windows
- Wikipedia
- QEMU - Debian Wiki
- QEMU Networking on gnome.org
- Networking QEMU Virtual BSD Systems
- QEMU on gnu.org
- QEMU on FreeBSD as host