sysrepo 开发者指南(一个基于libyang与支持rpc的数据库)

sysrepo 开发者指南(一个基于libyang与支持rpc的数据库)

日志记录

默认情况下,所有 Sysrepo 日志记录都处于关闭状态。如果启用,日志消息有 3 种输出。它们可以写入stderr、由 处理syslog或简单地传递给回调。

请务必注意,启用 Sysrepo 日志记录也会修改libyang日志记录设置。错误消息被视为标准 Sysrepo 错误,其他严重性较低的消息完全隐藏。要更改此行为,只需在启用 Sysrepo 日志记录后调整libyang日志记录设置。

此外,几乎每个 Sysrepo API 函数都会返回一个错误代码,如果需要,可以将其转换为字符串。

连接和会话

要开始使用 Sysrepo,必须先创建一个连接。通常,一个应用程序(进程)应该只创建一个连接,因为尽管允许创建多个连接,但没有理由创建多个连接,并且 Sysrepo 在这两种情况下都可以正常工作。Connection 存储主要共享内存映射和相应的libyang 上下文等。此上下文也可用于应用程序以了解 Sysrepo 模式或在处理数据以节省一些资源时使用,但永远不能修改!

然后,可以创建任意数量的会话。最重要的是,需要考虑线程模型。除此之外,Sysrepo 没有固有的限制,并且因为每个会话只需要很少的资源,所以拥有很多资源不会造成任何问题。

每个会话始终选择一个可以随时更改的数据存储。使用此会话的所有 API 调用都将在此数据存储上运行。如果会话与正在运行的数据存储区配合使用,并且在用于创建此会话的连接上启用了缓存,则不会每次都从 Sysrepo 加载数据,而是从缓存中复制数据。这可以显着提高性能或某些操作,并且建议始终使用缓存,除非应用程序对保持较小的内存占用有严格要求。

每次以 session 为参数的 API 调用后,都会更新 session 中的错误,如果没有错误发生,则将其清除。除了标准日志记录之外,这些错误还可以以任何所需的方式打印以推迟输出,例如。

此外,每个会话在所有 Sysrepo 会话中都有一个唯一的 ID。当操作因另一个会话(例如锁定的模块)而失败时,这很有用。此外,可以了解哪个会话发起了正在订阅回调中处理的事件。在这种情况下,如果发起方应用程序将其存储到 Sysrepo 会话中,甚至还有关于 NETCONF 会话的信息(其 ID)。

接下来,会话用户可以更改为系统上的任意用户。这对于仅用作 Sysrepo 的(远程)接口的应用程序很有用。但是,由于这允许完全绕过访问控制,因此只root允许这样做。

最后,当关闭连接时,在此连接上进行的所有会话和订阅也会自动释放。

模式

在可以处理任何数据之前,需要将 YANG 模式(模块)安装到 Sysrepo 中。但是,这种 YANG 模块更改不会立即执行。如果没有其他连接,这些更改(还包括删除、更新模块或更改其功能)仅计划执行并在新 Sysrepo 连接创建期间应用。这种机制的原因是当有一些数据连接到模块上下文时(libyang要求),模块上下文不能更改,并且它们通常甚至在没有执行 Sysrepo 功能时也是如此。这是始终使用所有模式创建上下文的代价,因此不需要临时模式。

如前所述,Sysrepo 允许更新已安装的模块以保留其当前数据。新模式应该遵循标准化的更新规则,但 Sysrepo 只要求模式修订版比以前的模式更新,并且存储的模块数据对新模式有效。这是在实际更新之前检查的。

然后,可以更改每个模块重放支持和权限(更多在访问控制中)。这必须始终单独执行,因为在安装期间无法设置这些属性并且使用默认值。

最后,可以从 Sysrepo 检索模块信息数据。其中包括特定于 Sysrepo 的每个模块的一些附加信息。但是,大多数信息都可以在libyang调用返回的数据树中找到,ly_ctx_info()这些信息应该用于从 Sysrepo 连接检索的上下文。

获取数据

从 Sysrepo 检索数据既简单又灵活。选择是使用XPath 1.0语言指定的。接受的表达式仅受libyang实现的限制,这意味着几乎所有内容都受支持。

读取数据时,在使用的会话中选择正确的数据存储非常重要。请注意,这些函数的每次调用最多只能返回一份缓存数据的副本(连接中提到的缓存),或者它可以从一个或多个需要为操作数据存储提供它们的应用程序请求一些子树。

最后,请注意所有数据都会被会话中准备好的更改(如果有)修改。

编辑数据

可以编辑所有数据存储、启动、运行、候选和操作。任何更改首先仅针对特定会话,并且不会对其他会话进行验证、持久化或可见。这些准备好的更改可以使用当前数据存储内容进行验证、丢弃或应用,这还将调用任何相关回调并使它们对所有会话可见。

未提交的更改以 NETCONF ( RFC )编辑配置内容的形式存储。也可以直接提供,而不是一一执行更改。

请注意,操作数据存储的更改以一种特殊的方式运行(更多在操作数据中)。

最后,可以简单地替换整个数据存储(仅常规数据存储,除SR_DS_OPERATIONAL之外的所有数据存储)或仅使用数据树替换特定模块数据。或者源配置也可能分别来自另一个数据存储或模块数据。

锁定

Sysrepo 支持显式锁定单独的模块或整个数据存储。以这种方式请求对数据的独占访问。这些数据存储锁与更改数据时隐式需要的写锁是互斥的。

订阅

每次*_subscribe()调用都会返回一个订阅结构。可以使用现有订阅进行订阅,然后单个订阅将处理多个事件。默认情况下,有一个专用线程来处理订阅结构中的所有事件,因此不需要进一步的操作。

如果不需要,可以在没有单独线程的情况下处理订阅事件。订阅时,需要使用标志SR_SUBSCR_NO_THREAD,这样线程就不会被创建。请注意,如果您使用它,则订阅存在并且事件可能会发生,但它们不会被处理,因此它们可能会超时,例如,除非手动处理。这可以通过处理订阅上所有挂起事件的函数来实现。sr_process_events()可以定期调用,也可以仅在有实际事件时调用。这可以通过准备好读取的订阅事件管道来学习。

要安全地销毁由自定义循环管理的订阅,需要执行特定步骤。首先,应该调用sr_unsubscribe_sub() with sub_id 0,然后事件循环应该停止处理订阅上的事件,最后可以调用sr_unsubscribe()。这可以防止在有待处理事件但由于订阅被释放而未处理时发生数据争用。

更改订阅

这些是最常见的订阅类型。可以将回调设置为在发生特定数据更改时调用,以便它可以适当地做出反应并调整系统或相应管理的任何内容。同一数据可以有多个订阅者,并且可以应用任意 XPath 过滤器。

可以订阅任何数据存储(启动、运行和操作)。数据存储由订阅时的当前数据存储决定(即调用sr_module_change_subscribe())。之后更改活动数据存储不会影响已经进行的订阅。例如,可以订阅正在运行的数据存储,切换到启动数据存储,订阅它,然后切换回编辑正在运行的数据存储,所有这些都使用一个会话和一个订阅上下文。

发生变化时,回调将通过事件调用。默认情况下,总是有 2 个事件一个接一个。在更改时,新的数据存储内容已准备好但尚未写入,因此可以出于任何原因拒绝更改。如果不是,则提交更改,因此对于任何后续操作都是可见的。在生成完成事件并调用回调之后。无法再还原更改。如果在更改事件期间至少有一个回调失败,则整个提交将中止。已经成功处理更改事件的回调将使用abort事件调用,以便它们可以恢复它们并保持 Sysrepo 和系统一致。

有一个特殊的事件更新,它只为请求它的订阅生成。此事件发生在前面提到的任何其他事件之前,因为它允许进一步修改正在处理的数据更改。此事件的回调可能会失败并导致更改被立即拒绝。

此外,订阅可以在SR_DS_RUNNING数据存储上请求启用事件,并在订阅时获取当前配置。这个事件通常跟在done事件之后,就像change事件一样。但是,即使当前配置为空,也会生成启用事件(因此回调中不会有任何更改)!

订阅操作数据存储更改时,只会确认推送更改并调用回调。拉订阅被忽略。

在事件update和change 上,回调可以返回一个特殊的SR_ERR_CALLBACK_SHELVE值。这会导致事件不被处理而被简单地跳过(搁置)。当下一次订阅上的所有事件都被处理时,再次调用这个具有相同事件的订阅回调。这个特殊的返回值可以多次返回,但要注意不要超时!通常,整个机制仅在事件由应用程序处理时使用,而不是由 Sysrepo 线程 ( SR_SUBSCR_NO_THREAD ) 处理。否则应用程序无法完全控制调用事件处理函数sr_process_events() (严格来说,即使 Sysrepo 线程正在处理此订阅,也可以直接调用它,但可能没有用例)。

对于这些事件中的每一个,都使用迭代器检索更改,该迭代器可以创建多次,并且可以选择仅使用选定的更改。

了解订阅运行数据对操作数据存储的影响很重要。

RPC/动作订阅

所有函数均可用于 RPC 和操作。如果没有匹配的订阅,则 RPC/action 甚至无法发送。回调按预期工作,在rpc事件中,它们每个都提供输入,并且可以失败或成功,并可选择生成一些发送回原始发件人的输出。订阅 XPath 上可以有谓词过滤仅特定的 RPC/操作实例。

如果有多个订阅匹配单个 RPC/操作,则只能有一个具有特定优先级的订阅。这个最低优先级(主)订阅将是为发送者生成输出的一个(之前的输出将被覆盖),此外,永远不会收到中止事件(如果它失败,只有所有其他更高优先级的回调将被中止) .

RPC 订阅还可以在rpc事件上返回SR_ERR_CALLBACK_SHELVE。

RPC/Action 订阅 API

通知订阅

允许发送和接收通知的特定订阅支持通知。如果特定模块以这种方式配置(在schemas 中提到),发送的通知也会被存储以备将来重播。

订阅通知时,可以指定多个选项,这些选项遵循NETCONF 通知 RFC 中的定义。通常,所有通知都是实时的。如果请求重播,这些是重播通知。如果重播完成并且订阅更改为标准订阅,则会发送重播完成通知。最后,一旦订阅因到达停止时间而应终止,则在删除订阅之前收到停止。

运营订阅

操作订阅允许提供客户端请求的数据。通常,这些可用于读取设备的当前状态,例如,然后将它们作为状态数据节点返回。但是,它们也可用于提供配置数据节点。在这种情况下,它们应仅返回受管设备实际使用的配置。更多细节和解释可以在NMDA RFC 中找到。

使用这些拉取操作数据订阅时,每当请求模块的操作数据存储数据时,订阅必须主动处理事件(因此这 2 个操作不能在单个线程中发生,因此它们必须具有单独的订阅结构)以避免超时。请注意,不仅在使用 getter 显式请求时,而且在验证操作数据存储(所有模块或同一模块)、设置推送操作数据(针对同一模块)或发送 RPC/操作或通知时,都需要操作数据存储数据(如果需要特定的模块数据进行验证)。

除非需要其数据,否则不会调用操作回调,因此请记住以下规则:

如果所提供数据的父级在操作数据存储中不存在,其后代也不存在,请参阅操作数据以了解有关数据存在的详细信息;

示例:如果您订阅了提供/mod:config-container/config-list/state-leaf,您的回调将被调用为每个现有实例/mod:config-container/config-list,如果没有,则根本不会调用。

如果存在嵌套订阅,则最后调用较深的订阅,以便可以创建其父订阅;

示例:如果您订阅了/mod:config-container/config-listand /mod:config-container/config-list/state-leaf,则前者的回调将在后者之前被调用,因此无论在第一次调用中创建了什么列表实例,只有那些才会检索叶值。

如果使用的过滤器不选择回调提供的数据,则通常不会调用此回调。此冗余检查仅以文本方式执行,因此永远不会涵盖所有情况。

示例:如果您订阅/mod:config-container/config-list[key=“val”]然后/mod:config-container/state-list/*被请求,您的回调将不会被调用。当被请求时也不会被调用/mod:config-container/config-list[key=“val2”]。但是,如果

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>