2017年4月25日 星期二

把 Windows XP 收納成 qemu 虛擬機

老婆的 (Windows XP!) 電腦壞了。 她忙著買新電腦; 我則要趁著最後一部裝著 xp 的 eeepc 還沒掛掉的時候, 趕快把它變成虛擬機備份起來, 因為上面有一些她無法放棄、 又無法升級到新版 windows 的應用軟體。 這是我第一次成功的 windows P2V (Physical to Virtual) 實戰, 其中有些步驟可能對 windows 7 的 P2V 也有幫助。

一、 為什麼要寫這篇?

如果是從零開始安裝 windows, 那很簡單 -- 不需要做 p2v, 直接開一部虛擬機、 配給它空硬碟就可以了。 但更常見的需求是: 一部運行一段時日的 windows, 上面已裝有許多軟體, 和已習慣的設定, 必須要將它虛擬化。

早在很多年前, 就已有 xp 實體轉虛擬 (P2V, physical-to-virtual) 的中文文章; 不過都是轉成 virtualbox, 而且不論是採用 Acronis True Image 或是 VirtualXP, 都需要先在實體機上安裝一些套件。

VirtualBox 也是自由軟體; 不過命令列控貴哥本來就更偏好 qemu-kvm。 而且直接變成 qemu 虛擬機, 以後就可以少一個轉換步驟, 直接整合進 proxmoxopenstack。 再來, 自從 Sun 被 Oracle 併購之後, 我就更不想用 VirtualBox 了。 最後, 上述連結 「需要啟動原來的實體機再安裝一些軟體」 的做法, 縮限了應用的場合。 例如可能有人在舊電腦還沒掛掉時, 就已經先備份了硬碟的映像檔, 但卻等到硬體真的掛掉了, 才來進行虛擬化還原生命。 (冷凍復活 的概念) 這時就不可能先把實體機再開起來安裝軟體啊!

鞋貓劍客 不過我先前試過 clonezilla、 這次還試過 fsarchiver (據說支援 ntfs), 但都沒成功。 最後成功的做法是土法鍊鋼的 dd 加上 Hiren's Boot CD。 HBCD 可以說是 windows 世界裡的 SystemRescueCd (迷你 linux 救援光碟) 的 windows 版。 感覺像是在地獄裡遇到鞋貓劍客一樣親切興奮! 請先一邊下載這兩張光碟, 一邊繼續往下做。

[快寫完時才找到這篇, 裡面記錄 windows p2v 變成 qemu 時可能遇到的很多關卡, 超讚! 筆記一下: Migration of (Windows) servers to Proxmox VE]

二、 底層舖好 zfs 軟墊比較舒服

你也可以省略這步啦。 不過等一下如果可以在 zfs 上面施工, 整個流程會變得輕鬆順利很多, 特別是可以省很多時間。 因為當你不小心做錯或不滿意先前的步驟時, zfs 的 snapshot 跟 rollback 讓你可以瞬間還原到先前的狀態。 如果把 xp 的映像檔放在普通的 ext4 檔案系統上來施工, 一旦做錯, 就要重新拷貝一次幾十 G 甚至幾百 G 的映像檔, 很累人的呀!

三、 把兩張救援碟放進開機隨身碟

HBCD 跟 SystemRescueCD 兩個 .iso 檔可以不需要燒成光碟, 因為等一下我們會用虛擬機去啟動它們。 不過這兩張光碟實在太好用了, 值得把它們放進開機隨身碟裡, 以後可能用得到。 如果你已經有一顆 extlinux 開機隨身碟, 步驟很簡單。

SystemRescueCd 請參考 這篇。 簡單地說, 就是在隨身碟的開機分割的根目錄下建立一個 sysrcd 子目錄, 並且把光碟根目錄裡的 sysrcd.dat、 sysrcd.md5、 及光碟 isolinux/ 底下的 {rescue,altker}{32,64} 這四個檔案 (其中之一即可) 外加 initram.igz 複製進去。

因為我對 windows 不熟, 所以... Hiren's Boot CD 的 .iso 檔就隨便放吧, 只要是在隨身碟的開機分割上就好。

最後在 extlinux.conf 裡面加上 (類似) 這兩段:

label SystemRescueCD
 menu label SystemRescueCD 4.9.6
 kernel /sysrcd/rescue32
 append initrd=/sysrcd/initram.igz subdir=sysrcd setkmap=us docache

label Hirens.BootCD.15.2
 menu Hiren's BootCD 15.2
 kernel memdisk
 append initrd=/HBCD.15.2.iso iso raw

(請自行修改檔案正確路徑。) 上面的語法會把 Hiren's BootCD 整張光碟都載入記憶體裡; 而 SystemRescueCD 則是因為 docache 選項, 也會試著把自己載入記憶體中。 所以啟動虛擬機時, 記得要給足夠的記憶體, 例如 1G 之類的。

[其實 HBCD 採用 grub4dos 開機 ( 1 2) 所以可能還有更經濟的做法...]

三、 dd 備份

有試過採用 qcow2 的方式來備份映像檔, 但不知道哪裡做錯了, 沒有成功。 只好用最原始的方式 dd 備份 (幾乎) 整顆硬碟。 希望當初你的 windows 有切分割, 把系統獨立出來放在一個較小的 C 槽, 跟放資料的 D 槽分開來。 因為 windows 很龜毛, 開機分割特別難處理, 需要整個分割 dd 出來。 如果系統跟資料混在同一個分割、 佔用整顆硬碟, 那你就需要一個很大的 (行動硬碟) 暫存空間。

  1. 用行動硬碟上的 SystemRescueCD 或 finnix 啟動裝有 xp 的實體機。
  2. 假設你的 C 槽容量是 40G, 而且假設它正好放在硬碟的最前面 (一般都是這樣啦); 後面還有幾個分割不重要。 先備份: dd count=88080384 < /dev/sda > /media/sdz99/xp-sda.raw 這裡的 /media/sdz99 是行動硬碟的掛載點; 88080384 = 42*1024*1024*2, 因為我們需要比 sda1 更大一些些的空間 (42G), 而 dd 的計算單位是 block (半 k)。
  3. 順便把 lscpu、 lspci、 dmesg 幾個指令的輸出也一起存起來, 以便歷史學家多年後的自己了解這部機器的硬體配備。
  4. 把這個 42G 的大映像檔搬到工作機的 zfs 的某個 dataset (例如叫做 rpool/revivexp 好了) 底下, 並且立即做畫面快照: zfs snapshot rpool/revivexp@0-fresh。 用 zfs file system 比用 zfs volume 更方便, 因為這樣可以用更多工具去處理這個映像檔。
  5. fdisk /rpool/revivexp/xp-sda.raw 進去之後, 把後面的分割通通砍掉, 以免 (42 G 之後, 不存在的空間) 被 windows 誤用; 儲存離開。
  6. (可省略) 如果你想要在後面剩下來的空間裡順便灌一個 finnix (加 SystemRescueCD 加 HBCD) 之類的, 可以用 qemu-nbd 去處理它, 或是更簡單地, 用 finnix 開機去處理它。
  7. (可省略) 可以試著啟動它: kvm -m 2048 -monitor stdio -vga std /rpool/revivexp/xp-sda.raw 注意: 不要用 -cpu host, 因為這會讓問題變得更複雜: 你需要進一步了解工作機的 cpu 是什麼型號的。 也不要用 -usbdevice mouse, 不知道為什麼, 這個 xp 只認得 ps2 mouse。

BSOD 0x0000007B 錯誤 最後的這個測試應該會失敗, 停在一個黑底白字選單讓你選擇是否要進入安全模式或回到上次良好設定等等。 如果想要欣賞藍底白字的 BSOD 畫面 完整地閱讀一閃而過的錯誤訊息, 可以在開機時迅速按 F8 並選擇 「停用系統失敗時自動重新啟動」, 就會看到藍底白字的 「A problem has been detected and windows has been shut down to prevent damage to your computer ... STOP: 0x0000007B ...」 要我檢查病毒、 硬碟、 硬碟控制器? 咦, 這種錯誤訊息的語氣聽起來跟 棄權就是安全 好像啊... 「因為硬碟控制器型號改變所以不能開機」 聽起來超弱的, 不像是技術問題, 比較像是因為它偵測到你好像換了一部電腦, 所以認為你盜版, 拒絕開機。 它當然不會分辨我是要盜版還是要 P2V, 不過從 xp 用戶的角度來看, 這比勒贖軟體更令人反感 -- 最起碼勒贖軟體還會給你一個 「付錢, 資料跟程式就救得回來」 的選項。 總之爬了很多文、 試過很多方法都沒用。 直到最後讀到 這篇 才遇到救星 Hiren's BootCD!

四、 HBCD 修復

點選 Registry 裡面的 Fix hard disk controller 請修改以下命令中的 iso 檔跟 xp-sda.raw 的路徑, 用 HBCD 啟動虛擬機, 準備修復 xp-sda.raw: kvm -m 512 -monitor stdio -vga std -boot order=dc -cdrom .../HBCD.15.2.iso /rpool/revivexp/xp-sda.raw

  1. 看到 HBCD 的開機選單時, 選擇 「Mini Windows Xp」
  2. 進入桌面後, 右下角時鐘旁邊就是 HBCD 的主選單。 點選 Registry 裡面的 Fix hard disk controller [fix_hdc.cmd]。
  3. 在 fix_hdc.cmd 的文字選單下, 先選 (T) Set TargetRoot, 照著敲入 C:\Windows, 再選 (M) 進行修復。

先選 Set TargetRoot、 再選 Update MassStorage drivers 既然都已經進來 HBCD 了, 就順便把產品認證金鑰抄一下。 從 HBCD 的主選單裡選 Password/Keys => Product Keys => 叫出 ProductKey [Windows Key Viewer]。 點一下 「Select Source」, 選 「Load the product keys from the external Windows directory」 (不是 local computer, 因為 local computer 是 HBCD 自己) 然後選取 C:\Windows, 按 「OK」, 就會出現原始機器內的 windows 產品金鑰。 如果你找不到原來的金鑰了, 這個功能超方便。

看起來 HBCD 還有很多特異功能; 不過我只想做 P2V, 其他的就沒再多研究了。 搜尋 「Hiren 光碟」 會找到一些中文推薦文。

HBCD 虛擬機關機之後, 馬上再做一個 zfs snapshot。

再次用 xp-sda.raw 啟動 kvm (這次不需要 HBCD 了), 應該就會成功開機。 Windows 叫我要 activate 才能登入。 我不知道一旦 activate 之後, 原來的實體機還能不能用, 所以決定不要冒險, 等實體機壞了再來 activate 好了。 反正對我來說, P2V 已經成功就夠了。

五、 gparted 縮骨

但是 42G 的映像檔好大啊! 不論是要備份或修改都很麻煩。 真正的系統其實只用了不到 20G, 可不可以把它縮小呢?

運氣比較好的狀況下, 概念上很簡單: 用 ntfsresize 指令把資料往前集中, 再用 fdisk 刪掉並重建一個較小的分割即可。 這篇 有很詳盡的細節跟參考連結。

但是我這部 eeepc 當初出廠前切分割時, 沒有做好 cylinder alignment, 所以切在不整齊的地方。 一旦用 fdisk 重新去切割, 它會把新的分割對齊到 cylinder 的邊界, 跟原來的位置不一致, 結果 windows 就無法開機了。 沒找到要如何叫 fdisk 不要自動對齊; 理論上也可以 計算 CHS 的 bits 並且用 hexedit 去改分割表啦, 不過我是懶惰的老教授, 不是修計算機概論、 學進位轉換的大一學生啊~~

gparted 縮小 ntfs 還好有 gparted! 它底層也是呼叫 ntfsresize, 更好的是它還可以幫我們保留分割的起點不變。 用 systemrescuecd 啟動 kvm (把第四節的 kvm 指令當中的 HBCD 的 iso 路徑改成 systemrescuecd 的 iso 路徑) 並且打 startx 進入圖形介面。 叫出 gparded 之後, 在 /dev/sda1 上面按右鍵, 選 「Resize/Move」。 把綠框的右側拉到理想的位置 (最好比你的實際資料再多保留一些空間)、 最重要的是 "align to" 選 "none"、 點最右下角的 「Resize/Move」。 這只是排入待辦行程而已, 最後還要從 Edit 底下選 「Apply All Operations」 才會真的生效。 等很久很久, 做完之後, 記得要 zfs snapshot 哦!

虛擬機關機, 回到 host (工作機) 之後, 還需要把磁碟映像檔砍小:

cd /rpool/revivexp
ls -l xp-sda.raw
truncate -s 21G sda.img
ls -l sda.img 

再做一個 zfs snapshot (假設叫做 3-shrunk 好了)、 再用 kvm 開進 windows 測試一下。 最好把整個映像檔複製到別部機器再 kvm 開機測試。

如果測試成功的話, 快把 zfs 打包壓縮: zfs send -R rpool/revivexp@3-shrunk | gzip > eeepc-xp.zsnap.gz 多備幾份吧!

[ps. 另一個方法: ntfsclone + ntfsresize。]

六、 結語

讀到一則新聞: 以後人類的個性可以永遠保存了! 如果把自己的社交媒體帳密交給 Eternime 公司, 他們的軟體 (AI 吧, 我猜) 會學習你的發言方式 讓你的個性永遠保存下來、 以你的語氣繼續跟親友互動。 相較之下, 電腦的 P2V 是不是很簡單呢 :-) 你照著這篇做 xp 的 P2V, 有成功嗎? 或是還需要多做哪些步驟呢? 這篇也適用於 windows server 2000 或 windows 7 嗎? 請分享成功或失敗的經驗 (含錯誤訊息), 讓我們一起把這些舊機器全都收進紫金紅葫蘆裡去, 不要再吃那麼多電跟機房空間了吧! (而且也比較方便用更多當代的工具去保護它們的資訊安全。)

沒有留言:

張貼留言