From da9bfcbb5388e1bcd6459e08ac17fb902c584981 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Fri, 27 Jan 2023 10:08:07 +0100 Subject: [PATCH] * 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 --- CHANGELOG.md | 13 ++- apps/backend/backend_client.c | 10 +-- apps/backend/backend_commit.c | 3 +- apps/backend/backend_get.c | 17 ++-- apps/backend/backend_main.c | 8 +- apps/backend/backend_plugin.c | 18 ++-- apps/backend/backend_socket.c | 2 +- apps/backend/clixon_backend_transaction.c | 71 ++++++++++++++- apps/backend/clixon_backend_transaction.h | 4 +- apps/cli/cli_generate.c | 2 +- apps/cli/cli_main.c | 3 +- apps/netconf/netconf_main.c | 7 +- apps/restconf/restconf_main_fcgi.c | 3 +- apps/restconf/restconf_main_native.c | 8 +- apps/snmp/snmp_handler.c | 4 +- apps/snmp/snmp_lib.c | 6 +- apps/snmp/snmp_main.c | 5 +- lib/clixon/clixon_log.h | 7 ++ lib/src/clixon_api_path_parse.y | 53 ++++++----- lib/src/clixon_datastore.c | 6 +- lib/src/clixon_datastore_read.c | 11 +-- lib/src/clixon_event.c | 8 +- lib/src/clixon_instance_id_parse.y | 72 ++++++++------- lib/src/clixon_json_parse.y | 8 +- lib/src/clixon_log.c | 15 ++-- lib/src/clixon_netconf_lib.c | 15 ++-- lib/src/clixon_options.c | 2 +- lib/src/clixon_path.c | 6 +- lib/src/clixon_proc.c | 4 +- lib/src/clixon_proto.c | 39 +++++--- lib/src/clixon_proto_client.c | 2 - lib/src/clixon_stream.c | 8 +- lib/src/clixon_xml.c | 5 +- lib/src/clixon_xml_io.c | 2 +- lib/src/clixon_xml_map.c | 10 ++- lib/src/clixon_xml_parse.y | 2 +- lib/src/clixon_xml_sort.c | 2 +- lib/src/clixon_xpath.c | 22 ++--- lib/src/clixon_xpath_eval.c | 2 +- lib/src/clixon_xpath_yang.c | 2 +- lib/src/clixon_yang.c | 5 +- lib/src/clixon_yang_parse_lib.c | 28 +++--- lib/src/clixon_yang_sub_parse.c | 4 +- test/test_netconf_monitoring_multiple.sh | 2 +- test/test_netconf_notifications.sh | 2 +- test/test_upgrade_checkold.sh | 2 +- test/test_yang_schema_mount.sh | 105 ++++++++++++++++++++++ 47 files changed, 425 insertions(+), 210 deletions(-) create mode 100755 test/test_yang_schema_mount.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ef25ddc..b03f41b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -89,15 +89,20 @@ Developers may need to change their code ### Minor features -* Clearer debug levels `clicon_debug()`: - * 1: Logical debug message - * 2: Input and output packets - * 3: Message dump in hex, xpath parse trees +* 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 * 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 ### 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: 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) diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c index 03f52b63..0c2f1da6 100644 --- a/apps/backend/backend_client.c +++ b/apps/backend/backend_client.c @@ -1532,7 +1532,7 @@ from_client_msg(clicon_handle h, char *namespace = NULL; int nr = 0; - clicon_debug(2, "%s", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); yspec = clicon_dbspec_yang(h); /* Return netconf message. Should be filled in by the dispatch(sub) functions * as wither rpc-error or by positive response. @@ -1708,7 +1708,7 @@ from_client_msg(clicon_handle h, if (cbuf_len(cbret) == 0) if (netconf_operation_failed(cbret, "application", clicon_errno?clicon_err_reason:"unknown")< 0) 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 parse errors */ 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: retval = 0; done: - clicon_debug(1, "%s retval:%d", __FUNCTION__, retval); + clicon_debug(CLIXON_DBG_DETAIL, "%s retval:%d", __FUNCTION__, retval); if (xnacm){ xml_free(xnacm); if (clicon_nacm_cache_set(h, NULL) < 0) @@ -1768,7 +1768,7 @@ from_client(int s, clicon_handle h = ce->ce_handle; int eof = 0; - clicon_debug(2, "%s", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); if (s != ce->ce_s){ clicon_err(OE_NETCONF, EINVAL, "Internal error: s != ce->ce_s"); goto done; @@ -1782,7 +1782,7 @@ from_client(int s, goto done; retval = 0; done: - clicon_debug(1, "%s retval=%d", __FUNCTION__, retval); + clicon_debug(CLIXON_DBG_DETAIL, "%s retval=%d", __FUNCTION__, retval); if (msg) free(msg); return retval; /* -1 here terminates backend */ diff --git a/apps/backend/backend_commit.c b/apps/backend/backend_commit.c index ea4082e1..5c1b3fdf 100644 --- a/apps/backend/backend_commit.c +++ b/apps/backend/backend_commit.c @@ -518,8 +518,7 @@ validate_common(clicon_handle h, &td->td_tcvec, /* changed: wanted values */ &td->td_clen) < 0) goto done; - if (clicon_debug_get()>1) - transaction_print(stderr, td); + transaction_dbg(h, CLIXON_DBG_DEFAULT, td, __FUNCTION__); /* Mark as changed in tree */ for (i=0; itd_dlen; i++){ /* Also down */ xn = td->td_dvec[i]; diff --git a/apps/backend/backend_get.c b/apps/backend/backend_get.c index cd168714..8f209706 100644 --- a/apps/backend/backend_get.c +++ b/apps/backend/backend_get.c @@ -199,11 +199,11 @@ client_get_streams(clicon_handle h, * */ static int -get_client_statedata(clicon_handle h, - char *xpath, - cvec *nsc, - withdefaults_type wdef, - cxobj **xret) +get_statedata(clicon_handle h, + char *xpath, + cvec *nsc, + withdefaults_type wdef, + cxobj **xret) { int retval = -1; yang_stmt *yspec; @@ -872,7 +872,8 @@ get_common(clicon_handle h, #else wdef = WITHDEFAULTS_EXPLICIT; #endif - clicon_debug(2, "%s", __FUNCTION__); + + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); username = clicon_username_get(h); if ((yspec = clicon_dbspec_yang(h)) == NULL){ clicon_err(OE_YANG, ENOENT, "No yang spec9"); @@ -997,7 +998,7 @@ get_common(clicon_handle h, break; case CONTENT_ALL: /* both config and state */ 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; if (ret == 0){ /* Error from callback (error in xret) */ if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) @@ -1049,7 +1050,7 @@ get_common(clicon_handle h, ok: retval = 0; done: - clicon_debug(2, "%s retval:%d", __FUNCTION__, retval); + clicon_debug(CLIXON_DBG_DETAIL, "%s retval:%d", __FUNCTION__, retval); if (xvec) free(xvec); if (xret) diff --git a/apps/backend/backend_main.c b/apps/backend/backend_main.c index d23ecfc0..e5653cd8 100644 --- a/apps/backend/backend_main.c +++ b/apps/backend/backend_main.c @@ -112,8 +112,9 @@ backend_terminate(clicon_handle h) /* Free changelog */ if ((x = clicon_xml_changelog_get(h)) != NULL) xml_free(x); - if ((yspec = clicon_dbspec_yang(h)) != NULL) + if ((yspec = clicon_dbspec_yang(h)) != NULL){ ys_free(yspec); + } if ((yspec = clicon_config_yang(h)) != NULL) ys_free(yspec); if ((yspec = clicon_nacm_ext_yang(h)) != NULL) @@ -133,6 +134,7 @@ backend_terminate(clicon_handle h) xpath_optimize_exit(); clixon_pagination_free(h); + if (pidfile) unlink(pidfile); if (sockfamily==AF_UNIX && lstat(sockpath, &st) == 0) @@ -1045,8 +1047,8 @@ main(int argc, goto done; if (clicon_socket_set(h, ss) < 0) goto done; - if (dbg) - clicon_option_dump(h, dbg); + clicon_option_dump(h, 1); + /* Depending on configure setting, privileges may be dropped here after * initializations */ if (check_drop_priv(h, gid, yspec) < 0) diff --git a/apps/backend/backend_plugin.c b/apps/backend/backend_plugin.c index d08c7eda..1758327b 100644 --- a/apps/backend/backend_plugin.c +++ b/apps/backend/backend_plugin.c @@ -115,7 +115,7 @@ clixon_plugin_reset_all(clicon_handle h, int retval = -1; 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 */ while ((cp = clixon_plugin_each(h, cp)) != NULL) { if (clixon_plugin_reset_one(cp, h, db) < 0) @@ -176,7 +176,7 @@ clixon_plugin_pre_daemon_all(clicon_handle h) int retval = -1; 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 */ while ((cp = clixon_plugin_each(h, cp)) != NULL) { if (clixon_plugin_pre_daemon_one(cp, h) < 0) @@ -238,7 +238,7 @@ clixon_plugin_daemon_all(clicon_handle h) int retval = -1; 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 */ while ((cp = clixon_plugin_each(h, cp)) != NULL) { if (clixon_plugin_daemon_one(cp, h) < 0) @@ -342,7 +342,7 @@ clixon_plugin_statedata_all(clicon_handle h, cbuf *cberr = NULL; cxobj *xerr = NULL; - clicon_debug(1, "%s", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); while ((cp = clixon_plugin_each(h, cp)) != NULL) { if ((ret = clixon_plugin_statedata_one(cp, h, nsc, xpath, &x)) < 0) goto done; @@ -368,7 +368,7 @@ clixon_plugin_statedata_all(clicon_handle h, x = NULL; 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 */ if ((ret = xml_bind_yang(x, YB_MODULE, yspec, &xerr)) < 0) goto done; @@ -464,7 +464,7 @@ clixon_plugin_lockdb_all(clicon_handle h, int retval = -1; 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) { if (clixon_plugin_lockdb_one(cp, h, db, lock, id) < 0) goto done; @@ -641,7 +641,7 @@ plugin_transaction_begin_all(clicon_handle h, int retval = -1; 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) { if (plugin_transaction_begin_one(cp, h, td) < 0) goto done; @@ -976,7 +976,7 @@ plugin_transaction_end_all(clicon_handle h, int retval = -1; 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) { if (plugin_transaction_end_one(cp, h, td) < 0) goto done; @@ -1028,7 +1028,7 @@ plugin_transaction_abort_all(clicon_handle h, int retval = -1; 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) { if (plugin_transaction_abort_one(cp, h, td) < 0) ; /* dont abort on error */ diff --git a/apps/backend/backend_socket.c b/apps/backend/backend_socket.c index a564b789..6e4083d5 100644 --- a/apps/backend/backend_socket.c +++ b/apps/backend/backend_socket.c @@ -241,7 +241,7 @@ backend_accept_client(int fd, uid_t guid; #endif - clicon_debug(2, "%s", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); len = sizeof(from); if ((s = accept(fd, &from, &len)) < 0){ clicon_err(OE_UNIX, errno, "accept"); diff --git a/apps/backend/clixon_backend_transaction.c b/apps/backend/clixon_backend_transaction.c index 868bf713..57d71c7c 100644 --- a/apps/backend/clixon_backend_transaction.c +++ b/apps/backend/clixon_backend_transaction.c @@ -201,12 +201,15 @@ transaction_clen(transaction_data td) return ((transaction_data_t *)td)->td_clen; } -/*! Print transaction on FILE for debug - * @see transaction_log +/*! Print info about transaction on FILE, including what has changed + * + * @param[in] f stdio FILE + * @param[in] th Transaction data + * @see transaction_dbg */ int -transaction_print(FILE *f, - transaction_data th) +transaction_print(FILE *f, + transaction_data th) { cxobj *xn; int i; @@ -235,6 +238,66 @@ transaction_print(FILE *f, 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; itd_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; itd_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; itd_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 * */ diff --git a/apps/backend/clixon_backend_transaction.h b/apps/backend/clixon_backend_transaction.h index f370b29e..6019ab54 100644 --- a/apps/backend/clixon_backend_transaction.h +++ b/apps/backend/clixon_backend_transaction.h @@ -62,7 +62,9 @@ cxobj **transaction_tcvec(transaction_data td); size_t transaction_clen(transaction_data td); 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 * @see pagination_data_t internal structure diff --git a/apps/cli/cli_generate.c b/apps/cli/cli_generate.c index ac099faf..6abd066f 100644 --- a/apps/cli/cli_generate.c +++ b/apps/cli/cli_generate.c @@ -1385,7 +1385,7 @@ yang2cli_yspec(clicon_handle h, clicon_log(LOG_NOTICE, "%s: Top-level cli-spec %s:\n%s", __FUNCTION__, treename, cbuf_get(cb)); 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)); if (cligen_parsetree_merge(pt0, NULL, pt) < 0){ clicon_err(OE_YANG, errno, "cligen_parsetree_merge"); diff --git a/apps/cli/cli_main.c b/apps/cli/cli_main.c index 0ecdb3fa..32bc1db7 100644 --- a/apps/cli/cli_main.c +++ b/apps/cli/cli_main.c @@ -780,8 +780,7 @@ main(int argc, if (logclisyntax) cli_logsyntax_set(h, logclisyntax); - if (dbg) - clicon_option_dump(h, dbg); + clicon_option_dump(h, 1); /* Join rest of argv to a single command */ restarg = clicon_strjoin(argc, argv, " "); diff --git a/apps/netconf/netconf_main.c b/apps/netconf/netconf_main.c index e65d662d..56568624 100644 --- a/apps/netconf/netconf_main.c +++ b/apps/netconf/netconf_main.c @@ -404,8 +404,8 @@ netconf_input_frame(clicon_handle h, int ret; netconf_framing_type framing; - clicon_debug(1, "%s", __FUNCTION__); - clicon_debug(2, "%s: \"%s\"", __FUNCTION__, cbuf_get(cb)); + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); + clicon_debug(CLIXON_DBG_MSG, "Recv ext: %s", cbuf_get(cb)); framing = clicon_option_int(h, "netconf-framing"); yspec = clicon_dbspec_yang(h); if ((str = strdup(cbuf_get(cb))) == NULL){ @@ -1011,8 +1011,7 @@ main(int argc, #endif if (clixon_event_reg_fd(0, netconf_input_cb, h, "netconf socket") < 0) goto done; - if (dbg) - clicon_option_dump(h, dbg); + clicon_option_dump(h, 1); if (tv.tv_sec || tv.tv_usec){ struct timeval t; gettimeofday(&t, NULL); diff --git a/apps/restconf/restconf_main_fcgi.c b/apps/restconf/restconf_main_fcgi.c index 692cf2df..58e7df03 100644 --- a/apps/restconf/restconf_main_fcgi.c +++ b/apps/restconf/restconf_main_fcgi.c @@ -529,8 +529,7 @@ main(int argc, goto done; /* Dump configuration options on debug */ - if (dbg) - clicon_option_dump(h, dbg); + clicon_option_dump(h, 1); /* Call start function in all plugins before we go interactive */ if (clixon_plugin_start_all(h) < 0) diff --git a/apps/restconf/restconf_main_native.c b/apps/restconf/restconf_main_native.c index b3f0ca31..afcb6d19 100644 --- a/apps/restconf/restconf_main_native.c +++ b/apps/restconf/restconf_main_native.c @@ -837,10 +837,7 @@ restconf_openssl_init(clicon_handle h, /* If debug was enabled here from config and not initially, * print clixn options and loaded yang files */ - if (dbg) { - clicon_option_dump(h, dbg); - yang_spec_dump(clicon_dbspec_yang(h), dbg); - } + clicon_option_dump(h, 1); } if ((x = xpath_first(xrestconf, nsc, "enable-core-dump")) != NULL) { /* core dump is enabled on RESTCONF process */ @@ -1273,8 +1270,7 @@ main(int argc, restconf_auth_type_set(h, CLIXON_AUTH_NONE); /* Dump configuration options on debug */ - if (dbg) - clicon_option_dump(h, dbg); + clicon_option_dump(h, 1); /* Initialize plugin module by creating a handle holding plugin and callback lists */ if (clixon_plugin_module_init(h) < 0) diff --git a/apps/snmp/snmp_handler.c b/apps/snmp/snmp_handler.c index cd06b4c7..ba45f05b 100644 --- a/apps/snmp/snmp_handler.c +++ b/apps/snmp/snmp_handler.c @@ -718,7 +718,7 @@ clixon_snmp_scalar_handler1(netsnmp_mib_handler *handler, netsnmp_variable_list *requestvb = request->requestvb; 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) goto done; /* 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; 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) goto done; if (sh->sh_ys == NULL){ diff --git a/apps/snmp/snmp_lib.c b/apps/snmp/snmp_lib.c index 1a0fa25a..6ccb1734 100644 --- a/apps/snmp/snmp_lib.c +++ b/apps/snmp/snmp_lib.c @@ -639,7 +639,7 @@ type_snmp2xml(yang_stmt *ys, } retval = 1; done: - clicon_debug(2, "%s %d", __FUNCTION__, retval); + clicon_debug(CLIXON_DBG_DETAIL, "%s %d", __FUNCTION__, retval); if (origtype) free(origtype); if (cv) @@ -709,7 +709,7 @@ type_xml2snmp_pre(char *xmlstr0, } retval = 1; done: - clicon_debug(2, "%s %d", __FUNCTION__, retval); + clicon_debug(CLIXON_DBG_DETAIL, "%s %d", __FUNCTION__, retval); return retval; fail: retval = 0; @@ -852,7 +852,7 @@ type_xml2snmp(char *snmpstr, } retval = 1; done: - clicon_debug(2, "%s %d", __FUNCTION__, retval); + clicon_debug(CLIXON_DBG_DETAIL, "%s %d", __FUNCTION__, retval); return retval; fail: retval = 0; diff --git a/apps/snmp/snmp_main.c b/apps/snmp/snmp_main.c index 76a1b751..5cfd3980 100644 --- a/apps/snmp/snmp_main.c +++ b/apps/snmp/snmp_main.c @@ -198,7 +198,7 @@ clixon_snmp_input_cb(int s, clicon_handle h = (clicon_handle)arg; int ret; - clicon_debug(2, "%s %d", __FUNCTION__, s); + clicon_debug(CLIXON_DBG_DETAIL, "%s %d", __FUNCTION__, s); FD_ZERO(&readfds); FD_SET(s, &readfds); (void)snmp_read(&readfds); @@ -514,8 +514,7 @@ main(int argc, if (clicon_nsctx_global_set(h, nsctx_global) < 0) goto done; - if (dbg) - clicon_option_dump(h, dbg); + clicon_option_dump(h, 1); /* Send hello request to backend to get session-id back * This is done once at the beginning of the session and then this is diff --git a/lib/clixon/clixon_log.h b/lib/clixon/clixon_log.h index 9b587b55..5619937a 100644 --- a/lib/clixon/clixon_log.h +++ b/lib/clixon/clixon_log.h @@ -43,11 +43,18 @@ /* * Constants */ +/* Where to log (masks) */ #define CLICON_LOG_SYSLOG 1 /* print logs on syslog */ #define CLICON_LOG_STDERR 2 /* print logs on stderr */ #define CLICON_LOG_STDOUT 4 /* print logs on stdout */ #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 */ diff --git a/lib/src/clixon_api_path_parse.y b/lib/src/clixon_api_path_parse.y index 0855f913..a04dad7e 100644 --- a/lib/src/clixon_api_path_parse.y +++ b/lib/src/clixon_api_path_parse.y @@ -114,10 +114,21 @@ #include "clixon_path.h" #include "clixon_api_path_parse.h" -/* - also called from yacc generated code * -*/ +/* Best debugging is to enable PARSE_DEBUG below and add -d to the LEX compile statement in the Makefile + * 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 clixon_api_path_parseerror(void *_ay, char *s) @@ -148,7 +159,7 @@ static clixon_path * path_append(clixon_path *list, clixon_path *new) { - clicon_debug(3, "%s()", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s()", __FUNCTION__); if (new == NULL) return NULL; ADDQ(new, list); @@ -161,7 +172,7 @@ static clixon_path * path_add_keyvalue(clixon_path *cp, cvec *cvk) { - clicon_debug(3, "%s()", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s()", __FUNCTION__); if (cp) cp->cp_cvk = cvk; return cp; @@ -173,7 +184,7 @@ path_new(char *module_name, { 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){ clicon_err(OE_UNIX, errno, "malloc"); goto done; @@ -203,7 +214,7 @@ static cvec * keyval_add(cvec *cvv, cg_var *cv) { - clicon_debug(3, "%s()", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s()", __FUNCTION__); if (cv == NULL) goto done; if (cvv == NULL && @@ -229,7 +240,7 @@ keyval_set(char *name, { 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){ clicon_err(OE_UNIX, errno, "cv_new"); 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; - clicon_debug(2,"list = list / element");} + _PARSE_DEBUG("list = list / element");} | { $$ = NULL; - clicon_debug(2,"list = ");} + _PARSE_DEBUG("list = ");} ; element : api_identifier { $$=$1; - clicon_debug(2,"element = api_identifier");} + _PARSE_DEBUG("element = api_identifier");} | 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); - clicon_debug(2,"api_identifier = module_name : IDENTIFIER");} + _PARSE_DEBUG("api_identifier = module_name : IDENTIFIER");} | IDENTIFIER { $$ = path_new(NULL, $1); free($1); - clicon_debug(2,"api_identifier = IDENTIFIER");} + _PARSE_DEBUG("api_identifier = IDENTIFIER");} ; 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); - 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; - 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; - 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"); } - | { $$ = keyval_set(NULL, ""); clicon_debug(2,"keyvalue->"); } +key_value : STRING { $$ = keyval_set(NULL, $1); free($1); _PARSE_DEBUG("keyvalue->STRING"); } + | { $$ = keyval_set(NULL, ""); _PARSE_DEBUG("keyvalue->"); } ; %% diff --git a/lib/src/clixon_datastore.c b/lib/src/clixon_datastore.c index b78cff7e..abe663cb 100644 --- a/lib/src/clixon_datastore.c +++ b/lib/src/clixon_datastore.c @@ -390,7 +390,7 @@ xmldb_exists(clicon_handle h, char *filename = NULL; 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) goto done; if (lstat(filename, &sb) < 0) @@ -445,7 +445,7 @@ xmldb_delete(clicon_handle h, char *filename = NULL; 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) goto done; if (xmldb_db2file(h, db, &filename) < 0) @@ -478,7 +478,7 @@ xmldb_create(clicon_handle h, db_elmnt *de = 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 ((xt = de->de_xml) != NULL){ xml_free(xt); diff --git a/lib/src/clixon_datastore_read.c b/lib/src/clixon_datastore_read.c index bfb21094..bb58d87b 100644 --- a/lib/src/clixon_datastore_read.c +++ b/lib/src/clixon_datastore_read.c @@ -994,16 +994,11 @@ xmldb_get_cache(clicon_handle h, if (disable_nacm_on_empty(x1t, yspec) < 0) goto done; } - /* Copy the matching parts of the (relevant) XML tree. - * 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; + clicon_debug_xml(CLIXON_DBG_DETAIL, x1t, "%s", __FUNCTION__); *xtop = x1t; retval = 1; done: - clicon_debug(2, "%s retval:%d", __FUNCTION__, retval); + clicon_debug(CLIXON_DBG_DETAIL, "%s retval:%d", __FUNCTION__, retval); if (xvec) free(xvec); return retval; @@ -1154,7 +1149,7 @@ xmldb_get_zerocopy(clicon_handle h, *xtop = x0t; retval = 1; done: - clicon_debug(2, "%s retval:%d", __FUNCTION__, retval); + clicon_debug(CLIXON_DBG_DETAIL, "%s retval:%d", __FUNCTION__, retval); if (xvec) free(xvec); return retval; diff --git a/lib/src/clixon_event.c b/lib/src/clixon_event.c index 252ca734..7ff34547 100644 --- a/lib/src/clixon_event.c +++ b/lib/src/clixon_event.c @@ -194,7 +194,7 @@ clixon_event_reg_fd(int fd, e->e_type = EVENT_FD; e->e_next = ee; 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; } @@ -276,7 +276,7 @@ clixon_event_reg_timeout(struct timeval t, } e->e_next = e1; *e_prev = e; - clicon_debug(2, "%s: %s", __FUNCTION__, str); + clicon_debug(CLIXON_DBG_DETAIL, "%s: %s", __FUNCTION__, str); return 0; } @@ -414,7 +414,7 @@ clixon_event_loop(clicon_handle h) if (n==0){ /* Timeout */ e = ee_timers; 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){ free(e); goto err; @@ -428,7 +428,7 @@ clixon_event_loop(clicon_handle h) } e_next = e->e_next; 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){ clicon_debug(1, "%s Error in: %s", __FUNCTION__, e->e_string); goto err; diff --git a/lib/src/clixon_instance_id_parse.y b/lib/src/clixon_instance_id_parse.y index a150a44b..b5966755 100644 --- a/lib/src/clixon_instance_id_parse.y +++ b/lib/src/clixon_instance_id_parse.y @@ -126,10 +126,16 @@ #include "clixon_path.h" #include "clixon_instance_id_parse.h" -/* - also called from yacc generated code * -*/ +/* Enable for debugging, steals some cycles otherwise */ +#if 0 +#define _PARSE_DEBUG(s) clicon_debug(1,(s)) +#else +#define _PARSE_DEBUG(s) +#endif +/* + * Also called from yacc generated code * + */ void clixon_instance_id_parseerror(void *_iy, char *s) @@ -160,7 +166,7 @@ static clixon_path * path_append(clixon_path *list, clixon_path *new) { - clicon_debug(2, "%s()", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s()", __FUNCTION__); if (new == NULL) return NULL; ADDQ(new, list); @@ -175,7 +181,7 @@ static clixon_path * path_add_keyvalue(clixon_path *cp, cvec *cvk) { - clicon_debug(2, "%s()", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s()", __FUNCTION__); if (cp == NULL) goto done; cp->cp_cvk = cvk; @@ -189,7 +195,7 @@ path_new(char *prefix, { 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){ clicon_err(OE_UNIX, errno, "malloc"); goto done; @@ -219,7 +225,7 @@ keyval_pos(char *uint) char *reason=NULL; int ret; - clicon_debug(2, "%s(%s)", __FUNCTION__, uint); + clicon_debug(CLIXON_DBG_DETAIL, "%s(%s)", __FUNCTION__, uint); if ((cvv = cvec_new(1)) == NULL) { clicon_err(OE_UNIX, errno, "cvec_new"); goto done; @@ -252,7 +258,7 @@ static cvec * keyval_add(cvec *cvv, cg_var *cv) { - clicon_debug(2, "%s()", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s()", __FUNCTION__); if (cv == NULL) goto done; if (cvv == NULL && @@ -278,7 +284,7 @@ keyval_set(char *name, { 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){ clicon_err(OE_UNIX, errno, "cv_new"); 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; - clicon_debug(3,"list = list / element");} + _PARSE_DEBUG("list = list / element");} | 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); - clicon_debug(3,"element = node_id element2");} + _PARSE_DEBUG("element = node_id element2");} ; 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); - 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"); } - | leaf_list_pred { $$=$1; clicon_debug(3,"element2 = leaf_list_pred"); } - | pos { $$=$1; clicon_debug(3,"element2 = key_preds"); } - | { $$=NULL; clicon_debug(3,"element2 = "); } +element2 : key_preds { $$=$1; _PARSE_DEBUG("element2 = key_preds"); } + | leaf_list_pred { $$=$1; _PARSE_DEBUG("element2 = leaf_list_pred"); } + | pos { $$=$1; _PARSE_DEBUG("element2 = key_preds"); } + | { $$=NULL; _PARSE_DEBUG("element2 = "); } ; leaf_list_pred : LSQBR leaf_list_pred_expr RSQBR { 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); - clicon_debug(3,"leaf_list_pred_expr = '.=' qstring"); } + _PARSE_DEBUG("leaf_list_pred_expr = '.=' qstring"); } ; 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; - 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; - clicon_debug(3,"key_preds = key_pred");} + _PARSE_DEBUG("key_preds = key_pred");} ; 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); - clicon_debug(3,"key_pred_expr = node_id_k = qstring"); } + _PARSE_DEBUG("key_pred_expr = node_id_k = qstring"); } ; 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? */ - 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; - clicon_debug(3,"qstring = \" string \""); } + _PARSE_DEBUG("qstring = \" string \""); } | DQUOTE DQUOTE { $$=strdup(""); - clicon_debug(3,"qstring = \" \""); } + _PARSE_DEBUG("qstring = \" \""); } | SQUOTE STRING SQUOTE { $$=$2; - clicon_debug(3,"qstring = ' string '"); } + _PARSE_DEBUG("qstring = ' string '"); } | SQUOTE SQUOTE { $$=strdup(""); - clicon_debug(3,"qstring = ''"); } + _PARSE_DEBUG("qstring = ''"); } ; %% diff --git a/lib/src/clixon_json_parse.y b/lib/src/clixon_json_parse.y index f5331d3f..a570c61f 100644 --- a/lib/src/clixon_json_parse.y +++ b/lib/src/clixon_json_parse.y @@ -183,7 +183,7 @@ json_current_new(clixon_json_yacc *jy, char *prefix = 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 */ if (nodeid_split(name, &prefix, &id) < 0) goto done; @@ -210,7 +210,7 @@ json_current_new(clixon_json_yacc *jy, static int json_current_pop(clixon_json_yacc *jy) { - clicon_debug(2, "%s", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); if (jy->jy_current) jy->jy_current = xml_parent(jy->jy_current); return 0; @@ -221,7 +221,7 @@ json_current_clone(clixon_json_yacc *jy) { cxobj *xn; - clicon_debug(2, "%s", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); if (jy->jy_current == NULL){ return -1; } @@ -254,7 +254,7 @@ json_current_body(clixon_json_yacc *jy, int retval = -1; 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) goto done; if (value && xml_value_append(xn, value) < 0) diff --git a/lib/src/clixon_log.c b/lib/src/clixon_log.c index 5db0dbed..3fa15f05 100644 --- a/lib/src/clixon_log.c +++ b/lib/src/clixon_log.c @@ -367,12 +367,12 @@ clicon_debug_get(void) * print message if level >= dbglevel. * The message is sent to clicon_log. EIther to syslog, stderr or both, depending on * clicon_log_init() setting - * The dbgdebug level strategy is: - * 1: Logical debug message - * 2: Input and output packets - * 3: Message dump in hex, xpath parse trees - * - * @param[in] dbglevel 0: No debug, 1-3: increasing levels of debug + * The dbgdebug level strategy is a mask of the following masks: + * 1: Basic debug message, espcially initialization + * 2: Input and output packets, read datastore + * 4: Details: message dump in hex, xpath parse trees, etc + * See CLIXON_DBG_* flags + * @param[in] dbglevel 0: No debug, 1-7 combined of the CLIXON_DBG_ flags above * @param[in] format Message to print as argv. * @see clicon_debug_xml Specialization for XML tree */ @@ -386,7 +386,8 @@ clicon_debug(int dbglevel, int retval = -1; 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; /* first round: compute length of debug message */ va_start(args, format); diff --git a/lib/src/clixon_netconf_lib.c b/lib/src/clixon_netconf_lib.c index 9fadd0fa..d63a9410 100644 --- a/lib/src/clixon_netconf_lib.c +++ b/lib/src/clixon_netconf_lib.c @@ -1589,7 +1589,9 @@ netconf_module_load(clicon_handle h) /* Load yang spec */ if (yang_spec_parse_module(h, "ietf-netconf", NULL, yspec)< 0) 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 (yang_spec_parse_module(h, "clixon-rfc5277", NULL, yspec)< 0) goto done; @@ -1685,7 +1687,7 @@ netconf_db_find(cxobj *xn, * printf("%s", cbuf_get(cb)); * cbuf_free(cb); * @endcode - * @see clixon_netconf_error + * @see clixon_netconf_error_fn */ int netconf_err2cb(cxobj *xerr, @@ -1877,6 +1879,7 @@ netconf_hello_server(clicon_handle h, * @param[in] xerr Netconf error xml tree on the form: * @param[in] format Format string * @param[in] arg String argument to format (optional) + * @see netconf_err2cb */ int clixon_netconf_error_fn(const char *fn, @@ -2130,8 +2133,9 @@ netconf_output(int s, char *buf = cbuf_get(cb); int len = cbuf_len(cb); - clicon_debug(1, "SEND %s", msg); - if (clicon_debug_get() > 1){ /* XXX: below only works to stderr, clicon_debug may log to syslog */ + clicon_debug(CLIXON_DBG_MSG, "Send ext: %s", cbuf_get(cb)); +#if 0 // Extra sanity check for debugging + { cxobj *xt = NULL; 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) @@ -2140,6 +2144,7 @@ netconf_output(int s, xml_free(xt); } } +#endif if (write(s, buf, len) < 0){ if (errno == EPIPE) clicon_debug(1, "%s write err SIGPIPE", __FUNCTION__); @@ -2224,7 +2229,7 @@ netconf_input_chunked_framing(char ch, { 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){ case 0: if (ch == '\n'){ diff --git a/lib/src/clixon_options.c b/lib/src/clixon_options.c index c61c1a3c..f44f91c0 100644 --- a/lib/src/clixon_options.c +++ b/lib/src/clixon_options.c @@ -211,7 +211,7 @@ parse_configfile_one(const char *filename, clicon_err(OE_UNIX, errno, "open configure file: %s", filename); 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) goto done; if (ret == 0){ diff --git a/lib/src/clixon_path.c b/lib/src/clixon_path.c index b2b28cb8..afae5ad7 100644 --- a/lib/src/clixon_path.c +++ b/lib/src/clixon_path.c @@ -805,7 +805,7 @@ api_path2xpath_cvv(cvec *api_path, nsc = NULL; } done: - clicon_debug(2, "%s retval:%d", __FUNCTION__, retval); + clicon_debug(CLIXON_DBG_DETAIL, "%s retval:%d", __FUNCTION__, retval); if (cberr) cbuf_free(cberr); if (valvec) @@ -1120,7 +1120,7 @@ api_path2xml_vec(char **vec, ok: retval = 1; /* OK */ done: - clicon_debug(2, "%s retval:%d", __FUNCTION__, retval); + clicon_debug(CLIXON_DBG_DETAIL, "%s retval:%d", __FUNCTION__, retval); if (cberr) cbuf_free(cberr); if (prefix) @@ -1185,7 +1185,7 @@ api_path2xml(char *api_path, cxobj *xroot; 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){ clicon_err(OE_UNIX, errno, "cbuf_new"); goto done; diff --git a/lib/src/clixon_proc.c b/lib/src/clixon_proc.c index e68065a1..5a40c18b 100644 --- a/lib/src/clixon_proc.c +++ b/lib/src/clixon_proc.c @@ -909,7 +909,7 @@ clixon_process_sched_register(clicon_handle h, struct timeval t; struct timeval t1 = {0, 100000}; /* 100ms */ - clicon_debug(2, "%s", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); gettimeofday(&t, NULL); if (delay) timeradd(&t, &t1, &t); @@ -917,7 +917,7 @@ clixon_process_sched_register(clicon_handle h, goto done; retval = 0; done: - clicon_debug(2, "%s retval:%d", __FUNCTION__, retval); + clicon_debug(CLIXON_DBG_DETAIL, "%s retval:%d", __FUNCTION__, retval); return retval; } diff --git a/lib/src/clixon_proto.c b/lib/src/clixon_proto.c index 25ccf91c..ce987aec 100644 --- a/lib/src/clixon_proto.c +++ b/lib/src/clixon_proto.c @@ -189,12 +189,13 @@ clicon_msg_decode(struct clicon_msg *msg, char *xmlstr; int ret; + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); /* hdr */ if (id) *id = ntohl(msg->op_id); /* 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) goto done; if (ret == 0) @@ -229,7 +230,7 @@ clicon_connect_unix(clicon_handle h, addr.sun_family = AF_UNIX; 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 (errno == EACCES) clicon_err(OE_CFG, errno, "connecting unix socket: %s. " @@ -292,16 +293,20 @@ atomicio(ssize_t (*fn) (int, void *, size_t), return (pos); } +#if 0 // Extra debug /*! Print message on debug. Log if syslog, stderr if not * @param[in] msg CLICON msg */ static int -msg_dump(struct clicon_msg *msg) +msg_dump(int dbglevel, + struct clicon_msg *msg) { int retval = -1; cbuf *cb = NULL; int i; + if ((dbglevel & clicon_debug_get()) == 0) /* compare debug level with global variable */ + goto ok; if ((cb = cbuf_new()) == NULL){ clicon_err(OE_CFG, errno, "cbuf_new"); goto done; @@ -310,7 +315,7 @@ msg_dump(struct clicon_msg *msg) for (i=0; iop_len); i++){ cprintf(cb, "%02x", ((char*)msg)[i]&0xff); if ((i+1)%32==0){ - clicon_debug(2, "%s", cbuf_get(cb)); + clicon_debug(CLIXON_DBG_DETAIL, "%s", cbuf_get(cb)); cbuf_reset(cb); cprintf(cb, "%s:", __FUNCTION__); } @@ -318,13 +323,15 @@ msg_dump(struct clicon_msg *msg) if ((i+1)%4==0) cprintf(cb, " "); } - clicon_debug(2, "%s", cbuf_get(cb)); + clicon_debug(dbglevel, "%s", cbuf_get(cb)); + ok: retval = 0; done: if (cb) cbuf_free(cb); return retval; } +#endif /*! Send a CLICON netconf message using internal IPC message * @@ -339,10 +346,12 @@ clicon_msg_send(int s, int retval = -1; 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)); - if (clicon_debug_get() > 2) - msg_dump(msg); +#if 0 // Extra debug + 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, s, msg, ntohl(msg->op_len)) < 0){ e = errno; @@ -384,6 +393,7 @@ clicon_msg_rcv(int s, sigfn_t oldhandler; uint32_t mlen; + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); *eof = 0; if (0) set_signal(SIGINT, atomicio_sig_handler, &oldhandler); @@ -402,7 +412,7 @@ clicon_msg_rcv(int s, goto done; } 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); if ((*msg = (struct clicon_msg *)malloc(mlen)) == NULL){ clicon_err(OE_CFG, errno, "malloc"); @@ -417,8 +427,10 @@ clicon_msg_rcv(int s, clicon_err(OE_CFG, errno, "body too short"); goto done; } - if (clicon_debug_get() > 2) - msg_dump(*msg); +#if 0 // Extra debug + msg_dump(CLIXON_DBG_EXTRA, *msg); +#endif + clicon_debug(CLIXON_DBG_MSG, "Recv: %s", (*msg)->op_body); retval = 0; done: if (0) @@ -447,7 +459,7 @@ clicon_msg_rcv1(int s, int xml_state = 0; int poll; - clicon_debug(1, "%s", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); *eof = 0; memset(buf, 0, sizeof(buf)); while (1){ @@ -484,6 +496,7 @@ clicon_msg_rcv1(int s, break; /* No data to read */ } /* while */ ok: + clicon_debug(CLIXON_DBG_MSG, "Recv: %s", cbuf_get(cb)); retval = 0; done: clicon_debug(1, "%s done", __FUNCTION__); @@ -502,6 +515,8 @@ clicon_msg_send1(int s, { 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, s, cbuf_get(cb), cbuf_len(cb)) < 0){ clicon_err(OE_CFG, errno, "atomicio"); diff --git a/lib/src/clixon_proto_client.c b/lib/src/clixon_proto_client.c index 2927c5d8..441fda99 100644 --- a/lib/src/clixon_proto_client.c +++ b/lib/src/clixon_proto_client.c @@ -201,7 +201,6 @@ clicon_rpc_msg(clicon_handle h, #ifdef RPC_USERNAME_ASSERT assert(strstr(msg->op_body, "username")!=NULL); /* XXX */ #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 */ if (clicon_rpc_msg_once(h, msg, &retdata, &eof, &s) < 0) goto done; @@ -232,7 +231,6 @@ clicon_rpc_msg(clicon_handle h, goto done; #endif } - clicon_debug(2, "%s retdata:%s", __FUNCTION__, retdata); if (retdata){ /* Cannot populate xret here because need to know RPC name (eg "lock") in order to associate yang diff --git a/lib/src/clixon_stream.c b/lib/src/clixon_stream.c index fbff0211..97a58a6e 100644 --- a/lib/src/clixon_stream.c +++ b/lib/src/clixon_stream.c @@ -251,7 +251,7 @@ stream_timer_setup(int fd, struct stream_replay *r; 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 * Could also be done by a separate timer. */ @@ -502,7 +502,7 @@ stream_notify1(clicon_handle h, int retval = -1; struct stream_subscription *ss; - clicon_debug(2, "%s", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); /* Go thru all subscriptions and find matches */ if ((ss = es->es_subscription) != NULL) do { @@ -557,7 +557,7 @@ stream_notify(clicon_handle h, struct timeval tv; event_stream_t *es; - clicon_debug(2, "%s", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); if ((es = stream_find(h, stream)) == NULL) goto ok; va_start(args, event); @@ -633,7 +633,7 @@ stream_notify_xml(clicon_handle h, struct timeval tv; event_stream_t *es; - clicon_debug(2, "%s", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); if ((es = stream_find(h, stream)) == NULL) goto ok; if ((yspec = clicon_dbspec_yang(h)) == NULL){ diff --git a/lib/src/clixon_xml.c b/lib/src/clixon_xml.c index 83303e2b..b22eca55 100644 --- a/lib/src/clixon_xml.c +++ b/lib/src/clixon_xml.c @@ -2436,7 +2436,7 @@ clicon_log_xml(int level, * @param[in] x XML tree that is logged without prettyprint * @param[in] format Message to print as argv. * @see clicon_log_xml For syslog - * @see clicon_debug base function + * @see clicon_debug base function and see CLIXON_DBG_* flags */ int clicon_debug_xml(int dbglevel, @@ -2450,7 +2450,8 @@ clicon_debug_xml(int dbglevel, int retval = -1; 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; /* Print xml as cbuf */ if ((cb = cbuf_new()) == NULL){ diff --git a/lib/src/clixon_xml_io.c b/lib/src/clixon_xml_io.c index 5b934134..4c3757c9 100644 --- a/lib/src/clixon_xml_io.c +++ b/lib/src/clixon_xml_io.c @@ -541,7 +541,7 @@ _xml_parse(const char *str, int failed = 0; /* yang assignment */ int i; - clicon_debug(2, "%s", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); if (strlen(str) == 0){ return 1; /* OK */ } diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index 2bad30ed..819a891e 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -205,7 +205,7 @@ xml2cvec(cxobj *xt, } } 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); } *cvv0 = cvv; @@ -825,6 +825,14 @@ xml2xpath1(cxobj *x, * @param[out] xpath Malloced xpath string. Need to free() after use * @retval 0 OK * @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() */ int diff --git a/lib/src/clixon_xml_parse.y b/lib/src/clixon_xml_parse.y index fde7dfb8..05d7af7a 100644 --- a/lib/src/clixon_xml_parse.y +++ b/lib/src/clixon_xml_parse.y @@ -86,7 +86,7 @@ /* Enable for debugging, steals some cycles otherwise */ #if 0 -#define _PARSE_DEBUG(s) clicon_debug(3,(s)) +#define _PARSE_DEBUG(s) clicon_debug(1,(s)) #else #define _PARSE_DEBUG(s) #endif diff --git a/lib/src/clixon_xml_sort.c b/lib/src/clixon_xml_sort.c index 9f3be0eb..bbc8fe1f 100644 --- a/lib/src/clixon_xml_sort.c +++ b/lib/src/clixon_xml_sort.c @@ -384,7 +384,7 @@ xml_cmp(cxobj *x1, break; } /* switch */ 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; } diff --git a/lib/src/clixon_xpath.c b/lib/src/clixon_xpath.c index fd2e7927..1557e5db 100644 --- a/lib/src/clixon_xpath.c +++ b/lib/src/clixon_xpath.c @@ -393,7 +393,7 @@ xpath_tree_eq(xpath_tree *xt1, /* pattern */ (xt2->xs_type == XP_PRIME_NR || xt2->xs_type == XP_PRIME_STR)) #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(xt2->xs_type)); goto neq; @@ -405,19 +405,19 @@ xpath_tree_eq(xpath_tree *xt1, /* pattern */ goto eq; } 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; } 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; } 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; } 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; } xc1 = xt1->xs_c0; @@ -426,7 +426,7 @@ xpath_tree_eq(xpath_tree *xt1, /* pattern */ ; else{ if (xc1 == NULL || xc2 == NULL){ - clicon_debug(2, "%s NULL\n", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s NULL\n", __FUNCTION__); goto neq; } if ((ret = xpath_tree_eq(xc1, xc2, vec, len)) < 0) @@ -440,7 +440,7 @@ xpath_tree_eq(xpath_tree *xt1, /* pattern */ ; else{ if (xc1 == NULL || xc2 == NULL){ - clicon_debug(2, "%s NULL\n", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s NULL\n", __FUNCTION__); goto neq; } if ((ret = xpath_tree_eq(xc1, xc2, vec, len)) < 0) @@ -531,7 +531,7 @@ xpath_parse(const char *xpath, clixon_xpath_yacc xpy = {0,}; cbuf *cb = NULL; - clicon_debug(2, "%s", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); if (xpath == NULL){ clicon_err(OE_XML, EINVAL, "XPath is NULL"); goto done; @@ -556,7 +556,7 @@ xpath_parse(const char *xpath, goto done; } 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_scan_exit(&xpy); @@ -602,7 +602,7 @@ xpath_vec_ctx(cxobj *xcur, xpath_tree *xptree = NULL; xp_ctx xc = {0,}; - clicon_debug(2, "%s", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); if (xpath_parse(xpath, &xptree) < 0) goto done; xc.xc_type = XT_NODESET; @@ -1082,7 +1082,7 @@ xpath2canonical(const char *xpath0, cbuf *xcb = NULL; int ret; - clicon_debug(2, "%s", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); /* Parse input xpath into an xpath-tree */ if (xpath_parse(xpath0, &xpt) < 0) goto done; diff --git a/lib/src/clixon_xpath_eval.c b/lib/src/clixon_xpath_eval.c index 9a0a52ff..fa4c26f0 100644 --- a/lib/src/clixon_xpath_eval.c +++ b/lib/src/clixon_xpath_eval.c @@ -277,7 +277,7 @@ nodetest_recursive(cxobj *xn, xsub = NULL; while ((xsub = xml_child_each(xn, xsub, node_type)) != NULL) { 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 (cxvec_append(xsub, &vec, &veclen) < 0) goto done; diff --git a/lib/src/clixon_xpath_yang.c b/lib/src/clixon_xpath_yang.c index 640e5dd2..0802883e 100644 --- a/lib/src/clixon_xpath_yang.c +++ b/lib/src/clixon_xpath_yang.c @@ -466,7 +466,7 @@ yang_path_arg(yang_stmt *ys, xp_yang_ctx *xyr = NULL; xp_yang_ctx *xy = NULL; - clicon_debug(2, "%s", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); if (path_arg == NULL){ clicon_err(OE_XML, EINVAL, "path-arg is NULL"); goto done; diff --git a/lib/src/clixon_yang.c b/lib/src/clixon_yang.c index 37f57996..e5a98c2c 100644 --- a/lib/src/clixon_yang.c +++ b/lib/src/clixon_yang.c @@ -1014,7 +1014,6 @@ yn_each(yang_stmt *yparent, return NULL; for (i=yprev?yprev->_ys_vector_i+1:0; iys_len; i++){ if ((yc = yparent->ys_stmt[i]) == NULL){ - assert(yc); /* XXX Check if happens */ continue; } /* make room for other conditionals */ @@ -1366,7 +1365,7 @@ yang_find_prefix_by_namespace(yang_stmt *ys, yang_stmt *yimport; yang_stmt *yprefix; - clicon_debug(2, "%s", __FUNCTION__); + clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); if (prefix == NULL){ clicon_err(OE_YANG, EINVAL, "prefix is NULL"); goto done; @@ -2957,7 +2956,7 @@ yang_features(clicon_handle h, ret = 0; if (yang_subparse(yang_argument_get(ys), ys, YA_IF_FEATURE, mainfile, 1, &ret) < 0) 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) goto disabled; } diff --git a/lib/src/clixon_yang_parse_lib.c b/lib/src/clixon_yang_parse_lib.c index 03d4e19b..0bb59e81 100644 --- a/lib/src/clixon_yang_parse_lib.c +++ b/lib/src/clixon_yang_parse_lib.c @@ -236,7 +236,7 @@ yang_augment_node(clicon_handle h, } /* */ 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 */ if (yang_abs_schema_nodeid(ys, schema_nodeid, &ytarget) < 0) goto done; @@ -881,7 +881,7 @@ filename2revision(const char *filename, clicon_err(OE_UNIX, errno, "strdup"); 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 */ *p = '\0'; if ((p = index(base, '@')) != NULL){ /* extract revision date */ @@ -904,19 +904,17 @@ filename2revision(const char *filename, * @param[in] h CLICON handle * @param[in] module Name of main YANG module. * @param[in] revision Revision or NULL - * @param[out] revactual Actual revision (if retval=1) - * @param[out] fbuf Buffer containing filename (if retval=1) - * @retval 1 Match found, Most recent entry returned in fbuf and revactual + * @param[out] fbuf Buffer containing filename or NULL (if retval=1) + * @retval 1 Match found, Most recent entry returned in fbuf * @retval 0 No matching entry found * @retval -1 Error * @note for bootstrapping, dir may have to be set. */ -static int -yang_parse_find_match(clicon_handle h, - const char *module, - const char *revision, - uint32_t *revactual, - cbuf *fbuf) +int +yang_file_find_match(clicon_handle h, + const char *module, + const char *revision, + cbuf *fbuf) { int retval = -1; cbuf *regex = NULL; @@ -960,7 +958,8 @@ yang_parse_find_match(clicon_handle h, /* Entries are sorted, last entry should be most recent date */ if (ndp != 0){ - cprintf(fbuf, "%s/%s", dir, dp[ndp-1].d_name); + if (fbuf) + cprintf(fbuf, "%s/%s", dir, dp[ndp-1].d_name); if (dp) free(dp); retval = 1; @@ -990,7 +989,8 @@ yang_parse_find_match(clicon_handle h, bestcv = cv; } if (bestcv){ - cprintf(fbuf, "%s", cv_string_get(bestcv)); /* file path */ + if (fbuf) + cprintf(fbuf, "%s", cv_string_get(bestcv)); /* file path */ retval = 1; /* found */ goto done; } @@ -1080,7 +1080,7 @@ yang_parse_module(clicon_handle h, goto done; } /* 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; if (nr == 0){ if ((cb = cbuf_new()) == NULL){ diff --git a/lib/src/clixon_yang_sub_parse.c b/lib/src/clixon_yang_sub_parse.c index 9e75c656..e76059a6 100644 --- a/lib/src/clixon_yang_sub_parse.c +++ b/lib/src/clixon_yang_sub_parse.c @@ -79,7 +79,7 @@ yang_subparse(char *str, int retval = -1; 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_linenum = linenum; if (enabled) @@ -120,7 +120,7 @@ yang_schema_nodeid_subparse(char *str, int retval = -1; 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_linenum = linenum; ife.if_mainfile = mainfile; diff --git a/test/test_netconf_monitoring_multiple.sh b/test/test_netconf_monitoring_multiple.sh index 01b00764..0639f535 100755 --- a/test/test_netconf_monitoring_multiple.sh +++ b/test/test_netconf_monitoring_multiple.sh @@ -55,9 +55,9 @@ EOF cat < $dir/startup_db <${DATASTORE_TOP}> + 42 default - 42 clixon-example 2000-01-01 diff --git a/test/test_netconf_notifications.sh b/test/test_netconf_notifications.sh index 3cda86cf..5a8fafd2 100755 --- a/test/test_netconf_notifications.sh +++ b/test/test_netconf_notifications.sh @@ -22,7 +22,7 @@ NCWAIT=10 # Wait (netconf valgrind may need more time) DATE=$(date -u +"%Y-%m-%d") cfg=$dir/conf.xml -fyang=$dir/stream.yang +fyang=$dir/example.yang xml=$dir/xml.xml # example diff --git a/test/test_upgrade_checkold.sh b/test/test_upgrade_checkold.sh index 574ab9ef..fb582c7d 100755 --- a/test/test_upgrade_checkold.sh +++ b/test/test_upgrade_checkold.sh @@ -106,7 +106,7 @@ EOF fi for modstate in true false; do if $modstate; then - modstatestr="default42A2016-01-01urn:example:a" + modstatestr="42defaultA2016-01-01urn:example:a" # modstatestr="42A2016-01-01urn:example:a" else modstatestr="" diff --git a/test/test_yang_schema_mount.sh b/test/test_yang_schema_mount.sh new file mode 100755 index 00000000..913102d8 --- /dev/null +++ b/test/test_yang_schema_mount.sh @@ -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 < $cfg + + $cfg + ${YANG_INSTALLDIR} + ${dir} + $fyang + true + /usr/local/lib/$APPNAME/clispec + /usr/local/lib/$APPNAME/cli + $APPNAME + /usr/local/var/$APPNAME/$APPNAME.sock + /usr/local/lib/$APPNAME/backend + /usr/local/var/$APPNAME/$APPNAME.pidfile + $dir + true + true + +EOF + +cat < $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" "xy" "" "" + +new "netconf commit" +expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "" "" "" + +new "Retrieve schema-mounts with Operation" +expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "" "clixon-exampletrue" + +if true; then +new "get yang-lib at mountpoint" +expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" ">" "xy" +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