2017/02/04

iGVT-g(XenGT)構築 パート2

前回のパート1ではプリセットされたISOをインストールしてみただけだったが、パート2ではカーネルビルドするところからやってみることにする。2つ目のゲストが起動しないという問題も原因がわかった。最後に原因についてまとめた。

Ubuntu-16.04.1-ServerをOpenSSHだけ入れた状態からスタート
自分の場合、LVMでdom0用に50% 残りはゲスト用に空けておく。イメージファイルとLVM両方試したいので。

ほとんどのコマンド実行が root権限が必要なので
$ sudo su -
その後のすべての操作をrootで行う。

事前準備の前準備
# apt update
# apt install emacs -y # <= 愛用のテキストエディタ
# apt upgrade -y
普通のXenを入れないように。xen tools関係が混乱する。自分はこれでハマった。
no! # apt install xen-hypervisor-4.6-amd64 -y

XenGTビルド 事前準備
前回取り扱ったISOファイルの中にXenGT/KVMGTをソースからビルドする手順が説明されているセットアップガイド(iGVT-g_Setup_Guide.txt)が入っている。ネット上にもほぼ同じものが見つかるが、ISO内のファイルより古いものしか見つからなかった。基本的にはこのガイド通りに進めていくが、ところどころ変更している。

ビルドに必要なパッケージをインストール
# apt install -y git clang libx11-dev autoconf python-dev bin86 bcc iasl uuid-dev libncurses5-dev libglib2.0-dev libpixman-1-dev libaio-dev libssl-dev libyajl-dev libc6-dev-i386 libsdl1.2-dev bc gettext

Qemu Compositor Modeを使う場合に必要なパッケージインストール
# apt-get install -y libegl1-mesa-dev libudev-dev
これもちょっとハマった・・・

# emacs /etc/initramfs-tools/modules
xengt
kvm
を追加。今回kvmはいらないかもしれないけど説明がそうなっているので一応。

カーネル ビルド&インストール
# git clone https://github.com/01org/igvtg-kernel kernel_src
# cd kernel_src/
# git checkout 2016q3-4.3.0
# cp config-4.3.0-host .config
# make -j8 && make modules_install
# mkinitramfs -o /boot/initrd.img-4.3.0-rc6-vgt+ -v 4.3.0-rc6-vgt+
# cp arch/x86/boot/bzImage /boot/vmlinuz-4.3.0-rc6-vgt+
# cp vgt.rules /etc/udev/rules.d
# chmod a+x vgt_mgr
# cp vgt_mgr /usr/bin
ここもハマりました。Ubuntuインストールしたディスクは、NVMeデバイスだったため上の手順だけではブートせず。
.config を編集
# sed -i "s/.*CONFIG_BLK_DEV_NVME.*/CONFIG_BLK_DEV_NVME=y/" .config
NVMeモジュールをbuilt-inにして make以降をやり直し。普通にSATAとかだったら不要。

Hypervisor(Xen) と Device model(QEMU) ビルド&インストール
# git clone https://github.com/01org/igvtg-xen xen_src
# cd xen_src/
# git checkout 2016q3-4.6
# git clone https://github.com/01org/igvtg-qemu.git -b 2016q3-2.3.0 qemu-xen
# cp -r qemu-xen/ tools/
# sed -i '/QEMU_UPSTREAM_URL/s:http\://xenbits.xen.org/git-http/qemu-upstream-4.6-testing.git:$(XEN_ROOT)/tools/qemu-xen:' Config.mk
# sed -i '/QEMU_UPSTREAM_URL/s:git\://xenbits.xen.org/qemu-upstream-4.6-testing.git:$(XEN_ROOT)/tools/qemu-xen:' Config.mk
# ./autogen.sh
# ./configure --prefix=/usr # XEN4.6 default path is /usr/local
# make -j8 xen tools
# cp xen/xen.gz /boot/xen-4.6-amd64-vgt.gz
# make install-tools PYTHON_PREFIX_ARG=
2つ目のsedは実行しても条件が合わず効果なし。Config.mkを以下のように変更する。 自分はやらなかった。
#QEMU_UPSTREAM_URL ?= git://vgt.sh.intel.com/qemu-xen.git
QEMU_UPSTREAM_URL ?= $(XEN_ROOT)/tools/qemu-xen

Xen自動起動設定
# update-rc.d xencommons defaults
# emacs /etc/fstab
none /proc/xen xenfs defaults 0 0
 の1行追加

Grub セットアップ
始めから用意されている/etc/grub.d/20_linux_xenをXenGT用のファイルにしてしまう。
# emacs /etc/grub.d/20_linux_xengt
is_top_level=true
の下に以下の2行を追加
OS='XenGT'
linux_list='/boot/vmlinuz-4.3.0-rc6-vgt+'

Grubデフォルト設定ファイル作成
# emacs /etc/default/grub.d/xengt.cfg
GRUB_DEFAULT='XenGT, with Xen hypervisor'
GRUB_CMDLINE_XEN='dom0_mem=2048M loglvl=all guest_loglvl=all conring_size=4M noreboot'
GRUB_CMDLINE_LINUX_XEN_REPLACE='rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 rhgb crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM ignore_loglevel console=tty0 console=hvc0 consoleblank=0 log_buf_len=4M i915.hvm_boot_foreground=1 i915.enable_cmd_parser=0'
Grub更新
# update-grub

ネットワーク設定
# apt install bridge-utils
# emacs /etc/network/interface
# The primary network interface
auto enp0s31f6 xenbr0
iface enp0s31f6 inet manual
iface xenbr0 inet dhcp
bridge_ports enp0s31f6

再起動
# reboot

これでほぼ完了だが、まだホストがUbuntuServerなので、フレームバッファが存在せず、qemuが起動しない。

オリジナルのセットアップガイド(iGVT-g_Setup_Guide.txt)には 3.5.1 Configuring Remote Control の項目でgnomeとvncserverを入れてどうこうするとか書いてある。実際やってみるととても使える環境とは言えない。
ここは自分の好みでシンプルX環境を作る。

最低限のX環境をインストール
# apt install xorg openbox obconf gconf2 fonts-takao menu menu-xdg
# apt install x11vnc xvfb
何度も実行するフレーズなので、.bash_aliasesとかに以下のaliasを記述しておく。
# alias xvnc='x11vnc -create -env FD_GEOM=1280x800 -env FD_PROG=openbox'
.x11vncrc ファイルはいつも通りこんな感じ。
nonc
shared
noxrecord
noxdamage
noxfixes
norc
xkb
repeat
scr_keyrepeat 4-6
o x11vnc.log
x11vncをXvfbで起動
# xvnc
ホスト:5900 にリモートでvnc接続する。シンプルなopenbox環境が起動しているはず。
デスクトップ4つとかウザいんで、obconfで1つに設定変更。 これで幸せになれる。この辺については 以前の記事 を参照。

ゲスト作成

インストールISOファイル ダウンロード
# wget http://archive.ubuntu.com/ubuntu/dists/xenial-updates/main/installer-amd64/current/images/netboot/mini.iso

ゲストディスク作成
# qemu-img-xen create -f qcow2 guest.qcow2 30G

ゲストインストール用 HVMファイル作成
# emacs guest.hvm
builder = "hvm"
name = "install"
memory = 1024
vcpus = 2
vif = [ 'type=ioemu,bridge=xenbr0,model=e1000' ]
disk=[ '/root/install.qcow2, qcow2,xvda,rw','file:/root/mini.iso,hdc,cdrom,r' ]
boot="dc"

device_model_version='qemu-xen'
device_model_override='/usr/lib/xen/bin/qemu-system-i386'
sdl = 1
serial='pty'
stdvga = 0
usb=1
usbdevice='tablet'
keymap='en-us'
acpi_s3=0
acpi_s4=0

ゲスト起動
# xl cr guest.hvm
好みのデスクトップ環境と、OpenSSHを入れる。Xorgを動かさないと意味が無いので、デスクトップ必須。

ゲスト用 HVMファイルへ更新
# emacs guest.hvm
disk=[ '/root/install.qcow2, qcow2,xvda,rw' ]
boot="c"
に変更して、ゲスト再起動
# xl cr guest.hvm
このときは普通にQemuウインドウ内で起動するはずなので、普通にログインするか
# xl console -t pv domID
でログインする。

vgtカーネルインストール
ホストと同じカーネルとカーネルモジュールでゲストも起動する必要があるが、パート1でやったが、ガイド通りだと nbd、kpartx、image mount という手順で面倒。今回は別の方法でやる。

1.ホストでコピーするファイル群をtarballにする
# tar zcf xengt.tgz /boot/initrd.img-4.3.0-rc6-vgt+ /boot/vmlinuz-4.3.0-rc6-vgt+ /lib/modules/4.3.0-rc6-vgt+ /etc/udev/rules.d/vgt.rules

2.ゲスト側からホストのxengt.tgzをscpして、'/'に展開
$ sudo tar zxf xengt.tgz -C /

3.ついでにGRUB設定する
$ sudo sed -i "/GRUB_DEFAULT/s:0:'1>Ubuntu, with Linux 4.3.0-rc6-vgt+':" /etc/default/grub
GRUB_DEFAULT='1>Ubuntu, with Linux 4.3.0-rc6-vgt+' な感じになると思う。

4.Grubアップデート
$ sudo update-grub

5.vgt有効な ゲスト HVMへ更新
vgt=1
vgt_low_gm_sz=128
vgt_high_gm_sz=384
vgt_fence_sz=4
を追加

6.ゲスト再起動
次回のゲスト作成時は1.を省略できる。こっちの方が簡単確実だ。条件はゲストにOpenSSHを入れる必要があるということだけ。

ゲストのデスクトップへリモート接続
リモートデスクトップ上のqemuゲストウインドウにはペンギンアイコンが出て止まっているようにみえるが、これで正常。
vgtが機能すると、物理ディスプレイ側のフレームバッファが使われるので仮想デスクトップには表示されないのだ。
ここまでの手順を物理ディスプレイ上のデスクトップ環境から操作しているならば、自動的にゲストにディスプレイが切り替わるが
自分はリモートでx11vnc接続なので、ゲストデスクトップ接続までに、ここから一手間いる。

ゲストへコンソール接続
# xl console -t pv domID
ログインしたら、こっちにもx11vncセットアップ
# apt install x11vnc
ホストから.x11vncrcファイルをコピー。手書きしてもいいけど。面倒なので。
# scp ホスト:.x11vncrc .
IPアドレス確認
# ifconfig
x11vnc起動
# x11vnc -auth guess -display :0

ホストにVNCするのと同じ要領でゲストにリモートVNC接続する。ゲストのデスクトップ(ログイン)画面が出てくる。

vgt カーネルオプション

/etc/default/grub.d/xengt.cfg で GRUB_CMDLINE_LINUX_XEN_REPLACE に色々設定したが、この中のi915.で始まるオプションがvgtカーネルオプション。幾つかの起動モードオプションがあるので、その辺を少し。

Foreground(Direct?) Mode
i915.hvm_boot_foreground=1
ゲスト起動で自動的に物理ディスプレイがゲストデスクトップに切り替わるモード。通常はこれでいい。

Indirect Mode
i915.propagate_monitor_to_guest=0
ゲストhvmファイルに以下を追加
vgt_monitor_config_file='/path/to/monitor.config'
monitor.configのサンプルがセットアップガイドに示されている。
# cat monitor.config
 # monitor.config file.
 # first bit 1 for text mode, and second bit 2 for number of ports in the config
 11
 # 04 for PORT_E; and 01 for PORT_B to be override (virtual VGA on physical DP)
 0401
 # Virtual VGA monitor EDID
 00ffffffffffff000469b1232df80000
 0f16010381331d782a5ea5a2554da026
 115054bfef00d1c095008140818081c0
 950fb300714f023a801871382d40582c
 4500fd1e1100001e000000ff0043344c
 4d54463036333533330a000000fd0032
 4b185311000a202020202020000000fc
 00415355532050413233380a202000e0
この辺はEDID変えてみたり、物理ディスプレイ接続をしたりしなかったり、色々やってみたが、機能している気がしない。不明。。

Qemu Compositor Display Mode
i915.hvm_boot_foreground=0
i915.enable_vgtbuffer=1
ホストデスクトップを物理ディスプレイ上で動かしている場合(egl extensionsが機能する状態)なら、ホストデスクトップのQemuウインドウにゲストデスクトップイメージが合成されるモード。事実上これもIndirectMode。
これはこれで楽しいけれど、モニタレスにしたい自分としては、Xvfb上でもコンポジットしてほしかった。eglExtensionな仮想FBドライバがあれば合成可能なのかな。

最終的に自分は、ダイレクトモードだけど自動切り替えなし。という状態に落ち着いた。x11vncでゲストへリモート接続するから。
i915.hvm_boot_foreground=0

この時点で最大の魅力は、物理ディスプレイを接続していなくても、デフォルト解像度固定ではあるが、モノホンのグラフィックスドライバが機能する(GPUが使えている)。WindowsゲストでもちゃんとIntelグラフィックスドライバが動く。

ゲストで、vgtイネーブル(vGPUが機能している状態)を軽く確認
$ sudo apt install mesa-utils glmark2
ドライバ、GPU、GL profile 情報とか見てみる
$ glxinfo
GLデモ動かしてみる
$ glmark2
GFXBenchを試してみたかったが起動するとシステムフリーズしてしまった。

最後に2つ目のゲストが起動できなかった原因と解決(?)
結論から言うとメモリリソース不足。シェアードメモリを1つ目のゲストが使い切っていたから。
BIOSでshard memory sizeを最大の1GBにしていたが、これでは十分じゃない? BIOSでAUTOにしても結果同じ。

vgtリソース情報を見やすくする簡単なスクリプトを用意した
# cat gminfo.py 
#!/usr/bin/python
import sys
words = sys.stdin.readlines()[0].split(",")
print int(words[0],16) ,'MB : total CPU visible Graphics memory size'
print int(words[1],16) ,'MB : free CPU visible graphics memory size'
print int(words[2],16) ,'MB : toal CPU invisible graphics memory size'
print int(words[3],16) ,'MB : free CPU invisible graphics memory size'
print int(words[4],16) ,' : total number of fence register'
print int(words[5],16) ,' : the number of free fence registers'
で、以下のように実行する
# cat /sys/kernel/vgt/control/available_resource | ./gminfo.py
と、こんな感じで表示される
256 MB : total CPU visible Graphics memory size
128 MB : free CPU visible graphics memory size
3840 MB : toal CPU invisible graphics memory size
3456 MB : free CPU invisible graphics memory size
32 : total number of fence register
28 : the number of free fence registers

この中の CPU visible Graphics memory size が問題。CPUから見えるグラフィックスメモリ。すなわちGPU/CPUシェアードメモリのことだと思うが、これが自分のBeebox-S 6200U では(なのか?)256MBしかないというのだ。これは納得出来ないが、 カーネルソースに、vgtシステムとして512MB取っているらしいのと、dom0で128MB消費してしまうらしい。
1GB-512MB-128MB=384MB 残りそうなものだが、なぜか トータル256MB、残り128MBということだ。

この状態で2つのゲストを動かすためには、ゲスト起動HVMオプションで
vgt_low_gm_sz=64
とすることで、2つゲスト起動可能となった。linuxでも64以上が望ましいということなので、自分の環境では2つが限界。
dom0の確保分を減らせないかとオプションで試してみたが、効果なし。

最終手段はカーネル側で確保しているサイズを小さくすることだが、今でもシステム不安定なのにこれ以上不安定にしてもなぁ。
ということで、今のところ諦める。

不安定といえば、vgtゲスト起動しっぱなしでしばらく時間が立つと突然マシン全体がフリーズしてしまったり、暴走してネットワークがフルトラフィック状態に陥ったり、色々してくれる・・・そのせいでかみさんに時々怒られている。実用はむりかなぁ。

次回は、KVMGTをビルドして稼働させてみようかと思う。XenGTとさほど変わらないと思うが、これも実験。


期待したいのはシェアードメモリ空き容量。安定性。どうかな。

0 件のコメント:

コメントを投稿