2015年2月25日 星期三

qemu-kvm 虛擬機俄羅斯套娃:五層祝福的電腦快照

五層 qemu-kvm 的架構 為了課程需要, 最近把 qemu 裝進 阿貴版 finnix 裡面 (ckhung15c 或更新的版本)。 然後就忍不住想要把虛擬機一層又一層地開進去。 我花了兩個多小時 (先前失敗/學習的時間不算) 製作出下面這張螢幕快照, 給大家拜個晚年, 送給讀者們五層的祝福!

好吧, 嚴格來說, 其實只有一到四層是虛擬機; 另一層 (叫它第 0 層好了) 是最底層的金屬機 (英文文件裡的 bare metal, 就是實體機)。

首先, 為了精簡, 我在 finnix 上面只安裝必要的 qemu-system-x86 跟 qemu-utils 套件。 所以啟動虛擬機的指令不是 kvm ... 而是 qemu-system-x86_64 -enable-kvm

如果沒有加上 -enable-kvm 「硬體及作業系統直接支援虛擬化」 (Kernel-based Virtual Machine)這個選項, 那麼 qemu 就用軟體去模擬硬體, 速度會變得超慢。 (仔細想想, 單是能做到軟體模擬的虛擬化就已經很神奇了。)

但問題是: 第一層虛擬機可以啟用 kvm ; 第二層或更高也可以這樣做嗎? 那就要看你的 cpu 設計得好不好了。 根據 這一篇 的說明, amd 的 cpu 早就支援 巢狀虛擬化 nested virtualization; intel 的 cpu 則是在 2011 年左右開始支援。 我的 x220i 筆電的 cpu 正好就是 2011 年出廠的四核心 Intel Core i3-2310M, 8GB 的 RAM。 另一部桌機的 cpu 則是 2009 年的雙核心 AMD Athlon II X2 250, 4GB 的 RAM。 果然, 在 AMD 桌機上面順利很多。

qemu-kvm 五層的祝福 以下簡要說明如何在 AMD 桌機上拍攝右圖。

  1. mk-boot-usb (其實背後是 grub 0.97) 或 extlinux 製作阿貴版 finnix (ckhung15c 或更新的版本) 開機隨身碟。
  2. 把很多 iso 映象檔 (其中一定要包含 finnix 的映象檔) 放在隨身碟的 iso/ 目錄底下。 另外, 也把本文 (主要是一堆很長的指令) 剪貼到這個目錄底下。
  3. 用隨身碟開機。 確認 cpu 有支援硬體虛擬化: egrep --color=auto 'vmx|svm' /proc/cpuinfo 應該出現紅色的 svm。
  4. 確認 cpu 的巢狀虛擬化功能已打開 (linux KVM 對 AMD cpu 的預設是打開的): cat /sys/module/kvm_amd/parameters/nested 應該出現 1 而不是 0。
  5. 啟動虛擬機的時候, 加這兩個選項以便把硬體支援傳遞進內層的 guest: -enable-kvm -cpu host 。 此外, 也要用 目錄任意門 9p 把 iso/ 子目錄分享給 guest。 最終, 我的指令長這樣: qemu-system-x86_64 -enable-kvm -cpu host -m 2047 -virtfs local,path=/iso,security_model=passthrough,readonly,mount_tag=iso_imgs -cdrom /iso/finnix-ckhung15c.iso & (已事先在根目錄建立 symbolic link
  6. 進入 guest 之後, startx 啟動 X Window。 然後 mkdir /iso ; mount -t 9p -o trans=virtio iso_imgs /iso 就可以看見 host 所分享的光碟映象檔。
  7. 在每一部更內層的 guest 裡面重複以上兩步驟, 直到你覺得慢到受不了為止。 每進一層, 記憶體 (-m 選項) 當然要分配少一點。 另外, finnix 光碟開機時, 建議按 tab 鍵, 並把 vga=791 (表示解析度 1024x768) 改成 vga=788 (800x600) 或 vga=785 (640x480)。 事實上我開金屬機的時候, 把解析度設成 1280x1024: vga=794。 其他更多解析度請見 這一頁。 當然, 也可直接縮小虛擬機視窗。
  8. 最後, 在第零層手動安裝 scrot 以便截取螢幕快照。 (ckhung15c 版還沒有放進去。)

啟動 antix puppy linux 的時候, 要加上 -vga std 才能正確進入圖形介面。 另外, 雖然 android-x86 放在第一層, 不知為什麼還是很慢。

第三層虛擬機的 finnix 圖形介面勉強還可以用; 最深 (第四層) 的 ttylinux 花大約兩分鐘開機。 (在第一層的時候, 不到 30 秒。) 其實記憶體還夠, 命令列反應也 ok; 最終阻止我繼續疊虛擬機的, 是反應超級 lag 的滑鼠。

再回來談 intel。 我在小黑 (x220i) 上面的實驗步驟如下:

  1. cat /sys/module/kvm_intel/parameters/nested 看到 N, 表示 linux 核心預設關閉 intel 的巢狀虛擬化功能。 如果此時啟動第一層虛擬機, 那麼想要啟動第二層或更深層的時候, 就無法加上 -enable-kvm 的選項。 到了第三層, ttylinux 開了半小時還開不完。
  2. 於是按照 archlinux 的 wiki 移除再重新載入模組, 並要求啟動巢狀虛擬化: rmmod kvm_intel ; modprobe kvm_intel nested=1 之後若再 cat 會看到 Y。
  3. 結果啟動第二層時就出現類似 這樣的錯誤訊息。 搜尋不到更有用的資訊。 (攤手)

結論與問題:

  1. 單就巢狀虛擬化而言, 在 linux 底下, 2009 年的 AMD cpu 勝過 2011 年的 Intel cpu。
  2. qemu 若要改善巢狀虛擬化, 應優先減輕滑鼠事件的程式碼。
  3. [MIB 星際戰警] 貓項圈裡面的銀河系, 它裡面不知道還有幾層宇宙?

沒有留言:

張貼留言