sonic cli application

内容分享10小时前发布
0 0 0

1. 基本流程

这个的主要流程比较简单,直接通过代码来看。

config acl add table
的命令处理入口:
sonic cli application

基于上述代码分析cli命令与redis数据库的交互过程实际上就只有两个步骤:
sonic cli application

命令行输入
config acl add ...
命令,处理入口位于
src/sonic-utilities/config/main.py:table()
:

解析命令行参数连接config_db数据库,向config_db的acl_table表中写入数据,索引为:ACL_TABLE|table_name – 这个过程不会对参数信息做任何检查与验证

创建的ACL_TABLE表在CONFIG_DB中,表信息如下:
sonic cli application

在ACL_TABLE表中只有四个字段:type、policy_desc、ports、stage

1.2 函数调用

下图是从
src/sonic-utilities/config/main.py:table()
开始的函数调用,调用过程比较长,下面只分析一些主要部分
sonic cli application

2. 命令解析

sonic cli application

解析从命令获取的参数,并且构建成字典格式:

table_type不做任何检查,直接写入字典description只做判空检查,默认为table_nameports只做判空检查,默认为所有的ports – 从config_db的port表中获取所有portsstage只做判空检查,默认为ingress最终字典形式为:

table_info{"type":"","policy_desc":"","ports":"","stage":""}

table_name: 必要的参数table_type: 必要的参数description: 可选参数,为空则默认为table_nameports: 可选参数,为空则默认为所有的端口stage: 可选参数,为空则默认为入口流量ingress

3. 数据库操作–CONFIG_DB

sonic cli application

如上所述,就是三个步骤:初始化数据库连接对象–>连接数据库–>写入数据库。

3.1 初始化数据库连接对象

3.1.1 对象初始化流程

ConfigDBConnector类是使用python编写的。看一下它的类图:
sonic cli application

ConfigDBConnector: CONFIG_DB数据库操作的抽象SonicV2ConnectorConfigDBConnector_Native:CONFIG_DB数据库操作的实际执行函数SonicV2Connector_Native

按照python的菱形继承依次调用父类初始化方法,为对象设置数据库基本信息。其中有一个获取当前数据库列表的操作,从
database_config.json
文件中获取初始化的数据库信息,并以属性的方式(set_attr)存入当前创建的连接对象中。
sonic cli application

3.1.2 获取数据库列表操作

sonic cli application


database_config.json
文件中获取信息。文件位置(sonic系统上):
/var/run/redis/sonic-database/
,文件信息如下:
sonic cli application

初始化SonicDBConfig对象
sonic cli applicationsonic cli application

验证namespace
验证当前namespace是否在配置文件中:

在单个asic芯片环境中,namespace默认为’’在多个asic芯片环境中才会存在多个namespace
返回对象
格式形如:
["APPL_DB","CONFIG_DB","ASIC_DB"...]

3.2 连接CONFIG_DB

sonic cli application

根据python菱形继承,最终连接过程定位到
ConfigDBConnector_Native::db_connect()
,连接步骤:

获取
CONFIG_DB
的分隔符

调用
hiredis
库与
redis
进行连接:使用
socket
文件;或者使用
host

port

dbname
信息 – 得到
DBConnector
对象,是一个提供所有
redis
命令操作的接口

配置
CONIFG_DB
库的键空间通知模式,默认为
"KEA"
,会发布所有支持的通知
sonic cli application


CONFIG_DB
中获取初始化指示值 – 怎么算初始化完成了,在哪里写入的这个值?
sonic cli application

如果已经初始化了,则结束

否则死循环并且设置超时阻塞监听这个值变化,直到这个值显示初始化完成,并取消事件订阅

订阅事件:
__keyspace@4__:CONFIG_DB_INITIALIZED
– 模式订阅开启循环监听匹配该模式的所有通知得到一个对应通知,查询
CONFIG_DB

CONFIG_DB_INITIALIZED
的值,判断是否初始化如果已经初始化,那么退出循环,取消该订阅事件;否则继续第iii步进行监听

3.2.1 connect

该流程对应连接过程第2步,具体代码对应到
DBInterface::_onetime_connect()
方法,得到一个新的DBConnector对象:
sonic cli application

DBConnector: 一个连接redis的数据库对象,提供对数据库所有操作的接口,如HGET/HGETALL/PUBSCRIBE/DEL等。RedisContext: 调用hiredis库的redisConnect()方法连接数据库,保存redisContext对象,存储的是连接信息

sonic cli application

得到数据库index以及分隔符信息初始化redisContext: 调用hiredis库的redisConnect()方法连接对应数据库,返回的是redisContext对象,redisContext是hiredis库中的一个结构体,保存的是连接信息,比较重要的成员变量是连接的fd选择数据库:执行
select index
命令 – 一个基本的命令写入过程
初始化RedisReply对象,构造函数: 调用redisAppendCommand()向redis发送命令,redisCommand是hiredis库中的一个执行redis命令的方法;调用getRedisReply()方法得到响应结果检查上个步骤命令执行结果 – 不会反馈到命令界面

3.2.2 订阅流程

该流程对应连接过程的第5步的订阅流程。 – 这是比较直接的订阅,也可以说是一次性订阅流程,得到结果就取消订阅。
sonic cli application

根据当前连接创建一个PubSub对象,主要是得到连接的fd;初始化Select对象,创建一个epoll_fd – Select对象的初始化暂时没找到在哪里,应该是一个全局共享变量
sonic cli application

PubSub: 扩充订阅、取消订阅、读取消息通知等操作,添加订阅对象的管理,如添加、删除等RedisSelect: 实现Selectable中的方法,并且提供订阅、取消订阅、读取消息通知等操作Selectable: 一个接口类,保存且操作events,比如是否有events、读取events等

判断是否已订阅当前fd,如果已经订阅:

从Select对象的订阅对象列表中移除从Select对象的待处理列表中移除从epoll红黑树中移除

向redis订阅事件通知:

根据当前连接创建一个新的连接,得到一个新的fd,专门用于接收订阅的事件通知使用当前连接向redis发布订阅命令

将当前处理订阅事件通知的socket加入监控列表等待处理

将新的fd加入Select对象进行监听将fd添加到epoll红黑树

3.2.3 监听流程

该流程对应连接过程的第5步的监听流程。 – 这是比较直接的监听,也可以说是一次性监听,和上面的订阅配合使用,得到结果就不再处理事件。
sonic cli application

for循环获取监听事件 – 这一步是具体的监听过程,后面会再详细的叙述,主要与Select类相关判断事件通知是否是模式订阅信息,如果是,则继续,否则回到第1步判断通知中的key是否是当前订阅的信息,如果是,则继续,否则回到第1步从config_db中获取对应属性:
GET CONFIG_DB_INITIALIZED
通过该value判断是否已经初始化完成,如果是则结束,否则回到第1步

3.3 写入CONFIG_DB

sonic cli application

根据python菱形继承,最终连接过程定位到
ConfigDBConnector_Native::set_entry()
,步骤如下:

构建hash值:
ACL_TABLE|table_name
从命令行解析的表信息是否为空,为空则执行删除操作,
DEL hash
,结束;不为空则继续从redis中获取hash对应的数据:
HGETALL hash
创建或者覆盖hash对应的数据:
HMSET hash ....
如果hash值原来就在redis数据库中,那么比较原来表字段信息与新的表字段信息:如果字段只存在于原来的表中,那么删除该字段,
HDEL hash field

© 版权声明

相关文章

暂无评论

none
暂无评论...