2011年03月10日
CentOS5と仮想化技術KVMと時々PCIパススルー(4/4)
そんな訳でようやく4回目、いろんな意味で長かった
Linux鯖で仮想マシンを動かしたい!という構想から試行錯誤を繰り返し、実用的に使えるまで結構時間がかかった。少なくとも3ヶ月以上は費やしてるはず?
(ハードウェア的にもソフトウェア的にもね)
まずCentOS5.5に標準実装されているKVM(KVM-83 QEMU-0.9.1)は古いバージョンなので、普通の仮想化をする分には問題はありませんが、PCIパススルーをするとなると、あまり具合がよろしくない
古いバージョンのKVMでPCIパススルーを試みた所、手持ちのカードでまともに使えたのは、100BASE LAN(i82557)とSCSIカード(AHA-2940UW)という、今となっては伝説級のクラシックカードしか動きませんでした。IEEE1394カードもPT2も謎のエラーを出して仮想マシンが起動しません
そんな理由から。CentOS標準実装のKVMを使うのは諦めて、インターネット上から最新版のQEMU-KVMをダウンロードしてきます
Linux鯖で仮想マシンを動かしたい!という構想から試行錯誤を繰り返し、実用的に使えるまで結構時間がかかった。少なくとも3ヶ月以上は費やしてるはず?
(ハードウェア的にもソフトウェア的にもね)
まずCentOS5.5に標準実装されているKVM(KVM-83 QEMU-0.9.1)は古いバージョンなので、普通の仮想化をする分には問題はありませんが、PCIパススルーをするとなると、あまり具合がよろしくない
古いバージョンのKVMでPCIパススルーを試みた所、手持ちのカードでまともに使えたのは、100BASE LAN(i82557)とSCSIカード(AHA-2940UW)という、今となっては伝説級のクラシックカードしか動きませんでした。IEEE1394カードもPT2も謎のエラーを出して仮想マシンが起動しません
そんな理由から。CentOS標準実装のKVMを使うのは諦めて、インターネット上から最新版のQEMU-KVMをダウンロードしてきます
2011年3月現在最新版のQEMU-KVMバージョンは0.14.0です
(CentOSに標準実装されているバージョンは多分0.09.1)
最新版QEMU-KVMは以下のサイトからダウンロードできます
http://sourceforge.net/projects/kvm/files/qemu-kvm/
qemu-kvm-0.14.0.tar.gzをダウンロードしてきてgzipで展開、ソースコードなのでコンパイルが必要です。もし開発環境がインストールされていない場合はインストールしてください
コンパイルが正常に終了すれば、/usr/local/binフォルダにqemu-system-x86_64という実行ファイルが作られます。余談ですが、バージョン0.13までのQEMU-KVMはCentOSでコンパイルすると、コンパイル自体は成功しますがなぜか仮想マシンが起動しないという(多分OS側の)バグ?があります
とりあえず、PCIパススルーとか無しに普通に仮想マシンを立ち上げてみる
パラメータ設定
CPU:Pentium3互換(マイクロコードだけ偽装)
CPU数:1個
メモリ:512MB(別に1GBでもいいケドね)
ビデオ:CirrusLogic 5446(どれ選んでも一緒)
その他:UHCI準拠USBコントローラ有効、タブレットデバイス指定
※サーバ用途なのでサウンドカード指定なし、またネットワーク設定は後々行います
基本的にパラメータはqemu-kvmと一緒です。SDLではなくVNCサーバを経由しているので、X-Window上で実行する場合は別途VNC Viewerをインストールしておく必要がアリ(VNCは自動的には立ち上がらない)
また、ここでは特に方法は書きませんが、ストレージとネットワークデバイス周りにvirtio準仮想化を用いた足元の「強化」をしてあります(virtioの導入は楽なようで難しい?)
ここで正常に起動・終了が出来るのを確認したら、いよいよ本講座のメインである「PCIパススルー」の手続きに入ります
パススルー対象デバイスは当初の目的どおり、IEEE1394カードとPT2にしようかと思いましたが、PT2は動作を確認できるまでの途中経過がやや面倒なので、たまたま転がっていたSil3512なSATAカードを使います
手順1:PCIカードの接続確認
赤く示したところが、今回パススルー対象となるPCIデバイスです。04:01.0/04:02.0という数字が後々必要になるので、メモしておいてください
手順2:ホストOSから対象デバイスの切り離し
当然といえば当然ですが、PCIパススルーを行う場合、ホストOSとゲストOSとでPCIデバイスを共有することはできませんので、ホストOS側から該当デバイスを使われないように切り離す必要が出てきます
旧来のKVMでは、lsmodコマンドでそのPCIカードが使用しているドライバを探してrmmodするのが定番でしたが、サウンドカードのように複数のモジュールにわたっている場合はすべて切り離すのは大変なので、該当デバイスの「根元」から切り離します
ちなみに、CentOS5ではsilicon imageなSATAカードはsata_silですが、IEEE1394はモジュールが含まれていないせいか、ドライバは組み込まれません(FedoraとかUbuntuとかDebianとかはfirewire_ohciかohci_1394が自動的に組み込まれるんだけど)
まずはpci_stubモジュールの確認
「lsmod | grep pci_stub」とコマンドを打って何も出てこなかった場合
「modprobe pci_stub」と打ってモジュールをロードする(初回のみ)
lspci -nで該当デバイスの情報を取得
04:0x.0というのはバス番号0600とか0106とかは多分PCIクラス(拡張カード種類識別)、8086や104cは製造ベンダ(8086→Intel)、8168とか3512はサブベンダ
※数字はマザーボードや拡張カードで変わってくるので各自で確認する必要があります
この情報のうち、必要になるのはバス番号、製造ベンダ、サブベンダです
仮想マシン上でパススルーさせるPCIカード分だけ設定を変えて繰り返します
この設定についてはあまりよく理解していないのですが、PCIデバイスをpci-stubドライバにバインドさせて、ホストOS側から切り離してしまうということだろうか?
手順3:PCIパススルー付き仮想マシン起動
先ほどの仮想マシン起動オプションに赤字の部分を追加する
旧来のKVMでは、-pcidevice host=XX:XX.Xと指定していましたが、バージョン0.14のKVMではこのオプションは無くなってしまったようです
これで仮想マシンが立ち上がれば成功です。別のコンソールからvncviewer localhostと打ち込んでVNCビューアーから確認してください。
PCIデバイスが正常に認識されていれば、起動直後から「新しいデバイスの追加」ポップアップウインドウが開いてドライバ要求ウインドウが(ドライバが必要であれば)開くと思います

ローカルディスク(C)がQEMU仮想ディスク
ボリューム(E)はIEEE1394接続された物理ディスク
WinXP(F)はSATA接続された物理ディスク
時折インターフェースカードだけ認識されていて、ディスクを繋いでも認識されない時があるので、動作確認の際には必ずデバイスを繋いでください
仮想マシンの性能ですが、Intel 440FXという15年位前のPCアーキテクチャを模倣しているので、あえてそれに沿ったベンチマークということで、当時のベストセラー(かもしれない)ベンチマークであるHDBENCH3.3で取っています(笑)
KVM(というより大元のQEMU)はFPU(浮動小数点演算器)はソフトウェアによるエミュレートになるので、性能的にはPentium133MHz相当、整数演算は仮想化支援によりPentiumD相当は出ている模様
CL-GD5446によるビデオ性能はもはやハナクソみたいなもんなので、仮想マシン上で動画のエンコードや再生を行うとかは無謀の極み(笑)
KVM+PCIパススルー編はこれで終わりですが、virtio導入によるパフォーマンスアップとか、USBデバイスパススルーとか、仮想マシン上でEHCI(USB2.0)を使うとか、本命のPT2を動かすとか、もう少しやりたいことがあるので「特別編」としてもう1回続きます
(CentOSに標準実装されているバージョンは多分0.09.1)
最新版QEMU-KVMは以下のサイトからダウンロードできます
http://sourceforge.net/projects/kvm/files/qemu-kvm/
qemu-kvm-0.14.0.tar.gzをダウンロードしてきてgzipで展開、ソースコードなのでコンパイルが必要です。もし開発環境がインストールされていない場合はインストールしてください
tar zxvf qemu-kvm-0.14.0.tar.gz cd qemu-kvm-0.14.0/ ./configure make make install |
コンパイルが正常に終了すれば、/usr/local/binフォルダにqemu-system-x86_64という実行ファイルが作られます。余談ですが、バージョン0.13までのQEMU-KVMはCentOSでコンパイルすると、コンパイル自体は成功しますがなぜか仮想マシンが起動しないという(多分OS側の)バグ?があります
とりあえず、PCIパススルーとか無しに普通に仮想マシンを立ち上げてみる
/usr/local/bin/qemu-system-x86_64 -name "Virtual WinXP" -hda /mnt/images/winxp.img -boot c -cpu pentium3 -m 512 -smp 1 -k ja -vga cirrus -localtime -usb -usbdevice tablet -vnc localhost |
パラメータ設定
CPU:Pentium3互換(マイクロコードだけ偽装)
CPU数:1個
メモリ:512MB(別に1GBでもいいケドね)
ビデオ:CirrusLogic 5446(どれ選んでも一緒)
その他:UHCI準拠USBコントローラ有効、タブレットデバイス指定
※サーバ用途なのでサウンドカード指定なし、またネットワーク設定は後々行います
基本的にパラメータはqemu-kvmと一緒です。SDLではなくVNCサーバを経由しているので、X-Window上で実行する場合は別途VNC Viewerをインストールしておく必要がアリ(VNCは自動的には立ち上がらない)
また、ここでは特に方法は書きませんが、ストレージとネットワークデバイス周りにvirtio準仮想化を用いた足元の「強化」をしてあります(virtioの導入は楽なようで難しい?)
ここで正常に起動・終了が出来るのを確認したら、いよいよ本講座のメインである「PCIパススルー」の手続きに入ります
パススルー対象デバイスは当初の目的どおり、IEEE1394カードとPT2にしようかと思いましたが、PT2は動作を確認できるまでの途中経過がやや面倒なので、たまたま転がっていたSil3512なSATAカードを使います
手順1:PCIカードの接続確認
# lspci 00:00.0 Host bridge : Intel Corporation Core Processor DRAM Controller (rev 18) 00:01.0 PCI bridge: Intel Corporation Core Processor PCI Express x16 Root Port (rev 18) ~途中省略~ 02:00.0 Ethernet controller: Intel Corporation 82572EI Gigabit Ethernet Controller (Copper) (rev 06) 03:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 03) 04:01.0 FireWire (IEEE 1394): Texas Instruments TSB12LV26 IEEE-1394 Controller (Link) 04:02.0 SATA controller: Silicon Image, Inc. SiI 3512 [SATALink/SATARaid] Serial ATA Controller (rev 01) |
手順2:ホストOSから対象デバイスの切り離し
当然といえば当然ですが、PCIパススルーを行う場合、ホストOSとゲストOSとでPCIデバイスを共有することはできませんので、ホストOS側から該当デバイスを使われないように切り離す必要が出てきます
旧来のKVMでは、lsmodコマンドでそのPCIカードが使用しているドライバを探してrmmodするのが定番でしたが、サウンドカードのように複数のモジュールにわたっている場合はすべて切り離すのは大変なので、該当デバイスの「根元」から切り離します
ちなみに、CentOS5ではsilicon imageなSATAカードはsata_silですが、IEEE1394はモジュールが含まれていないせいか、ドライバは組み込まれません(FedoraとかUbuntuとかDebianとかはfirewire_ohciかohci_1394が自動的に組み込まれるんだけど)
まずはpci_stubモジュールの確認
「lsmod | grep pci_stub」とコマンドを打って何も出てこなかった場合
「modprobe pci_stub」と打ってモジュールをロードする(初回のみ)
lspci -nで該当デバイスの情報を取得
# lspci -n 00:00.0 0600: 8086:0040 (rev 18) 00:01.0 0604: 8086:0041 (rev 18) ~途中省略~ 02:00.0 0200: 8086:10b9 (rev 06) 03:00.0 0200: 10ec:8168 (rev 03) 04:01.0 0c00: 104c:8020 04:02.0 0106: 1095:3512 (rev 01) |
04:0x.0というのはバス番号0600とか0106とかは多分PCIクラス(拡張カード種類識別)、8086や104cは製造ベンダ(8086→Intel)、8168とか3512はサブベンダ
※数字はマザーボードや拡張カードで変わってくるので各自で確認する必要があります
この情報のうち、必要になるのはバス番号、製造ベンダ、サブベンダです
# echo "104c 8020" > /sys/bus/pci/drivers/pci-stub/new_id # echo 0000:04:01.0 > /sys/bus/pci/devices/0000:04:01.0/driver/unbind # echo 0000:04:01.0 > /sys/bus/pci/drivers/pci-stub/bind # echo "1095 3512" > /sys/bus/pci/drivers/pci-stub/new_id # echo 0000:04:02.0 > /sys/bus/pci/devices/0000:04:02.0/driver/unbind # echo 0000:04:02.0 > /sys/bus/pci/drivers/pci-stub/bind |
仮想マシン上でパススルーさせるPCIカード分だけ設定を変えて繰り返します
この設定についてはあまりよく理解していないのですが、PCIデバイスをpci-stubドライバにバインドさせて、ホストOS側から切り離してしまうということだろうか?
手順3:PCIパススルー付き仮想マシン起動
/usr/local/bin/qemu-system-x86_64 -name "Virtual WinXP" -hda /mnt/images/winxp.img -boot c -cpu pentium3 -m 512 -smp 1 -k ja -vga cirrus -localtime -usb -usbdevice tablet -vnc localhost -device pci-assign,host=04:01.0 -device pci-assign,host=04:02.0 |
先ほどの仮想マシン起動オプションに赤字の部分を追加する
旧来のKVMでは、-pcidevice host=XX:XX.Xと指定していましたが、バージョン0.14のKVMではこのオプションは無くなってしまったようです
これで仮想マシンが立ち上がれば成功です。別のコンソールからvncviewer localhostと打ち込んでVNCビューアーから確認してください。
PCIデバイスが正常に認識されていれば、起動直後から「新しいデバイスの追加」ポップアップウインドウが開いてドライバ要求ウインドウが(ドライバが必要であれば)開くと思います
ボリューム(E)はIEEE1394接続された物理ディスク
WinXP(F)はSATA接続された物理ディスク
時折インターフェースカードだけ認識されていて、ディスクを繋いでも認識されない時があるので、動作確認の際には必ずデバイスを繋いでください
仮想マシンの性能ですが、Intel 440FXという15年位前のPCアーキテクチャを模倣しているので、あえてそれに沿ったベンチマークということで、当時のベストセラー(かもしれない)ベンチマークであるHDBENCH3.3で取っています(笑)
KVM(というより大元のQEMU)はFPU(浮動小数点演算器)はソフトウェアによるエミュレートになるので、性能的にはPentium133MHz相当、整数演算は仮想化支援によりPentiumD相当は出ている模様
CL-GD5446によるビデオ性能はもはやハナクソみたいなもんなので、仮想マシン上で動画のエンコードや再生を行うとかは無謀の極み(笑)
KVM+PCIパススルー編はこれで終わりですが、virtio導入によるパフォーマンスアップとか、USBデバイスパススルーとか、仮想マシン上でEHCI(USB2.0)を使うとか、本命のPT2を動かすとか、もう少しやりたいことがあるので「特別編」としてもう1回続きます