CESNET / netopeer

NETCONF Protocol Toolset
117 stars 65 forks source link

sysrepo ietf-interfaces plugin can not get the changes by sr_get_change_next #192

Closed adamzyg closed 3 years ago

adamzyg commented 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?

adamzyg commented 3 years ago

resolve by sr_get_changes_iter(session, "//.", &it)