数据结构-sysrepo笔记(3)

756 阅读1分钟

模块和数据节点的树结构

sysrepoyang文件节点数据及模块的解析是一个有层次的关系结构:

node_tree.jpeg

  • 顶级节点没有parent=NULL, 兄弟节点的parent是相同的。
  • 兄弟节点间是一个特殊的双向链表。第一个节点的prev指向最后一个节点,next指向下一个节点。如图所示,最后一个兄弟节点的nextNULL。如果只有一个节点,那么prev指向自身, next=NULL
  • 父节点的child指向第一个子节点。
  • 每个节点有对应的节点类型,根据节点类型有对应的value

模块管理

所有安装的模块由一个名为sysrepo的模块管理。这个模块的定义在https://github.com/sysrepo/sysrepo/blob/master/modules/sysrepo.yang文件中。

sysrepo.png

里面会记录哪些模块已经安装了,哪些模块待安装。module列表表示已经安装过的模块,存放模块的名称、版本、特性列表。每个安装的模块的依赖和反向依赖的模块列表,还可以存放这个模块是否将被移动或者被更新, 使能的特性列表等。新安装的模块在installed-module里面, 等待sysrepo没有连接的时候进行安装,从yang文件中解析出各种属性,添加为module列表的一个项。 已安装的yang文件默认会被存放到/etc/sysrepo/yang目录下,这个目录可以在编译的之前在CMakeList.txt文件中设置。

数据内容存储

所有相关的数据结构被存放在两个共享内存文件中, 分别是 sr_mainsr_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,沟通交流。