When user callbacks p_statedata() clixon_backend nolonger silently exit

This commit is contained in:
Olof hagsand 2017-11-14 23:14:51 +01:00
parent d9c126eed0
commit 61551b07d6
3 changed files with 49 additions and 34 deletions

View file

@ -1,7 +1,8 @@
# Clixon CHANGELOG # Clixon CHANGELOG
* When user callbacks such as statedata() call returns -1, clixon_backend no * When user callbacks p_statedata() or rpc callback call returns -1,
longer silently exits. Instead a log is printed and an RPC error is returned. clixon_backend nolonger silently exits. Instead a log is printed and an
RPC error is returned.
* Support for non-line scrolling in CLI, eg wrap lines. Set with: * Support for non-line scrolling in CLI, eg wrap lines. Set with:
CLICON_CLI_LINESCROLLING 0 CLICON_CLI_LINESCROLLING 0

View file

@ -275,6 +275,7 @@ from_client_get(clicon_handle h,
cxobj *xfilter; cxobj *xfilter;
char *selector = "/"; char *selector = "/";
cxobj *xret = NULL; cxobj *xret = NULL;
int ret;
if ((xfilter = xml_find(xe, "filter")) != NULL) if ((xfilter = xml_find(xe, "filter")) != NULL)
if ((selector = xml_find_value(xfilter, "select"))==NULL) if ((selector = xml_find_value(xfilter, "select"))==NULL)
@ -291,18 +292,30 @@ from_client_get(clicon_handle h,
} }
/* Get state data from plugins as defined by plugin_statedata(), if any */ /* Get state data from plugins as defined by plugin_statedata(), if any */
assert(xret); assert(xret);
if (backend_statedata_call(h, selector, xret) < 0) clicon_err_reset();
if ((ret = backend_statedata_call(h, selector, xret)) < 0)
goto done; goto done;
cprintf(cbret, "<rpc-reply>"); if (ret == 0){ /* OK */
if (xret==NULL) cprintf(cbret, "<rpc-reply>");
cprintf(cbret, "<data/>"); if (xret==NULL)
else{ cprintf(cbret, "<data/>");
if (xml_name_set(xret, "data") < 0) else{
goto done; if (xml_name_set(xret, "data") < 0)
if (clicon_xml2cbuf(cbret, xret, 0, 0) < 0) goto done;
goto done; if (clicon_xml2cbuf(cbret, xret, 0, 0) < 0)
goto done;
}
cprintf(cbret, "</rpc-reply>");
}
else { /* 1 Error from callback */
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>rpc</error-type>"
"<error-severity>error</error-severity>"
"<error-message>Internal error:%s</error-message>"
"</rpc-error></rpc-reply>", clicon_err_reason);
clicon_log(LOG_NOTICE, "%s Error in backend_statedata_call:%s", __FUNCTION__, xml_name(xe));
} }
cprintf(cbret, "</rpc-reply>");
ok: ok:
retval = 0; retval = 0;
done: done:

View file

@ -728,6 +728,7 @@ plugin_transaction_abort(clicon_handle h,
* @param[in,out] xml XML tree. * @param[in,out] xml XML tree.
* @retval -1 Error * @retval -1 Error
* @retval 0 OK * @retval 0 OK
* @retval 1 Statedata callback failed
*/ */
int int
backend_statedata_call(clicon_handle h, backend_statedata_call(clicon_handle h,
@ -755,8 +756,10 @@ backend_statedata_call(clicon_handle h,
if (p->p_statedata) { if (p->p_statedata) {
if ((x = xml_new("config", NULL)) == NULL) if ((x = xml_new("config", NULL)) == NULL)
goto done; goto done;
if ((p->p_statedata)(h, xpath, x) < 0) if ((p->p_statedata)(h, xpath, x) < 0){
goto done; retval = 1;
goto done; /* Dont quit here on user callbacks */
}
if (xml_merge(xtop, x, yspec) < 0) if (xml_merge(xtop, x, yspec) < 0)
goto done; goto done;
if (x){ if (x){
@ -765,27 +768,25 @@ backend_statedata_call(clicon_handle h,
} }
} }
} }
{ /* Code complex to filter out anything that is outside of xpath */
/* Code complex to filter out anything that is outside of xpath */ if (xpath_vec(xtop, xpath?xpath:"/", &xvec, &xlen) < 0)
if (xpath_vec(xtop, xpath?xpath:"/", &xvec, &xlen) < 0) goto done;
goto done;
/* If vectors are specified then mark the nodes found and /* If vectors are specified then mark the nodes found and
* then filter out everything else, * then filter out everything else,
* otherwise return complete tree. * otherwise return complete tree.
*/ */
if (xvec != NULL){ if (xvec != NULL){
for (i=0; i<xlen; i++) for (i=0; i<xlen; i++)
xml_flag_set(xvec[i], XML_FLAG_MARK); xml_flag_set(xvec[i], XML_FLAG_MARK);
}
/* Remove everything that is not marked */
if (!xml_flag(xtop, XML_FLAG_MARK))
if (xml_tree_prune_flagged_sub(xtop, XML_FLAG_MARK, 1, NULL) < 0)
goto done;
/* reset flag */
if (xml_apply(xtop, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset, (void*)XML_FLAG_MARK) < 0)
goto done;
} }
/* Remove everything that is not marked */
if (!xml_flag(xtop, XML_FLAG_MARK))
if (xml_tree_prune_flagged_sub(xtop, XML_FLAG_MARK, 1, NULL) < 0)
goto done;
/* reset flag */
if (xml_apply(xtop, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset, (void*)XML_FLAG_MARK) < 0)
goto done;
retval = 0; retval = 0;
done: done:
if (x) if (x)