使用 monitor command 監控 QEMU 運行狀態
在虛擬化的研究領域,QEMU 有着舉足輕重的地位。2007 年 2 月發佈的 Linux 2.6.20 內核中,集成了 KVM 作爲其虛擬化的具體實現。而 KVM 是基於 QEMU 並且利用 CPU 的輔助虛擬化特性而略加修改而成的。自此以後,QEMU 項目引起 Linux 開發人員的廣泛關注。
在啓動 QEMU 的時候,同時也會啓動 monitor 的控制檯,通過這個控制檯,可以與 QEMU 或者運行狀態的虛擬機進行交互。雖然現在有諸如 virt-manager 之類的圖形界面的虛擬機管理工具,但是在 monitor 的控制檯窗口輸入命令似乎更符合 Linux 程序員的開發習慣,而且還能完成一些圖形化管理工具所不具備的功能。在 monitor 控制檯中,可以完成很多常規操作,比如添加刪除設備、虛擬機音視頻截取、獲取虛擬機運行狀態、更改虛擬機運行時配置等等。
事實上,啓動 QEMU 後通常是看不到 monitor 界面的。要進入該界面,可以在 QEMU 窗口激活的時候按住 Ctrl+Alt+2 進入,切換回工作界面需要按 Ctrl+Alt+1。另外,還可以在 QEMU 啓動的時候指定 -monitor 參數。比如 -monitor stdio 將允許使用標準輸入作爲 monitor 命令源。這種方式和常見的 Linux 交互式的用戶程序無異,所以在做測試工作的時候,可以很方便的編寫出對虛擬機監控的 shell 腳本程序。
清單 1. 使用標準輸入作爲 QEMU monitor 命令源
[root@kvm]# qemu -hda rhel61-oc.img -m 1024 --enable-kvm -vnc :51 -monitor stdio Using CPU model "cpu64-rhel6" QEMU 0.12.1 monitor - type 'help' for more information (qemu) |
QEMU monitor 的命令非常繁雜,並且由於 QEMU 是廣受關注的開源項目,代碼更新也特別迅速。同樣,monitor 命令也會時常得到更新和升級。概括的說,命令可以分爲如下幾個部分:
有一部分命令可以稱爲輔助性命令,比如 info 和 help。help 可以查詢顯示某個命令的簡要幫助信息;info 命令主要用來顯示虛擬機的運行信息。比如 info blockstats 將顯示虛擬機中的塊設備的讀寫操作的信息:讀入字節、寫入字節、讀寫操作的次數等。
清單 2. Info 命令顯示塊設備狀態信息
(qemu) info blockstats ide0-hd0: rd_bytes=42276864 wr_bytes=828416 rd_operations=2352 wr_operations=119 ide1-cd0: rd_bytes=0 wr_bytes=0 rd_operations=0 wr_operations=0 floppy0: rd_bytes=0 wr_bytes=0 rd_operations=0 wr_operations=0 |
清單 3. Help 命令顯示 info 命令的幫助信息
(qemu) help savevm savevm [tag|id] -- save a VM snapshot. If no tag or id are provided, a new snapshot is created |
在某些場景下,需要遠程調試 QEMU。正常情況下需要被調試端安裝有 gdbserver 程序,否則將無法進行遠程調試。而在 QEMU 的 monitor 中集成了 gdbserver,就解決了這個問題。內置的 gdbserver 允許被調試端不安裝 gdbserver 就能進行遠程調試。清單 4 中在 tcp 端口 12345 開啓了 gdbserver 的遠程調試伺服程序。
清單 4. gdbserver 開啓調試端口
(qemu) gdbserver tcp::12345 Waiting for gdb connection on device 'tcp::12345' |
在客戶機,就可以通過 gdb 連接到 gdbserver 的監聽端口進行調試工作。與常規的本地程序調試程序相似,清單 5 中顯示了運行中的 qemu 的堆棧信息。
清單 5. 從客戶端連接 gdbserver 進行調試工作
$:~/work/qemu$ gdb qemu -q Reading symbols from /home/wdongxu/work/qemu/qemu...done. (gdb) target remote localhost:12345 Remote debugging using localhost:12345 Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done. Loaded symbols for /lib/ld-linux.so.2 0xc012c21a in ?? () from /lib/ld-linux.so.2 (gdb) break qcow2_co_readv Breakpoint 1 at 0x8077f1a: file block/qcow2.c, line 381. (gdb) bt #0 0x0018846b in ?? () #1 0x0032d067 in ?? () #2 0x0032d9d5 in ?? () #3 0x0032c729 in ?? () #4 0x0032d334 in ?? () #5 0x0037006c in ?? () #6 0x08123278 in configure_rtc_date_offset ( startdate=0x81267af "\213FH\211\a\213FD\211G\004\215\203\254q", legacy=-1080558488) at /home/wdongxu/work/qemu/vl.c:514 #7 0x0809cefa in bt_submit_hci (info=0xf2f1f0, data=0x3 <Address 0x3 out of bounds>, length=163370640) at /home/wdongxu/work/qemu/hw/bt-hci.c:1689 #8 0x0809d477 in bt_submit_hci (info=0xbf97fd44, data=0x438001 "_alloc_failed_handler", length=18894760) at /home/wdongxu/work/qemu/hw/bt-hci.c:1837 #9 0x081b6303 in cirrus_bitblt_rop_fwd_transp_notdst_16 (s=0x809d3b0, ---Type <return> to continue, or q <return> to quit--- |
x/xp 用法基本上同 gdb 中的 x 相似:
- x 用來打印虛地址的值。
- xp 用來打印從某實地址開始的特定格式的值,比如類似於 x 命令使用的 10 進制、16 進制,甚至能夠以 i 作爲格式打印指令序列。
清單 5 將打印 0x08123278 起始的一個字節,然後打印了 eip 寄存器所示地址開始的三條指令。
清單 6. 從客戶端連接 gdbserver 進行調試工作
(qemu) x/b 0x08123278 0000000008123278: 0x8b (qemu) xp /3i $eip 0x000000000018846b: les 0x208039c0(%ebx),%ecx 0x0000000000188471: add (%eax),%al 0x0000000000188473: add %cl,(%edi) |
print 可以進行數學運算,也可以引用某寄存器的值,類似於 gdb 中的 print 命令。如清單 6 所示:
清單 7. print 進行數學運算
(qemu) print 1 + 3 4 (qemu) print $eax 3079397632 (qemu) print $eax + 2 3079397634 |
在調試 QEMU 的時候,可能還會需要鑑別某一塊內存區域是否正確,這就需要 sum 命令來計算某一個內存區域的校驗和,也可以將內存轉儲到文件供日後分析。
清單 8. 內存轉儲
(qemu) x/10x 0x0809d477 000000000809d477: 0x8b 0x55 0xc8 0x8b 0x4d 0xc4 0x80 0x7d 000000000809d47f: 0xd0 0x00 (qemu) memsave 0x0809d477 10 mem.log |
清單 7 打印了一塊內存,並且將 10 個字節的內存轉儲到 mem.log 文件。清單 8 中用 hexdump 來校驗轉儲內存數據的正確性。
清單 9. 校驗內存轉儲
$:~/work/qemu$ hexdump -C mem.log 00000000 8b 55 c8 8b 4d c4 80 7d d0 00 |.U..M..}..| 0000000a 控制類命令 |
控制類命令操作虛擬機、虛擬磁盤和 qemu。
QEMU 運行的時候,如果指定 -snapshot 參數,則會允許虛擬機在運行的時候創建快照 (snapshot,類似於 Windows XP 中的一個系統還原點 )。在清單 9 中,首先用 info snapshots 查看當前已經存在的快照信息,然後用 savevm 命令創建了一個名爲 save_name_1 的快照。再使系統還原到 vm-20111025134936 快照時的狀態,最後刪除了名爲 save_name_1 的快照。
清單 10. snapshot 操作
(qemu) info snapshots ID TAG VM SIZE DATE VM CLOCK 1 vm-20111025134936 202M 2011-10-25 13:49:36 00:02:19.524 (qemu) savevm save_name_1 (qemu) info snapshots ID TAG VM SIZE DATE VM CLOCK 1 vm-20111025134936 202M 2011-10-25 13:49:36 00:02:19.524 2 save_name_1 202M 2011-10-25 13:51:53 00:04:28.395 (qemu) loadvm vm-20111025134936 (qemu) delvm save_name_1 (qemu) info snapshots ID TAG VM SIZE DATE VM CLOCK 1 vm-20111025134936 202M 2011-10-25 13:49:36 00:02:19.524 (qemu) |
由於塊設備允許使用緩存,所以會有在虛擬機運行的時候可能會有某些寫操作未實際寫到設備上。commit 命令將對塊設備執行強制刷新操作。對於仍然在緩存中的數據,將會立即寫入到塊設備上。
對於虛擬機的開關控制,system_reset/system_powerdown 則相當於在電腦上的 reset 和 powerdown 按鈕,將強制虛擬機進行重啓和關機操作。stop/cont 將使得虛擬機進入 / 退出掛起狀態。而 quit 則將直接退出 qemu.
change 命令用的比較廣泛。能在虛擬機運行的時候動態更改虛擬機的配置。清單 10 中首先將啓動 QEMU 時指定的 vnc :1 端口更改爲 :2,然後將 ubuntu-11.04-desktop-i386.iso 作爲虛擬 CD 插入到 ide1-cd0 中,最後將其彈出。我們可以通過 info block 來查看每步塊設備的變化情況。
清單 11. change 更改系統配置
(qemu) change vnc :2 (qemu) change ide1-cd0 /home/public/ubuntu-11.04-desktop-i386.iso (qemu) info block virtio0: removable=0 io-status=ok file=/tmp/vl.KsIMFQ \ backing_file=/home/public/ubuntu.img ro=0 drv=qcow2 encrypted=0 ide1-cd0: removable=1 locked=0 tray-open=0 io-status=ok \ file=/home/public/ubuntu-11.04-desktop-i386.iso ro=0 drv=raw encrypted=0 floppy0: removable=1 locked=0 tray-open=0 [not inserted] sd0: removable=1 locked=0 tray-open=0 [not inserted] (qemu) eject ide1-cd0 (qemu) info block virtio0: removable=0 io-status=ok file=/tmp/vl.KsIMFQ \ backing_file=/home/public/ubuntu.img ro=0 drv=qcow2 encrypted=0 ide1-cd0: removable=1 locked=0 tray-open=1 io-status=ok [not inserted] floppy0: removable=1 locked=0 tray-open=0 [not inserted] sd0: removable=1 locked=0 tray-open=0 [not inserted] |
可能是由於兼容性問題,QEMU 在鼠標的虛擬化方面做的並不是十分完美。經常有用戶抱怨客戶操作系統的光標和宿主光標不同步的問題。如果熟悉 monitor 命令,可以變通的解決這一問題。清單 11 將鼠標移動到 (500,500) 的位置,然後虛擬機中的鼠標按下了左鍵,最後向虛擬機發送了 Ctrl+Alt+Del。
清單 12. 鼠標和鍵盤操作
(qemu) mouse_move 500 500 (qemu) mouse_button 1 (qemu) sendkey ctrl-alt-del |
本文介紹了 QEMU monitor 的常用命令,並且大部分給出了運行的實例,希望對使用 QEMU 進行開發和測試的讀者有所幫助。當然 monitor 的命令還有很多,比如做遷移測試的時候可能會用到 migrate 系列的命令,需要讀者根據 QEMU 的進化演變逐漸地學習和體會。
轉自:http://blog.csdn.net/cybertan/article/details/8115866