模块和数据节点的树结构
sysrepo对yang文件节点数据及模块的解析是一个有层次的关系结构:
- 顶级节点没有parent=NULL, 兄弟节点的parent是相同的。
- 兄弟节点间是一个特殊的双向链表。第一个节点的
prev指向最后一个节点,next指向下一个节点。如图所示,最后一个兄弟节点的next为NULL。如果只有一个节点,那么prev指向自身, next=NULL - 父节点的
child指向第一个子节点。 - 每个节点有对应的节点类型,根据节点类型有对应的
value。
模块管理
所有安装的模块由一个名为sysrepo的模块管理。这个模块的定义在https://github.com/sysrepo/sysrepo/blob/master/modules/sysrepo.yang文件中。
里面会记录哪些模块已经安装了,哪些模块待安装。module列表表示已经安装过的模块,存放模块的名称、版本、特性列表。每个安装的模块的依赖和反向依赖的模块列表,还可以存放这个模块是否将被移动或者被更新, 使能的特性列表等。新安装的模块在installed-module里面, 等待sysrepo没有连接的时候进行安装,从yang文件中解析出各种属性,添加为module列表的一个项。 已安装的yang文件默认会被存放到/etc/sysrepo/yang目录下,这个目录可以在编译的之前在CMakeList.txt文件中设置。
数据内容存储
所有相关的数据结构被存放在两个共享内存文件中, 分别是 sr_main和 sr_ext。
sr_main
sr_main文件里面前面是sr_main_shm_t, 后面保存的是所有模块的信息sr_mod_t.
typedef struct {
uint32_t shm_ver; /**< Main and ext SHM version of all expected data stored in them. Is increased with
every change of their structure content (ABI change). */
pthread_mutex_t lydmods_lock; /**< Process-shared lock for accessing sysrepo module data. */
pthread_mutex_t ext_lock; /**< Process-shared lock for accessing holes and truncating ext SHM. */
uint32_t mod_count; /**< Number of installed modules stored after this structure. */
ATOMIC_T new_sr_cid; /**< Connection ID for a new connection. */
ATOMIC_T new_sr_sid; /**< SID for a new session. */
ATOMIC_T new_sub_id; /**< Subscription ID of a new subscription. */
ATOMIC_T new_evpipe_num; /**< Event pipe number for a new subscription. */
} sr_main_shm_t;
typedef struct {
struct sr_mod_lock_s {
sr_rwlock_t lock; /**< Process-shared lock for accessing module instance data and DS lock information. */
uint32_t ds_lock_sid; /**< SID of the module data datastore lock (NETCONF lock), the data can be modified only
by this session. If 0, the DS lock is not held. */
struct timespec ds_lock_ts; /**< Timestamp of the datastore lock. */
} data_lock_info[SR_DS_COUNT]; /**< Module data lock information for each datastore. */
sr_rwlock_t replay_lock; /**< Process-shared lock for accessing stored notifications for replay. */
uint32_t ver; /**< Module data version (non-zero). */
off_t name; /**< Module name (offset in main SHM). */
char rev[11]; /**< Module revision. */
ATOMIC_T replay_supp; /**< Whether module supports replay. */
off_t features; /**< Array of enabled features (off_t *) (offset in main SHM). */
uint16_t feat_count; /**< Number of enabled features. */
off_t rpcs; /**< Array of RPCs/actions of the module (offset in main SHM). */
uint16_t rpc_count; /**< Number of RPCs/actions. */
off_t notifs; /**< Array of notifications of the module (offset in main SHM). */
uint16_t notif_count; /**< Number of notifications. */
off_t deps; /**< Array of module data dependencies (offset in main SHM). */
uint16_t dep_count; /**< Number of module data dependencies. */
off_t inv_deps; /**< Array of inverse module data dependencies (off_t *) (offset in main SHM). */
uint16_t inv_dep_count; /**< Number of inverse module data dependencies. */
struct {
sr_rwlock_t lock; /**< Process-shared lock for reading or preventing changes (READ) or modifying (WRITE)
change subscriptions. */
off_t subs; /**< Array of change subscriptions (offset in ext SHM). */
uint32_t sub_count; /**< Number of change subscriptions. */
} change_sub[SR_DS_COUNT]; /**< Change subscriptions for each datastore. */
sr_rwlock_t oper_lock; /**< Process-shared lock for reading or preventing changes (READ) or modifying (WRITE)
operational subscriptions. */
off_t oper_subs; /**< Array of operational subscriptions (offset in ext SHM). */
uint32_t oper_sub_count; /**< Number of operational subscriptions. */
sr_rwlock_t notif_lock; /**< Process-shared lock for reading or preventing changes (READ) or modifying (WRITE)
notification subscriptions. */
off_t notif_subs; /**< Array of notification subscriptions (offset in ext SHM). */
uint32_t notif_sub_count; /**< Number of notification subscriptions. */
} sr_mod_t;
在sr_mod_t里面保存的都是各个数据在sr_ext里面对应的偏移, 具体的数据存在sr_ext里面。
sr_ext
sr_ext的头部是sr_ext_shm_t, 后面存的是一个个结构sr_ext_hole_t, 指向了各个模块的内存偏移。
/**
* @brief Ext SHM structure.
*/
typedef struct {
uint32_t first_hole_off; /**< Offset of the first memory hole, 0 if there is none. */
} sr_ext_shm_t;
/**
* @brief Ext SHM memory hole.
*/
typedef struct {
uint32_t size;
uint32_t next_hole_off;
} sr_ext_hole_t;
还有具体的数据也是存放在共享内存文件中, 不同模块的数据存放在不同的文件中, sr_modulename.datatype。
订阅的信息存放在sr_sub_xxxx等文件里。
后面再详细描述。
行动,才不会被动!
欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。