一、ovs-vswitchd 介绍
在 OVS 的总体架构 中提到过,ovs-vswitchd 是 OVS 运行在用户空间的守护进程,主要负责实现 OVS 的核心功能和逻辑,代码存放在 ovs-main/vswitchd/ 目录下,主要和 ovsdb 相关模块和 Datapath 模块进行通信。
二、ovs-vswitchd 代码实现
ovs-vswitchd 的主程序入口为 ovs-main/vswitchd/ovs-vswitchd.c 文件,以下代码为 ovs-vswitchd.c 的 main 函数主要部分:(此处为了节约空间,对代码做了省略和细微调整)
(1)初始化和进程启动
int main(int argc, char *argv[]) {
struct unixctl_server *unixctl;
......
set_program_name(argv[0]);
ovsthread_id_init();
dns_resolve_init(true);
ovs_cmdl_proctitle_init(argc, argv);
service_start(&argc, &argv);
remote = parse_options(argc, argv, &unixctl_path);
fatal_ignore_sigpipe();
daemonize_start(true, hw_rawio_access);
......
retval = unixctl_server_create(unixctl_path, &unixctl);
unixctl_command_register("exit", "[--cleanup]", 0, 1,
ovs_vswitchd_exit, NULL);
......
}
上述代码主要功能如下:
- 初始化程序名称、线程ID、DNS解析器和命令行参数处理等内容
- 设置进程为后台守护进程,并尝试锁定进程使用的内存页面
- 创建 Unix domain socket 服务器,用于处理外部的控制命令,如关闭程序等
由此可见 ovs-vswitchd 进程主要是通过 socket 实现远程控制的(被别人控制)。
(2)进程运行主循环
int main(int argc, char *argv[]) {
......
bridge_init(remote);
free(remote);
while (!exit_args.exiting) {
OVS_USDT_PROBE(main, run_start);
memory_run();
......
bridge_run();
unixctl_server_run(unixctl);
netdev_run();
memory_wait();
bridge_wait();
unixctl_server_wait(unixctl);
netdev_wait();
......
poll_block();
......
}
bridge_exit(exit_args.cleanup);
......
}
上述部分代码主要功能如下:
- 初始化网桥模块,并进入主循环
- 在主循环中主要执行以下内容:
- 运行内存管理任务
- 执行网桥处理逻辑
- 处理 Unix domain socket 服务器上的请求
- 处理网络设备的运行和等待
- 当收到退出信号时,进行网桥退出处理任务
本部分内容涉及交换机的核心功能逻辑实现
(3)进程结束和资源回收
int main(int argc, char *argv[]) {
......
for (size_t i = 0; i < exit_args.n_conns; i++) {
unixctl_command_reply(exit_args.conns[i], NULL);
}
free(exit_args.conns);
unixctl_server_destroy(unixctl);
service_stop();
vlog_disable_async();
ovsrcu_exit();
dns_resolve_destroy();
return 0;
}
上述部分代码主要功能如下:
- 回复所有未完成的 Unix domain socket 请求
- 销毁之前创建的相关资源
结语:
由于本人水平有限,以上内容如有不足之处欢迎大家指正(评论区/私信均可)。
参考资料:
Open vSwitch 源码阅读笔记(1) OVS 的总体架构-优快云博客