Vhost-user
使用Unix Domain Socket(UDS)
作为控制平面的通讯方式,所以通讯实现比较简单。在backend
这一侧,可以有多种选择,既可以作为Server
来等待虚机连接,也可以作为Client
来主动连接虚机。
作为Server
,可以选择监听一个或者是多个UDS
。在dpdk vhost-user
模块感知到虚机的主动连接的时候,就会回调注册过的设备发现函数。我们在该函数里,能获得虚机的设备ID,但是无法获取其它任何有效信息。
这也给SDN
的设计带来了难度,虚机虽然连接上来,但是我们无法知道虚机的基本信息,如MAC
信息等。假设按照监听一个UDS
的方案,那么必须得模拟交换机的方案,主动学习虚机的MAC
地址,然而SDN
内常常有多个虚拟交换机对应多个网段,故在广播的时候,很有可能造成不同网段的设备都获得广播信息,这是不符合实际网络的运行规律的。
我们进一步,使用多个UDS
,每个对应一个虚拟网段。这样就解决了上述的问题,在广播的时候,可以广播给对应网段的机器。但是我们还是需要主动学习虚机的MAC,并且设计一个未知设备列表,逻辑还是相对复杂的。
最简单的方案,就是对于每一个虚机都生成一个监听的UDS
,当虚机连接上来的时候,我们直接获取ifname
,就可以获取对应的socket path
,而这个path
可以保存一些虚机信息,如MAC
等,这样我们就能在虚机连接上来之后就获取虚机的信息了。
这个方案最主要的一点是,虚机必须有断线重连的功能,不然当虚拟交换机重启的时候,会造成虚机的网络故障。理论上qemu
的版本大于2.7即可支持,但是实际测试中没有重连,具体还需后续继续研究。
其实上述的方案,退化了多个UDS
监听,其实更像Client
方案。在Client
方案中,我们的虚拟交换机会主动地连接虚机,每个虚机都会预设一个UDS
,这样当连接成功的时候,我们就能知道该虚机的信息。这个方案不依赖qemu
的断线重连功能,该功能实现与虚拟交换机中。
其实上述两种方案都可行,作为开发者来说,虚拟交换机其实更像一个服务端,更偏向于它监听UDS
作为Server
的方案,但是这依赖qemu
的断线重连。假设依赖该方案,必须保证qemu
的断线重连生效,否则Client
的方案更稳妥一点,因为dpdk vhost-user
模块内已内置了断线重连功能。