虛擬化的技術這幾年變得十分的流行,記得早在 10 多年前 VMWare 剛出來的時候,Teddy 的同事發現了這個好東西,於是我們就在 VMWare Workstation 上面建了好幾個 VMs (virtual machines),安裝不同版本的瀏覽器作為測試之用。Teddy 目前則是使用免費的 VMWare Server 3.x 來作為虛擬化測試平台,它可以讓我們透過網頁介面來產生與管理 VMs,很方便也很好用。
VMWare Server 用了一陣子之後,Teddy 發現了幾個不方便的地方:
- Teddy 最近安裝了 Ubuntu 10.4 64-bit 作業系統,免費版的 WMWare Server 似乎無法直接安裝。雖然 google 了一下發現網路上也有人提到一些偏方,但是屬於 Linux 幼稚園小班的 Teddy 在嘗試了一下無法成功之後就自暴自棄輕易地放棄了。
- WMWare Server 無法設定配置給每一個 VM 的 CPU 數目,用起來爽度有點不夠(雖然在 Teddy 的使用情境下,大部分的 VM 也只需要配給它一顆 CPU... XD)。
- VMWare 的網頁介面有點小不穩,偶爾會出現一些不預期的錯誤,要 reload 好幾次才會正常。
- 沒有支援 live migration 功能(雖然此功能 Teddy 從來也沒用過,不過這又是牽涉到『爽度』的問題)。
就這樣,Teddy 最近安裝了
經過一番奮鬥之後,原來問題出在於 VirtualBox 對於 DMI (Desktop Management Interface) 的模擬實在是太遜了,不像 VMWare 做的那麼好,而我們的測試程式剛好需要透過 DMI 讀取一些關於主機板的資料,所以就槓龜了。
稍微解釋一下 DMI 是做什麼的,簡單的說,就是 BIOS 裡面會紀錄著一些主機板相關的資料,這些資料會被作業系統映射到某一塊特定的記憶體中。所以,如果應用程式需要得知與硬體相關的資料,例如主機板型號,BIOS 版本,實體記憶體大小等等,便可以讀取這些資料。讀取的方法有很多種,在 Linux 下有一個叫做 dmidecode 的程式可以直接看到這些資料,大概長成這個樣子:
root@Ubuntu:~# dmidecode
# dmidecode 2.9
SMBIOS 2.5 present.
30 structures occupying 1477 bytes.
Table at 0x0009F400.
Handle 0x0000, DMI type 0, 24 bytes
BIOS Information
Vendor: American Megatrends Inc.
Version: R01-C0L
Release Date: 06/17/2009
Address: 0xE0000
Runtime Size: 128 kB
ROM Size: 1024 kB
Characteristics:
ISA is supported
PCI is supported
PNP is supported
APM is supported
BIOS is upgradeable
BIOS shadowing is allowed
ESCD support is available
Boot from CD is supported
Selectable boot is supported
BIOS ROM is socketed
EDD is supported
5.25"/1.2 MB floppy services are supported (int 13h)
3.5"/720 KB floppy services are supported (int 13h)
3.5"/2.88 MB floppy services are supported (int 13h)
Print screen service is supported (int 5h)
8042 keyboard services are supported (int 9h)
Serial services are supported (int 14h)
Printer services are supported (int 17h)
CGA/mono video services are supported (int 10h)
ACPI is supported
USB legacy is supported
LS-120 boot is supported
ATAPI Zip drive boot is supported
BIOS boot specification is supported
Targeted content distribution is supported
BIOS Revision: 8.14
Handle 0x0001, DMI type 1, 27 bytes
System Information
Manufacturer: Acer
Product Name: Aspire M3203 <----- Teddy 花了 9999 所買的電腦型號
Version:
Serial Number:
UUID: Not Present
Wake-up Type: Power Switch
SKU Number: To Be Filled By O.E.M.
Family: To Be Filled By O.E.M.
(族繁不及備載,以下省略 )
***
講到這邊,以上所說和 exception handling 有何關聯?有滴,雖然這些 DMI 的資料和硬體有關,不是所有的主幾版都會提供完整的資料,但是幾個常見的資料結構都是會存在的。因此,我們的程式在開發的時候根本不會去想到會出現『讀不到 DMI 資料的問題』。在 VMWare 中,我們所需要的資料剛好都有被模擬到,因此程式在 VMs 裡面執行都沒問題。但是,VirtualBox 模擬的資料很少,因此我們的程式搬到 VirtualBox 中就有問題了。
原本我們的程式 RL = 2 (不知道什麼是 RL 的鄉民們請參考這一系列之前的文章),但是現在為了解決這個問題,必須要把 RL 提昇為 3,也就是要作到『behavior recovery』。
我們的程式原本是呼叫 native code 的方式來讀取 DMI 的資料,但是這段 code 在 VirtualBox 就是無法正常執行,而且不知道為什麼會讓整個 JVM 『卡住』。為了先避開這個問題,於是對於相同的工作,必須要多提供另外的實做,也就是 alternative methods。最後改完的程式有一個 primary method(或稱為 primary implementation) 與一個 alternative method (或稱為 alternative implementation):
- primary method:透過外部程式的方式呼叫 Linux 提供的 dmidecode 程式來讀取 DMI 資料。如果這個方法失敗,則改用 alternative method。因為 dmidecode 程式已經成為 Linux 內建的程式,因此原則上 primary method 應該都會成功。但是考慮到也許不同的 Linux 版本的 dmidecode 輸出格式可能不同,以及萬一遇到很念舊的 users 把我們的程式安裝在很古老的 Linux 版本中,因此還是保留一個 alternative method 當作備胎
- alternative method:以原本呼叫 native code 的方式來讀取 DMI 資料。
***
鄉民甲:為什麼不在開發之初就把程式設計成 RL3?
Teddy:如果把每一個 methods 都設計成 RL3 則開發成本至少要變成兩倍(因為至少要有一個 primary method 和一個 alternative method),這樣做成本太高。此外,在設計階段很可能根本沒辦法預期到會有哪些錯誤情況發生,因此也無從針對不同的錯誤情況來設計不同的 alternative。所以,採取『演進式』的方法,逐步提昇程式的 robustness 是比較符合 agile methods 的精神。
***
友藏內心獨白:例外處理的好,軟體系統才會頭好壯壯。
沒有留言:
張貼留言