libvirt を使って複数の KVM ゲストを管理していると、どのプロセスがリソースを多く使用しているのか top コマンドでは分かりづらいときがあります。リソースの使用状況を確認したい場合は virt-manager や virsh 、virt-top など専用のコマンドを使えばいいのですが、もう少しカジュアルに知りたいです。
はじめに (追記)
ここで話題にしている libvirt のバージョンは 0.8.3 です。
# virsh version Compiled against library: libvir 0.8.3 Using library: libvir 0.8.3 Using API: QEMU 0.8.3 Running hypervisor: QEMU 0.12.5@nakamuray さんに教えていただきましたが、libvirt 0.8.5 以降では /etc/libvirt/qemu.conf でプロセス名を指定するパラメータ
set_process_name
が使えるようです。どのように見えるかは後述します。
- libvirt: Releases
0.8.5: Oct 29 2010 Improvements: Add process= support for 'qemu-kvm -name' (John Morrissey),
- libvirt.org Git - libvirt.git/commit
KVMプロセスのコマンドラインは多くて長い
top コマンドの出力ではこのように kvm
という同じ名前のプロセスが見えます。
# top -b -n 1 -u libvirt-qemu | tail -n +7 PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 26745 libvirt- 20 0 1255m 1.0g 4420 S 16 6.5 2:30.66 kvm 26704 libvirt- 20 0 12.3g 677m 4404 S 2 4.2 0:47.46 kvm 26780 libvirt- 20 0 622m 272m 4392 S 2 1.7 0:24.72 kvm
-c
オプションを付ければコマンドラインが表示できますが、kvm(qemu)プロセスを起動する際のオプションは非常に多くて長く、そこから -name
を見つけるのも一苦労です。(だいたい同じ位置に現れますが)
# top -b -n 1 -u libvirt-qemu -c | tail -n +7 PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 26745 libvirt- 20 0 1255m 1.0g 4420 S 16 6.5 2:37.32 /usr/bin/kvm -S -M pc-0.12 -enable-kvm -m 1024 -smp 1,sockets=1,cores=1,threads=1 -name Windows8 -uuid c4e94fe7-5d2a-0d03-515b-f56d8fdf8449 -nodefaults -chardev socket,id=monitor,path=/var/lib/libvirt/qemu/Windows8.monitor,server,nowait -mon chardev=monitor 26704 libvirt- 20 0 12.3g 677m 4404 S 4 4.2 0:48.52 /usr/bin/kvm -S -M pc-0.12 -enable-kvm -m 12288 -smp 2,sockets=2,cores=1,threads=1 -name FreeBSD -uuid 2933345f-dd30-9f9b-c396-047654d44a64 -nodefaults -chardev socket,id=monitor,path=/var/lib/libvirt/qemu/FreeBSD.monitor,server,nowait -mon chardev=monitor, 26780 libvirt- 20 0 622m 272m 4392 S 2 1.7 0:25.03 /usr/bin/kvm -S -M pc-0.12 -enable-kvm -m 386 -smp 1,sockets=1,cores=1,threads=1 -name CentOS -uuid ef35e149-fb57-6e77-6730-07ad39214e58 -nodefaults -chardev socket,id=monitor,path=/var/lib/libvirt/qemu/CentOS.monitor,server,nowait -mon chardev=monitor,mode
KVM起動スクリプトを修正する
先日、virt-manager 上のコンソールでキーボードが正常に使用できない時の対策として libvirt が起動する KVM プロセス用のラッパースクリプトを作成しました。
kvm(qemu) の-name
オプションでは ,process=
でプロセス名も指定できるようですので、これを使用するようスクリプトを修正しました。
# kvm --help | grep -A1 -- -name -name string1[,process=string2] set the name of the guest string1 sets the window title and string2 the process name (on Linux)
-name
引数を先頭にする- プロセス名に仮想マシンの名前を表示する
このスクリプトを使用すると top コマンドの出力はこのようになり、前より分かりやすくなりました。
# top -b -n 1 -u libvirt-qemu | tail -n +7 PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 27500 libvirt- 20 0 1255m 1.0g 4420 S 51 6.5 0:51.56 kvm:Windows8 27538 libvirt- 20 0 12.3g 668m 4404 R 4 4.2 0:30.26 kvm:FreeBSD 27574 libvirt- 20 0 622m 304m 4392 S 2 1.9 0:19.15 kvm:CentOS
よく分からないところ
これで要望は満たせたのですが、このスクリプトに渡される引数($@)は実際には次のようになっています。
-device pci-assign,?top コマンドで見えるものとだいぶ違います。そして今回のスクリプトを通すと次のコマンドに置き換えられます。
exec /usr/bin/kvm -name -device pci-assign,?,process=kvm(-device pci-assign,?) -device pci-assign,? -device pci-assign,? -k en-usこれだけ見ると全くダメそうですが、最終的に実行されたプロセスのコマンドラインは次のようになっています。
# cat /proc/27500/cmdline | tr '\0' ' '; echo /usr/bin/kvm -name Windows8,process=kvm:Windows8 -S -M pc-0.12 -enable-kvm -m 1024 -smp 1,sockets=1,cores=1,threads=1 -uuid c4e94fe7-5d2a-0d03-515b-f56d8fdf8449 -nodefaults -chardev socket,id=monitor,path=/var/lib/libvirt/qemu/Windows8.monitor,server,nowait -mon chardev=monitor,mode=readline -rtc base=localtime -boot dc -drive if=none,media=cdrom,id=drive-ide0-1-0,readonly=on,format=raw -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 -drive file=/var/lib/libvirt/images/Windows8.img,if=none,id=drive-virtio-disk0,boot=on,format=raw -device virtio-blk-pci,bus=pci.0,addr=0x6,drive=drive-virtio-disk0,id=virtio-disk0 -device virtio-net-pci,vlan=0,id=net0,mac=52:54:00:46:7a:e9,bus=pci.0,addr=0x7 -net tap,fd=39,vlan=0,name=hostnet0 -chardev pty,id=serial0 -device isa-serial,chardev=serial0 -usb -device usb-tablet,id=input0 -vnc 0.0.0.0:0 -vga std -device AC97,id=sound0,bus=pci.0,addr=0x4 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5 -k en-usプロセスの生成と実行についての知識が乏しいのですが、おそらく libvirt がラッパースクリプトを通して生成したプロセスのコマンドラインをこの後の処理で置き換えて実行しているのだと思います。具体的にどのように行っているのかは、ソースを追う力量が無いので調べることはできませんでしたが、そのうち明らかにしたいなと思います。
libvirt 0.8.5 以降でset_process_nameを指定した場合(追記)
確認した環境は Debian GNU/Linux 7.0 (wheezy) の libvirt-bin 0.9.12-5 です。
root@wheezy:~# virsh version Compiled against library: libvir 0.9.12 Using library: libvir 0.9.12 Using API: QEMU 0.9.12 Running hypervisor: QEMU 1.1.2/etc/libvirt/qemu.conf の set_process_name の値はコメントアウトされているので外して有効にします。
# If enabled, libvirt will have QEMU set its process name to # "qemu:VM_NAME", where VM_NAME is the name of the VM. The QEMU # process will appear as "qemu:VM_NAME" in process listings and # other system monitoring tools. By default, QEMU does not set # its process title, so the complete QEMU command (emulator and # its arguments) appear in process listings. # # set_process_name = 1 set_process_name = 1COMMAND 列に表示される文字列は 15 文字のようなので仮想マシン名が長いと途中で切れてしまいますね。
root@wheezy:~# virsh list Id Name State ---------------------------------------------------- 2 OracleLinux running
root@wheezy:~# top -b -n 1 -u libvirt-qemu | tail -n +7 PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 9063 libvirt- 20 0 1286m 112m 6180 R 99.9 3.7 6:54.16 qemu:OracleLinu
root@wheezy:~# cat /proc/9063/cmdline | tr '\0' ' '; echo /usr/bin/kvm -S -M pc-1.1 -enable-kvm -m 1024 -smp 1,sockets=1,cores=1,threads=1 -name OracleLinux,process=qemu:OracleLinux -uuid 90544e15-ce49-efd9-1cde-f0c3cfdb4d16 -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/OracleLinux.monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=localtime -no-shutdown -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 -drive file=/var/lib/libvirt/images/NAS/OracleLinux.img,if=none,id=drive-virtio-disk0,format=raw -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x5,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=2 -drive if=none,id=drive-ide0-1-0,readonly=on,format=raw -device ide-cd,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0,bootindex=1 -netdev tap,fd=20,id=hostnet0 -device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:00:c5:91,bus=pci.0,addr=0x3 -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -device usb-tablet,id=input0 -vnc 127.0.0.1:0 -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6
おわりに
libvirt のような開発に勢いのあるソフトウェアはディストリビューションのパッケージだと欲しい機能が利用できない場合がありますが、今回は qemu にもともとある機能が libvirt 0.8.3 では呼び出せないのでラッパースクリプトで工夫したよということでした。手軽にカスタマイズできるシェルスクリプトっていいですよね。
0 件のコメント:
コメントを投稿