* Changed debug levels in clicon_debug() to be based on maskable flags

* Added flag names: `CLIXON_DBG_*`
  * Added maskable flags that can be combined when debugging:
    * `DEFAULT` = 1: Basic debug message, espcially initialization
    * `MSG` = 2: Input and output packets, read datastore
    * `DETAIL` = 4: Details: message dump in hex, xpath parse trees, etc
    * `EXTRA` = 8: Extra detailed logs
* Test: some errors in yang-lib where content-id was in wrong place
This commit is contained in:
Olof hagsand 2023-01-27 10:08:07 +01:00 committed by Olof Hagsand
parent 8342b74968
commit da9bfcbb53
47 changed files with 425 additions and 210 deletions

View file

@ -89,15 +89,20 @@ Developers may need to change their code
### Minor features ### Minor features
* Clearer debug levels `clicon_debug()`: * Changed debug levels in `clicon_debug()` to be based on maskable flags:
* 1: Logical debug message * Added flag names: `CLIXON_DBG_*`
* 2: Input and output packets * Added maskable flags that can be combined when debugging:
* 3: Message dump in hex, xpath parse trees * `DEFAULT` = 1: Basic debug message, espcially initialization
* `MSG` = 2: Input and output packets, read datastore
* `DETAIL` = 4: Details: message dump in hex, xpath parse trees, etc
* `EXTRA` = 8: Extra detailed logs
* Added `ISO/IEC 10646` encodings to XML parser: `&#[0-9]+;` and `&#[0-9a-fA-F]+;` * Added `ISO/IEC 10646` encodings to XML parser: `&#[0-9]+;` and `&#[0-9a-fA-F]+;`
* Added `CLIXON_CLIENT_SSH` to client API to communicate remotely via SSH netconf sub-system * Added `CLIXON_CLIENT_SSH` to client API to communicate remotely via SSH netconf sub-system
### Corrected Bugs ### Corrected Bugs
* Fixed: [SNMP accepts only u32 & u64 #405](https://github.com/clicon/clixon/issues/405)
* Fixed: [Yang leaves without smiv2:oid directive are not shown well in snmpwalk #398](https://github.com/clicon/clixon/issues/398)
* Fixed: [Netconf commit confirm session-id mismatch #407](https://github.com/clicon/clixon/issues/407) * Fixed: [Netconf commit confirm session-id mismatch #407](https://github.com/clicon/clixon/issues/407)
* Fixed: Initialized session-id to 1 instead of 0 following ietf-netconf.yang * Fixed: Initialized session-id to 1 instead of 0 following ietf-netconf.yang
* Fixed: [snmpwalk doesn't show properly SNMP boolean values which equal false](https://github.com/clicon/clixon/issues/400) * Fixed: [snmpwalk doesn't show properly SNMP boolean values which equal false](https://github.com/clicon/clixon/issues/400)

View file

@ -1532,7 +1532,7 @@ from_client_msg(clicon_handle h,
char *namespace = NULL; char *namespace = NULL;
int nr = 0; int nr = 0;
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
yspec = clicon_dbspec_yang(h); yspec = clicon_dbspec_yang(h);
/* Return netconf message. Should be filled in by the dispatch(sub) functions /* Return netconf message. Should be filled in by the dispatch(sub) functions
* as wither rpc-error or by positive response. * as wither rpc-error or by positive response.
@ -1708,7 +1708,7 @@ from_client_msg(clicon_handle h,
if (cbuf_len(cbret) == 0) if (cbuf_len(cbret) == 0)
if (netconf_operation_failed(cbret, "application", clicon_errno?clicon_err_reason:"unknown")< 0) if (netconf_operation_failed(cbret, "application", clicon_errno?clicon_err_reason:"unknown")< 0)
goto done; goto done;
clicon_debug(2, "%s cbret:%s", __FUNCTION__, cbuf_get(cbret)); // XXX clicon_debug(CLIXON_DBG_MSG, "Reply:%s", cbuf_get(cbret));
/* XXX problem here is that cbret has not been parsed so may contain /* XXX problem here is that cbret has not been parsed so may contain
parse errors */ parse errors */
if (send_msg_reply(ce->ce_s, cbuf_get(cbret), cbuf_len(cbret)+1) < 0){ if (send_msg_reply(ce->ce_s, cbuf_get(cbret), cbuf_len(cbret)+1) < 0){
@ -1731,7 +1731,7 @@ from_client_msg(clicon_handle h,
// ok: // ok:
retval = 0; retval = 0;
done: done:
clicon_debug(1, "%s retval:%d", __FUNCTION__, retval); clicon_debug(CLIXON_DBG_DETAIL, "%s retval:%d", __FUNCTION__, retval);
if (xnacm){ if (xnacm){
xml_free(xnacm); xml_free(xnacm);
if (clicon_nacm_cache_set(h, NULL) < 0) if (clicon_nacm_cache_set(h, NULL) < 0)
@ -1768,7 +1768,7 @@ from_client(int s,
clicon_handle h = ce->ce_handle; clicon_handle h = ce->ce_handle;
int eof = 0; int eof = 0;
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
if (s != ce->ce_s){ if (s != ce->ce_s){
clicon_err(OE_NETCONF, EINVAL, "Internal error: s != ce->ce_s"); clicon_err(OE_NETCONF, EINVAL, "Internal error: s != ce->ce_s");
goto done; goto done;
@ -1782,7 +1782,7 @@ from_client(int s,
goto done; goto done;
retval = 0; retval = 0;
done: done:
clicon_debug(1, "%s retval=%d", __FUNCTION__, retval); clicon_debug(CLIXON_DBG_DETAIL, "%s retval=%d", __FUNCTION__, retval);
if (msg) if (msg)
free(msg); free(msg);
return retval; /* -1 here terminates backend */ return retval; /* -1 here terminates backend */

View file

@ -518,8 +518,7 @@ validate_common(clicon_handle h,
&td->td_tcvec, /* changed: wanted values */ &td->td_tcvec, /* changed: wanted values */
&td->td_clen) < 0) &td->td_clen) < 0)
goto done; goto done;
if (clicon_debug_get()>1) transaction_dbg(h, CLIXON_DBG_DEFAULT, td, __FUNCTION__);
transaction_print(stderr, td);
/* Mark as changed in tree */ /* Mark as changed in tree */
for (i=0; i<td->td_dlen; i++){ /* Also down */ for (i=0; i<td->td_dlen; i++){ /* Also down */
xn = td->td_dvec[i]; xn = td->td_dvec[i];

View file

@ -199,7 +199,7 @@ client_get_streams(clicon_handle h,
* *
*/ */
static int static int
get_client_statedata(clicon_handle h, get_statedata(clicon_handle h,
char *xpath, char *xpath,
cvec *nsc, cvec *nsc,
withdefaults_type wdef, withdefaults_type wdef,
@ -872,7 +872,8 @@ get_common(clicon_handle h,
#else #else
wdef = WITHDEFAULTS_EXPLICIT; wdef = WITHDEFAULTS_EXPLICIT;
#endif #endif
clicon_debug(2, "%s", __FUNCTION__);
clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
username = clicon_username_get(h); username = clicon_username_get(h);
if ((yspec = clicon_dbspec_yang(h)) == NULL){ if ((yspec = clicon_dbspec_yang(h)) == NULL){
clicon_err(OE_YANG, ENOENT, "No yang spec9"); clicon_err(OE_YANG, ENOENT, "No yang spec9");
@ -997,7 +998,7 @@ get_common(clicon_handle h,
break; break;
case CONTENT_ALL: /* both config and state */ case CONTENT_ALL: /* both config and state */
case CONTENT_NONCONFIG: /* state data only */ case CONTENT_NONCONFIG: /* state data only */
if ((ret = get_client_statedata(h, xpath?xpath:"/", nsc, wdef, &xret)) < 0) if ((ret = get_statedata(h, xpath?xpath:"/", nsc, wdef, &xret)) < 0)
goto done; goto done;
if (ret == 0){ /* Error from callback (error in xret) */ if (ret == 0){ /* Error from callback (error in xret) */
if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0)
@ -1049,7 +1050,7 @@ get_common(clicon_handle h,
ok: ok:
retval = 0; retval = 0;
done: done:
clicon_debug(2, "%s retval:%d", __FUNCTION__, retval); clicon_debug(CLIXON_DBG_DETAIL, "%s retval:%d", __FUNCTION__, retval);
if (xvec) if (xvec)
free(xvec); free(xvec);
if (xret) if (xret)

View file

@ -112,8 +112,9 @@ backend_terminate(clicon_handle h)
/* Free changelog */ /* Free changelog */
if ((x = clicon_xml_changelog_get(h)) != NULL) if ((x = clicon_xml_changelog_get(h)) != NULL)
xml_free(x); xml_free(x);
if ((yspec = clicon_dbspec_yang(h)) != NULL) if ((yspec = clicon_dbspec_yang(h)) != NULL){
ys_free(yspec); ys_free(yspec);
}
if ((yspec = clicon_config_yang(h)) != NULL) if ((yspec = clicon_config_yang(h)) != NULL)
ys_free(yspec); ys_free(yspec);
if ((yspec = clicon_nacm_ext_yang(h)) != NULL) if ((yspec = clicon_nacm_ext_yang(h)) != NULL)
@ -133,6 +134,7 @@ backend_terminate(clicon_handle h)
xpath_optimize_exit(); xpath_optimize_exit();
clixon_pagination_free(h); clixon_pagination_free(h);
if (pidfile) if (pidfile)
unlink(pidfile); unlink(pidfile);
if (sockfamily==AF_UNIX && lstat(sockpath, &st) == 0) if (sockfamily==AF_UNIX && lstat(sockpath, &st) == 0)
@ -1045,8 +1047,8 @@ main(int argc,
goto done; goto done;
if (clicon_socket_set(h, ss) < 0) if (clicon_socket_set(h, ss) < 0)
goto done; goto done;
if (dbg) clicon_option_dump(h, 1);
clicon_option_dump(h, dbg);
/* Depending on configure setting, privileges may be dropped here after /* Depending on configure setting, privileges may be dropped here after
* initializations */ * initializations */
if (check_drop_priv(h, gid, yspec) < 0) if (check_drop_priv(h, gid, yspec) < 0)

View file

@ -115,7 +115,7 @@ clixon_plugin_reset_all(clicon_handle h,
int retval = -1; int retval = -1;
clixon_plugin_t *cp = NULL; clixon_plugin_t *cp = NULL;
clicon_debug(1, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
/* Loop through all plugins, call callbacks in each */ /* Loop through all plugins, call callbacks in each */
while ((cp = clixon_plugin_each(h, cp)) != NULL) { while ((cp = clixon_plugin_each(h, cp)) != NULL) {
if (clixon_plugin_reset_one(cp, h, db) < 0) if (clixon_plugin_reset_one(cp, h, db) < 0)
@ -176,7 +176,7 @@ clixon_plugin_pre_daemon_all(clicon_handle h)
int retval = -1; int retval = -1;
clixon_plugin_t *cp = NULL; clixon_plugin_t *cp = NULL;
clicon_debug(1, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
/* Loop through all plugins, call callbacks in each */ /* Loop through all plugins, call callbacks in each */
while ((cp = clixon_plugin_each(h, cp)) != NULL) { while ((cp = clixon_plugin_each(h, cp)) != NULL) {
if (clixon_plugin_pre_daemon_one(cp, h) < 0) if (clixon_plugin_pre_daemon_one(cp, h) < 0)
@ -238,7 +238,7 @@ clixon_plugin_daemon_all(clicon_handle h)
int retval = -1; int retval = -1;
clixon_plugin_t *cp = NULL; clixon_plugin_t *cp = NULL;
clicon_debug(1, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
/* Loop through all plugins, call callbacks in each */ /* Loop through all plugins, call callbacks in each */
while ((cp = clixon_plugin_each(h, cp)) != NULL) { while ((cp = clixon_plugin_each(h, cp)) != NULL) {
if (clixon_plugin_daemon_one(cp, h) < 0) if (clixon_plugin_daemon_one(cp, h) < 0)
@ -342,7 +342,7 @@ clixon_plugin_statedata_all(clicon_handle h,
cbuf *cberr = NULL; cbuf *cberr = NULL;
cxobj *xerr = NULL; cxobj *xerr = NULL;
clicon_debug(1, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
while ((cp = clixon_plugin_each(h, cp)) != NULL) { while ((cp = clixon_plugin_each(h, cp)) != NULL) {
if ((ret = clixon_plugin_statedata_one(cp, h, nsc, xpath, &x)) < 0) if ((ret = clixon_plugin_statedata_one(cp, h, nsc, xpath, &x)) < 0)
goto done; goto done;
@ -368,7 +368,7 @@ clixon_plugin_statedata_all(clicon_handle h,
x = NULL; x = NULL;
continue; continue;
} }
clicon_debug_xml(2, x, "%s %s STATE:", __FUNCTION__, clixon_plugin_name_get(cp)); clicon_debug_xml(CLIXON_DBG_DETAIL, x, "%s %s STATE:", __FUNCTION__, clixon_plugin_name_get(cp));
/* XXX: ret == 0 invalid yang binding should be handled as internal error */ /* XXX: ret == 0 invalid yang binding should be handled as internal error */
if ((ret = xml_bind_yang(x, YB_MODULE, yspec, &xerr)) < 0) if ((ret = xml_bind_yang(x, YB_MODULE, yspec, &xerr)) < 0)
goto done; goto done;
@ -464,7 +464,7 @@ clixon_plugin_lockdb_all(clicon_handle h,
int retval = -1; int retval = -1;
clixon_plugin_t *cp = NULL; clixon_plugin_t *cp = NULL;
clicon_debug(1, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
while ((cp = clixon_plugin_each(h, cp)) != NULL) { while ((cp = clixon_plugin_each(h, cp)) != NULL) {
if (clixon_plugin_lockdb_one(cp, h, db, lock, id) < 0) if (clixon_plugin_lockdb_one(cp, h, db, lock, id) < 0)
goto done; goto done;
@ -641,7 +641,7 @@ plugin_transaction_begin_all(clicon_handle h,
int retval = -1; int retval = -1;
clixon_plugin_t *cp = NULL; clixon_plugin_t *cp = NULL;
clicon_debug(1, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
while ((cp = clixon_plugin_each(h, cp)) != NULL) { while ((cp = clixon_plugin_each(h, cp)) != NULL) {
if (plugin_transaction_begin_one(cp, h, td) < 0) if (plugin_transaction_begin_one(cp, h, td) < 0)
goto done; goto done;
@ -976,7 +976,7 @@ plugin_transaction_end_all(clicon_handle h,
int retval = -1; int retval = -1;
clixon_plugin_t *cp = NULL; clixon_plugin_t *cp = NULL;
clicon_debug(1, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
while ((cp = clixon_plugin_each(h, cp)) != NULL) { while ((cp = clixon_plugin_each(h, cp)) != NULL) {
if (plugin_transaction_end_one(cp, h, td) < 0) if (plugin_transaction_end_one(cp, h, td) < 0)
goto done; goto done;
@ -1028,7 +1028,7 @@ plugin_transaction_abort_all(clicon_handle h,
int retval = -1; int retval = -1;
clixon_plugin_t *cp = NULL; clixon_plugin_t *cp = NULL;
clicon_debug(1, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
while ((cp = clixon_plugin_each(h, cp)) != NULL) { while ((cp = clixon_plugin_each(h, cp)) != NULL) {
if (plugin_transaction_abort_one(cp, h, td) < 0) if (plugin_transaction_abort_one(cp, h, td) < 0)
; /* dont abort on error */ ; /* dont abort on error */

View file

@ -241,7 +241,7 @@ backend_accept_client(int fd,
uid_t guid; uid_t guid;
#endif #endif
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
len = sizeof(from); len = sizeof(from);
if ((s = accept(fd, &from, &len)) < 0){ if ((s = accept(fd, &from, &len)) < 0){
clicon_err(OE_UNIX, errno, "accept"); clicon_err(OE_UNIX, errno, "accept");

View file

@ -201,8 +201,11 @@ transaction_clen(transaction_data td)
return ((transaction_data_t *)td)->td_clen; return ((transaction_data_t *)td)->td_clen;
} }
/*! Print transaction on FILE for debug /*! Print info about transaction on FILE, including what has changed
* @see transaction_log *
* @param[in] f stdio FILE
* @param[in] th Transaction data
* @see transaction_dbg
*/ */
int int
transaction_print(FILE *f, transaction_print(FILE *f,
@ -235,6 +238,66 @@ transaction_print(FILE *f,
return 0; return 0;
} }
/*! Log debug info about transaction on FILE, including what has changed
*
* @param[in] h Clixon handle
* @param[in] dbglevel Debuglevel as defined by CLIXON_DBG_* flags
* @param[in] th Transaction data
* @param[in] msg Debug msg tag
*/
int
transaction_dbg(clicon_handle h,
int dbglevel,
transaction_data th,
const char *msg)
{
cxobj *xn;
int i;
transaction_data_t *td;
cbuf *cb = NULL;
td = (transaction_data_t *)th;
if ((cb = cbuf_new()) == NULL){
clicon_err(OE_CFG, errno, "cbuf_new");
goto done;
}
for (i=0; i<td->td_dlen; i++){
xn = td->td_dvec[i];
if (clixon_xml2cbuf(cb, xn, 0, 0, -1, 0) < 0)
goto done;
}
if (i)
clicon_debug(dbglevel, "%s %" PRIu64 " %s del: %s",
__FUNCTION__, td->td_id, msg, cbuf_get(cb));
cbuf_reset(cb);
for (i=0; i<td->td_alen; i++){
xn = td->td_avec[i];
if (clixon_xml2cbuf(cb, xn, 0, 0, -1, 0) < 0)
goto done;
}
if (i)
clicon_debug(dbglevel, "%s %" PRIu64 " %s add: %s",
__FUNCTION__, td->td_id, msg, cbuf_get(cb));
cbuf_reset(cb);
for (i=0; i<td->td_clen; i++){
if (td->td_scvec){
xn = td->td_scvec[i];
if (clixon_xml2cbuf(cb, xn, 0, 0, -1, 0) < 0)
goto done;
}
xn = td->td_tcvec[i];
if (clixon_xml2cbuf(cb, xn, 0, 0, -1, 0) < 0)
goto done;
}
if (i)
clicon_debug(dbglevel, "%s %" PRIu64 " %s change: %s",
__FUNCTION__, td->td_id, msg, cbuf_get(cb));
done:
if (cb)
cbuf_free(cb);
return 0;
}
/*! Log a transaction /*! Log a transaction
* *
*/ */

View file

@ -62,7 +62,9 @@ cxobj **transaction_tcvec(transaction_data td);
size_t transaction_clen(transaction_data td); size_t transaction_clen(transaction_data td);
int transaction_print(FILE *f, transaction_data th); int transaction_print(FILE *f, transaction_data th);
int transaction_log(clicon_handle h, transaction_data th, int level, const char *id); int transaction_dbg(clicon_handle h, int dbglevel, transaction_data th, const char *msg);
int transaction_log(clicon_handle h, transaction_data th, int level, const char *op);
/* Pagination callbacks /* Pagination callbacks
* @see pagination_data_t internal structure * @see pagination_data_t internal structure

View file

@ -1385,7 +1385,7 @@ yang2cli_yspec(clicon_handle h,
clicon_log(LOG_NOTICE, "%s: Top-level cli-spec %s:\n%s", clicon_log(LOG_NOTICE, "%s: Top-level cli-spec %s:\n%s",
__FUNCTION__, treename, cbuf_get(cb)); __FUNCTION__, treename, cbuf_get(cb));
else else
clicon_debug(2, "%s: Top-level cli-spec %s:\n%s", clicon_debug(CLIXON_DBG_DETAIL, "%s: Top-level cli-spec %s:\n%s",
__FUNCTION__, treename, cbuf_get(cb)); __FUNCTION__, treename, cbuf_get(cb));
if (cligen_parsetree_merge(pt0, NULL, pt) < 0){ if (cligen_parsetree_merge(pt0, NULL, pt) < 0){
clicon_err(OE_YANG, errno, "cligen_parsetree_merge"); clicon_err(OE_YANG, errno, "cligen_parsetree_merge");

View file

@ -780,8 +780,7 @@ main(int argc,
if (logclisyntax) if (logclisyntax)
cli_logsyntax_set(h, logclisyntax); cli_logsyntax_set(h, logclisyntax);
if (dbg) clicon_option_dump(h, 1);
clicon_option_dump(h, dbg);
/* Join rest of argv to a single command */ /* Join rest of argv to a single command */
restarg = clicon_strjoin(argc, argv, " "); restarg = clicon_strjoin(argc, argv, " ");

View file

@ -404,8 +404,8 @@ netconf_input_frame(clicon_handle h,
int ret; int ret;
netconf_framing_type framing; netconf_framing_type framing;
clicon_debug(1, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
clicon_debug(2, "%s: \"%s\"", __FUNCTION__, cbuf_get(cb)); clicon_debug(CLIXON_DBG_MSG, "Recv ext: %s", cbuf_get(cb));
framing = clicon_option_int(h, "netconf-framing"); framing = clicon_option_int(h, "netconf-framing");
yspec = clicon_dbspec_yang(h); yspec = clicon_dbspec_yang(h);
if ((str = strdup(cbuf_get(cb))) == NULL){ if ((str = strdup(cbuf_get(cb))) == NULL){
@ -1011,8 +1011,7 @@ main(int argc,
#endif #endif
if (clixon_event_reg_fd(0, netconf_input_cb, h, "netconf socket") < 0) if (clixon_event_reg_fd(0, netconf_input_cb, h, "netconf socket") < 0)
goto done; goto done;
if (dbg) clicon_option_dump(h, 1);
clicon_option_dump(h, dbg);
if (tv.tv_sec || tv.tv_usec){ if (tv.tv_sec || tv.tv_usec){
struct timeval t; struct timeval t;
gettimeofday(&t, NULL); gettimeofday(&t, NULL);

View file

@ -529,8 +529,7 @@ main(int argc,
goto done; goto done;
/* Dump configuration options on debug */ /* Dump configuration options on debug */
if (dbg) clicon_option_dump(h, 1);
clicon_option_dump(h, dbg);
/* Call start function in all plugins before we go interactive */ /* Call start function in all plugins before we go interactive */
if (clixon_plugin_start_all(h) < 0) if (clixon_plugin_start_all(h) < 0)

View file

@ -837,10 +837,7 @@ restconf_openssl_init(clicon_handle h,
/* If debug was enabled here from config and not initially, /* If debug was enabled here from config and not initially,
* print clixn options and loaded yang files * print clixn options and loaded yang files
*/ */
if (dbg) { clicon_option_dump(h, 1);
clicon_option_dump(h, dbg);
yang_spec_dump(clicon_dbspec_yang(h), dbg);
}
} }
if ((x = xpath_first(xrestconf, nsc, "enable-core-dump")) != NULL) { if ((x = xpath_first(xrestconf, nsc, "enable-core-dump")) != NULL) {
/* core dump is enabled on RESTCONF process */ /* core dump is enabled on RESTCONF process */
@ -1273,8 +1270,7 @@ main(int argc,
restconf_auth_type_set(h, CLIXON_AUTH_NONE); restconf_auth_type_set(h, CLIXON_AUTH_NONE);
/* Dump configuration options on debug */ /* Dump configuration options on debug */
if (dbg) clicon_option_dump(h, 1);
clicon_option_dump(h, dbg);
/* Initialize plugin module by creating a handle holding plugin and callback lists */ /* Initialize plugin module by creating a handle holding plugin and callback lists */
if (clixon_plugin_module_init(h) < 0) if (clixon_plugin_module_init(h) < 0)

View file

@ -718,7 +718,7 @@ clixon_snmp_scalar_handler1(netsnmp_mib_handler *handler,
netsnmp_variable_list *requestvb = request->requestvb; netsnmp_variable_list *requestvb = request->requestvb;
int ret; int ret;
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
if (snmp_common_handler(handler, nhreg, reqinfo, request, 0, &sh) < 0) if (snmp_common_handler(handler, nhreg, reqinfo, request, 0, &sh) < 0)
goto done; goto done;
/* see net-snmp/agent/snmp_agent.h / net-snmp/library/snmp.h */ /* see net-snmp/agent/snmp_agent.h / net-snmp/library/snmp.h */
@ -1293,7 +1293,7 @@ clixon_snmp_table_handler1(netsnmp_mib_handler *handler,
netsnmp_variable_list *requestvb; netsnmp_variable_list *requestvb;
int err = 0; int err = 0;
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
if ((ret = snmp_common_handler(handler, nhreg, reqinfo, request, 1, &sh)) < 0) if ((ret = snmp_common_handler(handler, nhreg, reqinfo, request, 1, &sh)) < 0)
goto done; goto done;
if (sh->sh_ys == NULL){ if (sh->sh_ys == NULL){

View file

@ -639,7 +639,7 @@ type_snmp2xml(yang_stmt *ys,
} }
retval = 1; retval = 1;
done: done:
clicon_debug(2, "%s %d", __FUNCTION__, retval); clicon_debug(CLIXON_DBG_DETAIL, "%s %d", __FUNCTION__, retval);
if (origtype) if (origtype)
free(origtype); free(origtype);
if (cv) if (cv)
@ -709,7 +709,7 @@ type_xml2snmp_pre(char *xmlstr0,
} }
retval = 1; retval = 1;
done: done:
clicon_debug(2, "%s %d", __FUNCTION__, retval); clicon_debug(CLIXON_DBG_DETAIL, "%s %d", __FUNCTION__, retval);
return retval; return retval;
fail: fail:
retval = 0; retval = 0;
@ -852,7 +852,7 @@ type_xml2snmp(char *snmpstr,
} }
retval = 1; retval = 1;
done: done:
clicon_debug(2, "%s %d", __FUNCTION__, retval); clicon_debug(CLIXON_DBG_DETAIL, "%s %d", __FUNCTION__, retval);
return retval; return retval;
fail: fail:
retval = 0; retval = 0;

View file

@ -198,7 +198,7 @@ clixon_snmp_input_cb(int s,
clicon_handle h = (clicon_handle)arg; clicon_handle h = (clicon_handle)arg;
int ret; int ret;
clicon_debug(2, "%s %d", __FUNCTION__, s); clicon_debug(CLIXON_DBG_DETAIL, "%s %d", __FUNCTION__, s);
FD_ZERO(&readfds); FD_ZERO(&readfds);
FD_SET(s, &readfds); FD_SET(s, &readfds);
(void)snmp_read(&readfds); (void)snmp_read(&readfds);
@ -514,8 +514,7 @@ main(int argc,
if (clicon_nsctx_global_set(h, nsctx_global) < 0) if (clicon_nsctx_global_set(h, nsctx_global) < 0)
goto done; goto done;
if (dbg) clicon_option_dump(h, 1);
clicon_option_dump(h, dbg);
/* Send hello request to backend to get session-id back /* Send hello request to backend to get session-id back
* This is done once at the beginning of the session and then this is * This is done once at the beginning of the session and then this is

View file

@ -43,11 +43,18 @@
/* /*
* Constants * Constants
*/ */
/* Where to log (masks) */
#define CLICON_LOG_SYSLOG 1 /* print logs on syslog */ #define CLICON_LOG_SYSLOG 1 /* print logs on syslog */
#define CLICON_LOG_STDERR 2 /* print logs on stderr */ #define CLICON_LOG_STDERR 2 /* print logs on stderr */
#define CLICON_LOG_STDOUT 4 /* print logs on stdout */ #define CLICON_LOG_STDOUT 4 /* print logs on stdout */
#define CLICON_LOG_FILE 8 /* print logs on clicon_log_filename */ #define CLICON_LOG_FILE 8 /* print logs on clicon_log_filename */
/* Debug-level masks */
#define CLIXON_DBG_DEFAULT 1 /* Default logs */
#define CLIXON_DBG_MSG 2 /* In/out messages and datastore reads */
#define CLIXON_DBG_DETAIL 4 /* Detailed logs */
#define CLIXON_DBG_EXTRA 8 /* Extra Detailed logs */
/* /*
* Prototypes * Prototypes
*/ */

View file

@ -114,10 +114,21 @@
#include "clixon_path.h" #include "clixon_path.h"
#include "clixon_api_path_parse.h" #include "clixon_api_path_parse.h"
/* /* Best debugging is to enable PARSE_DEBUG below and add -d to the LEX compile statement in the Makefile
also called from yacc generated code * * And then run the testcase with -D 1
*/ * Disable it to stop any calls to clicon_debug. Having it on by default would mean very large debug outputs.
*/
#if 0
#define _PARSE_DEBUG(s) clicon_debug(1,(s))
#define _PARSE_DEBUG1(s, s1) clicon_debug(1,(s), (s1))
#else
#define _PARSE_DEBUG(s)
#define _PARSE_DEBUG1(s, s1)
#endif
/*
* Also called from yacc generated code *
*/
void void
clixon_api_path_parseerror(void *_ay, clixon_api_path_parseerror(void *_ay,
char *s) char *s)
@ -148,7 +159,7 @@ static clixon_path *
path_append(clixon_path *list, path_append(clixon_path *list,
clixon_path *new) clixon_path *new)
{ {
clicon_debug(3, "%s()", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s()", __FUNCTION__);
if (new == NULL) if (new == NULL)
return NULL; return NULL;
ADDQ(new, list); ADDQ(new, list);
@ -161,7 +172,7 @@ static clixon_path *
path_add_keyvalue(clixon_path *cp, path_add_keyvalue(clixon_path *cp,
cvec *cvk) cvec *cvk)
{ {
clicon_debug(3, "%s()", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s()", __FUNCTION__);
if (cp) if (cp)
cp->cp_cvk = cvk; cp->cp_cvk = cvk;
return cp; return cp;
@ -173,7 +184,7 @@ path_new(char *module_name,
{ {
clixon_path *cp = NULL; clixon_path *cp = NULL;
clicon_debug(3, "%s(%s,%s)", __FUNCTION__, module_name, id); clicon_debug(CLIXON_DBG_DETAIL, "%s(%s,%s)", __FUNCTION__, module_name, id);
if ((cp = malloc(sizeof(*cp))) == NULL){ if ((cp = malloc(sizeof(*cp))) == NULL){
clicon_err(OE_UNIX, errno, "malloc"); clicon_err(OE_UNIX, errno, "malloc");
goto done; goto done;
@ -203,7 +214,7 @@ static cvec *
keyval_add(cvec *cvv, keyval_add(cvec *cvv,
cg_var *cv) cg_var *cv)
{ {
clicon_debug(3, "%s()", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s()", __FUNCTION__);
if (cv == NULL) if (cv == NULL)
goto done; goto done;
if (cvv == NULL && if (cvv == NULL &&
@ -229,7 +240,7 @@ keyval_set(char *name,
{ {
cg_var *cv = NULL; cg_var *cv = NULL;
clicon_debug(3, "%s(%s=%s)", __FUNCTION__, name?name:"NULL", val); clicon_debug(CLIXON_DBG_DETAIL, "%s(%s=%s)", __FUNCTION__, name?name:"NULL", val);
if ((cv = cv_new(CGV_STRING)) == NULL){ if ((cv = cv_new(CGV_STRING)) == NULL){
clicon_err(OE_UNIX, errno, "cv_new"); clicon_err(OE_UNIX, errno, "cv_new");
goto done; goto done;
@ -256,43 +267,43 @@ keyval_set(char *name,
/* /*
*/ */
start : list X_EOF {clicon_debug(2,"top");_AY->ay_top=$1; YYACCEPT; } start : list X_EOF {_PARSE_DEBUG("top");_AY->ay_top=$1; YYACCEPT; }
; ;
list : list SLASH element { if (($$ = path_append($1, $3)) == NULL) YYABORT; list : list SLASH element { if (($$ = path_append($1, $3)) == NULL) YYABORT;
clicon_debug(2,"list = list / element");} _PARSE_DEBUG("list = list / element");}
| { $$ = NULL; | { $$ = NULL;
clicon_debug(2,"list = ");} _PARSE_DEBUG("list = ");}
; ;
element : api_identifier { $$=$1; element : api_identifier { $$=$1;
clicon_debug(2,"element = api_identifier");} _PARSE_DEBUG("element = api_identifier");}
| list_instance { $$=$1; | list_instance { $$=$1;
clicon_debug(2,"element = list_instance");} _PARSE_DEBUG("element = list_instance");}
; ;
api_identifier : module_name COLON IDENTIFIER { $$ = path_new($1, $3); free($1); free($3); api_identifier : module_name COLON IDENTIFIER { $$ = path_new($1, $3); free($1); free($3);
clicon_debug(2,"api_identifier = module_name : IDENTIFIER");} _PARSE_DEBUG("api_identifier = module_name : IDENTIFIER");}
| IDENTIFIER { $$ = path_new(NULL, $1); free($1); | IDENTIFIER { $$ = path_new(NULL, $1); free($1);
clicon_debug(2,"api_identifier = IDENTIFIER");} _PARSE_DEBUG("api_identifier = IDENTIFIER");}
; ;
module_name : IDENTIFIER { $$ = $1; module_name : IDENTIFIER { $$ = $1;
clicon_debug(2,"module_name = IDENTIFIER");} _PARSE_DEBUG("module_name = IDENTIFIER");}
; ;
list_instance : api_identifier EQUAL key_values { $$ = path_add_keyvalue($1, $3); list_instance : api_identifier EQUAL key_values { $$ = path_add_keyvalue($1, $3);
clicon_debug(2,"list_instance->api_identifier = key_values");} _PARSE_DEBUG("list_instance->api_identifier = key_values");}
; ;
key_values : key_values COMMA key_value { if (($$ = keyval_add($1, $3)) == NULL) YYABORT; key_values : key_values COMMA key_value { if (($$ = keyval_add($1, $3)) == NULL) YYABORT;
clicon_debug(2,"key_values->key_values , key_value");} _PARSE_DEBUG("key_values->key_values , key_value");}
| key_value { if (($$ = keyval_add(NULL, $1)) == NULL) YYABORT; | key_value { if (($$ = keyval_add(NULL, $1)) == NULL) YYABORT;
clicon_debug(2,"key_values->key_value");} _PARSE_DEBUG("key_values->key_value");}
; ;
key_value : STRING { $$ = keyval_set(NULL, $1); free($1); clicon_debug(2,"keyvalue->STRING"); } key_value : STRING { $$ = keyval_set(NULL, $1); free($1); _PARSE_DEBUG("keyvalue->STRING"); }
| { $$ = keyval_set(NULL, ""); clicon_debug(2,"keyvalue->"); } | { $$ = keyval_set(NULL, ""); _PARSE_DEBUG("keyvalue->"); }
; ;
%% %%

View file

@ -390,7 +390,7 @@ xmldb_exists(clicon_handle h,
char *filename = NULL; char *filename = NULL;
struct stat sb; struct stat sb;
clicon_debug(2, "%s %s", __FUNCTION__, db); clicon_debug(CLIXON_DBG_DETAIL, "%s %s", __FUNCTION__, db);
if (xmldb_db2file(h, db, &filename) < 0) if (xmldb_db2file(h, db, &filename) < 0)
goto done; goto done;
if (lstat(filename, &sb) < 0) if (lstat(filename, &sb) < 0)
@ -445,7 +445,7 @@ xmldb_delete(clicon_handle h,
char *filename = NULL; char *filename = NULL;
struct stat sb; struct stat sb;
clicon_debug(2, "%s %s", __FUNCTION__, db); clicon_debug(CLIXON_DBG_DETAIL, "%s %s", __FUNCTION__, db);
if (xmldb_clear(h, db) < 0) if (xmldb_clear(h, db) < 0)
goto done; goto done;
if (xmldb_db2file(h, db, &filename) < 0) if (xmldb_db2file(h, db, &filename) < 0)
@ -478,7 +478,7 @@ xmldb_create(clicon_handle h,
db_elmnt *de = NULL; db_elmnt *de = NULL;
cxobj *xt = NULL; cxobj *xt = NULL;
clicon_debug(2, "%s %s", __FUNCTION__, db); clicon_debug(CLIXON_DBG_DETAIL, "%s %s", __FUNCTION__, db);
if ((de = clicon_db_elmnt_get(h, db)) != NULL){ if ((de = clicon_db_elmnt_get(h, db)) != NULL){
if ((xt = de->de_xml) != NULL){ if ((xt = de->de_xml) != NULL){
xml_free(xt); xml_free(xt);

View file

@ -994,16 +994,11 @@ xmldb_get_cache(clicon_handle h,
if (disable_nacm_on_empty(x1t, yspec) < 0) if (disable_nacm_on_empty(x1t, yspec) < 0)
goto done; goto done;
} }
/* Copy the matching parts of the (relevant) XML tree. clicon_debug_xml(CLIXON_DBG_DETAIL, x1t, "%s", __FUNCTION__);
* If cache was empty, also update to datastore cache
*/
if (clicon_debug_get()>1)
if (clixon_xml2file(stderr, x1t, 0, 1, fprintf, 0, 0) < 0)
goto done;
*xtop = x1t; *xtop = x1t;
retval = 1; retval = 1;
done: done:
clicon_debug(2, "%s retval:%d", __FUNCTION__, retval); clicon_debug(CLIXON_DBG_DETAIL, "%s retval:%d", __FUNCTION__, retval);
if (xvec) if (xvec)
free(xvec); free(xvec);
return retval; return retval;
@ -1154,7 +1149,7 @@ xmldb_get_zerocopy(clicon_handle h,
*xtop = x0t; *xtop = x0t;
retval = 1; retval = 1;
done: done:
clicon_debug(2, "%s retval:%d", __FUNCTION__, retval); clicon_debug(CLIXON_DBG_DETAIL, "%s retval:%d", __FUNCTION__, retval);
if (xvec) if (xvec)
free(xvec); free(xvec);
return retval; return retval;

View file

@ -194,7 +194,7 @@ clixon_event_reg_fd(int fd,
e->e_type = EVENT_FD; e->e_type = EVENT_FD;
e->e_next = ee; e->e_next = ee;
ee = e; ee = e;
clicon_debug(2, "%s, registering %s", __FUNCTION__, e->e_string); clicon_debug(CLIXON_DBG_DETAIL, "%s, registering %s", __FUNCTION__, e->e_string);
return 0; return 0;
} }
@ -276,7 +276,7 @@ clixon_event_reg_timeout(struct timeval t,
} }
e->e_next = e1; e->e_next = e1;
*e_prev = e; *e_prev = e;
clicon_debug(2, "%s: %s", __FUNCTION__, str); clicon_debug(CLIXON_DBG_DETAIL, "%s: %s", __FUNCTION__, str);
return 0; return 0;
} }
@ -414,7 +414,7 @@ clixon_event_loop(clicon_handle h)
if (n==0){ /* Timeout */ if (n==0){ /* Timeout */
e = ee_timers; e = ee_timers;
ee_timers = ee_timers->e_next; ee_timers = ee_timers->e_next;
clicon_debug(2, "%s timeout: %s", __FUNCTION__, e->e_string); clicon_debug(CLIXON_DBG_DETAIL, "%s timeout: %s", __FUNCTION__, e->e_string);
if ((*e->e_fn)(0, e->e_arg) < 0){ if ((*e->e_fn)(0, e->e_arg) < 0){
free(e); free(e);
goto err; goto err;
@ -428,7 +428,7 @@ clixon_event_loop(clicon_handle h)
} }
e_next = e->e_next; e_next = e->e_next;
if(e->e_type == EVENT_FD && FD_ISSET(e->e_fd, &fdset)){ if(e->e_type == EVENT_FD && FD_ISSET(e->e_fd, &fdset)){
clicon_debug(2, "%s: FD_ISSET: %s", __FUNCTION__, e->e_string); clicon_debug(CLIXON_DBG_DETAIL, "%s: FD_ISSET: %s", __FUNCTION__, e->e_string);
if ((*e->e_fn)(e->e_fd, e->e_arg) < 0){ if ((*e->e_fn)(e->e_fd, e->e_arg) < 0){
clicon_debug(1, "%s Error in: %s", __FUNCTION__, e->e_string); clicon_debug(1, "%s Error in: %s", __FUNCTION__, e->e_string);
goto err; goto err;

View file

@ -126,10 +126,16 @@
#include "clixon_path.h" #include "clixon_path.h"
#include "clixon_instance_id_parse.h" #include "clixon_instance_id_parse.h"
/* /* Enable for debugging, steals some cycles otherwise */
also called from yacc generated code * #if 0
*/ #define _PARSE_DEBUG(s) clicon_debug(1,(s))
#else
#define _PARSE_DEBUG(s)
#endif
/*
* Also called from yacc generated code *
*/
void void
clixon_instance_id_parseerror(void *_iy, clixon_instance_id_parseerror(void *_iy,
char *s) char *s)
@ -160,7 +166,7 @@ static clixon_path *
path_append(clixon_path *list, path_append(clixon_path *list,
clixon_path *new) clixon_path *new)
{ {
clicon_debug(2, "%s()", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s()", __FUNCTION__);
if (new == NULL) if (new == NULL)
return NULL; return NULL;
ADDQ(new, list); ADDQ(new, list);
@ -175,7 +181,7 @@ static clixon_path *
path_add_keyvalue(clixon_path *cp, path_add_keyvalue(clixon_path *cp,
cvec *cvk) cvec *cvk)
{ {
clicon_debug(2, "%s()", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s()", __FUNCTION__);
if (cp == NULL) if (cp == NULL)
goto done; goto done;
cp->cp_cvk = cvk; cp->cp_cvk = cvk;
@ -189,7 +195,7 @@ path_new(char *prefix,
{ {
clixon_path *cp = NULL; clixon_path *cp = NULL;
clicon_debug(2, "%s(%s,%s)", __FUNCTION__, prefix, id); clicon_debug(CLIXON_DBG_DETAIL, "%s(%s,%s)", __FUNCTION__, prefix, id);
if ((cp = malloc(sizeof(*cp))) == NULL){ if ((cp = malloc(sizeof(*cp))) == NULL){
clicon_err(OE_UNIX, errno, "malloc"); clicon_err(OE_UNIX, errno, "malloc");
goto done; goto done;
@ -219,7 +225,7 @@ keyval_pos(char *uint)
char *reason=NULL; char *reason=NULL;
int ret; int ret;
clicon_debug(2, "%s(%s)", __FUNCTION__, uint); clicon_debug(CLIXON_DBG_DETAIL, "%s(%s)", __FUNCTION__, uint);
if ((cvv = cvec_new(1)) == NULL) { if ((cvv = cvec_new(1)) == NULL) {
clicon_err(OE_UNIX, errno, "cvec_new"); clicon_err(OE_UNIX, errno, "cvec_new");
goto done; goto done;
@ -252,7 +258,7 @@ static cvec *
keyval_add(cvec *cvv, keyval_add(cvec *cvv,
cg_var *cv) cg_var *cv)
{ {
clicon_debug(2, "%s()", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s()", __FUNCTION__);
if (cv == NULL) if (cv == NULL)
goto done; goto done;
if (cvv == NULL && if (cvv == NULL &&
@ -278,7 +284,7 @@ keyval_set(char *name,
{ {
cg_var *cv = NULL; cg_var *cv = NULL;
clicon_debug(2, "%s(%s=%s)", __FUNCTION__, name, val); clicon_debug(CLIXON_DBG_DETAIL, "%s(%s=%s)", __FUNCTION__, name, val);
if ((cv = cv_new(CGV_STRING)) == NULL){ if ((cv = cv_new(CGV_STRING)) == NULL){
clicon_err(OE_UNIX, errno, "cv_new"); clicon_err(OE_UNIX, errno, "cv_new");
goto done; goto done;
@ -307,74 +313,74 @@ keyval_set(char *name,
/* /*
*/ */
start : list X_EOF { clicon_debug(3,"top"); _IY->iy_top=$1; YYACCEPT; } start : list X_EOF { _PARSE_DEBUG("top"); _IY->iy_top=$1; YYACCEPT; }
; ;
list : list SLASH element { if (($$ = path_append($1, $3)) == NULL) YYABORT; list : list SLASH element { if (($$ = path_append($1, $3)) == NULL) YYABORT;
clicon_debug(3,"list = list / element");} _PARSE_DEBUG("list = list / element");}
| SLASH element { if (($$ = path_append(NULL, $2)) == NULL) YYABORT; | SLASH element { if (($$ = path_append(NULL, $2)) == NULL) YYABORT;
clicon_debug(3,"list = / element");} _PARSE_DEBUG("list = / element");}
; ;
element : node_id element2 { $$ = path_add_keyvalue($1, $2); element : node_id element2 { $$ = path_add_keyvalue($1, $2);
clicon_debug(3,"element = node_id element2");} _PARSE_DEBUG("element = node_id element2");}
; ;
node_id : IDENTIFIER { $$ = path_new(NULL, $1); free($1); node_id : IDENTIFIER { $$ = path_new(NULL, $1); free($1);
clicon_debug(3,"node_id = IDENTIFIER");} _PARSE_DEBUG("node_id = IDENTIFIER");}
| prefix COLON IDENTIFIER { $$ = path_new($1, $3); free($1); free($3); | prefix COLON IDENTIFIER { $$ = path_new($1, $3); free($1); free($3);
clicon_debug(3,"node_id = prefix : IDENTIFIER");} _PARSE_DEBUG("node_id = prefix : IDENTIFIER");}
; ;
prefix : IDENTIFIER { $$=$1; clicon_debug(3,"prefix = IDENTIFIER");} prefix : IDENTIFIER { $$=$1; _PARSE_DEBUG("prefix = IDENTIFIER");}
element2 : key_preds { $$=$1; clicon_debug(3,"element2 = key_preds"); } element2 : key_preds { $$=$1; _PARSE_DEBUG("element2 = key_preds"); }
| leaf_list_pred { $$=$1; clicon_debug(3,"element2 = leaf_list_pred"); } | leaf_list_pred { $$=$1; _PARSE_DEBUG("element2 = leaf_list_pred"); }
| pos { $$=$1; clicon_debug(3,"element2 = key_preds"); } | pos { $$=$1; _PARSE_DEBUG("element2 = key_preds"); }
| { $$=NULL; clicon_debug(3,"element2 = "); } | { $$=NULL; _PARSE_DEBUG("element2 = "); }
; ;
leaf_list_pred : LSQBR leaf_list_pred_expr RSQBR leaf_list_pred : LSQBR leaf_list_pred_expr RSQBR
{ if (($$ = keyval_add(NULL, $2)) == NULL) YYABORT; { if (($$ = keyval_add(NULL, $2)) == NULL) YYABORT;
clicon_debug(3,"leaf_list_pred = [ leaf_list_pred_expr ]"); } _PARSE_DEBUG("leaf_list_pred = [ leaf_list_pred_expr ]"); }
; ;
leaf_list_pred_expr : DOT EQUAL qstring { $$ = keyval_set(".", $3); free($3); leaf_list_pred_expr : DOT EQUAL qstring { $$ = keyval_set(".", $3); free($3);
clicon_debug(3,"leaf_list_pred_expr = '.=' qstring"); } _PARSE_DEBUG("leaf_list_pred_expr = '.=' qstring"); }
; ;
pos : LSQBR UINT RSQBR { $$ = keyval_pos($2); free($2); pos : LSQBR UINT RSQBR { $$ = keyval_pos($2); free($2);
clicon_debug(3,"pos = [ UINT ]"); } _PARSE_DEBUG("pos = [ UINT ]"); }
; ;
key_preds : key_preds key_pred { if (($$ = keyval_add($1, $2)) == NULL) YYABORT; key_preds : key_preds key_pred { if (($$ = keyval_add($1, $2)) == NULL) YYABORT;
clicon_debug(3,"key_preds = key_pred key_preds"); } _PARSE_DEBUG("key_preds = key_pred key_preds"); }
| key_pred { if (($$ = keyval_add(NULL, $1)) == NULL) YYABORT; | key_pred { if (($$ = keyval_add(NULL, $1)) == NULL) YYABORT;
clicon_debug(3,"key_preds = key_pred");} _PARSE_DEBUG("key_preds = key_pred");}
; ;
key_pred : LSQBR key_pred_expr RSQBR { $$ = $2; key_pred : LSQBR key_pred_expr RSQBR { $$ = $2;
clicon_debug(3,"key_pred = [ key_pred_expr ]"); } _PARSE_DEBUG("key_pred = [ key_pred_expr ]"); }
; ;
key_pred_expr : node_id_k EQUAL qstring { $$ = keyval_set($1, $3); free($1); free($3); key_pred_expr : node_id_k EQUAL qstring { $$ = keyval_set($1, $3); free($1); free($3);
clicon_debug(3,"key_pred_expr = node_id_k = qstring"); } _PARSE_DEBUG("key_pred_expr = node_id_k = qstring"); }
; ;
node_id_k : IDENTIFIER { $$ = $1; node_id_k : IDENTIFIER { $$ = $1;
clicon_debug(3,"node_id_k = IDENTIFIER %s", $1); } _PARSE_DEBUG("node_id_k = IDENTIFIER"); }
| prefix COLON IDENTIFIER { $$ = $3; /* ignore prefix in key? */ | prefix COLON IDENTIFIER { $$ = $3; /* ignore prefix in key? */
clicon_debug(3,"node_id_k = prefix %s : IDENTIFIER %s", $1, $3); free($1);} _PARSE_DEBUG("node_id_k = prefix : IDENTIFIER"); free($1);}
; ;
qstring : DQUOTE STRING DQUOTE { $$=$2; qstring : DQUOTE STRING DQUOTE { $$=$2;
clicon_debug(3,"qstring = \" string \""); } _PARSE_DEBUG("qstring = \" string \""); }
| DQUOTE DQUOTE { $$=strdup(""); | DQUOTE DQUOTE { $$=strdup("");
clicon_debug(3,"qstring = \" \""); } _PARSE_DEBUG("qstring = \" \""); }
| SQUOTE STRING SQUOTE { $$=$2; | SQUOTE STRING SQUOTE { $$=$2;
clicon_debug(3,"qstring = ' string '"); } _PARSE_DEBUG("qstring = ' string '"); }
| SQUOTE SQUOTE { $$=strdup(""); | SQUOTE SQUOTE { $$=strdup("");
clicon_debug(3,"qstring = ''"); } _PARSE_DEBUG("qstring = ''"); }
; ;
%% %%

View file

@ -183,7 +183,7 @@ json_current_new(clixon_json_yacc *jy,
char *prefix = NULL; char *prefix = NULL;
char *id = NULL; char *id = NULL;
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
/* Find colon separator and if found split into prefix:name */ /* Find colon separator and if found split into prefix:name */
if (nodeid_split(name, &prefix, &id) < 0) if (nodeid_split(name, &prefix, &id) < 0)
goto done; goto done;
@ -210,7 +210,7 @@ json_current_new(clixon_json_yacc *jy,
static int static int
json_current_pop(clixon_json_yacc *jy) json_current_pop(clixon_json_yacc *jy)
{ {
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
if (jy->jy_current) if (jy->jy_current)
jy->jy_current = xml_parent(jy->jy_current); jy->jy_current = xml_parent(jy->jy_current);
return 0; return 0;
@ -221,7 +221,7 @@ json_current_clone(clixon_json_yacc *jy)
{ {
cxobj *xn; cxobj *xn;
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
if (jy->jy_current == NULL){ if (jy->jy_current == NULL){
return -1; return -1;
} }
@ -254,7 +254,7 @@ json_current_body(clixon_json_yacc *jy,
int retval = -1; int retval = -1;
cxobj *xn; cxobj *xn;
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
if ((xn = xml_new("body", jy->jy_current, CX_BODY)) == NULL) if ((xn = xml_new("body", jy->jy_current, CX_BODY)) == NULL)
goto done; goto done;
if (value && xml_value_append(xn, value) < 0) if (value && xml_value_append(xn, value) < 0)

View file

@ -367,12 +367,12 @@ clicon_debug_get(void)
* print message if level >= dbglevel. * print message if level >= dbglevel.
* The message is sent to clicon_log. EIther to syslog, stderr or both, depending on * The message is sent to clicon_log. EIther to syslog, stderr or both, depending on
* clicon_log_init() setting * clicon_log_init() setting
* The dbgdebug level strategy is: * The dbgdebug level strategy is a mask of the following masks:
* 1: Logical debug message * 1: Basic debug message, espcially initialization
* 2: Input and output packets * 2: Input and output packets, read datastore
* 3: Message dump in hex, xpath parse trees * 4: Details: message dump in hex, xpath parse trees, etc
* * See CLIXON_DBG_* flags
* @param[in] dbglevel 0: No debug, 1-3: increasing levels of debug * @param[in] dbglevel 0: No debug, 1-7 combined of the CLIXON_DBG_ flags above
* @param[in] format Message to print as argv. * @param[in] format Message to print as argv.
* @see clicon_debug_xml Specialization for XML tree * @see clicon_debug_xml Specialization for XML tree
*/ */
@ -386,7 +386,8 @@ clicon_debug(int dbglevel,
int retval = -1; int retval = -1;
size_t trunc; size_t trunc;
if (dbglevel > clicon_debug_get()) /* compare debug level with global variable */ /* Mask debug level with global dbg variable */
if ((dbglevel & clicon_debug_get()) == 0)
return 0; return 0;
/* first round: compute length of debug message */ /* first round: compute length of debug message */
va_start(args, format); va_start(args, format);

View file

@ -1589,7 +1589,9 @@ netconf_module_load(clicon_handle h)
/* Load yang spec */ /* Load yang spec */
if (yang_spec_parse_module(h, "ietf-netconf", NULL, yspec)< 0) if (yang_spec_parse_module(h, "ietf-netconf", NULL, yspec)< 0)
goto done; goto done;
/* Load yang Netconf stream discovery */ /* Load yang Netconf stream discovery
* Actually add by default since create-subscription is in this module
*/
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277")) if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277"))
if (yang_spec_parse_module(h, "clixon-rfc5277", NULL, yspec)< 0) if (yang_spec_parse_module(h, "clixon-rfc5277", NULL, yspec)< 0)
goto done; goto done;
@ -1685,7 +1687,7 @@ netconf_db_find(cxobj *xn,
* printf("%s", cbuf_get(cb)); * printf("%s", cbuf_get(cb));
* cbuf_free(cb); * cbuf_free(cb);
* @endcode * @endcode
* @see clixon_netconf_error * @see clixon_netconf_error_fn
*/ */
int int
netconf_err2cb(cxobj *xerr, netconf_err2cb(cxobj *xerr,
@ -1877,6 +1879,7 @@ netconf_hello_server(clicon_handle h,
* @param[in] xerr Netconf error xml tree on the form: <rpc-error> * @param[in] xerr Netconf error xml tree on the form: <rpc-error>
* @param[in] format Format string * @param[in] format Format string
* @param[in] arg String argument to format (optional) * @param[in] arg String argument to format (optional)
* @see netconf_err2cb
*/ */
int int
clixon_netconf_error_fn(const char *fn, clixon_netconf_error_fn(const char *fn,
@ -2130,8 +2133,9 @@ netconf_output(int s,
char *buf = cbuf_get(cb); char *buf = cbuf_get(cb);
int len = cbuf_len(cb); int len = cbuf_len(cb);
clicon_debug(1, "SEND %s", msg); clicon_debug(CLIXON_DBG_MSG, "Send ext: %s", cbuf_get(cb));
if (clicon_debug_get() > 1){ /* XXX: below only works to stderr, clicon_debug may log to syslog */ #if 0 // Extra sanity check for debugging
{
cxobj *xt = NULL; cxobj *xt = NULL;
if (clixon_xml_parse_string(buf, YB_NONE, NULL, &xt, NULL) == 0){ if (clixon_xml_parse_string(buf, YB_NONE, NULL, &xt, NULL) == 0){
if (clixon_xml2file(stderr, xml_child_i(xt, 0), 0, 0, fprintf, 0, 0) < 0) if (clixon_xml2file(stderr, xml_child_i(xt, 0), 0, 0, fprintf, 0, 0) < 0)
@ -2140,6 +2144,7 @@ netconf_output(int s,
xml_free(xt); xml_free(xt);
} }
} }
#endif
if (write(s, buf, len) < 0){ if (write(s, buf, len) < 0){
if (errno == EPIPE) if (errno == EPIPE)
clicon_debug(1, "%s write err SIGPIPE", __FUNCTION__); clicon_debug(1, "%s write err SIGPIPE", __FUNCTION__);
@ -2224,7 +2229,7 @@ netconf_input_chunked_framing(char ch,
{ {
int retval = 0; int retval = 0;
clicon_debug(2, "%s ch:%c(%d) state:%d size:%zu", __FUNCTION__, ch, ch, *state, *size); clicon_debug(CLIXON_DBG_DETAIL, "%s ch:%c(%d) state:%d size:%zu", __FUNCTION__, ch, ch, *state, *size);
switch (*state){ switch (*state){
case 0: case 0:
if (ch == '\n'){ if (ch == '\n'){

View file

@ -211,7 +211,7 @@ parse_configfile_one(const char *filename,
clicon_err(OE_UNIX, errno, "open configure file: %s", filename); clicon_err(OE_UNIX, errno, "open configure file: %s", filename);
return -1; return -1;
} }
clicon_debug(2, "%s: Reading config file %s", __FUNCTION__, filename); clicon_debug(CLIXON_DBG_DETAIL, "%s: Reading config file %s", __FUNCTION__, filename);
if ((ret = clixon_xml_parse_file(fp, yspec?YB_MODULE:YB_NONE, yspec, &xt, &xerr)) < 0) if ((ret = clixon_xml_parse_file(fp, yspec?YB_MODULE:YB_NONE, yspec, &xt, &xerr)) < 0)
goto done; goto done;
if (ret == 0){ if (ret == 0){

View file

@ -805,7 +805,7 @@ api_path2xpath_cvv(cvec *api_path,
nsc = NULL; nsc = NULL;
} }
done: done:
clicon_debug(2, "%s retval:%d", __FUNCTION__, retval); clicon_debug(CLIXON_DBG_DETAIL, "%s retval:%d", __FUNCTION__, retval);
if (cberr) if (cberr)
cbuf_free(cberr); cbuf_free(cberr);
if (valvec) if (valvec)
@ -1120,7 +1120,7 @@ api_path2xml_vec(char **vec,
ok: ok:
retval = 1; /* OK */ retval = 1; /* OK */
done: done:
clicon_debug(2, "%s retval:%d", __FUNCTION__, retval); clicon_debug(CLIXON_DBG_DETAIL, "%s retval:%d", __FUNCTION__, retval);
if (cberr) if (cberr)
cbuf_free(cberr); cbuf_free(cberr);
if (prefix) if (prefix)
@ -1185,7 +1185,7 @@ api_path2xml(char *api_path,
cxobj *xroot; cxobj *xroot;
cbuf *cberr = NULL; cbuf *cberr = NULL;
clicon_debug(2, "%s api_path:%s", __FUNCTION__, api_path); clicon_debug(CLIXON_DBG_DETAIL, "%s api_path:%s", __FUNCTION__, api_path);
if ((cberr = cbuf_new()) == NULL){ if ((cberr = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new"); clicon_err(OE_UNIX, errno, "cbuf_new");
goto done; goto done;

View file

@ -909,7 +909,7 @@ clixon_process_sched_register(clicon_handle h,
struct timeval t; struct timeval t;
struct timeval t1 = {0, 100000}; /* 100ms */ struct timeval t1 = {0, 100000}; /* 100ms */
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
gettimeofday(&t, NULL); gettimeofday(&t, NULL);
if (delay) if (delay)
timeradd(&t, &t1, &t); timeradd(&t, &t1, &t);
@ -917,7 +917,7 @@ clixon_process_sched_register(clicon_handle h,
goto done; goto done;
retval = 0; retval = 0;
done: done:
clicon_debug(2, "%s retval:%d", __FUNCTION__, retval); clicon_debug(CLIXON_DBG_DETAIL, "%s retval:%d", __FUNCTION__, retval);
return retval; return retval;
} }

View file

@ -189,12 +189,13 @@ clicon_msg_decode(struct clicon_msg *msg,
char *xmlstr; char *xmlstr;
int ret; int ret;
clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
/* hdr */ /* hdr */
if (id) if (id)
*id = ntohl(msg->op_id); *id = ntohl(msg->op_id);
/* body */ /* body */
xmlstr = msg->op_body; xmlstr = msg->op_body;
clicon_debug(2, "%s %s", __FUNCTION__, xmlstr); // XXX clicon_debug(CLIXON_DBG_MSG, "Recv: %s", xmlstr);
if ((ret = clixon_xml_parse_string(xmlstr, yspec?YB_RPC:YB_NONE, yspec, xml, xerr)) < 0) if ((ret = clixon_xml_parse_string(xmlstr, yspec?YB_RPC:YB_NONE, yspec, xml, xerr)) < 0)
goto done; goto done;
if (ret == 0) if (ret == 0)
@ -229,7 +230,7 @@ clicon_connect_unix(clicon_handle h,
addr.sun_family = AF_UNIX; addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, sockpath, sizeof(addr.sun_path)-1); strncpy(addr.sun_path, sockpath, sizeof(addr.sun_path)-1);
clicon_debug(2, "%s: connecting to %s", __FUNCTION__, addr.sun_path); clicon_debug(CLIXON_DBG_DETAIL, "%s: connecting to %s", __FUNCTION__, addr.sun_path);
if (connect(s, (struct sockaddr *)&addr, SUN_LEN(&addr)) < 0){ if (connect(s, (struct sockaddr *)&addr, SUN_LEN(&addr)) < 0){
if (errno == EACCES) if (errno == EACCES)
clicon_err(OE_CFG, errno, "connecting unix socket: %s. " clicon_err(OE_CFG, errno, "connecting unix socket: %s. "
@ -292,16 +293,20 @@ atomicio(ssize_t (*fn) (int, void *, size_t),
return (pos); return (pos);
} }
#if 0 // Extra debug
/*! Print message on debug. Log if syslog, stderr if not /*! Print message on debug. Log if syslog, stderr if not
* @param[in] msg CLICON msg * @param[in] msg CLICON msg
*/ */
static int static int
msg_dump(struct clicon_msg *msg) msg_dump(int dbglevel,
struct clicon_msg *msg)
{ {
int retval = -1; int retval = -1;
cbuf *cb = NULL; cbuf *cb = NULL;
int i; int i;
if ((dbglevel & clicon_debug_get()) == 0) /* compare debug level with global variable */
goto ok;
if ((cb = cbuf_new()) == NULL){ if ((cb = cbuf_new()) == NULL){
clicon_err(OE_CFG, errno, "cbuf_new"); clicon_err(OE_CFG, errno, "cbuf_new");
goto done; goto done;
@ -310,7 +315,7 @@ msg_dump(struct clicon_msg *msg)
for (i=0; i<ntohl(msg->op_len); i++){ for (i=0; i<ntohl(msg->op_len); i++){
cprintf(cb, "%02x", ((char*)msg)[i]&0xff); cprintf(cb, "%02x", ((char*)msg)[i]&0xff);
if ((i+1)%32==0){ if ((i+1)%32==0){
clicon_debug(2, "%s", cbuf_get(cb)); clicon_debug(CLIXON_DBG_DETAIL, "%s", cbuf_get(cb));
cbuf_reset(cb); cbuf_reset(cb);
cprintf(cb, "%s:", __FUNCTION__); cprintf(cb, "%s:", __FUNCTION__);
} }
@ -318,13 +323,15 @@ msg_dump(struct clicon_msg *msg)
if ((i+1)%4==0) if ((i+1)%4==0)
cprintf(cb, " "); cprintf(cb, " ");
} }
clicon_debug(2, "%s", cbuf_get(cb)); clicon_debug(dbglevel, "%s", cbuf_get(cb));
ok:
retval = 0; retval = 0;
done: done:
if (cb) if (cb)
cbuf_free(cb); cbuf_free(cb);
return retval; return retval;
} }
#endif
/*! Send a CLICON netconf message using internal IPC message /*! Send a CLICON netconf message using internal IPC message
* *
@ -339,10 +346,12 @@ clicon_msg_send(int s,
int retval = -1; int retval = -1;
int e; int e;
clicon_debug(2, "%s: send msg len=%d", clicon_debug(CLIXON_DBG_DETAIL, "%s: send msg len=%d",
__FUNCTION__, ntohl(msg->op_len)); __FUNCTION__, ntohl(msg->op_len));
if (clicon_debug_get() > 2) #if 0 // Extra debug
msg_dump(msg); msg_dump(CLIXON_DBG_EXTRA, msg);
#endif
clicon_debug(CLIXON_DBG_MSG, "Send: %s", msg->op_body);
if (atomicio((ssize_t (*)(int, void *, size_t))write, if (atomicio((ssize_t (*)(int, void *, size_t))write,
s, msg, ntohl(msg->op_len)) < 0){ s, msg, ntohl(msg->op_len)) < 0){
e = errno; e = errno;
@ -384,6 +393,7 @@ clicon_msg_rcv(int s,
sigfn_t oldhandler; sigfn_t oldhandler;
uint32_t mlen; uint32_t mlen;
clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
*eof = 0; *eof = 0;
if (0) if (0)
set_signal(SIGINT, atomicio_sig_handler, &oldhandler); set_signal(SIGINT, atomicio_sig_handler, &oldhandler);
@ -402,7 +412,7 @@ clicon_msg_rcv(int s,
goto done; goto done;
} }
mlen = ntohl(hdr.op_len); mlen = ntohl(hdr.op_len);
clicon_debug(2, "%s: rcv msg len=%d", clicon_debug(CLIXON_DBG_DETAIL, "%s: rcv msg len=%d",
__FUNCTION__, mlen); __FUNCTION__, mlen);
if ((*msg = (struct clicon_msg *)malloc(mlen)) == NULL){ if ((*msg = (struct clicon_msg *)malloc(mlen)) == NULL){
clicon_err(OE_CFG, errno, "malloc"); clicon_err(OE_CFG, errno, "malloc");
@ -417,8 +427,10 @@ clicon_msg_rcv(int s,
clicon_err(OE_CFG, errno, "body too short"); clicon_err(OE_CFG, errno, "body too short");
goto done; goto done;
} }
if (clicon_debug_get() > 2) #if 0 // Extra debug
msg_dump(*msg); msg_dump(CLIXON_DBG_EXTRA, *msg);
#endif
clicon_debug(CLIXON_DBG_MSG, "Recv: %s", (*msg)->op_body);
retval = 0; retval = 0;
done: done:
if (0) if (0)
@ -447,7 +459,7 @@ clicon_msg_rcv1(int s,
int xml_state = 0; int xml_state = 0;
int poll; int poll;
clicon_debug(1, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
*eof = 0; *eof = 0;
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
while (1){ while (1){
@ -484,6 +496,7 @@ clicon_msg_rcv1(int s,
break; /* No data to read */ break; /* No data to read */
} /* while */ } /* while */
ok: ok:
clicon_debug(CLIXON_DBG_MSG, "Recv: %s", cbuf_get(cb));
retval = 0; retval = 0;
done: done:
clicon_debug(1, "%s done", __FUNCTION__); clicon_debug(1, "%s done", __FUNCTION__);
@ -502,6 +515,8 @@ clicon_msg_send1(int s,
{ {
int retval = -1; int retval = -1;
clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
clicon_debug(CLIXON_DBG_MSG, "Send: %s", cbuf_get(cb));
if (atomicio((ssize_t (*)(int, void *, size_t))write, if (atomicio((ssize_t (*)(int, void *, size_t))write,
s, cbuf_get(cb), cbuf_len(cb)) < 0){ s, cbuf_get(cb), cbuf_len(cb)) < 0){
clicon_err(OE_CFG, errno, "atomicio"); clicon_err(OE_CFG, errno, "atomicio");

View file

@ -201,7 +201,6 @@ clicon_rpc_msg(clicon_handle h,
#ifdef RPC_USERNAME_ASSERT #ifdef RPC_USERNAME_ASSERT
assert(strstr(msg->op_body, "username")!=NULL); /* XXX */ assert(strstr(msg->op_body, "username")!=NULL); /* XXX */
#endif #endif
clicon_debug(2, "%s request:%s", __FUNCTION__, msg->op_body);
/* Create a socket and connect to it, either UNIX, IPv4 or IPv6 per config options */ /* Create a socket and connect to it, either UNIX, IPv4 or IPv6 per config options */
if (clicon_rpc_msg_once(h, msg, &retdata, &eof, &s) < 0) if (clicon_rpc_msg_once(h, msg, &retdata, &eof, &s) < 0)
goto done; goto done;
@ -232,7 +231,6 @@ clicon_rpc_msg(clicon_handle h,
goto done; goto done;
#endif #endif
} }
clicon_debug(2, "%s retdata:%s", __FUNCTION__, retdata);
if (retdata){ if (retdata){
/* Cannot populate xret here because need to know RPC name (eg "lock") in order to associate yang /* Cannot populate xret here because need to know RPC name (eg "lock") in order to associate yang

View file

@ -251,7 +251,7 @@ stream_timer_setup(int fd,
struct stream_replay *r; struct stream_replay *r;
struct stream_replay *r1; struct stream_replay *r1;
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
/* Go thru callbacks and see if any have timed out, if so remove them /* Go thru callbacks and see if any have timed out, if so remove them
* Could also be done by a separate timer. * Could also be done by a separate timer.
*/ */
@ -502,7 +502,7 @@ stream_notify1(clicon_handle h,
int retval = -1; int retval = -1;
struct stream_subscription *ss; struct stream_subscription *ss;
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
/* Go thru all subscriptions and find matches */ /* Go thru all subscriptions and find matches */
if ((ss = es->es_subscription) != NULL) if ((ss = es->es_subscription) != NULL)
do { do {
@ -557,7 +557,7 @@ stream_notify(clicon_handle h,
struct timeval tv; struct timeval tv;
event_stream_t *es; event_stream_t *es;
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
if ((es = stream_find(h, stream)) == NULL) if ((es = stream_find(h, stream)) == NULL)
goto ok; goto ok;
va_start(args, event); va_start(args, event);
@ -633,7 +633,7 @@ stream_notify_xml(clicon_handle h,
struct timeval tv; struct timeval tv;
event_stream_t *es; event_stream_t *es;
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
if ((es = stream_find(h, stream)) == NULL) if ((es = stream_find(h, stream)) == NULL)
goto ok; goto ok;
if ((yspec = clicon_dbspec_yang(h)) == NULL){ if ((yspec = clicon_dbspec_yang(h)) == NULL){

View file

@ -2436,7 +2436,7 @@ clicon_log_xml(int level,
* @param[in] x XML tree that is logged without prettyprint * @param[in] x XML tree that is logged without prettyprint
* @param[in] format Message to print as argv. * @param[in] format Message to print as argv.
* @see clicon_log_xml For syslog * @see clicon_log_xml For syslog
* @see clicon_debug base function * @see clicon_debug base function and see CLIXON_DBG_* flags
*/ */
int int
clicon_debug_xml(int dbglevel, clicon_debug_xml(int dbglevel,
@ -2450,7 +2450,8 @@ clicon_debug_xml(int dbglevel,
int retval = -1; int retval = -1;
size_t trunc; size_t trunc;
if (dbglevel > clicon_debug_get()) /* compare debug level with global variable */ /* Mask debug level with global dbg variable */
if ((dbglevel & clicon_debug_get()) == 0)
return 0; return 0;
/* Print xml as cbuf */ /* Print xml as cbuf */
if ((cb = cbuf_new()) == NULL){ if ((cb = cbuf_new()) == NULL){

View file

@ -541,7 +541,7 @@ _xml_parse(const char *str,
int failed = 0; /* yang assignment */ int failed = 0; /* yang assignment */
int i; int i;
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
if (strlen(str) == 0){ if (strlen(str) == 0){
return 1; /* OK */ return 1; /* OK */
} }

View file

@ -205,7 +205,7 @@ xml2cvec(cxobj *xt,
} }
} }
if (clicon_debug_get() > 1){ if (clicon_debug_get() > 1){
clicon_debug(2, "%s cvv:\n", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s cvv:\n", __FUNCTION__);
cvec_print(stderr, cvv); cvec_print(stderr, cvv);
} }
*cvv0 = cvv; *cvv0 = cvv;
@ -825,6 +825,14 @@ xml2xpath1(cxobj *x,
* @param[out] xpath Malloced xpath string. Need to free() after use * @param[out] xpath Malloced xpath string. Need to free() after use
* @retval 0 OK * @retval 0 OK
* @retval -1 Error. (eg XML malformed) * @retval -1 Error. (eg XML malformed)
* @code
* char *xpath = NULL;
* cxobj *x;
* ... x is inside an xml tree ...
* if (xml2xpath(x, nsc, &xpath) < 0)
* err;
* free(xpath);
* @endcode
* @note x needs to be bound to YANG, see eg xml_bind_yang() * @note x needs to be bound to YANG, see eg xml_bind_yang()
*/ */
int int

View file

@ -86,7 +86,7 @@
/* Enable for debugging, steals some cycles otherwise */ /* Enable for debugging, steals some cycles otherwise */
#if 0 #if 0
#define _PARSE_DEBUG(s) clicon_debug(3,(s)) #define _PARSE_DEBUG(s) clicon_debug(1,(s))
#else #else
#define _PARSE_DEBUG(s) #define _PARSE_DEBUG(s)
#endif #endif

View file

@ -384,7 +384,7 @@ xml_cmp(cxobj *x1,
break; break;
} /* switch */ } /* switch */
done: done:
clicon_debug(3, "%s %s %s eq:%d nr: %d %d yi: %d %d", __FUNCTION__, xml_name(x1), xml_name(x2), equal, nr1, nr2, yi1, yi2); clicon_debug(CLIXON_DBG_DETAIL, "%s %s %s eq:%d nr: %d %d yi: %d %d", __FUNCTION__, xml_name(x1), xml_name(x2), equal, nr1, nr2, yi1, yi2);
return equal; return equal;
} }

View file

@ -393,7 +393,7 @@ xpath_tree_eq(xpath_tree *xt1, /* pattern */
(xt2->xs_type == XP_PRIME_NR || xt2->xs_type == XP_PRIME_STR)) (xt2->xs_type == XP_PRIME_NR || xt2->xs_type == XP_PRIME_STR))
#endif #endif
){ ){
clicon_debug(2, "%s type %s vs %s\n", __FUNCTION__, clicon_debug(CLIXON_DBG_DETAIL, "%s type %s vs %s\n", __FUNCTION__,
xpath_tree_int2str(xt1->xs_type), xpath_tree_int2str(xt1->xs_type),
xpath_tree_int2str(xt2->xs_type)); xpath_tree_int2str(xt2->xs_type));
goto neq; goto neq;
@ -405,19 +405,19 @@ xpath_tree_eq(xpath_tree *xt1, /* pattern */
goto eq; goto eq;
} }
if (xt1->xs_int != xt2->xs_int){ if (xt1->xs_int != xt2->xs_int){
clicon_debug(2, "%s int\n", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s int\n", __FUNCTION__);
goto neq; goto neq;
} }
if (xt1->xs_double != xt2->xs_double){ if (xt1->xs_double != xt2->xs_double){
clicon_debug(2, "%s double\n", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s double\n", __FUNCTION__);
goto neq; goto neq;
} }
if (clicon_strcmp(xt1->xs_s0, xt2->xs_s0)){ if (clicon_strcmp(xt1->xs_s0, xt2->xs_s0)){
clicon_debug(2, "%s s0\n", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s s0\n", __FUNCTION__);
goto neq; goto neq;
} }
if (clicon_strcmp(xt1->xs_s1, xt2->xs_s1)){ if (clicon_strcmp(xt1->xs_s1, xt2->xs_s1)){
clicon_debug(2, "%s s1\n", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s s1\n", __FUNCTION__);
goto neq; goto neq;
} }
xc1 = xt1->xs_c0; xc1 = xt1->xs_c0;
@ -426,7 +426,7 @@ xpath_tree_eq(xpath_tree *xt1, /* pattern */
; ;
else{ else{
if (xc1 == NULL || xc2 == NULL){ if (xc1 == NULL || xc2 == NULL){
clicon_debug(2, "%s NULL\n", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s NULL\n", __FUNCTION__);
goto neq; goto neq;
} }
if ((ret = xpath_tree_eq(xc1, xc2, vec, len)) < 0) if ((ret = xpath_tree_eq(xc1, xc2, vec, len)) < 0)
@ -440,7 +440,7 @@ xpath_tree_eq(xpath_tree *xt1, /* pattern */
; ;
else{ else{
if (xc1 == NULL || xc2 == NULL){ if (xc1 == NULL || xc2 == NULL){
clicon_debug(2, "%s NULL\n", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s NULL\n", __FUNCTION__);
goto neq; goto neq;
} }
if ((ret = xpath_tree_eq(xc1, xc2, vec, len)) < 0) if ((ret = xpath_tree_eq(xc1, xc2, vec, len)) < 0)
@ -531,7 +531,7 @@ xpath_parse(const char *xpath,
clixon_xpath_yacc xpy = {0,}; clixon_xpath_yacc xpy = {0,};
cbuf *cb = NULL; cbuf *cb = NULL;
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
if (xpath == NULL){ if (xpath == NULL){
clicon_err(OE_XML, EINVAL, "XPath is NULL"); clicon_err(OE_XML, EINVAL, "XPath is NULL");
goto done; goto done;
@ -556,7 +556,7 @@ xpath_parse(const char *xpath,
goto done; goto done;
} }
xpath_tree_print_cb(cb, xpy.xpy_top); xpath_tree_print_cb(cb, xpy.xpy_top);
clicon_debug(3, "xpath parse tree:\n%s", cbuf_get(cb)); clicon_debug(CLIXON_DBG_DETAIL, "xpath parse tree:\n%s", cbuf_get(cb));
} }
xpath_parse_exit(&xpy); xpath_parse_exit(&xpy);
xpath_scan_exit(&xpy); xpath_scan_exit(&xpy);
@ -602,7 +602,7 @@ xpath_vec_ctx(cxobj *xcur,
xpath_tree *xptree = NULL; xpath_tree *xptree = NULL;
xp_ctx xc = {0,}; xp_ctx xc = {0,};
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
if (xpath_parse(xpath, &xptree) < 0) if (xpath_parse(xpath, &xptree) < 0)
goto done; goto done;
xc.xc_type = XT_NODESET; xc.xc_type = XT_NODESET;
@ -1082,7 +1082,7 @@ xpath2canonical(const char *xpath0,
cbuf *xcb = NULL; cbuf *xcb = NULL;
int ret; int ret;
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
/* Parse input xpath into an xpath-tree */ /* Parse input xpath into an xpath-tree */
if (xpath_parse(xpath0, &xpt) < 0) if (xpath_parse(xpath0, &xpt) < 0)
goto done; goto done;

View file

@ -277,7 +277,7 @@ nodetest_recursive(cxobj *xn,
xsub = NULL; xsub = NULL;
while ((xsub = xml_child_each(xn, xsub, node_type)) != NULL) { while ((xsub = xml_child_each(xn, xsub, node_type)) != NULL) {
if (nodetest_eval(xsub, nodetest, nsc, localonly) == 1){ if (nodetest_eval(xsub, nodetest, nsc, localonly) == 1){
clicon_debug(2, "%s %x %x", __FUNCTION__, flags, xml_flag(xsub, flags)); clicon_debug(CLIXON_DBG_DETAIL, "%s %x %x", __FUNCTION__, flags, xml_flag(xsub, flags));
if (flags==0x0 || xml_flag(xsub, flags)) if (flags==0x0 || xml_flag(xsub, flags))
if (cxvec_append(xsub, &vec, &veclen) < 0) if (cxvec_append(xsub, &vec, &veclen) < 0)
goto done; goto done;

View file

@ -466,7 +466,7 @@ yang_path_arg(yang_stmt *ys,
xp_yang_ctx *xyr = NULL; xp_yang_ctx *xyr = NULL;
xp_yang_ctx *xy = NULL; xp_yang_ctx *xy = NULL;
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
if (path_arg == NULL){ if (path_arg == NULL){
clicon_err(OE_XML, EINVAL, "path-arg is NULL"); clicon_err(OE_XML, EINVAL, "path-arg is NULL");
goto done; goto done;

View file

@ -1014,7 +1014,6 @@ yn_each(yang_stmt *yparent,
return NULL; return NULL;
for (i=yprev?yprev->_ys_vector_i+1:0; i<yparent->ys_len; i++){ for (i=yprev?yprev->_ys_vector_i+1:0; i<yparent->ys_len; i++){
if ((yc = yparent->ys_stmt[i]) == NULL){ if ((yc = yparent->ys_stmt[i]) == NULL){
assert(yc); /* XXX Check if happens */
continue; continue;
} }
/* make room for other conditionals */ /* make room for other conditionals */
@ -1366,7 +1365,7 @@ yang_find_prefix_by_namespace(yang_stmt *ys,
yang_stmt *yimport; yang_stmt *yimport;
yang_stmt *yprefix; yang_stmt *yprefix;
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
if (prefix == NULL){ if (prefix == NULL){
clicon_err(OE_YANG, EINVAL, "prefix is NULL"); clicon_err(OE_YANG, EINVAL, "prefix is NULL");
goto done; goto done;
@ -2957,7 +2956,7 @@ yang_features(clicon_handle h,
ret = 0; ret = 0;
if (yang_subparse(yang_argument_get(ys), ys, YA_IF_FEATURE, mainfile, 1, &ret) < 0) if (yang_subparse(yang_argument_get(ys), ys, YA_IF_FEATURE, mainfile, 1, &ret) < 0)
goto done; goto done;
clicon_debug(2, "%s %s %d", __FUNCTION__, yang_argument_get(ys), ret); clicon_debug(CLIXON_DBG_DETAIL, "%s %s %d", __FUNCTION__, yang_argument_get(ys), ret);
if (ret == 0) if (ret == 0)
goto disabled; goto disabled;
} }

View file

@ -236,7 +236,7 @@ yang_augment_node(clicon_handle h,
} }
/* */ /* */
schema_nodeid = yang_argument_get(ys); schema_nodeid = yang_argument_get(ys);
clicon_debug(2, "%s %s", __FUNCTION__, schema_nodeid); clicon_debug(CLIXON_DBG_DETAIL, "%s %s", __FUNCTION__, schema_nodeid);
/* Find the target */ /* Find the target */
if (yang_abs_schema_nodeid(ys, schema_nodeid, &ytarget) < 0) if (yang_abs_schema_nodeid(ys, schema_nodeid, &ytarget) < 0)
goto done; goto done;
@ -881,7 +881,7 @@ filename2revision(const char *filename,
clicon_err(OE_UNIX, errno, "strdup"); clicon_err(OE_UNIX, errno, "strdup");
goto done; goto done;
} }
clicon_debug(2, "%s %s", __FUNCTION__, base); clicon_debug(CLIXON_DBG_DETAIL, "%s %s", __FUNCTION__, base);
if ((p = rindex(base, '.')) != NULL) /* strip postfix .yang */ if ((p = rindex(base, '.')) != NULL) /* strip postfix .yang */
*p = '\0'; *p = '\0';
if ((p = index(base, '@')) != NULL){ /* extract revision date */ if ((p = index(base, '@')) != NULL){ /* extract revision date */
@ -904,18 +904,16 @@ filename2revision(const char *filename,
* @param[in] h CLICON handle * @param[in] h CLICON handle
* @param[in] module Name of main YANG module. * @param[in] module Name of main YANG module.
* @param[in] revision Revision or NULL * @param[in] revision Revision or NULL
* @param[out] revactual Actual revision (if retval=1) * @param[out] fbuf Buffer containing filename or NULL (if retval=1)
* @param[out] fbuf Buffer containing filename (if retval=1) * @retval 1 Match found, Most recent entry returned in fbuf
* @retval 1 Match found, Most recent entry returned in fbuf and revactual
* @retval 0 No matching entry found * @retval 0 No matching entry found
* @retval -1 Error * @retval -1 Error
* @note for bootstrapping, dir may have to be set. * @note for bootstrapping, dir may have to be set.
*/ */
static int int
yang_parse_find_match(clicon_handle h, yang_file_find_match(clicon_handle h,
const char *module, const char *module,
const char *revision, const char *revision,
uint32_t *revactual,
cbuf *fbuf) cbuf *fbuf)
{ {
int retval = -1; int retval = -1;
@ -960,6 +958,7 @@ yang_parse_find_match(clicon_handle h,
/* Entries are sorted, last entry should be most recent date /* Entries are sorted, last entry should be most recent date
*/ */
if (ndp != 0){ if (ndp != 0){
if (fbuf)
cprintf(fbuf, "%s/%s", dir, dp[ndp-1].d_name); cprintf(fbuf, "%s/%s", dir, dp[ndp-1].d_name);
if (dp) if (dp)
free(dp); free(dp);
@ -990,6 +989,7 @@ yang_parse_find_match(clicon_handle h,
bestcv = cv; bestcv = cv;
} }
if (bestcv){ if (bestcv){
if (fbuf)
cprintf(fbuf, "%s", cv_string_get(bestcv)); /* file path */ cprintf(fbuf, "%s", cv_string_get(bestcv)); /* file path */
retval = 1; /* found */ retval = 1; /* found */
goto done; goto done;
@ -1080,7 +1080,7 @@ yang_parse_module(clicon_handle h,
goto done; goto done;
} }
/* Match a yang file with or without revision in yang-dir list */ /* Match a yang file with or without revision in yang-dir list */
if ((nr = yang_parse_find_match(h, module, revision, &revf, fbuf)) < 0) if ((nr = yang_file_find_match(h, module, revision, fbuf)) < 0)
goto done; goto done;
if (nr == 0){ if (nr == 0){
if ((cb = cbuf_new()) == NULL){ if ((cb = cbuf_new()) == NULL){

View file

@ -79,7 +79,7 @@ yang_subparse(char *str,
int retval = -1; int retval = -1;
clixon_yang_sub_parse_yacc ife = {0,}; clixon_yang_sub_parse_yacc ife = {0,};
clicon_debug(2, "%s %s", __FUNCTION__, str); clicon_debug(CLIXON_DBG_DETAIL, "%s %s", __FUNCTION__, str);
ife.if_parse_string = str; ife.if_parse_string = str;
ife.if_linenum = linenum; ife.if_linenum = linenum;
if (enabled) if (enabled)
@ -120,7 +120,7 @@ yang_schema_nodeid_subparse(char *str,
int retval = -1; int retval = -1;
clixon_yang_schemanode_yacc ife = {0,}; clixon_yang_schemanode_yacc ife = {0,};
clicon_debug(3, "%s %s", __FUNCTION__, str); clicon_debug(CLIXON_DBG_DETAIL, "%s %s", __FUNCTION__, str);
ife.if_parse_string = str; ife.if_parse_string = str;
ife.if_linenum = linenum; ife.if_linenum = linenum;
ife.if_mainfile = mainfile; ife.if_mainfile = mainfile;

View file

@ -55,9 +55,9 @@ EOF
cat <<EOF > $dir/startup_db cat <<EOF > $dir/startup_db
<${DATASTORE_TOP}> <${DATASTORE_TOP}>
<yang-library xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library"> <yang-library xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library">
<content-id>42</content-id> <!-- XXX should be on yang-library level -->
<module-set> <module-set>
<name>default</name> <name>default</name>
<content-id>42</content-id>
<module> <module>
<name>clixon-example</name> <name>clixon-example</name>
<revision>2000-01-01</revision> <revision>2000-01-01</revision>

View file

@ -22,7 +22,7 @@ NCWAIT=10 # Wait (netconf valgrind may need more time)
DATE=$(date -u +"%Y-%m-%d") DATE=$(date -u +"%Y-%m-%d")
cfg=$dir/conf.xml cfg=$dir/conf.xml
fyang=$dir/stream.yang fyang=$dir/example.yang
xml=$dir/xml.xml xml=$dir/xml.xml
# <CLICON_YANG_MODULE_MAIN>example</CLICON_YANG_MODULE_MAIN> # <CLICON_YANG_MODULE_MAIN>example</CLICON_YANG_MODULE_MAIN>

View file

@ -106,7 +106,7 @@ EOF
fi fi
for modstate in true false; do for modstate in true false; do
if $modstate; then if $modstate; then
modstatestr="<yang-library xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\"><module-set><name>default</name><content-id>42</content-id><module><name>A</name><revision>2016-01-01</revision><namespace>urn:example:a</namespace></module></module-set></yang-library>" modstatestr="<yang-library xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\"><content-id>42</content-id><module-set><name>default</name><module><name>A</name><revision>2016-01-01</revision><namespace>urn:example:a</namespace></module></module-set></yang-library>"
# modstatestr="<modules-state xmlns=\"urn:example:a\"><module-set-id>42</module-set-id><module><name>A</name><revision>2016-01-01</revision><namespace>urn:example:a</namespace></module></modules-state>" # modstatestr="<modules-state xmlns=\"urn:example:a\"><module-set-id>42</module-set-id><module><name>A</name><revision>2016-01-01</revision><namespace>urn:example:a</namespace></module></modules-state>"
else else
modstatestr="" modstatestr=""

105
test/test_yang_schema_mount.sh Executable file
View file

@ -0,0 +1,105 @@
#!/usr/bin/env bash
# Test for RFC8528 YANG Schema Mount
# Only if compiled with YANG_SCHEMA_MOUNT
# Magic line must be first in script (see README.md)
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
if true; then # enable YANG_SCHEMA_MOUNT
echo "...skipped: YANG_SCHEMA_MOUNT NYI"
rm -rf $dir
if [ -z "${CLIXON_YANG_PATCH}" -a "$s" = $0 ]; then exit 0; else return 0; fi
fi
APPNAME=example
cfg=$dir/conf_mount.xml
fyang=$dir/clixon-example.yang
cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config">
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
<CLICON_YANG_DIR>${YANG_INSTALLDIR}</CLICON_YANG_DIR>
<CLICON_YANG_DIR>${dir}</CLICON_YANG_DIR>
<CLICON_YANG_MAIN_FILE>$fyang</CLICON_YANG_MAIN_FILE>
<CLICON_YANG_LIBRARY>true</CLICON_YANG_LIBRARY>
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
<CLICON_SOCK>/usr/local/var/$APPNAME/$APPNAME.sock</CLICON_SOCK>
<CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
<CLICON_BACKEND_PIDFILE>/usr/local/var/$APPNAME/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE>
<CLICON_XMLDB_DIR>$dir</CLICON_XMLDB_DIR>
<CLICON_NETCONF_MONITORING>true</CLICON_NETCONF_MONITORING>
<CLICON_VALIDATE_STATE_XML>true</CLICON_VALIDATE_STATE_XML>
</clixon-config>
EOF
cat <<EOF > $fyang
module clixon-example{
yang-version 1.1;
namespace "urn:example:clixon";
prefix ex;
import ietf-yang-schema-mount {
prefix yangmnt;
}
container top{
list root{
key name;
leaf name{
type string;
}
yangmnt:mount-point "myroot"{
description "Root for other yang models";
}
}
}
}
EOF
new "test params: -f $cfg"
if [ $BE -ne 0 ]; then
new "kill old backend"
sudo clixon_backend -zf $cfg
if [ $? -ne 0 ]; then
err
fi
new "start backend -s init -f $cfg"
start_backend -s init -f $cfg
fi
new "wait backend"
wait_backend
new "Add two mountpoints: x and y"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><top xmlns=\"urn:example:clixon\"><root><name>x</name></root><root><name>y</name></root></top></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
new "netconf commit"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><commit/></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
new "Retrieve schema-mounts with <get> Operation"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get><filter type=\"subtree\"><schema-mounts xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-schema-mount\"></schema-mounts></filter></get></rpc>" "<rpc-reply $DEFAULTNS><data><schema-mounts xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-schema-mount\"><mount-point><module>clixon-example</module><label>myroot</label><config>true</config><inline/></mount-point></schema-mounts></data></rpc-reply>"
if true; then
new "get yang-lib at mountpoint"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get><filter type=\"subtree\"><top xmlns=\"urn:example:clixon\"><root></root></top>></filter></get></rpc>" "<rpc-reply $DEFAULTNS><data><top xmlns=\"urn:example:clixon\"><root><name>x</name></root><root><name>y</name></root></top></data></rpc-reply>"
fi
if [ $BE -ne 0 ]; then
new "Kill backend"
# Check if premature kill
pid=$(pgrep -u root -f clixon_backend)
if [ -z "$pid" ]; then
err "backend already dead"
fi
# kill backend
stop_backend -f $cfg
fi
rm -rf $dir
new "endtest"
endtest