Application hungs on cdb_subscribe api

In my application i have the requirement of having config data and also the operational data.

For config data i created a subscription socket and added the subscription points as per my Yang model.

For operational data I defined a Control socket and a Worker socket and registered the callbacks for the operational data as per the Yang.

Now while running my application, the application is getting stuck at cdb_subscribe().

If i remove cdb_subscribe then the callbacks works fine.

Can you please help me in understanding on how can i have all 3 type of sockets(Control, Worker and Subscription) working together in a single application?

This use case should work.

Let’s go with an example to illustrate your use case. Let’s modify the intro/5-c_stats example to add a top level configurable container called config with a leaf called test. Following are the changes for arpstat.c:

32d31
< #include <confd_cdb.h>
46d44
< static int subsock;
321,323d318
<     int status;
<     int spoint;
<     char *str;
341,360d335
<     /*
<      * Setup subscriptions
<      */
<     if ((subsock = socket(PF_INET, SOCK_STREAM, 0)) < 0 )
<         confd_fatal("Failed to open socket\n");
< 
<     if (cdb_connect(subsock, CDB_SUBSCRIPTION_SOCKET, (struct sockaddr*)&addr,
<                       sizeof (struct sockaddr_in)) < 0)
<         confd_fatal("Failed to cdb_connect() to confd \n");
< 
<     if ((status = cdb_subscribe(subsock, 3, arpe__ns, &spoint, "/config"))
<         != CONFD_OK) {
<         fprintf(stderr, "Terminate: subscribe %d\n", status);
<         exit(0);
<     }
<     if (cdb_subscribe_done(subsock) != CONFD_OK)
<         confd_fatal("cdb_subscribe_done() failed");
<     printf("Subscription point = %d\n", spoint);
< 
< 
396c371
<         struct pollfd set[3];
---
>         struct pollfd set[2];
407,410d381
<         set[2].fd = subsock;
<         set[2].events = POLLIN;
<         set[2].revents = 0;
< 
433,459d403
<         if (set[2].revents & POLLIN) {
<             int sub_points[1];
<             int reslen;
< 
<             if ((status = cdb_read_subscription_socket(subsock,
<                                                        &sub_points[0],
<                                                        &reslen)) != CONFD_OK) {
<                 fprintf(stderr, "terminate sub_read: %d\n", status);
<                 exit(1);
<             }
<             if (reslen > 0) {
<                 if ((status = cdb_get_modifications_cli(subsock, sub_points[0], 0, &str)) != CONFD_OK) {
<                     fprintf(stderr, "Terminate: cdb_get_modifications_cli %d\n", status);
<                     exit(1);
<                 }
<                 else {
<                     printf("CLI command of CDB changes:\n%s", str);
<                 }
<             }
< 
<             if ((status = cdb_sync_subscription_socket(subsock,
<                                                        CDB_DONE_PRIORITY))
<                 != CONFD_OK) {
<                 fprintf(stderr, "failed to sync subscription: %d\n", status);
<                 exit(1);
<             }
<         }

If I open up a CLI session to do a “show arpentries” followed by a config change of “config test good”, you should see the following TRACE output from the arpstat daemon:

### * In one terminal window, run: tail -f ./confd.log
### * In another terminal window, run queries
###   (try 'make query' for an example)
### * In this window, the arpstat confd daemon now starts:
PATH=/sbin:/usr/sbin:$PATH ./arpstat 
TRACE Connected (cdb) to ConfD
TRACE CDB_SUBSCRIBE /config --> CONFD_OK
TRACE CDB_SUBSCRIBE_DONE  --> CONFD_OK
Subscription point = 6
TRACE Connected (maapi) to ConfD
TRACE MAAPI_LOAD_ALL_NS
TRACE MAAPI_LOAD_HASH_DB
TRACE Connected (dp) to ConfD
TRACE Received daemon id 0
TRACE Connected (dp) to ConfD
TRACE Picked up old user session: 11 for user:system ctx:system
TRACE Picked up old user session: 10 for user:system ctx:system
TRACE Picked up old user session: 1 for user:system ctx:system
TRACE New user session: 12 for user:admin ctx:cli --> CONFD_OK
TRACE CALL trans init(thandle=7,mode="r",db=running) --> CONFD_OK
TRACE CALL data get_next(thandle=7, /arpentries/arpe, -1) --> CONFD_OK
TRACE CALL data get_next(thandle=7, /arpentries/arpe, -1) --> CONFD_OK
TRACE CALL data get_elem(thandle=7,/arpentries/arpe{10.0.0.1 en0}/hwaddr) ("58:23:8c:bf:2b:86")  --> CONFD_OK
TRACE CALL data get_elem(thandle=7,/arpentries/arpe{10.0.0.1 en0}/permanent) (true)  --> CONFD_OK
TRACE CALL data get_elem(thandle=7,/arpentries/arpe{10.0.0.1 en0}/published) (false)  --> CONFD_OK
TRACE CALL data get_next(thandle=7, /arpentries/arpe, 140295790409392) --> CONFD_OK
TRACE CALL data get_elem(thandle=7,/arpentries/arpe{224.0.0.251 en0}/hwaddr) ("1:0:5e:0:0:fb")  --> CONFD_OK
TRACE CALL data get_elem(thandle=7,/arpentries/arpe{224.0.0.251 en0}/permanent) (true)  --> CONFD_OK
TRACE CALL data get_elem(thandle=7,/arpentries/arpe{224.0.0.251 en0}/published) (false)  --> CONFD_OK
TRACE CALL data get_next(thandle=7, /arpentries/arpe, 0) --> CONFD_OK
TRACE CDB_SUBSCRIPTION_EVENT --> 6
TRACE CDB_GET_CLI  --> CONFD_OK
CLI command of CDB changes:
config test good
TRACE CDB_SYNC_SUB CDB_DONE_PRIORITY --> CONFD_OK
TRACE CALL trans finish(thandle=7) --> CONFD_OK
TRACE Close user sess 12
 --> CONFD_OK

If you are still having problem with your specific code, please file a RT support ticket with our support team and include your code.

Wai

Thanks for the Help, It worked for me.

Now i am facing some other issue.

I have this sample Yang

container summary {
config false;
tailf: cdb-oper;
leaf name {
type string;
}
}

So now this summarry container is operational data container for me.
what i want to do is to update the “name” field whenever i trigger the CLI “show summary”.

As per my understanding currently the “show” CLI’s does not send any trigger to the application and directly reads the cdb database and prints the value.

But i want a trigger of show CLI in my application and want to populate the fields in that trigger and then it should be printed.

Can you please help me in this use case also?

Thanks a lot in advance.

The best solution for your use case is to not store your operational data in CDB but instead implement an operational data provider application for your summary container. Refer to intro/5-c_stats for an example implementation.