2016年12月28日 星期三

書摘:Effective Debugging - Item 17 放大程式跑失敗的後果



Item 17: Increase the Prominence of a Failure's Effects


  • 使用版本控制來增加放大失敗效應的程式碼以便回溯,這樣才不會誤把測試程式放進 production code
  • 放大手段一:移除可能的程式碼片段。例如使用一個永遠成立的 if 條件式(ex. if(0))去執行有嫌疑的程式碼片段。
  • 放大手段二:修改程式碼,讓原本的輸出資料變得很容易觀察。例如把輸出資料故意變成原本的一千倍。
  • 放大手段三:壓力測試、並且使得失敗很快速地可以複製出來。例如使用 Apache JMeter 來執行對網站的 DDoS。故意指定超過的 thread number 來測試 concurrency。故意讓程式跑在資源缺乏的地方,例如寫入故意寫在小容量的 USB 磁碟裡。
  • 放大手段四:fuzzying。例如使用 zzuf 來亂數產生測試用的輸入資料。

書摘:Effective Debugging

最近在讀 Effective Debugging[1],發現編排方式非常適合早餐的時候閱讀 XD 作者將自身的經驗歸納成 66 個條目,每個條目長短剛好是一個早餐的閱讀份量。遣詞造句也算潛白,即使像我這種非英語母語人士也可以感受到閱讀樂趣。

當初進了 Canonical 公司[2]工作之後,基於之前大多經驗是開發 web 或是寫寫 script 跑科學計算 job,往往有完整的、成熟的 IDE 可以使用,因此有一小段時間對於除錯環境不一定well-prepared 的系統程式除錯感到不太適應。這三年摸索過去後,偶然間看到這本書,覺得很是幫自己過去三年在公司中遇到的問題做了很好的回顧和整理,當然也有啟發;因此一讀就欲罷不能 XD

接下來打算在每次閱讀之後,開始摘要 66 個條目中的內容與自己的心得。敬請期待。


Item 17 放大程式跑失敗的後果


[1] Effective Debugging: 66 Specific Ways to Debug Software and Systems (Effective Software Development Series) 1st Edition by Diomidis Spinellis,我讀的是 Amazon 上面的 Kindle 版本。
[2] https://zh.wikipedia.org/zh-tw/Canonical%E5%85%AC%E5%8F%B8

2016年12月22日 星期四

初探 PRIME 技術


最近收到通知說 12.0.5 的 mesa 打算 backport 回 Ubuntu 16.04,並且取代原本 16.04 中11.2.0 版本的 mesa,希望在正式釋出 backport 版本前提供更多測試。因此對這個技術稍微了解了一下,摘要如下。

詞彙

provider:
提供運算資源的單位,例如一張獨立顯卡。

sink output:
在這裡指有連接外部裝置 port 的 provider,但基本上不太負擔運算繪圖,只輸出。不要跟電路學中的 sink-source 混淆(電路學中是指裝置接地和電壓方式的不同)

source output:
在這裡是指負擔運算繪圖,但輸出由其他 provider.

multiplexer:
較早期不是採用動態切換時,需要關掉一個 GPU 再去啟動另外一個 GPU來達成切換,負責開關的裝置叫做 multiplexer[a],通常是一種硬體。比較新的裝置是不需要(硬體上的) multiplexer,稱為 muxless。附註資料[c][d]中的硬體透過 GCN (一種新的指令集架構)支援這種功能。


因此在處理這類問題,我們會需要知道(下文有對應指令):

  • provider 的資訊,包括他是 sink or source output
  • render 時的資訊;例如是誰在負責運算、運算結果的表現如何。

我們會需要執行下面這些動作(下文有對應指令):

  • 指定誰當 sink、誰當 source


使用情境

案例一:PRIME


一個支援 muxless 的系統有兩個顯卡,分別是主要的 integrated graphic 和第二顯卡。輸出 port 在 integrated graphic 上面。

因為 integrated graphic 是常駐的、低耗電的晶片裝置,所以平常的運算都交給他。有時如果要把運算負擔(loading)從 integrated graphic 交給第二顯卡,integrated graphic 只剩下把資料從 port 輸出,這個動作就叫做 offload。PRIME 技術就是提供 muxless 的裝置實作 offload 功能。

目前只有 AMD 的顯卡支援這技術[c][d],nvidia 還沒。

案例二:REVERSE PRIME


一個支援 muxless 的系統有兩個顯卡,分別是主要的 integrated graphic 和第二顯卡。輸出 port 在第二顯卡上面。例如 integrated graphic 是內建螢幕和 VGA 輸出,第二顯卡上則有 HDMI 和 display port 輸出,而使用者現在想用 display port 來輸出。

使用者現在想用 display port 來輸出,可是又不想用第二顯卡處理大量運算;因為第二顯卡雖然運算能力比較好,但是比較耗電。也就是說希望第二顯卡負責輸出就好,運算負擔還是 integrated graphic  在處理,只是 port 不是直接由 integrated graphic 控制。Reverse PRIME 技術可以實踐這種設定。


案例三:案例二的進階


一個支援 muxless 的系統有兩個顯卡,分別是主要的 integrated graphic 和第二顯卡。 integrated graphic 是內建螢幕輸出和 VGA 輸出,第二顯卡上則有 HDMI 和 display port 輸出。使用者想要四個 ports 都輸出,但是希望畫面流暢一點。

全部四個 ports 都由 integrated graphic 輸出的話,有可能會不流暢。因此使用者會希望運算盡量都是交給第二顯卡。


實作

案例一:PRIME

列出 provider 資訊

xrandr --listproviders

指定 provider 1 負責運算,provider 2 負責作為 sink output 輸出。(我把這個選項理解成:set provider 1 offload sink output)

xrandr --setprovideroffloadsink 1 0

在 default intel/modesetting driver 中,因為 DRI3 功能已經預設開啟,所以其實上述的設定已經是系統預設了,但手動再做一次並不會怎樣。[b]

這時候只要透過環境變數 DRI_PRIME 就可以動態地切換看是要哪個 provider 去繪圖。例如:

DRI_PRIME=1 <任何執行 render 的指令>

展示使用 provider 0 時(integrated graphic),對應的 opengl 參數 (glxinfo 這個工具可以透過安裝 mesa-utils 來取得)

DRI_PRIME=0 glxinfo

展示使用 provider 1 時(第二顯卡),對應的 opengl 參數

DRI_PRIME=1 glxinfo

這個 merge request 中,checkbox 被加入檢查系統是否具有支援 PRIME 技術的功能;如果有支援,那麼試著在接下來的測試中使用這個技術(同時也是測試這個技術),參見原始碼

從原始碼裡我們可以看到,要下面幾個條件被滿足才會判定系統支援 PRIME 技術,包括:

  • 系統有 amdgpu 這個套件(open source 版本的 AMD 顯卡 driver)
  • Ubuntu 系統是 Xenial
  • 有兩個以上的 GPU

案例二:REVERSE PRIME

略,參見[b]

案例三:案例二的進階

略,參見[b]



參考資料:
[a] https://wiki.archlinux.org/index.php/hybrid_graphics
[b] https://wiki.archlinux.org/index.php/PRIME
[c] https://en.wikipedia.org/wiki/Graphics_Core_Next
[d] https://en.wikipedia.org/wiki/AMD_Radeon_Rx_200_series
[e] xrandr manual

2016年4月7日 星期四

用 python 撰寫 GTK+3 架構下的視窗介面

最近想要寫一個小程式,隨手挑了一套 solution:

python - 程式語言
GTK+3 - 視窗介面程式框架
glade - 畫視窗介面的 IDE

其中 glade 可以把用 IDE 畫好的視窗 layout 直接存成 GTK 可以理解的 xml 格式檔案,藉此增加開發設計視窗外貌的速度。

選擇 GTK+3 的理由滿單純,因為我使用的系統** 上的 glib 會抱怨我所使用的 glade 必須是 3.x 版 ***


** 我是用 Ubuntu 14.04 64 bit
*** import gtk 這種語法似乎就是支援 GTK+2.x,細節可參考這個 stackoverflow 連結



步驟一:使用 glade 畫 layout 後轉成 XML


首先啟動 glade,接著創建一個視窗(在工作 panel 中按視窗即可),注意這個視窗有個名字(預設是 window1),這個名字會被 python GTK+3 拿來取得該視窗物件,所以如果你有更改視窗名稱的話,程式中呼叫的名字也要跟著改。

畫好之後就存檔,檔案本身就會是 XML 了。

步驟二:開始寫程式


整個 python GTK+3 架構大致如下:
使用 builder 取得視窗物件、註冊 signal、設定組態等等。最後開始執行 Gtk main loop 等待事件。

範例如下:

from gi.repository import Gtk

class HellowWorldGTK(object):
    """This is a Hello World GTK application"""
    def __init__(self):
        # layout generated by glade
        layout_filename = "layout.xml"
        builder = Gtk.Builder()
        builder.add_from_file(layout_filename)
        #builder.connect_signals(self)
        self.window = builder.get_object("window1")
        if self.window:
            self.window.connect("destroy", Gtk.main_quit)
        self.window.show_all()
if __name__ == "__main__":
    hwg = HellowWorldGTK()
    Gtk.main()


其中 layout.xml 是步驟一用 glade 存成的 XML 檔案名稱,window1 也是步驟一中提到的視窗名稱。這裡比較要注意的是使用這行程式碼來讓我們可以關掉視窗的時候,同時退出 Gtk main loop。如果沒有這行,程式一但執行後就會一直跑,只能另外請作業系統殺掉它了。

self.window.connect("destroy", Gtk.main_quit)


步驟三:執行


步驟二中的範例程式碼存成 go.py,執行 go.py 即可。




更多資訊可以參考 Python GTK+3 Tutorial (剛好昨天才 release!)

2016年3月3日 星期四

snap 套件包簡介

Canonical 公司最近提供了一種叫做 snap 的套件包格式,目的是希望可以改善開發 IoT 裝置的流程,甚至是進一步培育 IoT 的 App ecosystem。綜觀整個 snap 的孕育過程,snap 的前身似乎可以說是 click package,後來再針對 snappy 架構** 而改良的格式。以 snappy、Ubuntu core***、和 snap package 三者構成的開發與系統環境,成為 Canonical 公司的產品重心。這兩天 Canonical 和 MTK 合作的消息便是一個這樣的例子。

** snappy 是系統架構的方式。意指是一種使用 snap 當作系統管理(安裝、移除軟體)單位的手段。
*** 最常見的詞是 snappy Ubuntu Core,因為 snappy 架構常常和 Ubuntu Core 搭配使用。解讀方式是 snappy (形容詞) Ubuntu Core(名詞),就是 墊基於 Ubuntu Core 之上的 snappy 架構。Ubuntu Core 和以往的 Ubuntu (現在稱為 Ubuntu Desktop)的架構不同,細節請參考官方網頁


今天要介紹打包一個 snap。

實作上官方網頁其實寫得很清楚了,基本上下面的內容直接是取自與摘要該網頁 XD


  • 打包的工具叫做 snapcraft。Trusty 上面沒有,可以透過增加 PPA 來安裝。(我自己有試過編 github 上面的 source code 來玩,但不知道為什麼會 crash;我推測是因為最近自己系統上的 python 被我有點弄髒了 =.= )
  • 打包的設定寫在 snapcraft.yaml,這基本上可以類比於 debian/rules 這類型的檔案。
  • snapcraft 五大步驟是:pull build stage strip snap, 合稱 assemble
  • 概念上就是通通摻在一起做撒尿牛完:有點像是編靜態 shared library,把所有需要的東西拉下來、編譯、踢掉執行階段用不到的 binary、把剩下的 binary 弄成一包。這樣的設計應該是為了 IoT device 而做的。(是的,我也推測會相對肥大)

2016年2月17日 星期三

Ubuntu 下把 NEF 檔轉成 jpg


NEF 是 Nikon 系列相機的 raw 檔案,Ubuntu 可以使用 shottwell 或是預設的圖形瀏覽器去瀏覽。

如果想要抽取 RAW 中的 jpg 的部份(例如想要讓檔案尺寸小一些),可以使用 imagemagick 來批次轉檔。使用前要先另外安裝 ufraw-batch

sudo apt-get install ufraw-batch

接著(不會覆寫原本的 RAW)

for i in `ls *.NEF`; do convert $i $i.jpg; done

或是(會覆寫原本的 RAW)

convert xxx.NEF xxx.jpg

或是(會覆寫原本的 RAW)(試了一下這個指令,不知道為啥會失敗[1])

mogrify xxx.NEF xxx.jpg

PS 沒仔細研究,但看起來 RAW 往往會是 jpg + 一卡車自己定義的 EXIF 資訊?
PS2 mogrify 看起來是整合在 convert 裡面的工具之一

[1] 錯誤訊息:mogrify.im6: unable to open image `zzz.jpg': No such file or directory @ error/blob.c/OpenBlob/2638.

2016年1月14日 星期四

以 SOLVCON 專案為例,使用 conda 來維護、建立 python 執行與開發環境

一套可以正常運作的應用程式往往需要有很多其他配套的軟體互相支援,這造成了建構軟體中常見的「版本相依性」問題。如果是使用者的身份,這類問題可以透過(雖然這不一定是最好的方法)將所有相依的軟體都打成一包釋出。但身為開發者,常常遇到的問題是「開發者自己的作業系統環境」和「想開發的應用程式所需要的環境」有所不同。一般來說,開發者大概不太願意去更動自己的作業系統環境來配合自己的開發標的軟體,因為這可能會導致開發者自己的作業系統本身、或是作業系統下的其他應用程式無法正常運作。一個直觀的解決方案當然就是「那我弄一個專門給想開發的軟體使用的環境總可以了吧?」,conda 就是這樣的一個工具。

conda 是 anaconda 和 miniconda 所羅列的工具之一 。anaconda 和 miniconda 也是想做一樣的事情,但是前者可以堪稱是「包山包海」;這是優點也是缺點,優點就是一口氣把所有第三方的軟體都先準備好,以後幾乎不用再煩惱,缺點就是一定會準備了很多其實用不到的東西。miniconda 可以想像成是精簡版本的 anaconda 、然後有管理 python package 功能的 virtualenv[1]。

最近 SOLVCON 從原來的 python 2 移植到 python 3 ,主要的核心移植已經堪稱完成。然而最近想持續開發的 parallel 運算能力則在移植前便已經過時,剛好趁這次大搬家把這個 feature 修回來。

要熟悉一個程式的 feature,我還滿喜歡從研究它相關的 unittest 開始著手。理由如下:

從 unittest 中,我們可以看到
  1. 使用者的角度 - 這個功能如何被使用
  2. 測試者的角度 - 這個功能所產生的結果如何被解讀
有頭(如何 input 和使用)有尾(如何解讀 output)的情況下,就可以開始從外部行為來觀察程式執行 runtime 這個可以被視為黑盒子的部份。可以觀察外在的行為(unittest)加上可以觀察內在的行為(例如 source code)的話,幾乎就是一個說明清楚的 step by step tutorial。

有點扯太遠,總而言之要處理下面這兩件事情:
  1. 準備可以運行的 SOLVCON。SOLVCON 不再使用 scons 做套件管理(悲劇!!打包成 debian package 的 rule file 又要重寫 XD ),而改為使用 python setuptool ;因此要把對應的第三方工具告訴 setuptool。這裡我們採用 conda 當作解決方案。
  2. 利用 ftests 中的 nosetest 去研究和修復 SOLVCON 的平行運算功能。

準備好 conda 之後(這部份略過啦!好久以前就裝好了 XD 裝 anaconda 或是 miniconda 之後就有這個指令可以使用),先確認環境變數有告訴系統哪裡去找 conda 這個工具(通常是 anaconda 或是 miniconda 當初安裝的位置),例如有加入 PATH 變數。

啟動並且進入 conda 環境;我自己是把他寫成一個 alias 比較方便
alias solvconenv="export PATH=$MYLOCALINSTALLATION/miniconda3/solvcon-dev/bin:$PATH; source activate $MYLOCALINSTALLATION/miniconda3/solvcon-dev"

接著使用這個指令去安裝缺少的套件
conda search <package name>

安裝則是
conda install <package name>

例如安裝 python
conda install python
安裝 python3
conda install python=3
後面的等於3表示指定特定版本號碼。


更多使用方法請見 help
conda -h

[1] virtualenv 是用來建立獨立 python 套件環境的工具。









2016年1月13日 星期三

使用 flake8_docstrings python package 將 docstring 格式納入 flake8 檢查項目

長久以來一直都習慣在 Ubuntu 下使用 flake8 這個工具來檢查自己 python source code 有沒有符合 pep8 規範。

在 Ubuntu 下安裝 flake8

sudo apt-get install python-flake8

使用

flake8 <your source code>

這個工具同時也可以和 vim 共用,使得使用者在用 vim 的時候可以即時看到檢查結果。(但我今天沒打算聊這個 XD)

但今天被強者我同事糾正我的 docstring 沒有符合規範,建議我可以使用 flake8-docstrings 這個工具將檢查更完善一些。我才注意到 1. Ubuntu 下沒有這個 package 2. 以往我都漏掉這個檢查了。於是趕緊補上:

因為 Ubuntu 沒有納入管理 flake8-docstring 這個套件,所以我改用 pip 安裝工具來安裝:


sudo pip install flake8_docstrings

安裝之後再使用 flake8 就可以看到它會去掃出不符合規範的 docstring 了,例如:

$ flake8 <my source code>
......
D300 Use """triple double quotes"""
D400 First line should end with a period
D102 Missing docstring in public method
......


環境:Ubuntu Trusty

2016年1月11日 星期一

使用虛擬機器測試 secure boot (四) 使用 OVMF

前面提到我們已經用 OVMF (open source virtual machine firmware)建立一個虛擬機器了。現在我們想要讓 OVMF 這個 firmware 啟動 secure boot ,並且可以讓我們放入自己的 key 。這樣之後就可以模擬真實的 secure boot 的情形。

方法主要參考這篇文章,另外再根據自己環境的情況做調整。

使用 virsh 重新啟動稍早建立的虛擬機器

virsh list --all
virsh start <domain name>

開啟螢幕

virt-viewer <domain name>

啟動後,會 pop up 「Tianocore」,這是因為 OVMF 是移植並且開源 Intel 開發的 Tianocore 這個 firmware。因為還沒有安裝作業系統、虛擬機器的硬碟中也沒有 efi binary,所以會進入 OVMF 的 UEFI shell。輸入 exit 跳出後會進入到設定的畫面。如圖一路可以選到使用檔案匯入 key 的選項。當然,現在什麼檔案都沒有。所以問題變成是,我們要怎麼準備 key file 呢?










2016年1月6日 星期三

使用虛擬機器測試 secure boot (三) 使用 virtsh


呼叫使用提示
virsh help

顯示選項 list 的使用提示
virsh help list

連結本地端 qemu 這個 hypervisor (virsh 可以管理多種不同的 hypervisor,qemu 只是其中一種)
virsh connect qemu:///system
連進去後,
顯示 domains (但 inactive domain 不會顯示;一開始還以為沒有連成功,因為啥都沒顯示)
virsh list

顯示 domains (包括 inactive domain)
virsh list --all

立刻終止 active domain (相當於 virt-manager 下使用 force off )
virsh destroy <domain name>

刪除已經建立/定義好的 domain(要先 destroy 才可以 undefine)
virsh undefine <domain name>

virt-tools.org 這裡有簡單的教學。



virt-tools.org 的這個教學網頁裡也有提到如何透過 /proc/cpuinfo and demsg 檢查自身的機器是否支援虛擬化技術;如果有,又是哪一種虛擬化技術。簡單直白,值得一看(下面直接摘要):

/proc/cpuinfo flags #

/proc/cpuinfo will tell you if the processor supports virtualization and if it is enabled (but it could not show up in flags because it is disabled — more on this below).
The flags to look out for are:
  • vmx — Intel VT-x, basic virtualization
  • svm — AMD SVM, basic virtualization
  • ept — Extended Page Tables, an Intel feature to make emulation of guest page tables faster.
  • vpid — VPID, an Intel feature to make expensive TLB flushes unnecessary when context switching between guests.
  • npt — AMD Nested Page Tables, similar to EPT.
  • tpr_shadow and flexpriority — Intel feature that reduces calls into the hypervisor when accessing the Task Priority Register, which helps when running certain types of SMP guests.
  • vnmi — Intel Virtual NMI feature which helps with certain sorts of interrupt events in guests.

Kernel messages (dmesg) and the BIOS #

The next thing to look at are the kernel messages by running the command:
dmesg | less
The two messages to look out for are:
kvm: no hardware support
and
kvm: disabled by bios




詞彙:
hypervisor - 不精確地講,就是虛擬機器層。
domain - virtual machine instance

使用虛擬機器測試 secure boot (二) virt tool 的介紹

上文中使用到的 virt-install 是 virt-tools 中的其中一個,也是 virt-manager 專案下的一個功能。下面簡單說明幾個常被用但是稍微有點被混淆的名詞:

OpenStack - 一個軟體專案。但這個軟體專案並不是典型開發或是維護一個軟體的那種專案,比較接近是「組合或是開發各種工具以提供某種 IaaS (infrastructure as a service) 服務的解決方案」。libvirt 是它支援的工具之一。

libvirt - 一套用 c 語言寫成的 API

virt tools - libvirt 與其週邊相關的工具、產品。包括 virt-manager 。

virt-manager - 這個詞有兩個意思,一個意思是有個指令叫做 virt-manager,可以提供 GUI 來管理基於 virt-manager 這個專案下支援的工具(例如 virt-install)所建立的虛擬機器。第二個意思就是這是一個專案的名稱,集成很多基於 libvirt 開發出的工具,例如 virt-install。

virsh - 可以想成是指令列版本的 virt-manager 工具。

下一篇:virsh 的使用!






使用虛擬機器測試 secure boot (一)

最近工作上開始需要自動化測試有開啟 secure boot 的機器,鴕鳥了好多年終於開始要好好面對這件事情了 XD

下面是跟著這篇 wiki 的資訊所作的測試。有些指令我有根據自己的狀況(host machine:Ubuntu Trusty)調整。覺得太繁瑣的話可以直接跳到幾乎是最後面的小結 XDD

因為我的系統中沒有 uvt 這個指令,找了一下沒有看到 uvt 這個指令從哪來,所以採用 wiki 中提供的另外一種作法:

virt-install --connect=qemu:///system --name=sb-saucy-amd64 --arch=x86_64 --ram=768 \
--disk=path=<path to>/sb-saucy-amd64.qcow2,size=8,format=qcow2,bus=ide,sparse=True \
--virt-type=kvm --accelerate --hvm --cdrom=<path to>/saucy-desktop-amd64.iso \
--os-type=linux --os-variant=generic26 --graphics=vnc --network=network=default,model=virtio \
--video=cirrus --noreboot --boot=loader=OVMF.fd

但會得到:

ERROR    Format cannot be specified for unmanaged storage.

這看起來似乎是要事先先建立好給虛擬機器使用的 storage file。因為急著想要看到結果,我使用 --nodisk 來取代 --disk [1]

virt-install --connect=qemu:///system --name=sb-trusty-amd64-02 --arch=x86_64 --ram=768 --nodisk --virt-type=kvm --accelerate --hvm --cdrom=./uuu/ubuntu-14.04.2-desktop-amd64.iso --os-type=linux --os-variant=generic26 --graphics=vnc --network=network=default,model=virtio --video=cirrus --noreboot --boot=loader=OVMF.fd
如果遇到這個訊息

Starting install...
Creating domain...                                                                                                                                                                    |    0 B     00:00  
WARNING  Unable to connect to graphical console: virt-viewer not installed. Please install the 'virt-viewer' package.
Domain installation still in progress. You can reconnect to
the console to complete the installation process.

表示要安裝 virt-veiwer package 來顯示開機過程的畫面:

sudo apt-get install virt-viewer

接下來就會看到開機畫面啦!

下一篇打算來解釋細節,敬請期待。









要印螢幕的時候按了 alt ,鍵盤的訊號同時被 host machine 和 guest machine 捕捉到的一瞬間 XD




















根據這封 virt-tool mailing list 中的 email,這是因為我們沒有事先告訴 virt-manager (or virtsh) 使用的 disk storage 存放位置(專有名詞叫做「pool」,一個 pool 下面可以有好幾個 storage file。),所以 virt-manager 認為這個地方它不敢亂動。

首先綁定資料夾 /tmp 成為 pool 之一,名字叫做 tmppool 的 pool

virsh pool-define-as --name tmppool --type dir --target /tmp

啟動 pool

virsh pool-start tmppool

接下來把上面一長串中 --disk 選項後面指定的位置改為 /tmp (新的 pool 位置)就可以用了:

$ virt-install --connect=qemu:///system --name=thho-trusty-amd64-01 --arch=x86_64 --ram=768 --disk=path=/tmp/thho-trusty-amd64.qcow2,size=8,format=qcow2,bus=ide,sparse=True --virt-type=kvm --accelerate --hvm --cdrom=./uuu/ubuntu-14.04.2-desktop-amd64.iso --os-type=linux --os-variant=generic26 --graphics=vnc --network=network=default,model=virtio --video=cirrus --noreboot --boot=loader=OVMF.fd
Starting install...
Allocating 'thho-trusty-amd64.qcow2'                                                                                                                                                  | 8.0 GB     00:00  
Creating domain...  

檢查 pool 相關的指令有哪些
virsh help pool

驗證一下是不是真的多了 tmppool 這個 pool

$ virsh pool-list
 Name                 State      Autostart
-------------------------------------------
 default              active     yes    
 tmppool              active     no      
 uvtool               active     yes  

使用 virt-install 建立新的 virtual machine instance (domain) 之後,我們只選 try ubuntu 但是不安裝,然後關機 or reboot。下一次只要直接使用 connect 和 start 就可以開啟虛擬機器了(這兩個動作請見下篇解釋)

virsh --connect qemu:///system start thho-trusty-amd64-01

啟動後因為不像 virt-install 一樣有自己啟動 virt-viewer ,所以要自己開:

virt-viewer thho-trusty-amd64-01

(thho-trusty-amd64-01 是 domain name)

開啟了之後就會進入 UEFI shell 如圖。





因為 storage (可以想成是虛擬硬碟)中我們還沒有安裝任何作業系統(上面只選 try ubuntu 但沒有安裝),所以開機後會進入 UEFI shell。這個 shell 是 ovmf 提供的。




比較:
所有指令和選項都一樣,但把  --boot=loader=OVMF.fd 拿掉。
也就是說我們預期不使用 OVMF.fd 這個 bootloader 開機,所以應該要直接進入使用 cdrom 開機。

virt-install --connect=qemu:///system --name=thho-trusty-amd64-02 --arch=x86_64 --ram=768 --disk=path=/tmp/thho-trusty-amd64-02.qcow2,size=8,format=qcow2,bus=ide,sparse=True --virt-type=kvm --accelerate --hvm --cdrom=./uuu/ubuntu-14.04.2-desktop-amd64.iso --os-type=linux --os-variant=generic26 --graphics=vnc --network=network=default,model=virtio --video=cirrus --noreboot

果然直接進入 cdrom iso






小結:

  • 使用 virt-install 建立虛擬機器。並且是建立一個擁有 ovmf 這個韌體的虛擬機器。
  • 使用 virsh 啟動 virt-install 建立的虛擬機器,開始操作 ovmf 提供的 UEFI shell。





因為我有打算在不久的將來自動化這些指令,所以刻意選擇使用 virsh 而不是 virt-manager。virt-manger 應該也是可以作到上面說的這些事情,只是在自動化上大概就會遇到問題。

2016年1月5日 星期二

初探 ipython parallel

最近為了開發 SOLVCON 平行運算的功能,開始評估可能的解決方案。這一塊自己的知識趨近於零 XD 有點亂槍打鳥地亂看,想看看別的專案怎麼設計的,看是要模仿、參考或是甚至直接拿來用的可能性如何。

下面簡單摘要這個頁面關於 ipython parallel 的介紹:

指令列輸入這個指令,建立四個 ipython kernel 給接下來的運算使用:
ipcluster start -n 4 

然後開始玩 hello world:

In [1]: from IPython.parallel import Client
In [2]: c = Client()
In [4]: c.ids
Out[4]: set([0, 1, 2, 3])
In [5]: c[:].apply_sync(lambda : "Hello, World")
Out[5]: [ 'Hello, World', 'Hello, World', 'Hello, World', 'Hello, World' ]
ipython parallel 中很多組態設定和通訊方式是採用 JSON (或是可以轉成 JSON 的 data object)的格式,例如這資料夾下面的東西:

~/.ipython/profile_default/security/




給 kvm 虛擬機器增加 USB 儲存裝置

最近為了開發給在 Snappy 架構下的 Ubuntu Core 用的、可以自動化 USB storage 讀寫測試的工具,採用了 kvm 虛擬機器作為開發環境。因為要測試標的是 USB ,所以花了一點時間了解了一下如何連結實體的 USB storage 裝置到使用 kvm 啟動的 image 。

在 Ubuntu desktop 下使用指令:

sudo kvm -m 512 -redir :8090::80 -redir :8022::22 the-image-you-want-to-test.img -usb -device usb-host,hostbus=2,hostaddr=11

要注意的是指定最後面兩個參數的值時比較麻煩,因為該值會根據 host machine 的狀態而改變。我自己是這樣找對應的值:

  1. 插入 USB storage
  2. 使用指令 lsusb 去看上面的 Bus and Device number ,把這兩個數字記下
  3. 退出 USB storage
  4. 啟動 kvm ,啟動時,根據上面的 Bus and Device number 分別填數 hostbus and hostaddr 。要注意的是這時候 hostaddr 要加 1 (因為重新插拔了一次。現在的 Linux kernel 會給裝置編號加一表示是新找到的裝置,用來和前一次區隔)
  5. 這時候再插入 USB storage ,原本在 host machine 會自動掛載的行為不會發生(推測 event signal 被 kvm 攔下來了);稍候也可以看到在 guest machine 中的 dmesg 指令指出有新的 USB storage 插入了。