「QEMU」の版間の差分
細 (→仮想マシンのパフォーマンスを向上させる: テンプレートエラー) |
|||
(2人の利用者による、間の6版が非表示) | |||
565行目: | 565行目: | ||
$((start+size)) $((disksize-start-size)) zero" | dmsetup create qemu |
$((start+size)) $((disksize-start-size)) zero" | dmsetup create qemu |
||
− | {{ic|dmsetup}} への標準入力として提供されるテーブルは、 {{ic|VBoxManage}} によって作成された |
+ | {{ic|dmsetup}} への標準入力として提供されるテーブルは、 {{ic|VBoxManage}} によって作成された VMDK 記述子ファイル内のテーブルと同様のフォーマットを持ち、代わりに {{ic|dmsetup create qemu--table''table_file''}} でファイルからロードできます。仮想マシンには {{ic|/dev/hda''N''}} だけがアクセス可能で、ハードディスクの残りはゼロとして読み取られ、書き込まれたデータは最初のセクタを除いて破棄されます。 {{ic|dmsetup table qemu}} で {{ic|/dev/mapper/qemu}} のテーブルを表示できます ({{ic|udevadm info -rq name /sys/dev/block/''major'':''minor''}} で {{ic|''major'':''minor''}} を {{ic|/dev/''blockdevice''}} 名に変換してください) 。作成されたデバイスを削除するには {{ic|dmsetup remove qemu}} と {{ic|losetup -d $loop}} を使います。 |
この例が役に立つ状況は、マルチブート構成の既存の Windows XP インストールと、おそらくハイブリッドパーティションスキーム(物理ハードウェアでは、Windows XP が MBR パーティションテーブルを使用する唯一のオペレーティングシステムであり、同じコンピュータにインストールされた最新のオペレーティングシステムは GUID パーティションテーブルを使用できます)の場合です。Windows XP はハードウェアプロファイルをサポートしているため、同じインストールを異なるハードウェア構成で交互に使用できます(この場合はベアメタルと仮想)。Windows は新しく検出されたハードウェアのドライバをプロファイルごとに1回だけインストールする必要があります。この例ではコピーされた MBR のブートローダコードを更新して、元のシステムに存在するマルチブート対応のブートローダ(GRUB など)を起動するのではなく、 {{ic|/dev/hda''N''}} から直接 Windows XP をロードする必要があることに注意してください。または、ブートローダインストールを含むブートパーティションのコピーを MBR と同じ方法で仮想ディスクに含めることもできます。 |
この例が役に立つ状況は、マルチブート構成の既存の Windows XP インストールと、おそらくハイブリッドパーティションスキーム(物理ハードウェアでは、Windows XP が MBR パーティションテーブルを使用する唯一のオペレーティングシステムであり、同じコンピュータにインストールされた最新のオペレーティングシステムは GUID パーティションテーブルを使用できます)の場合です。Windows XP はハードウェアプロファイルをサポートしているため、同じインストールを異なるハードウェア構成で交互に使用できます(この場合はベアメタルと仮想)。Windows は新しく検出されたハードウェアのドライバをプロファイルごとに1回だけインストールする必要があります。この例ではコピーされた MBR のブートローダコードを更新して、元のシステムに存在するマルチブート対応のブートローダ(GRUB など)を起動するのではなく、 {{ic|/dev/hda''N''}} から直接 Windows XP をロードする必要があることに注意してください。または、ブートローダインストールを含むブートパーティションのコピーを MBR と同じ方法で仮想ディスクに含めることもできます。 |
||
571行目: | 571行目: | ||
===== リニア RAID を使う ===== |
===== リニア RAID を使う ===== |
||
− | <!-- 翻訳除外: {{Out of date|[ |
+ | <!-- 翻訳除外: {{Out of date|[https://github.com/torvalds/linux/commit/849d18e27be9a1253f2318cb4549cc857219d991 CONFIG_MD_LINEAR Removal] Linear RAID has been deprecated since 2021 and removed on Kernel Version 6.8.}} --> |
リニアモードのソフトウェア [[RAID]] ({{ic|linear.ko}} カーネルドライバが必要です)とループバックデバイスを使うこともできます: |
リニアモードのソフトウェア [[RAID]] ({{ic|linear.ko}} カーネルドライバが必要です)とループバックデバイスを使うこともできます: |
||
951行目: | 951行目: | ||
$ run-qemu -hda ''myvm.img'' -m 512 |
$ run-qemu -hda ''myvm.img'' -m 512 |
||
− | * パフォーマンスとセキュリティ上の理由で [ |
+ | * パフォーマンスとセキュリティ上の理由で [https://ebtables.netfilter.org/documentation/bridge-nf.html ブリッジ上のファイアウォール] は無効にすることをお勧めします: |
{{hc|/etc/sysctl.d/10-disable-firewall-on-bridge.conf|<nowiki> |
{{hc|/etc/sysctl.d/10-disable-firewall-on-bridge.conf|<nowiki> |
||
1,153行目: | 1,153行目: | ||
=== VDE2 Bridge === |
=== VDE2 Bridge === |
||
− | [https://selamatpagicikgu.wordpress.com/2011/06/08/quickhowto-qemu-networking-using-vde-tuntap-and-bridge/ quickhowto: qemu networking using vde, tun/tap, and bridge] に基づいています。vde に接続された仮想マシンは外部から参照 |
+ | [https://selamatpagicikgu.wordpress.com/2011/06/08/quickhowto-qemu-networking-using-vde-tuntap-and-bridge/ quickhowto: qemu networking using vde, tun/tap, and bridge] に基づいています。vde に接続された仮想マシンは外部から参照できる状態になります。例えば、ADSL ルーターから直接 DHCP の設定を個々の仮想マシンが受け取ることが可能です。 |
==== 基本 ==== |
==== 基本 ==== |
||
1,684行目: | 1,684行目: | ||
* {{ic|-cpu host}} オプションで QEMU により一般的な CPU ではなくホストの正確な CPU をエミュレートさせる。 |
* {{ic|-cpu host}} オプションで QEMU により一般的な CPU ではなくホストの正確な CPU をエミュレートさせる。 |
||
* 特に Windows ゲストの場合、[https://blog.wikichoon.com/2014/07/enabling-hyper-v-enlightends-with-kvm.html Hyper-V enlightenments] を有効にする: {{ic|1=-cpu host,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time}}。詳細とフラグについては [https://www.qemu.org/docs/master/system/i386/hyperv.html QEMU documentation] を参照。 |
* 特に Windows ゲストの場合、[https://blog.wikichoon.com/2014/07/enabling-hyper-v-enlightends-with-kvm.html Hyper-V enlightenments] を有効にする: {{ic|1=-cpu host,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time}}。詳細とフラグについては [https://www.qemu.org/docs/master/system/i386/hyperv.html QEMU documentation] を参照。 |
||
− | * {{ic|-smp cores |
+ | * {{ic|1=-smp cores=x,threads=y,sockets=1,maxcpus=z}} オプションを使用して、複数のコアをゲストに割り当てることができます。threads パラメータは、[https://www.tomshardware.com/reviews/simultaneous-multithreading-definition,5762.html SMT コア] の割り当てに使用されます。QEMU、ハイパーバイザ、およびホストシステムがスムーズに動作できるように物理コアを残しておくことは、非常に有益です。 |
* 仮想マシンに十分なメモリーが割り当てられていることを確認する。デフォルトでは、QEMU は各仮想マシンに 128 MiB のメモリーのみを割り当てます。より多くのメモリーを割り当てるには、{{ic|-m}} オプションを使用します。たとえば、{{ic|-m 1024}} は 1024 MiB のメモリーを持つ仮想マシンを実行します。 |
* 仮想マシンに十分なメモリーが割り当てられていることを確認する。デフォルトでは、QEMU は各仮想マシンに 128 MiB のメモリーのみを割り当てます。より多くのメモリーを割り当てるには、{{ic|-m}} オプションを使用します。たとえば、{{ic|-m 1024}} は 1024 MiB のメモリーを持つ仮想マシンを実行します。 |
||
* ゲストオペレーティングシステムのドライバでサポートされている場合は、ネットワークデバイスやブロックデバイスに virtio を使用する。[[#virtio ドライバーのインストール]] を参照してください。 |
* ゲストオペレーティングシステムのドライバでサポートされている場合は、ネットワークデバイスやブロックデバイスに virtio を使用する。[[#virtio ドライバーのインストール]] を参照してください。 |
||
1,871行目: | 1,871行目: | ||
QEMU は {{ic|qemu-vdagent}} という spice vdagent chardev の独自の実装を提供しています。この実装は、スパイス-vdagent ゲストサービスとのインタフェースとなり、ゲストとホストがクリップボードを共有できるようにします。 |
QEMU は {{ic|qemu-vdagent}} という spice vdagent chardev の独自の実装を提供しています。この実装は、スパイス-vdagent ゲストサービスとのインタフェースとなり、ゲストとホストがクリップボードを共有できるようにします。 |
||
− | QEMU の GTK ディスプレイでこの共有クリップボードにアクセスするには、{{ic|--enable-gtk-clipboard}} 設定パラメータを指定して [[ |
+ | QEMU の GTK ディスプレイでこの共有クリップボードにアクセスするには、{{ic|--enable-gtk-clipboard}} 設定パラメータを指定して [[Arch build system|ソースから]] QEMU をコンパイルする必要があります。インストールされている {{ic|qemu-ui-gtk}} パッケージを置き換えるだけで十分です。 |
{{Note| |
{{Note| |
||
2,201行目: | 2,201行目: | ||
* [https://www.ibm.com/support/knowledgecenter/en/linuxonibm/liaat/liaatkvm.htm KVM on IBM Knowledge Center] |
* [https://www.ibm.com/support/knowledgecenter/en/linuxonibm/liaat/liaatkvm.htm KVM on IBM Knowledge Center] |
||
− | {{TranslationStatus|QEMU|2024- |
+ | {{TranslationStatus|QEMU|2024-05-27|804107}} |
2024年8月5日 (月) 19:18時点における版
QEMU about page によると、"QEMU は汎用的なオープンソースのマシンエミュレータでありバーチャライザです。"
マシンエミュレータとして使う場合、QEMU はあるマシン (例: ARM ボード) 用に作られた OS やプログラムを他のマシン (例: x86 PC) で動かすことができます。動的変換を利用することによって、素晴らしいパフォーマンスを実現します。
QEMU は Xen や KVM などの他のハイパーバイザを使用して、仮想化のための CPU 拡張命令 (HVM) を利用することができます。バーチャライザとして使う場合、ゲストコードをホスト CPU で直接実行することにより QEMU はネイティブに近いパフォーマンスを得ることができます。
目次
- 1 インストール
- 2 QEMU のグラフィカルフロントエンド
- 3 新しい仮想化システムの作成
- 4 仮想化システムを実行する
- 5 ホスト・ゲスト OS 間でデータを移動する
- 6 ネットワーク
- 7 グラフィックカード
- 8 SPICE
- 9 VNC
- 10 オーディオ
- 11 virtio ドライバーのインストール
- 12 QEMU モニタ
- 13 QEMU マシンプロトコル
- 14 ヒントとテクニック
- 14.1 仮想マシンのパフォーマンスを向上させる
- 14.2 ブート時に QEMU 仮想マシンを開始する
- 14.3 マウスの統合
- 14.4 ホスト USB デバイスのパススルー
- 14.5 SPICE による USB リダイレクト
- 14.6 KSM の有効化
- 14.7 マルチモニターのサポート
- 14.8 Custom display resolution
- 14.9 コピーアンドペースト
- 14.10 Windows 特有のノート
- 14.11 物理機器にインストールされた Linux システムのクローン
- 14.12 x86_64 から arm/arm64 環境への chrooting
- 14.13 マウス入力をつかまない
- 15 トラブルシューティング
- 15.1 マウスカーソルが敏感すぎたり迷走する
- 15.2 カーソルが表示されない
- 15.3 2つの異なるマウスカーソルが表示される
- 15.4 VNC 使用時のキーボードの問題
- 15.5 キーボードが壊れているまたは矢印キーが動作しない
- 15.6 キーマップファイルを読み込めない
- 15.7 ウィンドウのリサイズでゲストのディスプレイが引き伸ばされる
- 15.8 ioctl(KVM_CREATE_VM) failed: 16 Device or resource busy
- 15.9 libgfapi エラーメッセージ
- 15.10 ライブ環境でカーネルパニックが発生する
- 15.11 Windows 7 ゲストの音質が酷い
- 15.12 Could not access KVM kernel module: Permission denied
- 15.13 Windows 仮想マシンを起動したときに "System Thread Exception Not Handled"
- 15.14 特定の Windows のゲームやアプリケーションでクラッシュやブルスクリーンが発生する
- 15.15 仮想マシン内のアプリケーションで長い遅延が発生したり開始に長い時間がかかる
- 15.16 高い割り込みレイテンシとマイクロスタッタリング
- 15.17 QXL ビデオの低解像度化
- 15.18 セキュアブート対応 OVMF を使用すると仮想マシンが起動しない
- 15.19 仮想マシンが Arch ISO で起動しない
- 15.20 ゲスト CPU の割り込みが発生しない
- 15.21 sddm を使用した KDE でログイン時に spice-vdagent が自動的に起動しない
- 15.22 Error starting domain: Requested operation is not valid: network 'default' is not active
- 16 参照
インストール
qemu-full パッケージ (または GUI が必要ない場合は qemu-base とデフォルトで x86 エミュレーションのみの qemu-desktop) をインストールしてください。また、任意で以下のパッケージもインストールしてください:
- qemu-block-gluster - GlusterFS ブロックのサポート
- qemu-block-iscsi - iSCSI ブロックのサポート
- samba - SMB/CIFS サーバーのサポート
あるいは、ユーザーモードと静的のバリアントとして qemu-user-static が存在します。
QEMU バリアンツ
QEMUには、さまざまなユースケースに適したいくつかのバリアンツが用意されています。
最初の分類として、QEMU はフルシステムエミュレーションモードとユーザーモードエミュレーションモードの 2 種類を提供しています:
- フルシステムエミュレーション
- このモードでは、QEMU は 1 つまたは複数のプロセッサとさまざまな周辺機器を含むフルシステムをエミュレートします。より正確ですが速度は遅く、エミュレートする OS は Linux である必要がありません。
- フルシステムエミュレーション用の QEMU コマンドは
qemu-system-target_architecture
という名前が付けられています。例えば x86_64 CPU のエミュレーション用のqemu-system-x86_64
、インテル 32-bit x86 CPU 用のqemu-system-i386
、ARM (32 bits) 用のqemu-system-arm
、ARM64 用のqemu-system-aarch64
などです。 - ターゲットアーキテクチャがホスト CPU と一致する場合、このモードでも KVM や Xen のようなハイパーバイザを使うことで大幅なスピードアップの恩恵を受けられるかもしれません。
- ユーザーモードエミュレーション
- このモードでは、QEMU はホストシステムのリソースを利用することで、(潜在的に)異なるアーキテクチャ用にコンパイルされた Linux 実行ファイルを呼び出すことができます。互換性の問題がある場合があります。例えば、一部の機能が実装されていない、動的リンクされた実行ファイルがそのままでは動作しない(これについては #x86_64 から arm/arm64 環境への Chrooting を参照)、そして Linux のみがサポートされています(ただし Windows 実行ファイルの実行には Wine が使用できる 場合があります)。
- ユーザーモードエミュレーション用の QEMU コマンドには
qemu-target_architecture
という名前が付けられており、例えば 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-guest-agent.
- qemu-user-static は QEMU がサポートする全てのターゲットアーキテクチャにユーザーモードと静的バリアントを提供します。インストールされる QEMU コマンドは
qemu-target_architecture-static
という名前で、例えば intel 64-bit CPU 用はqemu-x86_64-static
です。
QEMU のグラフィカルフロントエンド
VirtualBox や VMware などの他の仮想化プログラムと違って、QEMU は仮想マシンを管理するための GUI(仮想マシン実行時に表示されるウィンドウを除く)を提供せず、保存された設定を使って永続的な仮想マシンを作成する方法も提供しません。仮想マシンを起動するためのカスタムスクリプトを作成していない限り、仮想マシンを実行するためのすべてのパラメータは、起動のたびにコマンドラインで指定する必要があります。
Libvirt は、QEMU 仮想マシンを管理するための便利な方法を提供します。利用可能なフロントエンドについては、libvirtクライアントの一覧 を参照してください。
新しい仮想化システムの作成
ハードディスクイメージの作成
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 仮想マシンを起動することができます (仮想化システムを実行するを参照):
$ 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 の両方で使えます。例えば、イメージ容量を 10GiB 増やすには、次を実行してください:
$ qemu-img resize disk_image +10G
ディスクイメージを拡大した後、仮想マシン内でファイルシステムおよびパーティションツールを使用して、新しいスペースを実際に使い始める必要があります。
イメージの縮小
ディスクイメージを縮小する場合は、仮想マシン内のファイルシステムおよびパーティションツールを使用してまず割り当てられたファイル・システムとパーティション・サイズを縮小し、それに応じてディスクイメージを縮小する必要があります。Windows ゲストの場合、"ハードディスクパーティションの作成とフォーマット" コントロールパネルを開きます。
イメージ領域を 10 GiB 減らすために、次のコマンドを実行します:
$ qemu-img resize --shrink disk_image -10G
イメージの変換
qemu-img convert
を使用して、イメージを他のフォーマットに変換できます。次の例では、 raw イメージを qcow2 に変換する方法を示します:
$ qemu-img convert -f raw -O qcow2 input.img output.qcow2
元の入力ファイルは削除されません。
インストールメディアを準備する
ディスクイメージにオペレーティングシステムをインストールするには、オペレーティングシステムのインストールメディア (例: 光ディスク、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 イメージを起動することができます( #仮想化システムを実行する を参照)。
仮想化システムを実行する
qemu-system-*
バイナリ (例えば qemu-system-i386
や qemu-system-x86_64
など、エミュレートするアーキテクチャによって異なります) を使って仮想化システムを実行します。使用方法は:
$ qemu-system-x86_64 options disk_image
全ての qemu-system-*
バイナリでオプションは共通です、全てのオプションのドキュメントは qemu(1) を見て下さい。
通常、オプションに多くの可能な値がある場合は、
$ qemu-system-x86_64 option help
を使って、すべての可能な値をリストアップできます。プロパティをサポートしている場合は
$ qemu-system-x86_64 option value,help
を使って、使用可能なプロパティをすべて一覧表示できます。
例えば:
$ qemu-system-x86_64 -machine help $ qemu-system-x86_64 -machine q35,help $ qemu-system-x86_64 -device help $ qemu-system-x86_64 -device qxl,help
これらのメソッドと qemu(1) ドキュメントを使用して、以降のセクションで使用されるオプションを理解できます。
デフォルトで、QEMU は仮想マシンのビデオ出力をウィンドウに表示します。注意: QEMU ウィンドウの中をクリックすると、マウスポインタが取り込まれます。ポインタを戻すには、Ctrl+Alt+g
を押して下さい。
KVM を有効にする
VM (Kernel-based Virtual Machine) による完全な仮想化をあなたの Linux カーネルとハードウェアがサポートし、必要なカーネルモジュールがロードされている必要があります。詳細については、KVM を参照してください。
QEMU を KVM モードで開始するには、開始オプションに -accel kvm
を追加してください。実行中の仮想マシンで KVM が有効になっているかどうか確認するには、Ctrl+Alt+Shift+2
を使って #QEMU モニタ に入り、info kvm
と入力してください。
IOMMU (Intel VT-d/AMD-Vi) サポートを有効にする
最初に IOMMU を有効にします。OVMF による PCI パススルー#IOMMU の有効化 を参照してください。
-device intel-iommu
を追加して IOMMU デバイスを作成してください:
$ qemu-system-x86_64 -enable-kvm -machine q35 -device intel-iommu -cpu host ..
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/x64/OVMF.4m.fd
をコピーして書き込み可能にし、pflash ドライブとして利用する方法です:
-drive if=pflash,format=raw,file=/copy/of/OVMF.4m.fd
UEFI 設定への全ての変更はこのファイルに直接保存されます。
もう一つのより好ましい方法は OVMF を二つのファイルに分割することです。最初のファイルは読み込み専用でファームウェアの実行ファイルを保存し、2番目のファイルは書き込み可能な変数ストアとして使われます。利点はファームウェアファイルをコピーせずに直接使うことができ、 pacman によって自動的にアップデートされることです。
/usr/share/edk2/x64/OVMF_CODE.4m.fd
を最初のリードオンリーの pflash ドライブとして使用します。/usr/share/edk2/x64/OVMF_VARS.4m.fd
をコピーして書き込み可能にし、2台目の書き込み可能な pflash ドライブとして使用します:
-drive if=pflash,format=raw,readonly=on,file=/usr/share/edk2/x64/OVMF_CODE.4m.fd \ -drive if=pflash,format=raw,file=/copy/of/OVMF_VARS.4m.fd
セキュアブートが必要な場合、q35 マシンタイプを使用し、/usr/share/edk2/x64/OVMF_CODE.4m.fd
を /usr/share/edk2/x64/OVMF_CODE.secboot.4m.fd
に置き換えます。
Trusted Platform Module のエミュレーション
QEMU は、Windows 11 (TPM 2.0 が必要)などの一部のシステムで必要とされる 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
すると、仮想マシン内で TPM が使用できるようになります。仮想マシンをシャットダウンすると、swtpm は自動的に終了します。
詳しくは the QEMU documentation を参照してください。
もしゲスト OS が TPM デバイスを認識しない場合、CPU モデルとトポロジー オプションを調整してみてください。問題を引き起こしているかもしれません。
ホスト・ゲスト 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 はホストからゲストへポートを転送し、例えばホストからゲスト上で動作している 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.ランダムな文字列
にある自動生成の smb.conf
ファイルでホスト上で Samba を起動し、別の IP アドレス(デフォルトでは 10.0.2.4)でゲストからアクセス可能にするだけのものです。これはユーザーネットワークでのみ動作し、ホスト上で通常の Samba サービスを起動したくない場合に便利です。ホスト上で共有を設定した場合、ゲストもアクセスすることができます。
オプション 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 を使う
QEMU ドキュメント を参照してください。
virtiofsd によるホストファイル共有
virtiofsd は QEMU パッケージに同梱されています。ドキュメントは オンライン[リンク切れ 2023-05-06] または /usr/share/doc/qemu/qemu/tools/virtiofsd.html
が qemu-docs がインストールされたローカルファイルシステムにあります。
virtiofsd ソケットにアクセスする必要があるため、qemu を実行するユーザを 'kvm' ユーザーグループ に追加します。変更を反映するにはログアウトする必要があるかもしれません。
virtiofsd を root で開始します:
# /usr/lib/virtiofsd --socket-path=/var/run/qemu-vm-001.sock --shared-dir /tmp/vm-001 --cache always
ここで
/var/run/qemu-vm-001.sock
はソケットファイルです。/tmp/vm-001
はホストとゲスト仮想マシン間の共有ディレクトリです。
作成されたソケットファイルは root のみアクセス権を持っています。以下のようにグループ kvm にアクセス権を与えます:
# chgrp kvm qemu-vm-001.sock; chmod g+rxw qemu-vm-001.sock
仮想マシン開始時に以下の設定オプションを追加します:
-object memory-backend-memfd,id=mem,size=4G,share=on \ -numa node,memdev=mem \ -chardev socket,id=char0,path=/var/run/qemu-vm-001.sock \ -device vhost-user-fs-pci,chardev=char0,tag=myfs
ここで
size=4G
は-m 4G
オプションで指定したサイズと一致する必要があります。/var/run/qemu-vm-001.sock
は先に起動されたソケットファイルを指します。
ゲストでは共有が有効となるように設定されている必要があることに注意してください。 Windows の場合、手順書 があります。一度設定すると、Windows の Z:
ドライブに共有ディレクトリの内容が自動的にマップされます。
以下のものがあれば、Windows 10 ゲストシステムは適切に設定されています。
- VirtioFSSService windows サービス
- WinFsp.Launcher windows サービス
- Windows の "デバイスマネージャー" の "システムデバイス" の下の VirtIO FS Device driver
上記がインストールされていても Z:
ドライブが表示されない場合は、Windows の プログラムの追加と削除 から "Virtio-win-guest-tools" を修復してみてください。
ゲストのパーティションをホストにマウントする
ホストシステムの下にドライブイメージをマウントすると、ゲストへのファイルの出し入れに便利な場合があります。これは仮想マシンが動作していないときに行う必要があります。
ホストにドライブをマウントする手順は、qemu イメージの raw や qcow2 といった種類によって異なります。この2つの形式のドライブをマウントする手順については、#rawイメージからのパーティションのマウント と #qcow2イメージからのパーティションのマウント で詳しく説明します。完全なドキュメントは Wikibooks:QEMU/Images#Mounting an image on the host を参照してください。
raw イメージからパーティションをマウントする
ループバックデバイスとして設定することで、 raw ディスクイメージファイル内のパーティションをマウントできます。
手動でバイトオフセットを指定する
ディスクイメージのパーティションをマウントする一つの方法として、次のようなコマンドを使って特定のオフセットでディスクイメージをマウントする方法があります:
# 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
パラメータを設定してロードしてください。また、loop デバイスの最大数はmax_loop
パラメータで制御できます。
イメージをループバックデバイスとして設定:
# losetup -f -P disk_image
これで、作成されたデバイスが /dev/loop0
の場合、追加のデバイス /dev/loop0pX
が自動的に作成されます。X はパーティションの番号です。これらのパーティションのループバックデバイスは直接マウントすることができます。例えば:
# mount /dev/loop0p1 mountpoint
udisksctl でディスクイメージをマウントする方法は Udisks#ループデバイスのマウント を参照してください。
kpartx を使う
multipath-tools パッケージの kpartx はデバイス上のパーティションテーブルを読み込んでパーティションごとに新しいデバイスを作成することができます。例えば:
# kpartx -a disk_image
これでループバックデバイスがセットアップされ、/dev/mapper/
に必要なパーティションデバイスが作成されます。
qcow2 イメージからパーティションをマウントする
NBD (network block device) プロトコルを使ってディスクイメージを共有することができる qemu-nbd
を使用してみます。
まず、nbdモジュールをロードする必要があります:
# modprobe nbd max_part=16
次に、ディスクを共有してデバイスエントリを作成します:
# qemu-nbd -c /dev/nbd0 /path/to/image.qcow2
パーティションを検出します:
# partprobe /dev/nbd0
fdisk を使用して nbd0
内のさまざまなパーティションに関する情報を取得できます:
# fdisk -l /dev/nbd0
Disk /dev/nbd0: 25.2 GiB, 27074281472 bytes, 52879456 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0xa6a4d542 Device Boot Start End Sectors Size Id Type /dev/nbd0p1 * 2048 1026047 1024000 500M 7 HPFS/NTFS/exFAT /dev/nbd0p2 1026048 52877311 51851264 24.7G 7 HPFS/NTFS/exFAT
次に、ドライブイメージの任意のパーティション、例えばパーティション 2 をマウントします:
# mount /dev/nbd0p2 mountpoint
使用後は、イメージをアンマウントし、前の手順を逆にすることが重要です。つまり、パーティションをアンマウントし nbd デバイスを切断します:
# umount mountpoint # qemu-nbd -d /dev/nbd0
実際のパーティションをハードディスクイメージのシングルプライマリパーティションとして使う
場合によって、QEMU の中からシステムパーティションのどれかを使いたくなることもあるでしょう。仮想マシンでの raw パーティションの使用は、読み書きの操作が物理ホストのファイルシステムレイヤーを通過しないため、パフォーマンスが高くなります。そのようなパーティションをホストとゲストでのデータの共有手段として使うこともできます。
Arch Linux では、raw パーティションのデバイスファイルは、デフォルトで、root と disk グループが所有者です。root 以外のユーザーで raw パーティションに読み書きできるようにしたい場合は、パーティションのデバイスファイルの所有者をそのユーザーに変えるか、そのユーザーを disk グループに追加するか、ACL を使用してより詳細なアクセス制御を行う必要があります。
その後、パーティションを QEMU の仮想マシンに仮想ディスクとしてアタッチできます。
ただし、仮想マシン 全体 をパーティションに収めたいときは、事態は多少複雑になります。そのような場合、実際に仮想マシンを起動するディスクイメージファイルがないために、MBR でパーティション分けされたデバイスではなくファイルシステムとしてフォーマットされたパーティションにブートローダーをインストールすることができません。このような仮想マシンは次のいずれかの方法でブートできます: #カーネルと initrd を手動で指定する、#MBR で仮想ディスクをシミュレートする、#device-mapper を使う、#リニア RAID を使う、または#ネットワークブロックデバイスを使う。
カーネルと 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'
MBR で仮想ディスクをシミュレートする
ファイルシステムでフォーマットされたパーティションを維持しながらゲストのパーティションをまるでディスクであるかのようなパーティションにしないで、仮想マシンで物理パーティションを使用するもっと複雑な方法として、MBR をシミュレートして GRUB などのブートローダーを使って起動できるようにする方法があります。
次の例では、マウントされていないプレーンな /dev/hdaN'
パーティションがあり、その中に QEMU ディスクイメージの一部にしたいファイルシステムがあるとします。秘訣は、 QEMU rawディスクイメージに組み込みたい実パーティションに、動的にマスターブートレコード (MBR) を付加することです。より一般的には、このパーティションは、より大きなシミュレートされたディスクの任意の部分、特に元の物理ディスクをシミュレートしますが /dev/hda
N
だけを仮想マシンに公開するブロックデバイスにすることができます。
このタイプの仮想ディスクは、MBRとパーティションへの参照(コピー)を含む VMDK ファイルで表すことができますが、 QEMU はこの VMDK フォーマットをサポートしていません。たとえば、 以下のように作成された 仮想ディスクは
$ VBoxManage internalcommands createrawvmdk -filename /path/to/file.vmdk -rawdisk /dev/hda
以下のエラーメッセージとともに QEMU によって拒否されます
Unsupported image type 'partitionedDevice'
VBoxManage
は file.vmdk
と file-pt.vmdk
の2つのファイルを作成します。後者は MBR のコピーであり、テキスト・ファイル file.vmdk
が参照します。ターゲットパーティションまたは MBR の外側への読取り操作にはゼロが返され、書き込まれたデータは破棄されます。
device-mapper を使う
VMDK ディスクリプタ・ファイルを利用するのと同様の方法で、 device-mapper を利用して、 MBR ファイルに付属するループ・デバイスを対象パーティションにプリペンドする方法があります。仮想ディスクのサイズがオリジナルと同じである必要がない場合、まず MBR を保持するためのファイルを作成します。
$ dd if=/dev/zero of=/path/to/mbr count=2048
これで、最新のディスクパーティションツールが使用するパーティションアライメントポリシーに従った 1 MiB (2048*512バイト) のファイルが作成されます。古いパーティショニングソフトウェアとの互換性のために、2048 セクタではなく 63 セクタが必要になる場合があります。MBR に必要なブロックは 512 バイトのみです。追加の空き領域は BIOS ブートパーティションや、ハイブリッドパーティショニングスキームの場合は GUID パーティションテーブルに使用できます。次に、ループデバイスを MBR ファイルにアタッチします:
# losetup --show -f /path/to/mbr
/dev/loop0
この例では、結果のデバイスは /dev/loop0
です。device mapper を使って MBR とパーティションを結合します:
# echo "0 2048 linear /dev/loop0 0 2048 `blockdev --getsz /dev/hdaN` linear /dev/hdaN 0" | dmsetup create qemu
生成された /dev/mapper/qemu
は、 QEMU の raw ディスクイメージとして使用します。仮想ディスク上にパーティションテーブル(例としてリニア RAID の使用について説明したセクションを参照)とブートローダーコード(/path/to/mbr
に保存されます)を作成するには、追加の手順が必要です。
次の設定例では、仮想ディスク上の {ic|/dev/hdaN}} の位置を物理ディスク上と同じにし、コピーとして提供される MBR を除き、ディスクの残りの部分を非表示にしています:
# dd if=/dev/hda count=1 of=/path/to/mbr # loop=`losetup --show -f /path/to/mbr` # start=`blockdev --report /dev/hdaN | tail -1 | awk '{print $5}'` # size=`blockdev --getsz /dev/hdaN` # disksize=`blockdev --getsz /dev/hda` # echo "0 1 linear $loop 0 1 $((start-1)) zero $start $size linear /dev/hdaN 0 $((start+size)) $((disksize-start-size)) zero" | dmsetup create qemu
dmsetup
への標準入力として提供されるテーブルは、 VBoxManage
によって作成された VMDK 記述子ファイル内のテーブルと同様のフォーマットを持ち、代わりに dmsetup create qemu--tabletable_file
でファイルからロードできます。仮想マシンには /dev/hdaN
だけがアクセス可能で、ハードディスクの残りはゼロとして読み取られ、書き込まれたデータは最初のセクタを除いて破棄されます。 dmsetup table qemu
で /dev/mapper/qemu
のテーブルを表示できます (udevadm info -rq name /sys/dev/block/major:minor
で major:minor
を /dev/blockdevice
名に変換してください) 。作成されたデバイスを削除するには dmsetup remove qemu
と losetup -d $loop
を使います。
この例が役に立つ状況は、マルチブート構成の既存の Windows XP インストールと、おそらくハイブリッドパーティションスキーム(物理ハードウェアでは、Windows XP が MBR パーティションテーブルを使用する唯一のオペレーティングシステムであり、同じコンピュータにインストールされた最新のオペレーティングシステムは GUID パーティションテーブルを使用できます)の場合です。Windows XP はハードウェアプロファイルをサポートしているため、同じインストールを異なるハードウェア構成で交互に使用できます(この場合はベアメタルと仮想)。Windows は新しく検出されたハードウェアのドライバをプロファイルごとに1回だけインストールする必要があります。この例ではコピーされた MBR のブートローダコードを更新して、元のシステムに存在するマルチブート対応のブートローダ(GRUB など)を起動するのではなく、 /dev/hdaN
から直接 Windows XP をロードする必要があることに注意してください。または、ブートローダインストールを含むブートパーティションのコピーを MBR と同じ方法で仮想ディスクに含めることもできます。
リニア RAID を使う
リニアモードのソフトウェア RAID (linear.ko
カーネルドライバが必要です)とループバックデバイスを使うこともできます:
最初に、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 を使って "マージされた" 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
を押してエキスパートメニューを開きます。トラック毎のセクタ数を設定 ('s') してシリンダーの容量が 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 を使ってディスクイメージにブートローダーを設定できます。
ネットワークブロックデバイスを使う
Network Block Device によって、Linux はリモートサーバをブロックデバイスの1つとして使うことができます。 nbd-server
(nbd パッケージ)を使って、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 [...]
仮想マシン内部で物理ディスクデバイス全体を使用する
別の OS(Windows など)を搭載した2台目のディスクがあり、仮想マシン内でも起動できるようにしたいと思うかもしれません。 ディスクアクセスは raw のため、仮想マシン内でのディスクパフォーマンスは非常に良好です。
Windows 仮想マシンブートの前提条件
仮想マシンで起動する前に、必ずそのディスクの OS の中に virtio ドライバ をインストールしておいてください。 Win 7 では、バージョン 0.1.173-4 を使用してください。 新しい virtio ビルドの個別ドライバは Win 7 で使用できるかもしれませんが、デバイスマネージャを使用して手動でインストールする必要があります。 Win 10 では、最新の virtio ビルドを使用できます。
Windows ディスクインタフェースドライバを設定する
仮想マシンを起動しようとすると、0x0000007B
ブルースクリーンが表示されることがあります。これは、Windows が必要とするディスクインタフェースドライバがロードされていないか、手動で起動するように設定されているため、起動の初期段階でドライブにアクセスできないことを意味します。
解決策は、これらのドライバをブート時に起動するようにする ことです。
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services
で aliide, amdide, atapi, cmdide, iastor (無いかもしれません), iastorV, intelide, LSI_SAS, msahci, pciide and viaide
フォルダを探します。
これらのそれぞれの中で、ブート時に有効にするためにすべての "start" の値を 0 に設定します。
ドライブが PCIe NVMe ドライブの場合、そのドライバ(存在するはずです)も有効にします。
ディスクの固有パスを検索する
ls /dev/disk/by-id/
を実行します: 仮想マシンに挿入するドライブの ID、例えば ata-TS512GMTS930L_C199211383
を選択します。
次に、その ID を /dev/disk/by-id/
に追加して、/dev/disk/by-id/ata-TS512GMTS930L_C199211383
を取得します。
これが、そのディスクへの固有パスです。
QEMU CLI でディスクを追加する
QEMU CLI では、おそらく次のようになります:
-drive file=/dev/disk/by-id/ata-TS512GMTS930L_C199211383,format=raw,media=disk
"file=" をドライブの固有パスに変更するだけです。
libvirt でディスクを追加する
libvirt XML では、次のように変換されます
$ virsh edit vmname
... <disk type="block" device="disk"> <driver name="qemu" type="raw" cache="none" io="native"/> <source dev="/dev/disk/by-id/ata-TS512GMTS930L_C199211383"/> <target dev="sda" bus="sata"/> <address type="drive" controller="0" bus="0" target="0" unit="0"/> </disk> ...
"source dev" をあなたのドライブの固有パスに変更するだけです。
virt-manager でディスクを追加する
仮想マシンを作成する際に、"既存のドライブをインポート" を選択し、固有パスを貼り付けるだけです。 すでに仮想マシンがある場合、デバイスとストレージを追加してから、カスタムストレージを選択または作成します。 そして固有パスを貼り付けます。
ネットワーク
仮想ネットワークのパフォーマンスはユーザーモードネットワークまたは vde よりも tap デバイスやブリッジの方が良くなるはずです。tap デバイスやブリッジはカーネル内で実装されているからです。
加えて、デフォルトの e1000 NIC のエミュレーションではなく virtio ネットワークデバイスを仮想マシンに指定することでネットワークのパフォーマンスを向上させることができます。詳しくは #virtio ドライバーのインストール を参照。
リンク層アドレス
QEMU に -net nic
引数を与えると、デフォルトで、仮想マシンにリンク層アドレス 52:54:00:12:34:56
のネットワークインターフェイスが割り当てられます。しかしながら、ブリッジネットワークで複数の仮想マシンを使用する場合、個別の仮想マシンには tap デバイスの仮想マシン側からそれぞれ固有のリンク層 (MAC) アドレスを設定しなくてはなりません。設定を行わないと、ブリッジが上手く動きません。同一のリンク層アドレスを持つ複数のソースからパケットを受け取ることになるからです。たとえ tap デバイス自体に固有のリンク層アドレスを設定していたとしても、ソースのリンク層アドレスは tap デバイスを通過するときに書き換えられないため、問題が発生します。
個々の仮想マシンに固有のリンク層アドレスを設定、それも、どのアドレスも 52:54:
で始まるように設定してください。以下のオプションを使って下さい (X は任意の16進数の数字に置き換えてください):
$ qemu-system-x86_64 -net nic,macaddr=52:54:XX:XX:XX:XX -net vde disk_image
固有のリンク層アドレスの生成は複数の方法で行うことができます:
- NIC ごとに固有のリンク層アドレスを手動で指定する。仮想マシンを起動するたびに同じ IP アドレスが DHCP サーバーによって割り当てられるという利点がありますが、仮想マシンが大量にある場合は現実的ではありません。
- 仮想マシンを起動するたびにランダムなリンク層アドレスを生成する。衝突する可能性はほとんどゼロですが、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
- 以下のスクリプト
qemu-mac-hasher.py
を使ってハッシュ関数を利用し仮想マシンの名前からリンク層アドレスを生成する。仮想マシンの名前を一意なものとして、上記の方法の良いところを組み合わせています。スクリプトが実行されるたびに同一のリンク層アドレスが生成される上、衝突する可能性はほとんどありません。
qemu-mac-hasher.py
#!/usr/bin/env python # usage: qemu-mac-hasher.py <VMName> import sys import zlib crc = str(hex(zlib.crc32(sys.argv[1].encode("utf-8")))).replace("x", "")[-8:] 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 上の他のマシンが仮想マシンに通信できるようにしたい場合に価値があります。
ユーザーモードネットワークセクションで示したように、tap デバイスはユーザーモードよりも高いネットワーク性能を提供します。ゲスト OS が virtio ネットワークドライバーをサポートする場合、ネットワーク性能も大幅に向上します。tap0 デバイスを使用し、virtio ドライバがゲストで使用され、ネットワークの開始/停止を補助するスクリプトが使用されていない場合、qemu コマンドの一部は次のようになります:
-device virtio-net,netdev=network0 -netdev tap,id=network0,ifname=tap0,script=no,downscript=no
しかし、すでに virtio ネットワークドライバで tap デバイスを使用している場合は、vhost を有効にすることでネットワーク性能を向上させることもできます:
-device virtio-net,netdev=network0 -netdev tap,id=network0,ifname=tap0,script=no,downscript=no,vhost=on
詳細は [2] を参照してください。
ホストオンリーネットワーク
ブリッジに 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 やブリッジに対応することができます。 /usr/lib/qemu/qemu-bridge-helper
バイナリを使用して、既存のブリッジに tap デバイスを作成できます。
まず、QEMU が使用するすべてのブリッジの名前を含む設定ファイルを作成します:
/etc/qemu/bridge.conf
allow br0 allow br1 ...
/etc/qemu/
の パーミッション が 755
であることを確認してください。そうでない場合、 QEMU の問題 と GNS3 の問題 が発生する可能性があります。
次に仮想マシンを起動します; デフォルトのネットワークヘルパーとデフォルトのブリッジ br0
で QEMU を実行する最も基本的な使い方は:
$ qemu-system-x86_64 -nic bridge [...]
ブリッジ br1
と virtio ドライバを使用するには:
$ qemu-system-x86_64 -nic bridge,br=br1,model=virtio-net-pci [...]
ブリッジを手動で作成する
以下では仮想マシンを eth0
などのホストインターフェイスにブリッジする方法を説明しています。おそらく一番よく使われている設定です。この設定では、物理的なホストマシンと同一の Ethernet セグメントに、直接外部ネットワークに仮想マシンが位置するようになります。
通常の Ethernet アダプタをブリッジアダプタで置き換えて、通常の Ethernet アダプタをブリッジアダプタに bind することにします。
- ブリッジを制御するための
brctl
が入っている bridge-utils をインストール。
- IPv4 フォワーディングを有効にする:
# sysctl -w net.ipv4.ip_forward=1
変更を永続的にするために、/etc/sysctl.d/99-sysctl.conf
の net.ipv4.ip_forward = 0
を net.ipv4.ip_forward = 1
に変えます。
tun
モジュールをロードして起動時にロードするように設定してください。詳しくはカーネルモジュールを参照。
- オプションでブリッジを作成します。詳細は netctl でブリッジ接続 を参照してください。ブリッジに
br0
という名前を付けるか、以下のスクリプトをブリッジの名前に変更してください。以下のrun-qemu
スクリプトでは、リストにない場合は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
- 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 : ' e.g. with img created via: qemu-img create -f qcow2 example.img 90G run-qemu -cdrom archlinux-x86_64.iso -boot order=d -drive file=example.img,format=qcow2 -m 4G -enable-kvm -cpu host -smp 4 run-qemu -drive file=example.img,format=qcow2 -m 4G -enable-kvm -cpu host -smp 4 ' nicbr0() { sudo ip link set dev $1 promisc on up &> /dev/null sudo ip addr flush dev $1 scope host &>/dev/null sudo ip addr flush dev $1 scope site &>/dev/null sudo ip addr flush dev $1 scope global &>/dev/null sudo ip link set dev $1 master br0 &> /dev/null } _nicbr0() { sudo ip link set $1 promisc off down &> /dev/null sudo ip link set dev $1 nomaster &> /dev/null } HASBR0="$( ip link show | grep br0 )" if [ -z $HASBR0 ] ; then ROUTER="192.168.1.1" SUBNET="192.168.1." NIC=$(ip link show | grep en | grep 'state UP' | head -n 1 | cut -d":" -f 2 | xargs) IPADDR=$(ip addr show | grep -o "inet $SUBNET\([0-9]*\)" | cut -d ' ' -f2) sudo ip link add name br0 type bridge &> /dev/null sudo ip link set dev br0 up sudo ip addr add $IPADDR/24 brd + dev br0 sudo ip route del default &> /dev/null sudo ip route add default via $ROUTER dev br0 onlink nicbr0 $NIC sudo iptables -I FORWARD -m physdev --physdev-is-bridged -j ACCEPT fi USERID=$(whoami) precreationg=$(ip tuntap list | cut -d: -f1 | sort) sudo ip tuntap add user $USERID mode tap postcreation=$(ip tuntap list | cut -d: -f1 | sort) TAP=$(comm -13 <(echo "$precreationg") <(echo "$postcreation")) nicbr0 $TAP 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,model=virtio \ -net tap,ifname=$TAP,script=no,downscript=no,vhost=on \ $@ _nicbr0 $TAP sudo ip link set dev $TAP down &> /dev/null sudo ip tuntap del $TAP mode tap if [ -z $HASBR0 ] ; then _nicbr0 $NIC sudo ip addr del dev br0 $IPADDR/24 &> /dev/null sudo ip link set dev br0 down sudo ip link delete br0 type bridge &> /dev/null sudo ip route del default &> /dev/null sudo ip link set dev $NIC up sudo ip route add default via $ROUTER dev $NIC onlink &> /dev/null fi
それから仮想マシンを起動するために、以下のようにコマンドを実行して下さい
$ run-qemu -hda myvm.img -m 512
- パフォーマンスとセキュリティ上の理由で ブリッジ上のファイアウォール は無効にすることをお勧めします:
/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
起動時に上記のパラメータを適用するには、ブート時に br-netfilter モジュールをロードする必要があります。そうしないと、sysctl がパラメータを変更しようとしたときに、そのパラメータが存在しないことになります。
/etc/modules-load.d/br_netfilter.conf
br_netfilter
すぐに変更を適用するには sysctl -p /etc/sysctl.d/10-disable-firewall-on-bridge.conf
を実行してください。
libvirt wiki や Fedora bug 512206 を参照。起動中にファイルが存在しないというエラーが起こるときは、起動時に bridge
モジュールをロードするようにしてください。カーネルモジュール#systemd を参照。
または、次のようにルールを追加することで全てのトラフィックをブリッジで通すように iptables を設定することができます:
-I FORWARD -m physdev --physdev-is-bridged -j ACCEPT
iptables による物理デバイスと Tap デバイスのネットワーク共有
ブリッジネットワークは、有線インターフェイス (eth0 など) 間では正常に動作し、セットアップも簡単です。ただし、ホストがワイヤレスデバイスを介してネットワークに接続されている場合、ブリッジはできません。
参考として ネットワークブリッジ#ブリッジ上の無線インターフェイス を参照。
これを克服する1つの方法は、tap デバイスに静的 IP を設定し、linux に自動的にルーティングを処理させ、iptables ルールで tap インターフェイスとネットワークに接続されたデバイス間のトラフィックを転送することです。
参考として インターネット共有 を参照。
tap や tun など、デバイス間でネットワークを共有するために必要なものを見つけることができます。次に、必要なホスト構成のヒントを示します。上記の例で示したように、クライアントは、tap インターフェイスに割り当てられた IP をゲートウェイとして、静的 IP を設定する必要があります。注意点は、DNS サーバーがネットワークに接続されているホストデバイスから別のホストデバイスに変更された場合は、クライアント上の DNS サーバーを手動で編集する必要があることです。
起動毎に IP 転送を行うようにするには、/etc/sysctl.d
内の sysctl 設定ファイルに次の行を追加する必要があります:
net.ipv4.ip_forward = 1 net.ipv6.conf.default.forwarding = 1 net.ipv6.conf.all.forwarding = 1
iptables のルールは以下のようになります:
# Forwarding from/to outside iptables -A FORWARD -i ${INT} -o ${EXT_0} -j ACCEPT iptables -A FORWARD -i ${INT} -o ${EXT_1} -j ACCEPT iptables -A FORWARD -i ${INT} -o ${EXT_2} -j ACCEPT iptables -A FORWARD -i ${EXT_0} -o ${INT} -j ACCEPT iptables -A FORWARD -i ${EXT_1} -o ${INT} -j ACCEPT iptables -A FORWARD -i ${EXT_2} -o ${INT} -j ACCEPT # NAT/Masquerade (network address translation) iptables -t nat -A POSTROUTING -o ${EXT_0} -j MASQUERADE iptables -t nat -A POSTROUTING -o ${EXT_1} -j MASQUERADE iptables -t nat -A POSTROUTING -o ${EXT_2} -j MASQUERADE
上記は、ネットワークに接続された3つのデバイスが、1つの内部デバイスとトラフィックを共有していると仮定しています。例えば次のようなものです:
INT=tap0 EXT_0=eth0 EXT_1=wlan0 EXT_2=tun0
上記は、tap デバイスとの有線および無線接続の共有を可能にする転送を示しています。
示されている転送ルールはステートレスであり、純粋な転送のためのものです。特定のトラフィックを制限し、ゲストや他の人を保護するためにファイアウォールを設置することを考えることができます。しかし、これらはネットワークパフォーマンスを低下させます。一方、シンプルなブリッジにはそのようなものはありません。
おまけ: 接続が有線または無線のいずれであっても、tun デバイスを使用してリモートサイトに VPN 経由で接続された場合、その接続用にオープンされた tun デバイスが tun0 であり、事前のiptablesルールが適用されていると仮定すると、リモート接続もゲストと共有されます。これにより、ゲストも VPN 接続をオープンする必要がなくなります。繰り返しますが、ゲストネットワークは静的である必要があるため、この方法でホストをリモート接続する場合、おそらくゲスト上の DNS サーバーを編集する必要あります。
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 -s "$TAP_NETWORK"/"$TAP_MASK" -o "$NIC" -j MASQUERADE # Bring tap interface down ip link set "$TAP_DEV" down # Kill VDE switch pgrep 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
に 実行可能属性 を付与するようにパーミッションを変更。
通常通り qemu-network-env.service
を 開始 できます。
他の方法
上の方法が動作しない場合やカーネル設定, TUN, dnsmasq, iptables を変えたくない場合は以下のコマンドで同じ結果になります。
# vde_switch -daemon -mod 660 -group users # slirpvde --dhcp --daemon
ホストのネットワークの接続を使って仮想マシンを起動するには:
$ 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 をさまざまなネットワーク・オプションとともに頻繁に使用している場合、-netdev
と -device
の引数のペアを大量に作成している可能性があり、かなり反復的になっています。代わりに -nic
引数を使って、 -netdev
と -device
を結合することもできます。たとえば、次のような引数は:
-netdev tap,id=network0,ifname=tap0,script=no,downscript=no,vhost=on -device virtio-net-pci,netdev=network0
こうなります:
-nic tap,script=no,downscript=no,vhost=on,model=virtio-net-pci
ネットワーク ID がないこと、およびデバイスが model=
で作成されたことに注意してください。-nic
パラメータの前半は -netdev
パラメータですが、後半 (model=
の後) はデバイスに関連付けられています。同じパラメータ (たとえば、 smb=
) が使用されます。ネットワークを完全に無効にするには、 -nic none
を使用します。
使用できるパラメーターの詳細については、 QEMU ネットワークのドキュメント を参照してください。
グラフィックカード
QEMU は -display curses
コマンド・ライン・オプションを使用して、標準のグラフィックカードのテキストモードをエミュレートできます。これにより、テキストターミナル内でテキストを入力しテキスト出力を直接見ることができます。代わりに、 -nographic
も同様の目的を果たします。
QEMU はいくつかのタイプの VGA カードをエミュレートできます。カードタイプは -vga type
コマンドラインオプションで渡され、 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
カーネルモジュールをロードしてください。
QXL デバイスのデフォルトの VGA メモリサイズは 16M です。これは QHD(2560x1440) までの解像度を駆動するのに十分です。より高い解像度を有効にするには、 vga_memmb を増やします。
vmware
多少バグが存在しますが、std や cirrus よりもパフォーマンスが上です。Arch Linux ゲスト用の VMware ドライバー xf86-video-vmware と xf86-input-vmmouse をインストールします。
virtio
virtio-vga
/ virtio-gpu
は virgl ベースの準仮想化 3D グラフィックスドライバです。成熟しており、現在はオプション galla-drivers=virgl
でコンパイルされた mesa (>=11.2) を持つごく最近 (>=4.4) のLinux ゲストのみをサポートしています。
ゲストシステムで 3D アクセラレーションを有効にするには、-device virtio-vga-gl
でこの vga を選択し、ディスプレイデバイスで sdl および gtk ディスプレイ出力に対してそれぞれ -display sdl,gl=on
または -display gtk,gl=on
を使用して OpenGL コンテキストを有効にします。ゲスト側のカーネルログを見ることで設定が問題ないか確認できます:
# dmesg | grep drm
[drm] pci: virtio-vga detected [drm] virgl 3d acceleration enabled
cirrus
cirrus グラフィカルアダプタは 2.2 以前まではデフォルト でした。新しいシステムでは 使用しないほうがよい とされています。
none
これは VGA カードが全くない PC と同じようになります。-vnc
オプションを使ってもアクセスすることはできません。また、QEMU に VGA カードをエミュレートさせ SDL ディスプレイを無効にする -nographic
オプションとは異なります。
SPICE
SPICE プロジェクト は、仮想マシンへのリモートアクセスをシームレスに行うための完全なオープンソースソリューションを提供することを目的としています。
ホストで SPICE サポートを有効にする
リモートデスクトッププロトコルとして SPICE を使用して起動する例を示します。これには、ホストからのコピーと貼り付けのサポートも含まれています:
$ qemu-system-x86_64 -vga qxl -device virtio-serial-pci -spice port=5930,disable-ticketing=on -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 -chardev spicevmc,id=spicechannel0,name=vdagent
パラメータの意味は次のとおりです:
-device virtio-serial-pci
は virtio-serial デバイスを追加します-spice port=5930,disable-ticketing=on
は spice チャネルを待ち受ける TCP ポート5930
を設定し、クライアントが認証なしで接続できるようにします-device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0
は virtio-serial デバイスの spice vdagent 用のポートを開きます。-chardev spicevmc,id=spicechannel0,name=vdagent
は、そのポートに spicevmc の chardev を追加します。virtserialport
デバイスのchardev=
オプションが、chardev
オプション (この例では {ic|spicechannel0}}) に指定されたid=
オプションと一致することが重要です。また、ポート名がcom.redhat.spice.0
であることも重要です。これは、vdagent がゲスト内で探している名前空間であるためです。最後にname=vdagent
を指定して、spice がこのチャネルの目的を認識できるようにします。
SPICE クライアントでゲストに接続する
ゲストに接続するには SPICE クライアントが必要です。Arch では、次のクライアントを使用できます:
- virt-viewer — プロトコル開発者が推奨する SPICE クライアント。virt-manager プロジェクトのサブセットです。
- spice-gtk — SPICE GTK クライアント。SPICE プロジェクトのサブセットです。他のアプリケーションにウィジェットとして埋め込まれています。
スマートフォンやその他のプラットフォームで動作するクライアントについては、spice-space download の その他のクライアント セクションを参照してください。
SPICE クライアントを手動で実行する
Unix ソケット /tmp/vm_spice.socket
で待ち受けるゲストに接続する方法の1つは、望みのクライアントに応じて $remote-viewer spice+unix:///tmp/vm_spice.socket
または $spicy--uri="spice+unix:///tmp/vm_spice.socket"
を使用して SPICE クライアントを手動で実行することです。SPICE モードの QEMU はリモートデスクトップサーバーのように振る舞うため、-daemonize
パラメータを指定してデーモンモードで QEMU を実行する方が便利な場合があります。
QEMU で SPICE クライアントを実行する
ディスプレイが -display spice-app
パラメータを使用して SPICE に設定されている場合、QEMU は適切なソケットで SPICE クライアントを自動的に起動できます。これは、XDG MIME Applications#mimeapps.list mimeapps.list ファイルによって決定されたシステムのデフォルト SPICE クライアントをビューアとして使用します。
ゲストで SPICE サポートを有効にする
Arch Linux ゲスト では、マルチモニタまたはクリップボード共有のサポートを改善するために、以下のパッケージをインストールする必要があります:
- spice-vdagent: クライアントと X-session などとの間でコピー&ペーストを可能にする Spice エージェント xorg クライアント。(GNOME 以外のデスクトップで動作させるための回避策については、修正されるまで、この イシュー を参照してください。)
- xf86-video-qxl: Xorg X11 qxl ビデオドライバ
- x-resizeAUR: GNOME 以外のデスクトップ環境では、SPICE クライアントウィンドウのサイズが変更されても自動的には反応しません。このパッケージは、udev ルールと xrandr を使用して、すべての X11 ベースのデスクトップ環境とウィンドウマネージャに自動リサイズ機能を実装します。
その他のオペレーティングシステム のゲストについては、spice-space download の ゲスト セクションを参照してください。
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 サーバに接続するためのパスワードを要求するようになります。
SPICE による TLS 暗号化通信
SPICE サーバと通信するために TLS 暗号化を設定することもできます。まず、次のファイルを含むディレクトリを作成する必要があります(名前は指定されたとおりでなければなりません):
ca-cert.pem
: CA マスター証明書。server-cert.pem
:ca-cert.pem
で署名されたサーバ証明書。server-key.pem
: サーバの秘密キー。
Spice User Manual に、サーバ用に独自に作成した認証局で自己署名証明書を生成する例が示されています。
その後、上記の説明と同様に SPICE を使用して QEMU を実行しますが、-spice
引数として: -spice tls-port=5901,password=yourpassword,x509-dir=/path/to/pki_certs
を使用します。、/path/to/pki_certs
は、前述の3つの必要なファイルを含むディレクトリのパスとなります。
これで、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-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
VNC
-vnc :X
オプションを追加すると、QEMU に VGA ディスプレイを VNC セッションにリダイレクトさせることができます。ディスプレイ番号を X
に置き換えます (0 は 5900 で、1 は 5901... でリッスンします)。
$ qemu-system-x86_64 -vnc :0
#ブート時に QEMU 仮想マシンを起動する セクションにも例が示されています。
基本的なパスワード認証
アクセスパスワードは password
オプションを使用して簡単に設定できます。QEMU モニターでパスワードを指定する必要があり、パスワードが提供された場合にのみ接続が可能になります。
$ qemu-system-x86_64 -vnc :0,password -monitor stdio
QEMU モニターでは、change vnc password
コマンドを使用してパスワードを設定し、次にパスワードを指定します。
次のコマンドラインは、直接 vnc をパスワードを付きで実行します。
$ printf "change vnc password\n%s\n" MYPASSWORD | qemu-system-x86_64 -vnc :0,password -monitor stdio
オーディオ
オーディオバックエンドを作成する
-audiodev
フラグは、ホスト上のオーディオバックエンドドライバとそのオプションを設定します。
利用可能なオーディオバックエンドドライバを一覧表示するには:
$ qemu-system-x86_64 -audiodev help
オプション設定のリストについては qemu(1) のマニュアルページに詳細があります。
最低限、オーディオバックエンドを選択し、PulseAudio の ID を設定する必要があります。たとえば:
-audiodev pa,id=snd0
オーディオバックエンドを使用する
Intel HD Audio
Intel HD Audio エミュレーションの場合は、コントローラーとコーデックデバイスの両方を追加してください。使用可能なインテル HDA Audio デバイスを一覧するには:
$ qemu-system-x86_64 -device help | grep hda
オーディオコントローラを追加するには:
-device ich9-intel-hda
そして、オーディオコーデックを追加し、ホストオーディオバックエンド ID にマップします:
-device hda-output,audiodev=snd0
Intel 82801AA AC97
AC97 エミュレーションの場合は、オーディオカードデバイスを追加し、ホストオーディオバックエンド ID にマップするだけです:
-device AC97,audiodev=snd0
VirtIO sound
VirtIO sound も QEMU 8.2.0 より利用できます。使い方は:
-device virtio-sound-pci,audiodev=my_audiodev -audiodev alsa,id=my_audiodev
詳細な情報が QEMU documentation にあります。
virtio ドライバーのインストール
QEMU は virtio ドライバを使って準仮想化ブロックデバイスとネットワークデバイスを使用する機能をゲストに提供し、より良いパフォーマンスとより低いオーバーヘッドを実現します。
- virtio ブロックデバイスは、ディスクイメージを渡すためのオプション
-drive
と、パラメータif=virtio
を必要とします:
$ qemu-system-x86_64 -drive file=disk_image,if=virtio
- ネットワークでもほぼ同じです:
$ qemu-system-x86_64 -nic user,model=virtio-net-pci
Arch Linux ゲストを用意する
Arch Linux ゲストをインストールした後 virtio デバイスを使うには、次のモジュールをゲストでロードする必要があります: virtio
, virtio_pci
, virtio_blk
, virtio_net
, virtio_ring
。32ビットゲストの場合、特定の "virtio" モジュールは必要ありません。
virtio ディスクから起動したい場合、イニシャル ramdisk に必要なモジュールを含める必要があります。デフォルトでは、mkinitcpio の autodetect
フックによって管理されています。もしくは /etc/mkinitcpio.conf
の MODULES
配列を使用して必要なモジュールを組み込み、イニシャル ramdisk をリビルドしてください。
/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 コマンドのサポートを得ることができます。
Windows ゲストを用意する
Windows 用の virtio ドライバ
Windows には virtio ドライバは付属していません。最新の安定版バージョンのドライバは Fedora によって定期的にビルドされており、ドライバのダウンロードの詳細は virtio-win on GitHub で提供されています。以降のセクションでは、ここで提供されている安定版 ISO ファイル virtio-win.iso を主に使用します。または、virtio-winAUR を使用します。
ブロックデバイスドライバ
Windows の新規インストール
インストール時にドライバをロードする必要があります。手順としては、プライマリディスクデバイスおよび Windows ISO インストールメディアとともに cdrom デバイスで virtio ドライバを含む ISO イメージをロードします。
$ qemu-system-x86_64 ... \ -drive file=disk_image,index=0,media=disk,if=virtio \ -drive file=windows.iso,index=2,media=cdrom \ -drive file=virtio-win.iso,index=3,media=cdrom \ ...
インストール中、Windows インストーラが "Where do you want to install Windows?" と尋ねる段階で、ディスクを見つけられないという警告が表示されます。以下の手順に従ってください (アップデート適用済みの Windows Server 2012 R2 がベース):
- Load Drivers オプションを選択。
- Hide drivers that are not compatible with this computer's hardware のチェックを外す。
- Browse ボタンをクリックして virtio iso の CDROM を開く。通常 "virtio-win-XX" という名前になります。
E:\viostor\[your-os]\amd64
を選択して OK を押す。
これで virtio ディスクが表示されるので、選択して、フォーマット・インストールすることができます。
virtio を使用するように既存の Windows 仮想マシンを変更する
virtio ディスクから起動するように既存の Windows ゲストを変更するには、起動時にゲストによって virtio ドライバがロードされる必要があります。 そのため、virtio モードでディスクイメージを起動できるようにする前に、起動時に virtio ドライバーをロードするように Windows に教える必要があります。
このためには、まず virtio モードで接続される新しいディスクイメージを作成し、ドライバの検索をトリガします:
$ qemu-img create -f qcow2 dummy.qcow2 1G
ブートディスクは IDE モードのまま、フェイクディスクを virtio モード、ドライバ ISO イメージを使用して元の Windows ゲストを実行します。
$ qemu-system-x86_64 -m 4G -drive file=disk_image,if=ide -drive file=dummy.qcow2,if=virtio -cdrom virtio-win.iso
Windows はフェイクディスクを検出して適切なドライバを探します。失敗した場合は、デバイスマネージャ に移動し、感嘆符アイコン(開いているはず)が表示されている SCSI ドライブを探し、ドライバの更新 をクリックして仮想 CD-ROM を選択します。CD-ROM 内のドライバフォルダに移動せず、単に CD-ROM ドライブを選択するだけで、Windows は適切なドライバを自動的に検索します (Windows 7 SP1 でテスト済み)。
Windows に次回起動時にセーフモードで起動するように要求します。これは、Windows の msconfig.exe ツールを使用して行うことができます。セーフモードでは新しい virtio ドライバを含むすべてのドライバが起動時にロードされます。Windows は、起動時に virtio ドライバが必要であることを認識すると、将来の起動のためにそれを記憶します。
セーフモードで起動するように指示されたら、仮想マシンをオフにして再度起動できます。今度の起動ディスクは virtio モードで接続されています:
$ qemu-system-x86_64 -m 4G -drive file=disk_image,if=virtio
virtio ドライバがロードされた状態のセーフモードで起動されているはずです。これで msconfig.exe に戻り、セーフモードでの起動を無効にして、Windows を再起動できます。
ネットワークドライバ
virtio ネットワークドライバーのインストールは少し簡単で、単に -nic
引数を追加するだけです。
$ qemu-system-x86_64 -m 4G -drive file=windows_disk_image,if=virtio -nic user,model=virtio-net-pci -cdrom virtio-win.iso
ネットワークアダプタが検出され、そのドライバが検索されます。失敗した場合は、デバイスマネージャ に移動し、感嘆符アイコン(開いているはず)が表示されているネットワークアダプタを探し、ドライバの更新 をクリックして仮想 CD-ROM を選択してください。ディレクトリを再帰的に検索するチェックボックスを選択することを忘れないでください。
バルーンドライバ
(virsh
コマンドの dommemstat
などで) ゲストのメモリ状態を追跡したり実行時にゲストのメモリサイズを変えたい場合 (メモリサイズは変更できませんが、バルーンドライバを膨張させることでメモリ使用量を制限できます) 、ゲストにバルーンドライバをインストールする必要があります。
このためには、デバイス マネージャー にアクセスし、システム デバイス (またはほかのデバイス から認識されない PCI コントローラ) で PCI 標準 RAM コントローラ を検索し、ドライバの更新 を選択してください。ウィンドウが開いたら コンピュータを参照して... を選択し、CD-ROM を選択してください(そして サブフォルダーも検索する チェックボックスを忘れないでください)。インストール後に再起動してください。これによりドライバがインストールされ、バルーンを膨らませることができます (たとえば 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_load="YES" virtio_pci_load="YES" virtio_blk_load="YES" if_vtnet_load="YES" virtio_balloon_load="YES"
そして次を実行して /etc/fstab
を修正してください:
# sed -ibak "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
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、nmap、または 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
あるいは nmap で:
$ ncat -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
で実行すると、QEMU が実行されているのと同じ端末から自動的にモニタにアクセスできます。
モニタコンソールを使って仮想マシンにキーボードの押下を送信する
設定によっては仮想マシン上で一部のキーの組み合わせがホストによって邪魔されて使えない場合があります (顕著な例として、アクティブな 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 を実行するだけで仮想マシンを frozen 状態で実行でき、仮想マシンの電源がオフになったときにすべての変更を破棄できます。ゲストによるディスクイメージの書き込みがあった場合、変更は /tmp
内の一時ファイルに保存され QEMU が停止したときに破棄されます。
ただし、マシンが frozen モードで実行している場合でも、後で必要に応じて、モニタコンソールを使用して次のコマンドを実行することにより、変更をディスクイメージに保存することができます。
(qemu) commit all
frozen モードで実行中にスナップショットが作成された場合、変更が明示的にディスクにコミットされない限り、QEMU の終了時に破棄されます。
モニタコンソールによる一時停止と電源オプション
モニタコマンドを使って物理マシンの操作の一部を QEMU でエミュレートできます:
system_powerdown
は仮想マシンに ACPI シャットダウンリクエストを送信します。物理マシンの電源ボタンを押したときと同じような効果があります。system_reset
は物理マシンのリセットボタンと同じように仮想マシンをリセットします。仮想マシンが正常に再起動されないためデータが消失したりファイルシステムが破損する可能性があります。stop
は仮想マシンを停止します。cont
は仮想マシンを以前に停止した状態から復帰します。
仮想マシンのスクリーンショットを取得する
モニタコンソールで次のコマンドを実行することで PPM 形式で仮想マシンのグラフィックディスプレイのスクリーンショットを取得できます:
(qemu) screendump file.ppm
QEMU マシンプロトコル
QEMU マシンプロトコル (QMP) は、アプリケーションが QEMU インスタンスを制御できるようにする JSON ベースのプロトコルです。#QEMU モニタ の様に実行中のマシンと対話する方法を提供し、JSON プロトコルによりプログラム的に行うことを可能にします。すべての QMP コマンドの説明は qmp-commands に記載されています。
QMP を開始する
QMP プロトコルを使用してゲストを制御する通常の方法は、-qmp
オプションを使用してマシンを起動するときに TCP ソケットを開くことです。ここでは、例えば TCP ポート 4444 を使用しています:
$ qemu-system-x86_64 [...] -qmp tcp:localhost:4444,server,nowait
QMP エージェントと通信する方法の1つは netcatを使用することです:
nc localhost 4444
{"QMP": {"version": {"qemu": {"micro": 0, "minor": 1, "major": 3}, "package": ""}, "capabilities": []} }
この段階で、認識できるコマンドは qmp_capabilities
のみであるため、QMP はコマンドモードに入ります。次を入力:
{"execute": "qmp_capabilities"}
これで、QMP はコマンドを受信できるようになりました。認識されたコマンドのリストを取得するには、次のコマンドを使用します:
{"execute": "query-commands"}
親イメージへの子イメージのライブマージ
block-commit
コマンドを発行すると、実行中のスナップショットを親にマージできます。最も単純な形式では、次の行は子を親にコミットします:
{"execute": "block-commit", "arguments": {"device": "devicename"}}
このコマンドを受信すると、ハンドラはベースイメージを探し、読み取り専用モードから読み取り/書き込みモードに変換し、コミットジョブを実行します。
block-commit 操作が完了すると、イベント BLOCK_JOB_READY
が発生し、同期が完了したことが通知されます。次のコマンド block-job-complete
を発行すると、ジョブを正常に完了できます。
{"execute": "block-job-complete", "arguments": {"device": "devicename"}}
このようなコマンドが発行されるまで、commit 操作はアクティブなままです。 正常に完了した後、ベースイメージは読み取り/書き込みモードのままとなり、新しいアクティブレイヤになります。一方、子イメージは無効になり、クリーンアップするのはユーザの責任となります。
新しいスナップショットのライブ作成
実行中のイメージから新しいスナップショットを作成するには、次のコマンドを実行します:
{"execute": "blockdev-snapshot-sync", "arguments": {"device": "devicename","snapshot-file": "new_snapshot_name.qcow2"}}
これにより new_snapshot_name.qcow2
という名前のオーバーレイファイルが作成され、新しいアクティブレイヤになります。
ヒントとテクニック
仮想マシンのパフォーマンスを向上させる
仮想マシンのパフォーマンスを向上させるために使用できるテクニックは数多くあります。例えば:
- 完全な仮想化のために #KVM を有効にする。
-cpu host
オプションで QEMU により一般的な CPU ではなくホストの正確な CPU をエミュレートさせる。- 特に Windows ゲストの場合、Hyper-V enlightenments を有効にする:
-cpu host,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time
。詳細とフラグについては QEMU documentation を参照。 -smp cores=x,threads=y,sockets=1,maxcpus=z
オプションを使用して、複数のコアをゲストに割り当てることができます。threads パラメータは、SMT コア の割り当てに使用されます。QEMU、ハイパーバイザ、およびホストシステムがスムーズに動作できるように物理コアを残しておくことは、非常に有益です。- 仮想マシンに十分なメモリーが割り当てられていることを確認する。デフォルトでは、QEMU は各仮想マシンに 128 MiB のメモリーのみを割り当てます。より多くのメモリーを割り当てるには、
-m
オプションを使用します。たとえば、-m 1024
は 1024 MiB のメモリーを持つ仮想マシンを実行します。 - ゲストオペレーティングシステムのドライバでサポートされている場合は、ネットワークデバイスやブロックデバイスに virtio を使用する。#virtio ドライバーのインストール を参照してください。
- ユーザーモードネットワーキングの代わりに TAP デバイスを使用する。#QEMU の Tap ネットワーク を参照してください。
- ゲスト OS がディスクに大量の書き込みを行っている場合、ホストのファイルシステムの特定のマウントオプションの恩恵を受けられます。たとえば、
barrier=0
オプションを指定して ext4 ファイルシステム をマウントできます。ファイルシステムのパフォーマンス向上オプションはデータ整合性を犠牲にする場合があるため、変更したオプションについてはドキュメントを参照してください。 - raw ディスクまたはパーティションがある場合、キャッシュを無効にしても良いでしょう:
$ qemu-system-x86_64 -drive file=/dev/disk,if=virtio,cache=none
- native Linux AIO を使う:
$ qemu-system-x86_64 -drive file=disk_image,if=virtio,aio=native,cache.direct=on
- 同じオペレーティングシステムがインストールされている複数の仮想マシンを同時に実行している場合、kernel same-page merging を有効にすることでメモリを節約できます。#KSMの有効化 を参照してください。
- 場合によっては、ゲストオペレーティングシステムでメモリバルーニングドライバを実行し、
-device virtio-balloon
で QEMU を起動すると実行中の仮想マシンからメモリを回収できることがあります。 - ICH-9 AHCI コントローラのエミュレーションレイヤを使用することができます(ただし、不安定な場合があります)。AHCI エミュレーションは Wikipedia:Native_Command_Queuing NCQ をサポートしているため、複数の読み書き要求を同時に発行できます:
$ qemu-system-x86_64 -drive id=disk,file=disk_image,if=none -device ich9-ahci,id=ahci -device ide-drive,drive=disk,bus=ahci.0
詳しくは https://www.linux-kvm.org/page/Tuning_KVM を参照してください。
ブート時に QEMU 仮想マシンを開始する
libvirt を使う
仮想マシンが libvirt でセットアップされている場合、virsh autostart
または virt-manager GUI を使用して、仮想マシンの Boot Options に移動して Start virtual machine on host boot up を選択することで、ホストのブート時に仮想マシンを開始するように構成できます。
systemd サービスを使う
ブート時に QEMU 仮想マシンを実行するには、次の systemd ユニットと設定を使うことができます。
/etc/systemd/system/qemu@.service
[Unit] Description=QEMU virtual machine [Service] Environment="haltcmd=kill -INT $MAINPID" EnvironmentFile=/etc/conf.d/qemu.d/%i ExecStart=/usr/bin/qemu-system-x86_64 -name %i -enable-kvm -m 512 -nographic $args ExecStop=/usr/bin/bash -c ${haltcmd} ExecStop=/usr/bin/bash -c 'while nc localhost 7100; do sleep 1; done' [Install] WantedBy=multi-user.target
次に、変数 args
と haltcmd
がセットされた /etc/conf.d/qemu.d/vm_name
という名前の VM 毎の設定ファイルを作成します。設定例は:
/etc/conf.d/qemu.d/one
args="-hda /dev/vg0/vm1 -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
/etc/conf.d/qemu.d/two
args="-hda /srv/kvm/vm2 -serial telnet:localhost:7001,server,nowait,nodelay -vnc :1" haltcmd="ssh powermanager@vm2 sudo poweroff"
変数の説明は次のとおりです。
args
- 使用する QEMU コマンドライン引数です。haltcmd
- 仮想マシンを安全にシャットダウンするためのコマンド。最初の例では、QEMU モニターは-monitor telnet:..
を使用して telnet 経由で公開され、仮想マシンはnc
コマンドでsystem_powerdown
をモニターに送信することで ACPI 経由で電源がオフになります。他の例では、SSH が使われます。
ブートアップ時にどの仮想マシンを開始するかを設定するには、qemu@vm_name.service
systemd ユニットを 有効化 します。
マウスの統合
ゲストオペレーティングシステムのウィンドウをクリックしたときにマウスをつかまれないようにするには、-usb -device usb-tablet
オプションを追加します。これにより、 QEMU はマウスをつかむことなくマウスの位置を伝えることができるようになります。また、このコマンドは有効化されている場合 PS/2 マウスエミュレーションを上書きします。例えば:
$ qemu-system-x86_64 -hda disk_image -m 512 -usb -device usb-tablet
それでもうまくいかない場合、-vga qxl
パラメータを使ってみてください。また、#マウスカーソルが敏感すぎたり迷走する も参照してみて下さい。
ホスト USB デバイスのパススルー
ゲストからホストの USB ポートに接続された物理デバイスにアクセスできます。最初のステップはデバイスが接続されている場所を特定することです。これは lsusb
コマンドを実行して確認できます。例えば:
$ lsusb
... Bus 003 Device 007: ID 0781:5406 SanDisk Corp. Cruzer Micro U3
上記の太字の出力は、それぞれ host_bus と host_addr 、または vendor_id と product_id を識別するのに役立ちます。
qemu では、-device usb-ehci,id=ehci
または -device qemu-xhci,id=xhci
オプションを使用して EHCI (USB 2) または XHCI (USB 1.1 USB 2 USB 3) コントローラーをエミュレートし、次に -device usb-host,..
オプションを使用して物理デバイスをこのコントローラーに接続するという考え方になっています。このセクションの残りの部分では controller_id が ehci
または xhci
であるとみなします。
次に、qemu でホストの USB に接続する方法は2つあります:
- デバイスを識別し、ホスト上でデバイスが接続されているバスとアドレスでデバイスに接続します。一般的な構文は次のとおりです:
-device usb-host,bus=controller_id.0,vendorid=0xvendor_id,productid=0xproduct_id
上の例で使用されているデバイスに適用すると、次のようになります:-device usb-ehci,id=ehci -device usb-host,bus=ehci.0,vendorid=0x0781,productid=0x5406
前のオプションに...,port=port_number
設定を追加して、デバイスを接続する仮想コントローラの物理ポートを指定することもできます。これは、複数の USB デバイスを仮想マシンに追加したい場合に便利です。もう1つのオプションは QEMU 5.1.0 以降で利用可能なusb-host
の新しいhostdevice
プロパティを使用することで、構文は次のとおりです:-device qemu-xhci,id=xhci -device usb-host,hostdevice=/dev/bus/usb/003/007
- 任意の USB バスとアドレスに接続されているものを接続します。構文は次のようになります:
-device usb-host,bus=controller_id.0,hostbus=host_bus,host_addr=host_addr
上記の例のバスとアドレスに適用すると、次のようになります:-device usb-ehci,id=ehci -device usb-host,bus=ehci.0,hostbus=3,hostaddr=7
詳しくは QEMU/USB エミュレーション を参照してください。
SPICE による USB リダイレクト
#SPICE を使用しているのであれば、QEMU コマンドで指定しなくてもクライアントから仮想マシンに USB デバイスをリダイレクトすることが可能です。リダイレクトされたデバイスが利用できる USB スロットの数を設定することができます (スロットの数によって、同時にリダイレクトできるデバイスの最大数が決まります)。前述の -usbdevice
方式と比較して、リダイレクトに SPICE を使用する主な利点は、仮想マシンの開始後に USB デバイスをホットスワップできることで、リダイレクトから USB デバイスを削除したり新しいデバイスを追加したりするために USB デバイスを停止する必要がありません。また、ネットワーク経由でクライアントからサーバーに USB デバイスをリダイレクトすることもできます。まとめると、これは QEMU 仮想マシンで USB デバイスを使用する最も柔軟な方法です。
利用可能な USB リダイレクトスロットごとに1つの EHCI/UHCI コントローラを追加し、さらにスロットごとに1つの SPICE リダイレクションチャネルを追加する必要があります。たとえば、SPICE モードで仮想マシンを開始するために使用する QEMU コマンドに以下の引数を追加すると、リダイレクトに利用可能な3つの USB スロットを持つ仮想マシンが開始されます:
-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/usbredir を参照してください。
spice-gtk (Input>Select USB Devices for redirection) の spicy
と virt-viewer (File>USB device selection) の remote-viewer
の両方がこの機能をサポートしています。この機能が期待どおりに動作するために必要な SPICE ゲストツールが仮想マシンにインストールされていることを確認してください (詳細については、#SPICE セクションを参照してください)。
udev による自動 USB 転送
通常、転送されるデバイスは仮想マシンの起動時に利用可能になっている必要があります。デバイスが切断されると、転送されなくなります。
udev を使用して、デバイスがオンラインになったときに自動的にデバイスを接続できます。ディスク上のどこかに hostdev
エントリを作成します。root に chown し、他のユーザーが変更できないようにします。
/usr/local/hostdev-mydevice.xml
<hostdev mode='subsystem' type='usb'> <source> <vendor id='0x03f0'/> <product id='0x4217'/> </source> </hostdev>
次に、デバイスをアタッチ/デタッチする udev ルールを作成します。
/usr/lib/udev/rules.d/90-libvirt-mydevice
ACTION=="add", \ SUBSYSTEM=="usb", \ ENV{ID_VENDOR_ID}=="03f0", \ ENV{ID_MODEL_ID}=="4217", \ RUN+="/usr/bin/virsh attach-device GUESTNAME /usr/local/hostdev-mydevice.xml" ACTION=="remove", \ SUBSYSTEM=="usb", \ ENV{ID_VENDOR_ID}=="03f0", \ ENV{ID_MODEL_ID}=="4217", \ RUN+="/usr/bin/virsh detach-device GUESTNAME /usr/local/hostdev-mydevice.xml"
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つの同じような仮想マシンが動いている)、/sys/kernel/mm/ksm/pages_shared
はゼロになりません。詳しくは https://docs.kernel.org/admin-guide/mm/ksm.html を参照。
マルチモニターのサポート
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
オプションも増やす必要があります。
Custom display resolution
A custom display resolution can be set with -device VGA,edid=on,xres=1280,yres=720
(see EDID and display resolution).
コピーアンドペースト
SPICE
ホストとゲストの間でクリップボードを共有する方法の1つは、SPICE リモートデスクトッププロトコルを有効にし、SPICE クライアントを使用してクライアントにアクセスすることです。 #SPICE で説明されている手順に従う必要があります。この方法で実行されるゲストは、ホストとのコピーペーストをサポートします。
qemu-vdagent
QEMU は qemu-vdagent
という spice vdagent chardev の独自の実装を提供しています。この実装は、スパイス-vdagent ゲストサービスとのインタフェースとなり、ゲストとホストがクリップボードを共有できるようにします。
QEMU の GTK ディスプレイでこの共有クリップボードにアクセスするには、--enable-gtk-clipboard
設定パラメータを指定して ソースから QEMU をコンパイルする必要があります。インストールされている qemu-ui-gtk
パッケージを置き換えるだけで十分です。
以下の QEMU コマンドライン引数を追加します:
-device virtio-serial,packed=on,ioeventfd=on -device virtserialport,name=com.redhat.spice.0,chardev=vdagent0 -chardev qemu-vdagent,id=vdagent0,name=vdagent,clipboard=on,mouse=off
これらの引数は、libvirt 形式 に変換した場合にも有効です。
Linux ゲストでは、spice-vdagent.service ユーザーユニット を手動で 開始 できます。Windows ゲストでは、spice-agent のスタートアップタイプを自動に設定します。
Windows 特有のノート
QEMU は Windows 95 から Windows 11 まで全てのバージョンの Windows を動かすことができます。
QEMU で Windows PE を実行することも可能です。
高速スタートアップ
Windows 8 (またはそれ以降) のゲストでは、次の フォーラムページ で説明されているようにコントロールパネルの電源オプションから "高速スタートアップを有効にする(推奨)" を無効にすることをお勧めします。この設定は、1回おきの起動時にゲストがハングする原因となるためです。
-smp
オプションへの変更を正しく適用するには、高速スタートアップを無効にする必要がある場合もあります。
リモートデスクトッププロトコル
MS Windows ゲストを使っている場合、RDP を使ってゲスト仮想マシンに接続する方法もあります。VLAN を使用していてゲストが同じネットワークにない場合、次を使って下さい:
$ qemu-system-x86_64 -nographic -nic user,hostfwd=tcp::5555-:3389
次に、rdesktop または freerdp を使用してゲストに接続します。例えば:
$ xfreerdp -g 2048x1152 localhost:5555 -z -x lan
物理機器にインストールされた Linux システムのクローン
物理的な機器にインストールされた Linux システムをクローンして、QEMU 仮想マシン上で動作させることができます。QEMU 仮想マシンのためにハードウェアから Linux システムをクローンする を参照してください。
x86_64 から arm/arm64 環境への chrooting
実際の ARM ベースのデバイスではなく、ディスクイメージを直接操作する方が簡単な場合もあります。これは、root パーティションを含む SD カード/ストレージをマウントし、そこに chroot することで実現できます。
ARM chroot のもうひとつのユースケースは、x86_64 マシン上で ARM パッケージを構築することです。ここで、chroot 環境を Arch Linux ARM のイメージ tarball から作成することができます - このアプローチの詳細は [3] を参照してください。
いずれにせよ、chroot から pacman を実行し、より多くのパッケージをインストールしたり、大きなライブラリをコンパイルしたりできるようになるはずです。実行可能ファイルは ARM アーキテクチャ用なので、x86 への変換は QEMU で行う必要があります。
x86_64 マシン/ホストに qemu-user-static を、qemu バイナリを binfmt サービスに登録するために qemu-user-static-binfmt インストールしてください。
qemu-user-static は他のアーキテクチャーからコンパイルされたプログラムの実行を許可するために使用されます。これは qemu-emulators-full で提供されるているものと似ていますが、chroot には static バリアントが必要です。例えば:
qemu-arm-static path_to_sdcard/usr/bin/ls qemu-aarch64-static path_to_sdcard/usr/bin/ls
これらの2行はそれぞれ 32ビット ARM と 64ビット ARM 用にコンパイルされた ls
コマンドを実行します。これは、ホストシステムに存在しないライブラリを探すため、chroot なしでは動作しないことに注意してください。
qemu-user-static では、ARM 実行可能ファイルの前に qemu-arm-static
または qemu-aarch64-static
を自動的に付けることができます。
ARM 実行可能サポートがアクティブであることを確認します:
$ ls /proc/sys/fs/binfmt_misc
qemu-aarch64 qemu-arm qemu-cris qemu-microblaze qemu-mipsel qemu-ppc64 qemu-riscv64 qemu-sh4 qemu-sparc qemu-sparc64 status qemu-alpha qemu-armeb qemu-m68k qemu-mips qemu-ppc qemu-ppc64abi32 qemu-s390x qemu-sh4eb qemu-sparc32plus register
それぞれの実行可能ファイルがリストアップされている必要があります。
アクティブでない場合は、systemd-binfmt.service
を 再起動 してください。
SD カードを /mnt/sdcard
にマウントしてください(デバイス名は異なる場合があります)。
# mount --mkdir /dev/mmcblk0p2 /mnt/sdcard
必要に応じてブートパーティションをマウントします(ここでも適切なデバイス名を使用します):
# mount /dev/mmcblk0p1 /mnt/sdcard/boot
最後に Chroot#chroot を使う の説明に従って SD カードのルートに chroot してください:
# chroot /mnt/sdcard /bin/bash
arch-install-scripts の arch-chroot を使用することもできます。これはネットワークサポートを得るためのより簡単な方法を提供します:
# arch-chroot /mnt/sdcard /bin/bash
systemd-nspawn を使用して ARM 環境に chroot することもできます:
# systemd-nspawn -D /mnt/sdcard -M myARMMachine --bind-ro=/etc/resolv.conf
--bind-ro=/etc/resolv.conf
はオプションで、chroot内部で動作中のネットワーク DNS を提供します。
sudo in chroot
chroot に sudo をインストールし、使用する際に次ののエラーが発生した場合:
sudo: effective uid is not 0, is /usr/bin/sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?
binfmt フラグを変更する必要がある場合があります。例えば、aarch64
の場合:
# cp /usr/lib/binfmt.d/qemu-aarch64-static.conf /etc/binfmt.d/ # vi /etc/binfmt.d/qemu-aarch64-static.conf
このファイルの最後に C
を追加:
:qemu-aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-aarch64-static:FPC
次に、systemd-binfmt.service
を 再起動 し、変更が有効になっていることを確認します(flags 行の C
に注意してください):
# cat /proc/sys/fs/binfmt_misc/qemu-aarch64
enabled interpreter /usr/bin/qemu-aarch64-static flags: POCF offset 0 magic 7f454c460201010000000000000000000200b700 mask ffffffffffffff00fffffffffffffffffeffffff
詳細については、カーネル binfmt ドキュメント の "flags" セクションを参照してください。
マウス入力をつかまない
タブレットモードには、QEMU ウィンドウでマウス入力をつかまないという副作用があります:
-usb -device usb-tablet
いくつかの -vga
バックエンドで動作しますが、そのうちのひとつは virtio です。
トラブルシューティング
マウスカーソルが敏感すぎたり迷走する
カーソルが画面を飛び回って手に負えない場合、QEMU を起動する前にターミナルに次を入力することで直るかもしれません:
$ export SDL_VIDEO_X11_DGAMOUSE=0
このコマンドで直ったら、~/.bashrc
ファイルにコマンドを追加することができます。
カーソルが表示されない
マウスカーソルを表示するには -display default,show-cursor=on
を QEMU のオプションに追加してください。
オプションを追加しても表示されない場合、ディスプレイデバイスが正しく設定されているか確認してください。例: -vga qxl
。
#マウスの統合 で説明されているように -usb-device usb-tablet
を試すこともできます。これはデフォルトの PS/2 マウスエミュレーションを上書きし、追加のボーナスとしてホストとゲスト間でポインタ位置を同期させます。
2つの異なるマウスカーソルが表示される
ヒント #マウスの統合 を適用してください。
VNC 使用時のキーボードの問題
VNC の使用中、ここに (生々しく詳細に) 書かれているキーボードの問題を経験するかもしれません。解決策は QEMU で -k
オプションを使用 しない ことと、gtk-vnc の gvncviewer
を使用することです。libvirt のメーリングリストに投稿された この メッセージも参照してください。
キーボードが壊れているまたは矢印キーが動作しない
キーの一部が動かなかったり間違ったキーが "押されてしまう" (特に矢印キー) ときは、おそらくキーボードレイアウトをオプションとして指定する必要があります。キーボードレイアウトは /usr/share/qemu/keymaps
で探すことができます。
$ qemu-system-x86_64 -k keymap disk_image
キーマップファイルを読み込めない
qemu-system-x86_64: -disnplay vnc=0.0.0.0:0: could not read keymap file: 'en'
-k
引数に渡された無効な keymap が原因です。たとえば、en
は無効ですが、en-us
は有効です。/usr/share/qemu/keymaps/
を参照してください。
ウィンドウのリサイズでゲストのディスプレイが引き伸ばされる
デフォルトのウィンドウサイズに戻すには、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)
または起動を妨げる他の処理(例えば initramfs をアンパックできない、サービス foo を起動できない)など。
-m VALUE
スイッチを付けて適当な量の RAM を指定して仮想マシンを開始してみてください。メモリスイッチがない場合、RAM が足りなくなると上記のような問題が発生することがあります。
Windows 7 ゲストの音質が酷い
Windows 7 ゲストで hda
オーディオドライバを使用すると、音質が低下する場合があります。-soundhw ac97
引数をQEMU に渡してオーディオドライバを 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 234 は 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 のゲームやアプリケーションでクラッシュやブルスクリーンが発生する
物理マシンでは問題なく動作するのに、仮想マシンで実行すると予期せずにクラッシュすることがあります。root で dmesg -wH
を実行したときに MSR
というエラーが発生した場合、クラッシュの原因はゲストがサポートされていない Model-specific registers (MSRs) にアクセスしようとすると、KVM が一般保護違反 (GPF) を起こすためです。これにより、ゲストアプリケーション/OS がクラッシュすることがよくあります。これらの問題の多くは、KVM モジュールに ignore_msrs=1
オプションを指定して実装されていない MSR を無視することで解決できます。
/etc/modprobe.d/kvm.conf
... options kvm ignore_msrs=1 ...
上記のオプションが役に立つのは以下のような場合です:
- GeForce Experience でサポートされていない CPU が存在するとエラーが表示される。
- StarCraft 2 や L.A.Noire で
KMODE_EXCEPTION_NOT_HANDLED
が発生して Windows 10 が確実にブルースクリーンになる。これらの場合、ブルースクリーン情報はドライバファイルを識別しません。
仮想マシン内のアプリケーションで長い遅延が発生したり開始に長い時間がかかる
これは、仮想マシンで使用可能なエントロピーが不足していることが原因である可能性があります。VirtIO RNGデバイス を仮想マシンに追加するか、Haveged などのエントロピー生成デーモンをインストールすることによって、ゲストがホストのエントロピープールにアクセスできるようにすることを検討してください。
逸話として、OpenSSH は不十分なエントロピーの下で接続を受け入れ始めるのに時間がかかりますが、その理由はログには示されません。
高い割り込みレイテンシとマイクロスタッタリング
この問題は小さな一時停止(カクつき)として現れ、特にゲームなどのグラフィックスを多用するアプリケーションで顕著になります。
- 原因の1つは、CPU 周波数スケーリング によって制御される CPU の省電力機能です。すべてのプロセッサコアについて
performance
に変更してください。 - もう1つの原因として、PS/2 入力が考えられます。PS/2 入力から Virtio 入力に切り替えてください。OVMF_による_PCI_パススルー#Evdev でキーボード・マウスを接続 を参照してください。
QXL ビデオの低解像度化
QEMU 4.1.0 では、QXL ビデオがスパイスで表示されると低解像度に戻るというリグレッションが発生しました。[4] たとえば、KMS が開始すると、テキストの解像度が 4x10 文字に低下することがあります。GUI の解像度を上げようとすると、サポートされている最低の解像度になることがあります。
回避策として、次の形式でデバイスを作成してください:
-device qxl-vga,max_outputs=1...
セキュアブート対応 OVMF を使用すると仮想マシンが起動しない
edk2-ovmf の OVMF_CODE.secboot.4m.fd
と OVMF_CODE.secboot.fd
ファイルは SMM サポート付きでビルドされています。仮想マシンで S3 サポートが無効になっていない場合、仮想マシンがまったく起動しない可能性があります。
qemu コマンドに -global ICH9-LPC.disable_s3=1
オプションを追加してください。
QEMU でセキュアブートを使用するために必要なオプションの詳細は FS#59465および https://github.com/tianocore/edk2/blob/master/OvmfPkg/README を参照してください。
仮想マシンが Arch ISO で起動しない
Arch ISO イメージから初めて仮想マシンを起動しようとすると、ブートプロセスがハングします。ブートメニューで e
を押して console=ttyS0
をカーネルブートオプションに追加すると、さらに多くのブートメッセージと次のエラーが表示されます:
:: Mounting '/dev/disk/by-label/ARCH_202204' to '/run/archiso/bootmnt' Waiting 30 seconds for device /dev/disk/by-label/ARCH_202204 ... ERROR: '/dev/disk/by-label/ARCH_202204' device did not show up after 30 seconds... Falling back to interactive prompt You can try to fix the problem manually, log out when you are finished sh: can't access tty; job control turned off
このエラーメッセージは、実際の問題が何なのかを明確に示すものではありません。問題は、QEMU が仮想マシンに割り当てるデフォルトの 128MB の RAM にあります。-m 1024
で制限を 1024MB に増やすと問題が解決し、システムが起動します。その後、通常どおり Arch Linux のインストールを続けることができます。インストールが完了したら、仮想マシンへのメモリ割り当てを減らすことができます。1024MB が必要になるのは、RAM ディスクの要件とインストールメディアのサイズによるものです。 arch-releng メーリングリストのこのメッセージ とこのフォーラムのスレッド を参照してください。
ゲスト CPU の割り込みが発生しない
OSDev wiki に従って独自のオペレーティングシステムを作成している場合や、QEMU の gdb
インターフェースで -s
フラグを使用してゲストアーキテクチャアセンブリコードをステップ実行している場合、QEMU を含む多くのエミュレーターが、通常はいくつかの CPU 割り込みを実装し、多くのハードウェア割り込みは実装していないということを知っておくと役に立ちます。あなたのコードが割り込みを発生させているかどうかを知る1つの方法は、以下を使用して:
-d int
標準出力に割り込み/例外の表示を有効にすることです。
QEMU が提供するその他のゲストデバッグ機能については、以下を参照してください:
qemu-system-x86_64 -d help
もしくは、x86_64
をあなたの選択したゲストアーキテクチャに置き換えてください。
sddm を使用した KDE でログイン時に spice-vdagent が自動的に起動しない
/etc/xdg/autostart/spice-vdagent.desktop
から X-GNOME-Autostart-Phaseテンプレート:=WindowManager
を削除するかコメントアウトしてください。 [5]
Error starting domain: Requested operation is not valid: network 'default' is not active
何らかの理由でデフォルトネットワークが非アクティブになっている場合、そのネットワークを使用するように設定されているゲスト仮想マシンを開始することはできません。最初の試みは、virsh でネットワークを開始することです。
# virsh net-start default
その他のトラブルシューティング手順については、[6] を参照してください。
参照
- QEMU 公式ウェブサイト
- KVM 公式ウェブサイト
- QEMU エミュレータユーザドキュメント
- QEMU Wikibook
- Hardware virtualization with QEMU by AlienBOB (2008年最終更新)
- Building a Virtual Army by Falconindy
- 最新ドキュメント
- QEMU on Windows
- Wikipedia
- Debian Wiki - QEMU
- QEMU Networking on gnome.org[リンク切れ 2022-09-22]
- Networking QEMU Virtual BSD Systems
- QEMU on gnu.org
- QEMU on FreeBSD as host
- KVM/QEMU Virtio Tuning and SSD VM Optimization Guide[リンク切れ 2022-09-22]
- Managing Virtual Machines with QEMU - openSUSE documentation
- KVM on IBM Knowledge Center