SDNLAB技术分享(五):浅谈Open vSwitch移植

------------------------------------------
分享嘉宾

徐小冰,2012年毕业于一个三流学校,专业是计算机科学,在校期间学习过web技术、window编程、工作后一直基于linux开发。现在就职于一个普通小公司,有幸加入社区,结交各位大牛。感谢大家在百忙之中能够在这里参加我的分享,谢谢大家。

-------------------------------------
好了我们开始今天的主题吧!!


前一段时间自己私下一直学习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架构图,如下所示:
SDNLAB技术分享(五):浅谈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系列。
SDNLAB技术分享(五):浅谈Open vSwitch移植

通过读INSTALL.RHEL.md文件,有三点需要说明:

1)Open vSwitch安装方式默认是rpm包方式,对于我们移植来说显然是不可取的。

2)安装Open vSwitch必备条件,所以我们必须安装这些软件,才能保证编译顺利
SDNLAB技术分享(五):浅谈Open vSwitch移植3)通过阅读说明文件,能够大致知道编译顺序,但是在第三步make dist需要修改成make。因为make dist命令编译并打包即生成rpm。
SDNLAB技术分享(五):浅谈Open vSwitch移植

2、查看configure配置说明

通过查看说明文件,我们能够清楚的知道编译方式,但是为了能够顺利移植我们还需要查看一下configure配置。

通过configure --help,可能会打印出很多内容,但是我们关心只有两项Optional Features、Optional Packages。具体内容如下图示:

SDNLAB技术分享(五):浅谈Open vSwitch移植
SDNLAB技术分享(五):浅谈Open vSwitch移植

上面内容都是一些特性选项,各个公司可能要求不一样,可以根据公司要求打开某些选项,在这里不进行详细介绍。这里想说一下dpdk。如果我们想让Open vSwitch支持dpdk,我们必须指定—with-dpdk即configure –with-dpdk=/usr/ pathxx/dpdk,这样生成的makefile将会支持dpdk编译。


3、执行编译步骤(在编译过程中可能会出现各种错误,也可能不会有错,取决于你自己机器中是否安装Open vSwitch所依赖的库)


本想把一些错误记录下来,拿出来和大家分享一下,可是在我编译过程中比较走运,没有任何错误!!


我们按照上面说的进行编译,下面编译过程都是我自己私下编译过程的:

首先下载源码:

SDNLAB技术分享(五):浅谈Open vSwitch移植默认下载代码,git分支是master分支,master分支是主线分支,不是很稳定,因此我们进行分支切换,切换到
SDNLAB技术分享(五):浅谈Open vSwitch移植branch-2.5是发布分支,是稳定分支。 一般公司都是基于发布分支进行开发。
SDNLAB技术分享(五):浅谈Open vSwitch移植
SDNLAB技术分享(五):浅谈Open vSwitch移植
SDNLAB技术分享(五):浅谈Open vSwitch移植
此处为了加速编译,我指定了多线程编译:make –j32
SDNLAB技术分享(五):浅谈Open vSwitch移植
SDNLAB技术分享(五):浅谈Open vSwitch移植
我这里编译的非常顺利,没有任何错误,这样对于移植一个软件来说,无疑是件好事。下面为了方便移植,我们需要重新编译一次而且把编译过程重定向到一个文件中。如下命令行:

SDNLAB技术分享(五):浅谈Open vSwitch移植

4、查看编译过程build.out.txt


查看编译过程主要是为了确定,可执行程序链接哪些库文件,这样在移植到我们自己产品中也需要链接对应的库。如下图所示:

SDNLAB技术分享(五):浅谈Open vSwitch移植

通过链接过程可以清楚知道,某个程序需要哪些文件,我们只需要把这些文件移植到我们产品中就行了。


三、移植vswitchd模块

今天介绍一下我是如何进行vswtichd移植的。通过上面链接过程,vswitchd在链接过程会链接下面这些库以及.o文件:

下面是临时文件.o:
SDNLAB技术分享(五):浅谈Open vSwitch移植
下面是Open vSwitch自带的静态库文件:
SDNLAB技术分享(五):浅谈Open vSwitch移植
下面是系统库:
SDNLAB技术分享(五):浅谈Open vSwitch移植

以上文件就是vswitchd所需要的文件,然而上面那些静态库文件我们是不知道由哪些源文件组成?那好我们可以再看一下编译过程,查找一下这些静态库由哪些文件组成。


如下图所示:
SDNLAB技术分享(五):浅谈Open vSwitch移植
SDNLAB技术分享(五):浅谈Open vSwitch移植
SDNLAB技术分享(五):浅谈Open vSwitch移植

以上所有文件,就是我们需要的源文件,将这些源文件移植到自己平台中即可。当然只单纯的移植源文件是无法编译通过,还需要移植对应的头文件,这些工作都是体力活,没有什么技巧。


如果有人需要移植ovsdb-server也可以参考上面过程,过程相似。


四、编译参数

假设我们移植完所有源文件和头文件,接下来就需要编写makefile。如果不熟悉makefile语法的同学,若想移植一个软件估计是十分痛苦的。好在的是,公司有相应的编译框架,我们完全可以依靠现有资源。这里不想说makefile,而是说一下如何设置编译参数。编译参数对于编译出来的可执行程序,起着至关重要的作用,甚至影响移植后软件功能的准确性。那么我们如何做到编译参数正确性?其实很简单,还是查看编译过程。下面我截取一下编译过程:

SDNLAB技术分享(五):浅谈Open vSwitch移植

五、如何保证移植后的软件功能的正确性?

其实我起这个话题是不好回答的,因为我不知道有哪些技巧能够保证软件的正确性。我这里只是总结一下吧:


1、按照上面流程,如果能够顺利移植并且编译出相应的可执行程序,那么可以保证80%的准确性。

2、如果可执行程序能够顺利运行起来,比如说vswitchd能够运行起来并且能够和控制器正常通信,基本上能够保证软件可靠性为95%。

3、进行日常测试,靠测试进行保证。


好了今天分享就到这里,感谢大家给面!!希望大家移植顺利。


Q&A

Q1:移植过程中好像没有修改OVS源代码,那源码中有没有跟特定平台相关的代码呢?(应该有与linux内核交互的部分吧)

A1:我在学习ovs时候,看到只有windows、linux平台。而linux平台下面只有一个dpdk是intel特定平台相关的,其他并没有


Q2:目前是否有已知的需要修改源代码的地方呢

A2:这个需要与公司特定产品才能进行改造。像我之前修改OpenFlow协议


Q3:假设 我要移植到2.6.x内核 怎么办? 2.6.31之前的一个版本不支持dpdk

A3:那就没有办法 dpdk也是有最低要求,如果这些不能满足是无法使用dpdk功能的


Q4:切换分支时候使用的是 git checkout -b 命令,-b 是否应该不用呢?因为这好像是会新建分支的

A4:git checkout -b 分支名 表示创建分支并且切换到新分支名


Q5:我看到你移植了vswitchd模块,但是OVS偶尔性很高,其会牵扯到和ovsdb-sever之间的交互等多模块,只是移植vswitchd这部分,可以完成ovs一个完整的功能吗?耦合性 

A5:不可以的 vswtichd只是用户态核心程序,内核态核心程序是dataplane。在分享过程中也说了,虽然ovs耦合性很高,但好在很多公司都是全部移植


Q6:文中需要找的源文件比如 ofproto/.libs/ libofproto.a完整路径是/ ofproto/.libs/ libofproto.a吗?

A6SDNLAB技术分享(五):浅谈Open vSwitch移植


Q7:目前基于ovs做开发的很多,一般只是打印输出,但是效率很低,能否介绍一下开发过程中调试的一些经验和工具。

A7:1、能用gdb调试就用gdb。 在我之前博客中有一篇介绍main函数,里面会涉及到gdb调试,你可以参考一下。但是gdb调试多线程的时候 需要特别注意

2、日志。 对于多线程、多进程的ovs,日志特别重要。日志需要把ovs的日志开关打开,里面会有详细日志,其他方面我也不是很清楚。


Q8:请教下,编译时指定dpdk选项后是否意味着ovs与dpdk协同工作,不再需要改动其他地方?另外指定dpdk后比原来效率提高明显嘛? 

A8:开启了dpdk选项,就必须与dpdk结合,因为源码中有些函数是条件编译。dpdk官方号称 使用dpdk性能会有所提升。但是通过我查看相关资料,dpdk配置还是比较麻烦,如果设置不好,反而性能会下降。编译选项这个地方有预编译

SDNLAB技术分享(五):浅谈Open vSwitch移植


Q9:如果想调试比较靠后过程中的一段代码(可能已经不是main函数所在的文件代码),比如说是匹配过程代码等,是否gdb可以直接调试操作?

A9:一样可以的,我调试过的,你按照函数名进行断点调试

 


Q10:gdb调试文档在哪里?

A10:gdb是很高深的内容,你可以先查看一下gdb简单介绍,比如说:如何设置断点、如何查看堆栈等,建议百度。


Q11:这个是我参照你那篇main调试的,不知道为什么总是出现这个问题 

SDNLAB技术分享(五):浅谈Open vSwitch移植A11:SDNLAB技术分享(五):浅谈Open vSwitch移植把ovs-vswitchd 去掉,r参数。


上一篇:构建Apache WEB服务器三部曲之三 虚拟主机


下一篇:23种设计模式之静态代理模式