2017/02/10

iGVT-g(KVMGT)構築

XenGT同様とりあえず動かしてみたかったので、またまたカーネルビルドするところからやってみた。目指すのは、物理ディスプレイを一切使わずにリモート操作のみで構築・使用すること。

Ubuntu16.04.1 LTS Install
[*] standard system utilities
[ ] Virtual Machine host
[*] OpenSSH server
こっちもlibvirtは入れない。
# apt update
# apt upgrade -y
# apt install emacs nmap

最低限のXorg環境(リモートで操作すること前提。自分にとってここが重要
# apt install xorg openbox menu gconf2 fonts-takao x11vnc xvfb
.bash_aliases
alias xvnc='x11vnc -create -env FD_GEOM=1024x800 -env FD_PROG=openbox'
.x11vncrc をこんな感じで用意
nopw
nonc
shared
noxrecord
noxdamage
noxfixes
norc
noscr
no6
xkb
repeat
scr_keyrepeat 4-6
forever
bg
o x11vnc.log
foreverとbgおよびnoscrを追加。noscrを入れるとぐっと安定する気がする。

ビルドツールインストール
# apt install -y git clang
自分は最近clangですが、build-essential でもいいと思う。

ビルドパッケージインストール
# apt install -y 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 bison flex

Qemu Compositor Display Mode を使いたい場合
# apt install -y  libegl1-mesa-dev libudev-dev

/etc/initramfs-tools/modules に次の1行記述
kvm

カーネルビルド スクリプト (XenGT/KVMGT共に共通)
./build_kernel
#!/bin/sh
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
sed -i "s/.*CONFIG_BLK_DEV_NVME.*/CONFIG_BLK_DEV_NVME=y/" .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

Qemuビルド スクリプト
./build_qemu
#!/bin/sh
git clone https://github.com/01org/igvtg-qemu -b 2016q3-2.3.0 qemu_src
cd qemu_src/
git submodule update --init dtc
git submodule update --init roms/seabios
./configure --prefix=/usr --enable-kvm --enable-sdl --disable-werror  --target-list=x86_64-softmmu
make -j8
cd roms/seabios
git checkout master
LC_ALL=C make -j8
cd -
make install
cp `pwd`/roms/seabios/out/bios.bin /usr/bin/bios.bin

ビルド&インストール
# ./build_kernel && ./build_qemu

Grubセットアップ
少し変則的な方法にしましたが、極力シンプルで扱いやすくということでこんな感じに。
/root/grub-kvmgt.cfg 作成
OS='KVMGT'
GRUB_CMDLINE_LINUX='intel_iommu=igfx_off i915.hvm_boot_foreground=1 i915.enable_cmd_parser=0 loglvl=all guest_loglvl=all conring_size=4M noreboot'
list='/boot/vmlinuz-4.3.0-rc6-vgt+'
./etc/grub.d/09_linux_kvmgt 作成
# cp /etc/grub.d/10_linux /etc/grub.d/09_linux_kvmgt
# sed -i "/top_level=true$/a . '/root/grub-kvmgt.cfg'" /etc/grub.d/09_linux_kvmgt
Brubアップデート
# update-grub

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

ゲストにホストと同じカーネルとモジュール類をコピーするので、持って行きやすくアーカイブする
kernel/modulesアーカイブ
# tar zcf /home/user/vgt.tgz /boot/vmlinuz-4.3.0-rc6-vgt+ /boot/initrd.img-4.3.0-rc6-vgt+ /lib/modules/4.3.0-rc6-vgt+ /etc/udev/rules.d/vgt.rules /root/.x11vncrc
x11vncはゲストでも使うので、.x11vncrc ファイルもアーカイブセットに入れておく。

ゲスト起動で使用する /root/qemu-ifup シェルスクリプトを用意
#!/bin/bash

switch=$(brctl show| sed -n 2p |awk '{print $1}')
if [ -n $switch ]; then
  tunctl -u `whoami` -t $1
  ip link set $1 up
  /sbin/ifconfig $1 0.0.0.0 up
  brctl addif $switch $1
  exit 0
else
  echo Error: no interface specified
  exit 1
fi
実行権限セット
# chmod +x qemu-ifup

この辺で一度リブート
# reboot
ビルドしたカーネルで起動する。

これ以降はデスクトップ上でやるので、x11vnc起動してリモートデスクトップから操作する
# xvnc
リモートからtightvncかTourboVNCで接続

ゲスト作成
installer iso ダウンロード
ディスク作成
# qemu-img create -f qcow2 guest.img 30G
LVMで作る場合は
# lvcreate -n LVNAME VGNAME(どのVGに作るか) -L 10G

ゲスト起動(OSインストール。何らかのDesktopを入れないと面白くない)
/usr/bin/qemu-system-x86_64 \
  -m 2048 \
  -smp 2 \
  -bios /usr/bin/bios.bin \
  -enable-kvm \
  -M pc \
  -machine kernel_irqchip=on \
  -net nic -net tap,script=/root/qemu-ifup,downscript=no \
  -hda /root/guest.img \
  -cdrom /root/mini.iso \
  -boot d
LVMの場合は -hda を
-drive file=/dev/mapper/VGNAME-LVNAME,if=ide,index=0,cache=none,format=raw \
にする。

作っておいたvgt.tgzをゲスト側から scp で取得して展開。ついでにGrubデフォルト設定
$ scp user@host:vgt.tgz .
$ sudo tar zxf vgt.tgz -C /
$ sudo sed -i 's/DEFAULT=0/DEFAULT="1>Ubuntu, with Linux 4.3.0-rc6-vgt+"/' /etc/default/grub
$ sudo update-grub
$ sudo apt install x11vnc
$ sudo shutdown -h now
このタイミングでx11vnc入れておく。

これでKVMGTなゲストが起動できる準備は整いました。
だけど残念ながら、libvirtやvirt-managerは使えません。物理FBが使用されるので、virt-viewerも使えません。
ゲストコンソールにアクセスしてもうんともすんとも。色々頑張ればどうにかなるのだろうか。。
この辺りは、Xenの方が管理ツールが少し使える分扱いやすいかも。

最初に書いたとおりリモート操作前提なので、ゲスト上でx11vncを起動する必要がある。もちろんIPアドレスが分からないといけない。
そこで、以下のような起動スクリプトにした。

ゲスト起動スクリプト
#!/bin/sh
/usr/bin/qemu-system-x86_64 \
  -daemonize \
  -m 4096 \
  -smp 2 \
  -bios /usr/bin/bios.bin \
  -enable-kvm \
  -M pc \
  -machine kernel_irqchip=on \
  -net nic -net tap,script=/root/qemu-ifup,downscript=no \
  -hda /root/guest.img \
  -vgt -vga vgt \
  -vgt_low_gm_sz 128 \
  -vgt_high_gm_sz 384 \
  -vgt_fence_sz 4
## 苦肉の策
sleep 1
tcpdump ip -itap0 | awk '/DHCP/{print $_}'
起動してゲストのネットワークが確立するとき、ルータとのDHCPハンドシェイクでIPアドレスがわかる。
それを表示するのが最後の1ラインスクリプト。表示されてIPアドレスが分かったらCtrl+Cでシェルスクリプトを終わらせる。
OpenSSHはどんな場合でも入れているので、IPさえ分かれば何とかなる。

ゲストにsshログイン
$ ssh username@guest-ip-address

ゲストでx11vnc起動
$ sudo x11vncrc -auth guess -display :0

ゲストデスクトップへ接続
ホストから xtightvncviewer で、もしくはリモートから、TourboVNC Viewer で接続
これで、物理ディスプレイ前にいなくても、めでたくゲストデスクトップへ接続できたと。

ゲストディスプレイ解像度は、物理ディスプレイが接続されていればそれに依存する。
物理ディスプレイが接続されていなければデフォルトの 1024x768 になるようだ。
物理ディスプレイやEDIDエミュレータとか繋がなくても、ゲストで物理FBとGPUを使うことが出来るのが最大の魅力。
しかし完全に自由な解像度で、というわけには行かないようだ。
インダイレクトモードでのmonitor.configがその要求に答えてくれそうだが、機能しているかどうか体感できず。

XenGTとKVMGT両方やってみたが何はともあれ、安定性は大差ない気がする。
XenGTの方がXenツールも込みなので、ゲスト管理がしやすいかな。

最後に
ここに書いたように無理にx11vnc使ってリモート操作する必要はない。物理ディスプレイ前に座っていられるならゲスト起動すれば(カーネルオプション  i915.hvm_boot_foreground=1 にしていれば)自動的にディスプレイが切り替わる。そして普通に使える。


自分がやりたいのは、物理も仮想もモニタレスでリモートでGPUアクセラレーションが効いていて全てを同時に使うことなので、こんな流れになった。もっと素直に使えばもう少し安定するっぽいけど、それではつまらないのでね。

0 件のコメント:

コメントを投稿