淺談Open vSwitch移植
前一段時間自己私下一直學習Open vSwitch。起初學習Open vSwitch的目的,只是為了更好的學習OpenFlow協議,然而當我看到Open vSwitch處理OpenFlow協議的入口函式時(即handle_OpenFlow__),突然感覺這程式碼的寫的太NB啦。為什麼這麼說呢?因為Open vSwitch最新版本,號稱支援of1.0,of1.1,of1.2,of1.3,of1.4,of1.5。然而它只用一個switch-case解決了協議版本差異性,它是怎麼做到呢?帶著這種疑問,開始了我學習Open vSwitch原始碼之旅。
隨著學習一步一步的深入,發現了很多聞所未聞的新名詞,比如說:DPDK,NetLink,NUMA等。這些新的名詞(只是我沒有聽說過,其實業界早已不新鮮)令我產生了濃厚的興趣,這樣我就一點一點搜尋相關資料,慢慢了解。以上就是我學習Open vSwitch背景,或者緣由吧。
今天我不打算進行原始碼分析,今天主要是想說一下如何移植Open vSwitch。
很多人可能覺得移植Open vSwitch太難了,不知道應該如何移植?的確Open vSwitch這套程式碼太過於龐大,而且耦合度也比較大,要移植的確不容易。下面我把這兩年工作中積累的一點經驗和大家分享一下,如有不好之處,希望各位批評指出。
移植的時候我們需要考慮以下兩個大方向:
1、是簡單移植?還是將軟體做為公司產品的一個元件,即二次開發移植?
2、平臺。首先我們需要確定要移植到平臺,Window、x86、arm、mips、ios等。
I、簡單移植
如果只是簡單的移植,那就非常方便了,只需要將程式碼下載後放到對應平臺下,進行編譯即可。如果是移植到arm、mips平臺下,可能需要進行交叉編譯。公司一般都有交叉環境,我們只需要在configure過程中指定對應的平臺即可,例如:
./configure --build=i386-linux,--host=arm-linux,然後就可以執行make進行交叉編譯了。這些步驟對於大家應該不陌生,這裡不在多說了。
II、二次開發移植
相信很多公司都是基於開源軟體進行二次開發,並且將開源軟體作為公司產品的一個元件或一個服務而存在。那麼接下來的問題就是如何移植到自己產品中呢?移植後的軟體工作是否正常?
下面我們針對這兩個問題並結合Open vSwitch進行簡單剖析。接下來的一些分享內容,都是我提前準備好的,比如說編譯環境、截圖等。說句實在話,搞IT的,有些時候我們必須自己走一遍才可以,所以我私下移植了一下。
一、Open vSwitch框架
我們在移植一個軟體的時候,第一要務就是了解軟體架構,不必十分了解,最起碼能夠知道這個軟體由哪些元件組成。針對Open vSwitch架構圖,如下所示:
此圖是之前一位網友在群裡發出來,我覺得比較經典便儲存起來。通過上圖可知,Open vSwitch分為三層:
1)管理層即:ovs-dpctl、ovs-vsctl、ovs-ofctl、ovsdb-tool。
2)業務邏輯層即:vswitchd、ovsdb。
3)底層服務層即:datapath。
前兩個都是使用者態應用程式,最後一個是核心態應用程式。
我們移植一個軟體的時候有些時候只需要移植一部分,有些時候需要全部移植過去。通過圖1可知,Open vSwitch整個框架耦合度較大,若想單獨移植某一個模組,難度較大。好在大多數基於Open vSwitch進行二次開發都是全部移植。這裡呢,我只介紹一下如何移植vswitchd,起到拋磚引玉的效果。
二、正常編譯
大家都知道linux下面編譯一個軟體是,configure、make、make install。不同之處往往就是configure配置過程。還有一點,像Open vSwitch這樣一個非常成熟的一個軟體,網上有很多教程如何編譯它,因此我們不必花費心思去讀文件說明。對於一個新的軟體,網上可能沒有具體教程,那麼我們只能看官方提供的README檔案了。
我只做過x86平臺上的移植,所以下面介紹均是以x86平臺進行解說
1、檢視INSTALL.RHEL.md
每一個開源軟體都會有有一個README.md檔案,因此我們來看一下README.md檔案。在這個檔案裡面有下面這樣一句話,即Open vSwitch所支援的平臺以及對應平臺安裝說明。我的linux是Centos6.7即RedHad系列。
通過讀INSTALL.RHEL.md檔案,有三點需要說明:
1)Open vSwitch安裝方式預設是rpm包方式,對於我們移植來說顯然是不可取的。
2)安裝Open vSwitch必備條件,所以我們必須安裝這些軟體,才能保證編譯順利
3)通過閱讀說明檔案,能夠大致知道編譯順序,但是在第三步make dist需要修改成make。因為make dist命令編譯並打包即生成rpm。
2、檢視configure配置說明
通過檢視說明檔案,我們能夠清楚的知道編譯方式,但是為了能夠順利移植我們還需要檢視一下configure配置。
通過configure --help,可能會打印出很多內容,但是我們關心只有兩項Optional Features、Optional Packages。具體內容如下圖示:
上面內容都是一些特性選項,各個公司可能要求不一樣,可以根據公司要求開啟某些選項,在這裡不進行詳細介紹。這裡想說一下dpdk。如果我們想讓Open vSwitch支援dpdk,我們必須指定—with-dpdk即configure –with-dpdk=/usr/ pathxx/dpdk,這樣生成的makefile將會支援dpdk編譯。
3、執行編譯步驟(在編譯過程中可能會出現各種錯誤,也可能不會有錯,取決於你自己機器中是否安裝Open vSwitch所依賴的庫)
本想把一些錯誤記錄下來,拿出來和大家分享一下,可是在我編譯過程中比較走運,沒有任何錯誤!!
我們按照上面說的進行編譯,下面編譯過程都是我自己私下編譯過程的:
首先下載原始碼:
預設下載程式碼,git分支是master分支,master分支是主線分支,不是很穩定,因此我們進行分支切換,切換到
branch-2.5是釋出分支,是穩定分支。 一般公司都是基於釋出分支進行開發。
此處為了加速編譯,我指定了多執行緒編譯:make –j32
我這裡編譯的非常順利,沒有任何錯誤,這樣對於移植一個軟體來說,無疑是件好事。下面為了方便移植,我們需要重新編譯一次而且把編譯過程重定向到一個檔案中。如下命令列:
Shell
1 2 | make clean make > build .out .txt 2 > & 1 |
4、檢視編譯過程build.out.txt
檢視編譯過程主要是為了確定,可執行程式連結哪些庫檔案,這樣在移植到我們自己產品中也需要連結對應的庫。如下圖所示:
通過連結過程可以清楚知道,某個程式需要哪些檔案,我們只需要把這些檔案移植到我們產品中就行了。
三、移植vswitchd模組
今天介紹一下我是如何進行vswtichd移植的。通過上面連結過程,vswitchd在連結過程會連結下面這些庫以及.o檔案:
下面是臨時檔案.o:
1 2 | vswitchd / bridge .o vswitchd / ovs - vswitchd .o vswitchd / system - stats .o vswitchd / xenserver .o |
下面是Open vSwitch自帶的靜態庫檔案:
Shell
1 2 3 | ofproto / .libs / libofproto .a lib / .libs / libsflow .a lib / .libs / libOpen vSwitch .a |
下面是系統庫:
Shell1 | - lssl - lcrypto - lcap - ng - lrt – lm |
以上檔案就是vswitchd所需要的檔案,然而上面那些靜態庫檔案我們是不知道由哪些原始檔組成?那好我們可以再看一下編譯過程,查詢一下這些靜態庫由哪些檔案組成。
如下圖所示:
以上所有檔案,就是我們需要的原始檔,將這些原始檔移植到自己平臺中即可。當然只單純的移植原始檔是無法編譯通過,還需要移植對應的標頭檔案,這些工作都是體力活,沒有什麼技巧。
如果有人需要移植ovsdb-server也可以參考上面過程,過程相似。
四、編譯引數
假設我們移植完所有原始檔和標頭檔案,接下來就需要編寫makefile。如果不熟悉makefile語法的同學,若想移植一個軟體估計是十分痛苦的。好在的是,公司有相應的編譯框架,我們完全可以依靠現有資源。這裡不想說makefile,而是說一下如何設定編譯引數。編譯引數對於編譯出來的可執行程式,起著至關重要的作用,甚至影響移植後軟體功能的準確性。那麼我們如何做到編譯引數正確性?其實很簡單,還是檢視編譯過程。下面我擷取一下編譯過程: