Closed adamzyg closed 3 years ago
versions:
libyang: 1.0.184 libnetconfd: 1.1.26 sysrepo: 1.4.70 netopeer2: 1.1.39
sysrepoctl -l
Sysrepo repository: /home/zyg/netconf/sysrepo/build/repository Module Name | Revision | Flags | Owner | Permissions | Submodules | Features -------------------------------------------------------------------------------------------------------------------------------------------------------------- iana-crypt-hash | 2014-08-06 | i | | | | iana-hardware | 2018-03-13 | I | zyg:zyg | 666 | | iana-if-type | 2017-01-19 | I | zyg:zyg | 666 | | ietf-crypto-types | 2019-07-02 | I | zyg:zyg | 600 | | ietf-datastores | 2018-02-14 | I | zyg:zyg | 666 | | ietf-dhcpv6-types | 2018-01-30 | I | zyg:zyg | 666 | | ietf-hardware | 2018-03-13 | I | zyg:zyg | 666 | | entity-mib hardware-state hardware-sensor ietf-hardware-state | 2018-03-13 | I | zyg:zyg | 666 | | ietf-inet-types | 2013-07-15 | i | | | | ietf-interfaces | 2018-02-20 | I | zyg:zyg | 666 | | arbitrary-names pre-provisioning if-mib ietf-ip | 2018-02-22 | I | zyg:zyg | 666 | | ipv4-non-contiguous-netmasks ipv6-privacy-autoconf ietf-keystore | 2019-07-02 | I | zyg:zyg | 600 | | keystore-supported ietf-netconf | 2013-09-29 | I | zyg:zyg | 666 | | writable-running candidate rollback-on-error validate startup url xpath ietf-netconf-acm | 2018-02-14 | I | zyg:zyg | 600 | | ietf-netconf-monitoring | 2010-10-04 | I | zyg:zyg | 600 | | ietf-netconf-nmda | 2019-01-07 | I | zyg:zyg | 600 | | origin with-defaults ietf-netconf-notifications | 2012-02-06 | I | zyg:zyg | 666 | | ietf-netconf-server | 2019-07-02 | I | zyg:zyg | 600 | | ssh-listen ssh-call-home tls-listen tls-call-home ietf-netconf-with-defaults | 2011-06-01 | I | zyg:zyg | 666 | | ietf-origin | 2018-02-14 | I | zyg:zyg | 666 | | ietf-ssh-common | 2019-07-02 | I | zyg:zyg | 600 | | ietf-ssh-server | 2019-07-02 | I | zyg:zyg | 600 | | local-client-auth-supported ietf-tcp-client | 2019-07-02 | I | zyg:zyg | 600 | | ietf-tcp-common | 2019-07-02 | I | zyg:zyg | 600 | | keepalives-supported ietf-tcp-server | 2019-07-02 | I | zyg:zyg | 600 | | ietf-tls-common | 2019-07-02 | I | zyg:zyg | 600 | | ietf-tls-server | 2019-07-02 | I | zyg:zyg | 600 | | local-client-auth-supported ietf-truststore | 2019-07-02 | I | zyg:zyg | 600 | | truststore-supported x509-certificates ietf-x509-cert-to-name | 2014-12-10 | I | zyg:zyg | 600 | | ietf-yang-library | 2019-01-04 | I | zyg:zyg | 666 | | ietf-yang-metadata | 2016-08-05 | i | | | | ietf-yang-types | 2013-07-15 | i | | | | nc-notifications | 2008-07-14 | I | zyg:zyg | 600 | | notifications | 2008-07-14 | I | zyg:zyg | 600 | | o-ran-dhcp | 2019-07-03 | I | zyg:zyg | 666 | | o-ran-hardware | 2019-07-03 | I | zyg:zyg | 666 | | ENERGYSAVING o-ran-interfaces | 2019-07-03 | I | zyg:zyg | 666 | | UDPIP-BASED-CU-PLANE ALIASMAC-BASED-CU-PLANE o-ran-mplane-int | 2019-07-03 | I | zyg:zyg | 666 | | o-ran-operations | 2019-07-03 | I | zyg:zyg | 666 | | o-ran-sync | 2019-07-03 | I | zyg:zyg | 666 | | GNSS ANTI-JAM o-ran-usermgmt | 2019-07-03 | I | zyg:zyg | 666 | | oven | 2018-01-19 | I | zyg:zyg | 666 | | sysrepo-monitoring | 2020-04-17 | I | zyg:zyg | 600 | | yang | 2017-02-20 | I | zyg:zyg | 666 | |
ietf-interfaces sysrepo plugin ietf-interfaces.c
#include <stdlib.h> #include <string.h> #include <pthread.h> #include <unistd.h> #include <sysrepo.h> #include <libyang/libyang.h> /* no synchronization is used in this example even though most of these * variables are shared between 2 threads, but the chances of encountering * problems is low enough to ignore them in this case */ /* session of our plugin, can be used until cleanup is called */ sr_session_ctx_t *sess; /* structure holding all the subscriptions */ sr_subscription_ctx_t *subscription; static int ietf_interfaces_config_change_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, sr_event_t event, uint32_t request_id, void *private_data) { sr_change_iter_t *it = NULL; int rc = SR_ERR_OK; sr_val_t *new_val = NULL; sr_val_t *old_val = NULL; sr_val_t *it_val = NULL; char change_path[100] = {0}; SRP_LOG_WRN("ietf-interfaces module callback: module_name: %s, xpath=%s", module_name, xpath); sr_get_item(session, "/ietf-interfaces:interfaces/interface[name='eth1']/name", 0, &it_val); SRP_LOG_INF("DEBUG: %s", it_val->data.string_val); snprintf(change_path, 100, "/%s:*", module_name); if ((rc = sr_get_changes_iter(session, change_path, &it) != SR_ERR_OK)) { SRP_LOG_ERR("%s: sr get changes iter failed, return %d", module_name, rc); goto cleanup; } sr_change_oper_t op = SR_OP_CREATED; while ((rc = sr_get_change_next(session, it, &op, &old_val, &new_val)) == SR_ERR_OK) { SRP_LOG_INF("xpath: %s type: %d data: %s", new_val->xpath, new_val->type, new_val->data.string_val); } op = SR_OP_MODIFIED; while ((rc = sr_get_change_next(session, it, &op, &old_val, &new_val)) == SR_ERR_OK) { SRP_LOG_INF("xpath: %s type: %d data: %s", new_val->xpath, new_val->type, new_val->data.string_val); } op = SR_OP_DELETED; while ((rc = sr_get_change_next(session, it, &op, &old_val, &new_val)) == SR_ERR_OK) { SRP_LOG_INF("xpath: %s type: %d data: %s", new_val->xpath, new_val->type, new_val->data.string_val); } op = SR_OP_MOVED; while ((rc = sr_get_change_next(session, it, &op, &old_val, &new_val)) == SR_ERR_OK) { SRP_LOG_INF("xpath: %s type: %d data: %s", new_val->xpath, new_val->type, new_val->data.string_val); } SRP_LOG_INF("module %s parse over", module_name); sr_free_change_iter(it); return SR_ERR_OK; cleanup: sr_free_change_iter(it); return SR_ERR_NOT_FOUND; } static int ietf_interfaces_interfaces_config_change_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, const char *request_xpath, uint32_t request_id, struct lyd_node **parent, void *private_data) { sr_change_iter_t *it = NULL; int rc = SR_ERR_OK; sr_val_t *new_val = NULL; sr_val_t *old_val = NULL; char change_path[100] = {0}; SRP_LOG_WRN("ietf-interfaces-interfaces callback: module_name: %s, xpath=%s", module_name, xpath); snprintf(change_path, 100, "/%s:interfaces*", module_name); if ((rc = sr_get_changes_iter(session, change_path, &it) != SR_ERR_OK)) { SRP_LOG_ERR("%s: sr get changes iter failed, return %d", module_name, rc); goto cleanup; } sr_change_oper_t op = SR_OP_CREATED; while ((rc = sr_get_change_next(session, it, &op, &old_val, &new_val)) == SR_ERR_OK) { SRP_LOG_INF("xpath: %s type: %d data: %s", new_val->xpath, new_val->type, new_val->data.string_val); } op = SR_OP_MODIFIED; while ((rc = sr_get_change_next(session, it, &op, &old_val, &new_val)) == SR_ERR_OK) { SRP_LOG_INF("xpath: %s type: %d data: %s", new_val->xpath, new_val->type, new_val->data.string_val); } op = SR_OP_DELETED; while ((rc = sr_get_change_next(session, it, &op, &old_val, &new_val)) == SR_ERR_OK) { SRP_LOG_INF("xpath: %s type: %d data: %s", new_val->xpath, new_val->type, new_val->data.string_val); } op = SR_OP_MOVED; while ((rc = sr_get_change_next(session, it, &op, &old_val, &new_val)) == SR_ERR_OK) { SRP_LOG_INF("xpath: %s type: %d data: %s", new_val->xpath, new_val->type, new_val->data.string_val); } SRP_LOG_INF("ietf-interfaces-interfaces %s parse over", module_name); sr_free_change_iter(it); return SR_ERR_OK; cleanup: sr_free_change_iter(it); return SR_ERR_NOT_FOUND; } int sr_plugin_init_cb(sr_session_ctx_t *session, void **private_data) { int rc; (void)private_data; /* remember the session of our plugin */ sess = session; rc = sr_module_change_subscribe(session, "ietf-interfaces", "/ietf-interfaces:interfaces", ietf_interfaces_config_change_cb, NULL, 0, SR_SUBSCR_DEFAULT | SR_SUBSCR_OPER_MERGE, &subscription); if (rc != SR_ERR_OK) { goto error; } rc = sr_oper_get_items_subscribe(session, "ietf-interfaces", "/ietf-interfaces:interfaces", ietf_interfaces_interfaces_config_change_cb, NULL, SR_SUBSCR_CTX_REUSE, &subscription); if (rc != SR_ERR_OK) { goto error; } /* sysrepo/plugins.h provides an interface for logging */ SRP_LOG_DBGMSG("ietf-interfaces: ietf-interfaces plugin initialized successfully."); return SR_ERR_OK; error: SRP_LOG_ERR("ietf-interfaces: ietf-interfaces plugin initialization failed: %s.", sr_strerror(rc)); sr_unsubscribe(subscription); return rc; } void sr_plugin_cleanup_cb(sr_session_ctx_t *session, void *private_data) { (void)session; (void)private_data; /* nothing to cleanup except freeing the subscriptions */ sr_unsubscribe(subscription); SRP_LOG_DBGMSG("ietf-interfaces: ietf-interfaces plugin cleanup finished."); }
ietf-interfaces-add-interface.xml:
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"> <interface> <name>eth1</name> <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type> </interface> <interface> <name>eth2</name> <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type> </interface> </interfaces>
sysrepo-plugind -d -v 4:
[DBG]: plugin: OVEN: Oven plugin initialized successfully. [DBG]: plugin: ietf-interfaces: ietf-interfaces plugin initialized successfully. [INF]: There are no subscribers for "oven" notifications. [INF]: Processing "ietf-interfaces" "change" event with ID 1 priority 0 (remaining 1 subscribers). [WRN]: plugin: ietf-interfaces module callback: module_name: ietf-interfaces, xpath=/ietf-interfaces:interfaces [INF]: plugin: DEBUG: eth1 [INF]: plugin: module ietf-interfaces parse over [INF]: Successful processing of "change" event with ID 1 priority 0 (remaining 0 subscribers). [INF]: Processing "ietf-interfaces" "done" event with ID 1 priority 0 (remaining 1 subscribers). [WRN]: plugin: ietf-interfaces module callback: module_name: ietf-interfaces, xpath=/ietf-interfaces:interfaces [INF]: plugin: DEBUG: eth1 [INF]: plugin: module ietf-interfaces parse over [INF]: Successful processing of "done" event with ID 1 priority 0 (remaining 0 subscribers).
question: why sr_get_change_next cann't get the change?
resolve by sr_get_changes_iter(session, "//.", &it)
sr_get_changes_iter(session, "//.", &it)
versions:
sysrepoctl -l
ietf-interfaces sysrepo plugin ietf-interfaces.c
ietf-interfaces-add-interface.xml:
sysrepo-plugind -d -v 4:
question: why sr_get_change_next cann't get the change?