QEMU
関連記事
QEMU about page によると:
- QEMU は汎用的なオープンソースのマシンエミュレータでありバーチャライザです。
- マシンエミュレータとして使う場合、QEMU はあるマシン (例: ARM ボード) 用に作られた OS やプログラムを他のマシン (例: x86 PC) で動かすことができます。動的変換を利用することによって、素晴らしいパフォーマンスを実現します。
QEMU は Xen や KVM などの他のハイパーバイザを使用して、仮想化のための CPU 拡張命令 (HVM) を利用することができます。バーチャライザとして使う場合、QEMU はゲストコードをホスト CPU で直接実行することで、ネイティブに近いパフォーマンスを実現します。
目次
- 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 実際のパーティションをハードディスクイメージのシングルプライマリパーティションとして使う
- 14.3 ブート時に QEMU 仮想マシンを開始する
- 14.4 マウスの統合
- 14.5 ホスト USB デバイスのパススルー
- 14.6 SPICE による USB リダイレクト
- 14.7 KSM の有効化
- 14.8 マルチモニターのサポート
- 14.9 Custom display resolution
- 14.10 コピーアンドペースト
- 14.11 Windows 特有のノート
- 14.12 物理機器にインストールされた Linux システムのクローン
- 14.13 x86_64 から arm/arm64 環境への chrooting
- 14.14 マウス入力をつかまない
- 15 トラブルシューティング
- 16 参照
インストール
qemu-full パッケージ (または GUI が必要ない場合は qemu-base とデフォルトで x86_64 エミュレーションのみの 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 イメージを起動することができます( #仮想化システムを実行する を参照)。
既製の仮想マシンイメージ
多くの場合、クラウド環境などで自分でオペレーティングシステムを手動でインストールする必要はありませんし、望ましくないこともあります。幸い、多くの既製のイメージがさまざまなプロバイダーからダウンロード可能です。
Arch Linux の場合、arch-boxes プロジェクトに 毎週のイメージリリース があります。
同様のイメージは、Fedora や Debian でも利用可能です。
仮想化システムを実行する
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
セキュアブートを有効にする
VM でセキュアブートを有効にするための最初の要件は、マシンタイプとして q35 を使用し、/usr/share/edk2/x64/OVMF_CODE.4m.fd を /usr/share/edk2/x64/OVMF_CODE.secboot.4m.fd に置き換えることです。
次の要件は、セキュアブートキーがインストールされた OVMF_VARS ファイルを使用することですが、これは上流プロジェクト [1] では提供されていません
他のディストリビューションと異なり、Arch は (2024-12-06 現在) /usr/share/edk2/x64/OVMF_VARS.secboot.4m.fd ファイル(事前登録済みキー付き)を提供していません: 詳しくは テンプレート:Issue を参照。
簡単な回避策として このフォーラム投稿 の Fedora 版を使う方法があります:
- Fedora の edk2-ovmf の noarch RPM を ビルド一覧 からダウンロードする (2024-12-06 時点の最新 F42 版の 直接リンク)
- アーカイブを展開し、対象ファイルを適切なフォーマットに変換する [2]:
$ qemu-img convert -O raw -f qcow2 edk2-ovmf-*.noarch/usr/share/edk2/ovmf/OVMF_VARS_4M.secboot.qcow2 OVMF_VARS_4M.secboot.fd
これで作成した OVMF_VARS_4M.secboot.fd のコピーを作成し、セキュアブートを有効化した VM で使用できます。
セキュアブート用のファームウェアイメージに手動でキーを登録する方法については、KVM#セキュアブート も参照してください。
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 間でデータを共有することができます、ただしネットワークを適切に設定して適切なサービスを有効にする必要があります。
デフォルトの SLIRP ベースのユーザーモードネットワークは 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
vsock 経由で SSH にアクセスする
VM に接続するための安全で便利な方法は、vsock(7) を使用して SSH を使うことです。この方法を利用するには、VM が systemd ベースである必要があります。
まず、特別なデバイスを使用して QEMU を起動します:
-device vhost-vsock-pci,id=vhost-vsock-pci0,guest-cid=555
cid はユーザーが有効な 32 ビット番号として選択する必要があります(vsock(7) を参照)。systemd が VM が vhost-vsock デバイスで起動されたことを検出すると、自動的に systemd-ssh-generator を使用して SSH サーバーを起動します。
次に、以下のように VM に接続できます:
$ ssh user@vsock/555
これが動作するのは、/etc/ssh/ssh_config.d/20-systemd-ssh-proxy.conf が SSH クライアントに systemd-ssh-proxy を使用して vsock 経由で SSH を使うよう指示しているためです。
さらに、systemd.system-credentials(7) を使用することで、ダウンロードしたイメージを実行しようとする場合に便利な root ユーザーの認証済みキー ファイルを注入できます。これを次のように行うことができます:
-smbios type=11,value=io.systemd.credential.binary:ssh.authorized_keys.root=c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSU9sVFE4ejlpeWxoMTMreCtFVFJ1R1JEaHpIVVRnaCt2ekJLOGY3TEl5eTQ=
公開鍵行は base64 エンコードされた文字列として提供する必要があります。次のように行えます:
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOlTQ8z9iylh13+x+ETRuGRDhzHUTgh+vzBK8f7LIyy4" | base64
-smbios type=11,value=io.systemd... の仕組みを使って、systemd によって処理されるさまざまなその他の魔法のような変数を注入することもできます。詳細については、systemd ドキュメント: システムとサービスの資格情報 を参照してください。
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 として利用可能になります。
9pfs VirtFS によるホストファイル共有
QEMU ドキュメント を参照してください。
virtiofsd によるホストファイル共有
virtiofsd は virtiofsd パッケージに含まれています。これは、ホストとゲストの間でファイルを簡単に共有するための最新の高性能な方法です。利用可能なオプションの全リストは オンラインドキュメントまたは /usr/share/doc/virtiofsd/README.md を参照してください。
virtiofsd は、root または通常のユーザーとして実行するか選択できます。
通常のユーザーとして virtiofsd を実行する
まず virtiofsd を実行するユーザーに subuid(5) および subgid(5) の設定項目があることを確認します。Podman 記事の関連するセクション も参照してください。
次にvirtiofsd を起動します:
$ unshare -r --map-auto -- /usr/lib/virtiofsd --socket-path=/tmp/vm-share.sock --shared-dir /tmp/vm-share --sandbox chroot
unshare -rは、以後の新しいコマンドが、現在のユーザが root にマップされた状態で新しいユーザ名前空間で起動されるようにします。virtiofsd は root として実行されることを想定しているため、これは重要です。/tmp/vm-share.sockはソケットファイルです/tmp/vm-shareはホストとゲスト仮想マシン間の共有ディレクトリです
root として virtiofsd を実行する
QEMU を実行するユーザーを kvm ユーザーグループ に追加してください。これは virtiofsd のソケットにアクセスするために必要です。変更を反映させるには、一度ログアウトが必要な場合があります。
root で virtiofsd を開始します:
# /usr/lib/virtiofsd --socket-path /tmp/vm-share.sock --socket-group kvm --shared-dir /tmp/vm-share
ここで
/tmp/vm-share.sockはソケットファイルです/tmp/vm-shareはホストとゲスト仮想マシン間の共有ディレクトリです
QEMU を起動する
仮想マシン開始時に以下の設定オプションを追加します:
-m 4G -object memory-backend-memfd,id=mem,size=4G,share=on -numa node,memdev=mem \ -chardev socket,id=char0,path=/tmp/vm-share.sock -device vhost-user-fs-pci,chardev=char0,tag=myfs
ここで
size=4Gは-m 4Gオプションで指定したサイズと一致する必要がある/tmp/vm-share.sockは先に開始されたソケットファイルを指すmyfsは後でゲストで共有をマウントするために使用する識別子
rootfs を直接ブートする
rootfs を virtiofsd 経由で直接ブートすることも可能です。上述の引数に加えて、次のオプションを追加してください:
-kernel /path/to/vmlinux -initrd /path/to/initramfs -append 'rootfstype=virtiofs root=myfs rootflags=rw,noatime'
Linux ゲストで共有を使う
ゲストに root でログインしたら、最新のディストリビューションで共有をマウントするだけです:
# mount -t virtiofs myfs /mnt
このディレクトリはホストとゲストで共有されるはずです。
Windows ゲストで共有を使う
関連する Windows section を参照してください。
ゲストのパーティションをホストにマウントする
ホストシステムの下にドライブイメージをマウントすると、ゲストへのファイルの出し入れに便利な場合があります。これは仮想マシンが動作していないときに行う必要があります。
ホストにドライブをマウントする手順は、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
ネットワーク
仮想ネットワークのパフォーマンスはユーザーモードネットワークまたは 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
ユーザーモードネットワーク
SLIRP
デフォルトで、-netdev 引数をつけていないと、QEMU は DHCP サーバーが内蔵された SLIRP ベースの ユーザーモードネットワークを使用します。DHCP クライアントを実行したときに仮想マシンには IP アドレスが与えられ、QEMU による IP マスカレードを通して物理ホストのネットワークにアクセスできるようになります。
ホストがインターネットに接続されていれば、このデフォルトの設定で簡単に仮想マシンをインターネットにアクセスさせることができますが、外部ネットワークからは仮想マシンは直接は見えず、また、複数の仮想マシンを同時に起動していても仮想マシン同士が通信することはできません。
QEMU のユーザーモードネットワークには内蔵の TFTP や SMB サーバー、ゲストを VLAN に追加してゲストの通信を可能にするなどの機能があります。詳しくは -net user フラグの QEMU ドキュメントを参照してください。
ただし、SLIRP ベースのユーザーモードネットワークには有用性とパフォーマンスの両方で制約があります。より高度なネットワーク設定をするには tap デバイスや他の方法を使って下さい。
passt
Users can choose to use passt-based user-mode networking. passt has several advantages over SLIRP such as better performance, full IPv6 support (including ICMPv6), better security, and more control.
To get started, install passt. There are two ways to launch it: Either via socket-based communication or via shared vhost-user. The latter method has better performance.
For the socket-based way, first launch passt:
$ passt -f
Then, for your QEMU command, add these parameters:
-device virtio-net-pci,netdev=s -netdev stream,id=s,server=off,addr.type=unix,addr.path=/tmp/passt_1.socket
For the vhost-user way, launch passt with --vhost-user
$ passt -f --vhost-user
Then, for your QEMU command, add these parameters:
-m 4G -chardev socket,id=chr0,path=/tmp/passt_1.socket -netdev vhost-user,id=netdev0,chardev=chr0 -device virtio-net,netdev=netdev0 -object memory-backend-memfd,id=memfd0,share=on,size=4G -numa node,memdev=memfd0
Notice the memory sizes of -m 4G and size=4G have to match exactly.
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
詳細は [4] を参照してください。
ホストオンリーネットワーク
ブリッジに 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 [...]
高度なネットワーキング
仮想マシンのネットワーク設定において、より詳細な制御が必要な場合や、前述のセクションでは対応できない特定の要件がある場合は、QEMU/高度なネットワーキング を参照してください。
省略記法の設定
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-vmwareAUR と 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 コマンドのサポートを得ることができます。
メモリバルーニング
ゲストのメモリ使用量をホストから見て縮小可能にするには、ゲスト側が不要になったページをホストに通知する必要があります。カーネルには Free Page Reporting と呼ばれる API があり、これは組み込みのため QEMU を開始するだけで使えます:
$ qemu-system-x86_64 ... -device virtio-balloon,free-page-reporting=on
この後、ゲスト内でワークロードを実行すると、ゲストのメモリ使用量が一旦増加し、その後縮小する様子がホスト側から確認できるはずです。
ただし、このパラメータによってページが解放されたときにゲストのメモリ使用量がホストから見て縮小されることは確かですが、ゲストがキャッシュ用途に使っているメモリには自動的に対応できません。ゲストは未使用メモリのほとんどをキャッシュに使う傾向があるため、free-page-reporting=on が無意味になる可能性があることに注意してください。この問題を緩和する方法については次のセクションを参照してください。
Using virtio pmem to bypass the guest's page cache
You might want to rely on the host's page cache instead of the guest's in order to allow for more efficient memory usage. Coupled with KSM, this allows you to make your virtual machines quite memory efficient, duplicating only few pages.
One way to achieve this is to use a file-mapped virtio pmem device. Add this config to your QEMU:
-object memory-backend-file,id=mem1,share,mem-path=./virtio_pmem.img,size=32G -device virtio-pmem-pci,memdev=mem1,id=nv1 -m 64G,maxmem=96G
whereby virtio_pmem.img is a local file on the host that will serve as our memory backend in side the guest. The -m part is important here: Set the maxmem parameter so that it is regular memory + memory-backend-file size. In this case: 64G + 32G = 96G.
Start the guest with those options. Inside the guest, you will find a new device at /dev/pmem0 which we will need to format with a DAX-compatible filesystem such as ext4 (btrfs is not supported):
# mkfs.ext4 /dev/pmem0 mount /dev/pmem0 /mnt -o dax=always
Any files you write into /mnt will then bypass the guest's page cache.
It's also possible to have the whole root filesystem DAX-enabled in this way.
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 はサポートされているすべての値を出力するはずです。
virtiofsd の共有を使う
このセクションに進む前に、まず virtiofsd によるホストファイル共有の設定 を済ませてください。
まず、上流の手順 に従ってください。設定が完了すると、Windows の Z: ドライブに共有ディレクトリの内容が自動的にマップされます。
以下のものがあれば、Windows 11 ゲストシステムは適切に設定されています:
- VirtioFSSService windows サービス
- WinFsp.Launcher windows サービス
- Windows の "デバイスマネージャー" の "システムデバイス" の下の VirtIO FS Device driver
上記がインストールされていても Z: ドライブが表示されない場合は、Windows の プログラムの追加と削除 から "Virtio-win-guest-tools" を修復してみてください。
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"}}
このコマンドを受信すると、ハンドラはベースイメージを探し、読み取り専用モードから読み取り/書き込みモードに変換し、コミットジョブを実行します。
fblock-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の有効化 を参照してください。
- 場合によっては、ゲストオペレーティングシステムでメモリバルーニングドライバを実行することでメモリを回収できることがあります。 #メモリバルーニング を参照してください。
- 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 の中からシステムパーティションのどれかを使いたくなることもあるでしょう。仮想マシンでの 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/hdaN だけを仮想マシンに公開するブロックデバイスにすることができます。
このタイプの仮想ディスクは、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 [...]
ブート時に QEMU 仮想マシンを開始する
libvirt を使う
仮想マシンが libvirt でセットアップされている場合、virsh autostart または virt-manager GUI を使用して、仮想マシンの Boot Options に移動して Start virtual machine on host boot up を選択することで、ホストのブート時に仮想マシンを開始するように構成できます。
systemd サービスを使う
ブート時に QEMU 仮想マシンを実行するには、次の systemd ユニットと設定を使うことができます。
/etc/systemd/system/[email protected]
[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 パラメータを使ってみてください。また、QEMU/トラブルシューティング#マウスカーソルが敏感すぎたり迷走する も参照してみて下さい。
ホスト 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
時間基準
デフォルトでは、Windows はファームウェアのクロックがローカル時刻で設定されていると仮定しますが、QEMU を使用する場合は通常そうではありません。
この問題を解決するには、インストール後に Windows を UTC に設定 するか、コマンドラインに
を追加して仮想クロックをローカル時刻に設定する方法があります。
物理機器にインストールされた Linux システムのクローン
物理的な機器にインストールされた Linux システムをクローンして、QEMU 仮想マシン上で動作させることができます。QEMU 仮想マシンのためにハードウェアから Linux システムをクローンする を参照してください。
x86_64 から arm/arm64 環境への chrooting
実際の ARM ベースのデバイスではなく、ディスクイメージを直接操作する方が簡単な場合もあります。これは、root パーティションを含む SD カード/ストレージをマウントし、そこに chroot することで実現できます。
ARM chroot のもうひとつのユースケースは、x86_64 マシン上で ARM パッケージを構築することです。ここで、chroot 環境を Arch Linux ARM のイメージ tarball から作成することができます - このアプローチの詳細は [5] を参照してください。
いずれにせよ、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-binfmt では、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/トラブルシューティング を参照してください。
参照
- QEMU 公式ウェブサイト
- KVM 公式ウェブサイト
- QEMU エミュレータユーザドキュメント
- QEMU Wikibook
- Hardware virtualization with QEMU by AlienBOB (2008年最終更新)
- Building a Virtual Army by Falconindy
- QEMU documentation
- QEMU on Windows
- Wikipedia
- Debian Wiki - QEMU
- Networking QEMU Virtual BSD Systems
- QEMU on gnu.org
- QEMU on FreeBSD as host
- Managing Virtual Machines with QEMU - openSUSE documentation
- KVM on IBM Knowledge Center