* New clixon-lib@2020-04-23.yang revision
* Added: stats RPC for clixon XML and memory statistics.
* Added: restart-plugin RPC for restarting individual plugins without restarting backend.
* xml-stats moved from clixon-config.yang as state data to an rpc `datastats` in clixon-lib.yang
* Experimental: restart_plugin
* Two new plugin callbacks added
* ca_daemon: Called just after a server has "daemonized", ie put in background.
* ca_trans_commit_done: Called when all plugin commits have been done.
* Note: If you have used "end" callback and usign transaction data, you should probably use this instead.
This commit is contained in:
parent
1c99bd6a9b
commit
9a8c6cf3e6
25 changed files with 926 additions and 308 deletions
|
|
@ -316,6 +316,7 @@ client_statedata(clicon_handle h,
|
|||
char *namespace;
|
||||
cbuf *cb = NULL;
|
||||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
||||
clicon_err(OE_YANG, ENOENT, "No yang spec");
|
||||
goto done;
|
||||
|
|
@ -367,7 +368,7 @@ client_statedata(clicon_handle h,
|
|||
if (ret == 0)
|
||||
goto fail;
|
||||
}
|
||||
if ((ret = clixon_plugin_statedata(h, yspec, nsc, xpath, xret)) < 0)
|
||||
if ((ret = clixon_plugin_statedata_all(h, yspec, nsc, xpath, xret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
|
|
@ -980,6 +981,7 @@ from_client_get(clicon_handle h,
|
|||
cxobj *xb;
|
||||
int ret;
|
||||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
username = clicon_username_get(h);
|
||||
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
||||
clicon_err(OE_YANG, ENOENT, "No yang spec9");
|
||||
|
|
@ -1405,11 +1407,11 @@ from_client_ping(clicon_handle h,
|
|||
* @retval -1 Error
|
||||
*/
|
||||
static int
|
||||
from_client_datastats(clicon_handle h,
|
||||
cxobj *xe,
|
||||
cbuf *cbret,
|
||||
void *arg,
|
||||
void *regarg)
|
||||
from_client_stats(clicon_handle h,
|
||||
cxobj *xe,
|
||||
cbuf *cbret,
|
||||
void *arg,
|
||||
void *regarg)
|
||||
{
|
||||
int retval = -1;
|
||||
uint64_t nr;
|
||||
|
|
@ -1430,6 +1432,55 @@ from_client_datastats(clicon_handle h,
|
|||
return retval;
|
||||
}
|
||||
|
||||
#ifdef RESTART_PLUGIN_RPC
|
||||
/*! Request restart of specific plugins
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] xe Request: <rpc><xn></rpc>
|
||||
* @param[out] cbret Return xml tree, eg <rpc-reply>..., <rpc-error..
|
||||
* @param[in] arg client-entry
|
||||
* @param[in] regarg User argument given at rpc_callback_register()
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*/
|
||||
static int
|
||||
from_client_restart_plugin(clicon_handle h,
|
||||
cxobj *xe,
|
||||
cbuf *cbret,
|
||||
void *arg,
|
||||
void *regarg)
|
||||
{
|
||||
int retval = -1;
|
||||
char *name;
|
||||
cxobj **vec = NULL;
|
||||
size_t veclen;
|
||||
int i;
|
||||
clixon_plugin *cp;
|
||||
int ret;
|
||||
|
||||
if (xpath_vec(xe, NULL, "plugin", &vec, &veclen) < 0)
|
||||
goto done;
|
||||
for (i=0; i<veclen; i++){
|
||||
name = xml_body(vec[i]);
|
||||
if ((cp = clixon_plugin_find(h, name)) == NULL){
|
||||
if (netconf_bad_element(cbret, "application", "plugin", "No such plugin") < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
if ((ret = from_client_restart_one(h, cp, cbret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto ok; /* cbret set */
|
||||
}
|
||||
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
||||
ok:
|
||||
retval = 0;
|
||||
done:
|
||||
if (vec)
|
||||
free(vec);
|
||||
return retval;
|
||||
}
|
||||
#endif /* RESTART_PLUGIN_RPC */
|
||||
|
||||
/*! Verify nacm user with peer uid credentials
|
||||
* @param[in] mode Peer credential mode: none, exact or except
|
||||
* @param[in] peername Peer username if any
|
||||
|
|
@ -1685,7 +1736,7 @@ from_client_msg(clicon_handle h,
|
|||
cbuf_free(cbret);
|
||||
/* Sanity: log if clicon_err() is not called ! */
|
||||
if (retval < 0 && clicon_errno < 0)
|
||||
clicon_log(LOG_NOTICE, "%s: Internal error: No clicon_err call on error (message: %s)",
|
||||
clicon_log(LOG_NOTICE, "%s: Internal error: No clicon_err call on RPC error (message: %s)",
|
||||
__FUNCTION__, rpc?rpc:"");
|
||||
// clicon_debug(1, "%s retval:%d", __FUNCTION__, retval);
|
||||
return retval;// -1 here terminates backend
|
||||
|
|
@ -1791,9 +1842,14 @@ backend_rpc_init(clicon_handle h)
|
|||
if (rpc_callback_register(h, from_client_ping, NULL,
|
||||
CLIXON_LIB_NS, "ping") < 0)
|
||||
goto done;
|
||||
if (rpc_callback_register(h, from_client_datastats, NULL,
|
||||
CLIXON_LIB_NS, "datastats") < 0)
|
||||
if (rpc_callback_register(h, from_client_stats, NULL,
|
||||
CLIXON_LIB_NS, "stats") < 0)
|
||||
goto done;
|
||||
#ifdef RESTART_PLUGIN_RPC
|
||||
if (rpc_callback_register(h, from_client_restart_plugin, NULL,
|
||||
CLIXON_LIB_NS, "restart-plugin") < 0)
|
||||
goto done;
|
||||
#endif
|
||||
retval =0;
|
||||
done:
|
||||
return retval;
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ startup_common(clicon_handle h,
|
|||
}
|
||||
/* Here xt is old syntax */
|
||||
/* General purpose datastore upgrade */
|
||||
if (clixon_plugin_datastore_upgrade(h, db, xt, msd) < 0)
|
||||
if (clixon_plugin_datastore_upgrade_all(h, db, xt, msd) < 0)
|
||||
goto done;
|
||||
/* Module-specific upgrade callbacks */
|
||||
if ((ret = clixon_module_upgrade(h, xt, msd, cbret)) < 0)
|
||||
|
|
@ -230,7 +230,7 @@ startup_common(clicon_handle h,
|
|||
}
|
||||
|
||||
/* 4. Call plugin transaction start callbacks */
|
||||
if (plugin_transaction_begin(h, td) < 0)
|
||||
if (plugin_transaction_begin_all(h, td) < 0)
|
||||
goto done;
|
||||
|
||||
/* 5. Make generic validation on all new or changed data.
|
||||
|
|
@ -244,11 +244,11 @@ startup_common(clicon_handle h,
|
|||
goto fail; /* STARTUP_INVALID */
|
||||
}
|
||||
/* 6. Call plugin transaction validate callbacks */
|
||||
if (plugin_transaction_validate(h, td) < 0)
|
||||
if (plugin_transaction_validate_all(h, td) < 0)
|
||||
goto done;
|
||||
|
||||
/* 7. Call plugin transaction complete callbacks */
|
||||
if (plugin_transaction_complete(h, td) < 0)
|
||||
if (plugin_transaction_complete_all(h, td) < 0)
|
||||
goto done;
|
||||
ok:
|
||||
retval = 1;
|
||||
|
|
@ -289,14 +289,14 @@ startup_validate(clicon_handle h,
|
|||
if ((td = transaction_new()) == NULL)
|
||||
goto done;
|
||||
if ((ret = startup_common(h, db, td, cbret)) < 0){
|
||||
plugin_transaction_abort(h, td);
|
||||
plugin_transaction_abort_all(h, td);
|
||||
goto done;
|
||||
}
|
||||
if (ret == 0){
|
||||
plugin_transaction_abort(h, td);
|
||||
plugin_transaction_abort_all(h, td);
|
||||
goto fail;
|
||||
}
|
||||
plugin_transaction_end(h, td);
|
||||
plugin_transaction_end_all(h, td);
|
||||
/* Clear cached trees from default values and marking */
|
||||
if (xmldb_get0_clear(h, td->td_target) < 0)
|
||||
goto done;
|
||||
|
|
@ -347,10 +347,10 @@ startup_commit(clicon_handle h,
|
|||
if (ret == 0)
|
||||
goto fail;
|
||||
/* 8. Call plugin transaction commit callbacks */
|
||||
if (plugin_transaction_commit(h, td) < 0)
|
||||
if (plugin_transaction_commit_all(h, td) < 0)
|
||||
goto done;
|
||||
/* After commit, make a post-commit call (sure that all plugins have committed) */
|
||||
if (plugin_transaction_commit_done(h, td) < 0)
|
||||
if (plugin_transaction_commit_done_all(h, td) < 0)
|
||||
goto done;
|
||||
/* Clear cached trees from default values and marking */
|
||||
if (xmldb_get0_clear(h, td->td_target) < 0)
|
||||
|
|
@ -373,12 +373,12 @@ startup_commit(clicon_handle h,
|
|||
if (ret == 0)
|
||||
goto fail;
|
||||
/* 10. Call plugin transaction end callbacks */
|
||||
plugin_transaction_end(h, td);
|
||||
plugin_transaction_end_all(h, td);
|
||||
retval = 1;
|
||||
done:
|
||||
if (td){
|
||||
if (retval < 1)
|
||||
plugin_transaction_abort(h, td);
|
||||
plugin_transaction_abort_all(h, td);
|
||||
xmldb_get0_free(h, &td->td_target);
|
||||
transaction_free(td);
|
||||
}
|
||||
|
|
@ -477,7 +477,7 @@ from_validate_common(clicon_handle h,
|
|||
xml_apply_ancestor(xn, (xml_applyfn_t*)xml_flag_set, (void*)XML_FLAG_CHANGE);
|
||||
}
|
||||
/* 4. Call plugin transaction start callbacks */
|
||||
if (plugin_transaction_begin(h, td) < 0)
|
||||
if (plugin_transaction_begin_all(h, td) < 0)
|
||||
goto done;
|
||||
|
||||
/* 5. Make generic validation on all new or changed data.
|
||||
|
|
@ -488,11 +488,11 @@ from_validate_common(clicon_handle h,
|
|||
goto fail;
|
||||
|
||||
/* 6. Call plugin transaction validate callbacks */
|
||||
if (plugin_transaction_validate(h, td) < 0)
|
||||
if (plugin_transaction_validate_all(h, td) < 0)
|
||||
goto done;
|
||||
|
||||
/* 7. Call plugin transaction complete callbacks */
|
||||
if (plugin_transaction_complete(h, td) < 0)
|
||||
if (plugin_transaction_complete_all(h, td) < 0)
|
||||
goto done;
|
||||
retval = 1;
|
||||
done:
|
||||
|
|
@ -539,10 +539,10 @@ candidate_commit(clicon_handle h,
|
|||
}
|
||||
|
||||
/* 7. Call plugin transaction commit callbacks */
|
||||
if (plugin_transaction_commit(h, td) < 0)
|
||||
if (plugin_transaction_commit_all(h, td) < 0)
|
||||
goto done;
|
||||
/* After commit, make a post-commit call (sure that all plugins have committed) */
|
||||
if (plugin_transaction_commit_done(h, td) < 0)
|
||||
if (plugin_transaction_commit_done_all(h, td) < 0)
|
||||
goto done;
|
||||
|
||||
/* Clear cached trees from default values and marking */
|
||||
|
|
@ -576,14 +576,14 @@ candidate_commit(clicon_handle h,
|
|||
}
|
||||
|
||||
/* 9. Call plugin transaction end callbacks */
|
||||
plugin_transaction_end(h, td);
|
||||
plugin_transaction_end_all(h, td);
|
||||
|
||||
retval = 1;
|
||||
done:
|
||||
/* In case of failure (or error), call plugin transaction termination callbacks */
|
||||
if (td){
|
||||
if (retval < 1)
|
||||
plugin_transaction_abort(h, td);
|
||||
plugin_transaction_abort_all(h, td);
|
||||
xmldb_get0_free(h, &td->td_target);
|
||||
xmldb_get0_free(h, &td->td_src);
|
||||
transaction_free(td);
|
||||
|
|
@ -771,7 +771,7 @@ from_client_validate(clicon_handle h,
|
|||
* use clicon_err. */
|
||||
if (xret && clicon_xml2cbuf(cbret, xret, 0, 0, -1) < 0)
|
||||
goto done;
|
||||
plugin_transaction_abort(h, td);
|
||||
plugin_transaction_abort_all(h, td);
|
||||
if (!cbuf_len(cbret) &&
|
||||
netconf_operation_failed(cbret, "application", clicon_err_reason)< 0)
|
||||
goto done;
|
||||
|
|
@ -780,13 +780,13 @@ from_client_validate(clicon_handle h,
|
|||
|
||||
if (xmldb_get0_clear(h, td->td_src) < 0 ||
|
||||
xmldb_get0_clear(h, td->td_target) < 0){
|
||||
plugin_transaction_abort(h, td);
|
||||
plugin_transaction_abort_all(h, td);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Optionally write (potentially modified) tree back to candidate */
|
||||
if (clicon_option_bool(h, "CLICON_TRANSACTION_MOD")){
|
||||
plugin_transaction_abort(h, td);
|
||||
plugin_transaction_abort_all(h, td);
|
||||
if ((ret = xmldb_put(h, "candidate", OP_REPLACE, td->td_target,
|
||||
clicon_username_get(h), cbret)) < 0)
|
||||
goto done;
|
||||
|
|
@ -794,13 +794,13 @@ from_client_validate(clicon_handle h,
|
|||
}
|
||||
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
||||
/* Call plugin transaction end callbacks */
|
||||
plugin_transaction_end(h, td);
|
||||
plugin_transaction_end_all(h, td);
|
||||
ok:
|
||||
retval = 0;
|
||||
done:
|
||||
if (td){
|
||||
if (retval < 0)
|
||||
plugin_transaction_abort(h, td);
|
||||
plugin_transaction_abort_all(h, td);
|
||||
xmldb_get0_free(h, &td->td_target);
|
||||
xmldb_get0_free(h, &td->td_src);
|
||||
transaction_free(td);
|
||||
|
|
@ -810,3 +810,143 @@ from_client_validate(clicon_handle h,
|
|||
return retval;
|
||||
} /* from_client_validate */
|
||||
|
||||
#ifdef RESTART_PLUGIN_RPC
|
||||
int
|
||||
from_client_restart_one(clicon_handle h,
|
||||
clixon_plugin *cp,
|
||||
cbuf *cbret)
|
||||
{
|
||||
int retval = -1;
|
||||
char *db = "tmp";
|
||||
transaction_data_t *td = NULL;
|
||||
plgreset_t *resetfn; /* Plugin auth */
|
||||
trans_cb_t *fn;
|
||||
int ret;
|
||||
cxobj *xerr = NULL;
|
||||
yang_stmt *yspec;
|
||||
int i;
|
||||
cxobj *xn;
|
||||
|
||||
yspec = clicon_dbspec_yang(h);
|
||||
if (xmldb_db_reset(h, db) < 0)
|
||||
goto done;
|
||||
/* Application may define extra xml in its reset function*/
|
||||
if ((resetfn = cp->cp_api.ca_reset) != NULL){
|
||||
if ((retval = resetfn(h, db)) < 0) {
|
||||
clicon_debug(1, "plugin_start() failed");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
/* 1. Start transaction */
|
||||
if ((td = transaction_new()) == NULL)
|
||||
goto done;
|
||||
/* This is the state we are going to */
|
||||
if (xmldb_get0(h, "running", NULL, "/", 0, &td->td_target, NULL) < 0)
|
||||
goto done;
|
||||
if ((ret = xml_yang_validate_all_top(h, td->td_target, &xerr)) < 0)
|
||||
goto done;
|
||||
if (ret == 0){
|
||||
if (clicon_xml2cbuf(cbret, xerr, 0, 0, -1) < 0)
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
/* This is the state we are going from */
|
||||
if (xmldb_get0(h, db, NULL, "/", 0, &td->td_src, NULL) < 0)
|
||||
goto done;
|
||||
|
||||
/* 3. Compute differences */
|
||||
if (xml_diff(yspec,
|
||||
td->td_src,
|
||||
td->td_target,
|
||||
&td->td_dvec, /* removed: only in running */
|
||||
&td->td_dlen,
|
||||
&td->td_avec, /* added: only in candidate */
|
||||
&td->td_alen,
|
||||
&td->td_scvec, /* changed: original values */
|
||||
&td->td_tcvec, /* changed: wanted values */
|
||||
&td->td_clen) < 0)
|
||||
goto done;
|
||||
|
||||
/* Mark as changed in tree */
|
||||
for (i=0; i<td->td_dlen; i++){ /* Also down */
|
||||
xn = td->td_dvec[i];
|
||||
xml_flag_set(xn, XML_FLAG_DEL);
|
||||
xml_apply(xn, CX_ELMNT, (xml_applyfn_t*)xml_flag_set, (void*)XML_FLAG_DEL);
|
||||
xml_apply_ancestor(xn, (xml_applyfn_t*)xml_flag_set, (void*)XML_FLAG_CHANGE);
|
||||
}
|
||||
for (i=0; i<td->td_alen; i++){ /* Also down */
|
||||
xn = td->td_avec[i];
|
||||
xml_flag_set(xn, XML_FLAG_ADD);
|
||||
xml_apply(xn, CX_ELMNT, (xml_applyfn_t*)xml_flag_set, (void*)XML_FLAG_ADD);
|
||||
xml_apply_ancestor(xn, (xml_applyfn_t*)xml_flag_set, (void*)XML_FLAG_CHANGE);
|
||||
}
|
||||
for (i=0; i<td->td_clen; i++){ /* Also up */
|
||||
xn = td->td_scvec[i];
|
||||
xml_flag_set(xn, XML_FLAG_CHANGE);
|
||||
xml_apply_ancestor(xn, (xml_applyfn_t*)xml_flag_set, (void*)XML_FLAG_CHANGE);
|
||||
xn = td->td_tcvec[i];
|
||||
xml_flag_set(xn, XML_FLAG_CHANGE);
|
||||
xml_apply_ancestor(xn, (xml_applyfn_t*)xml_flag_set, (void*)XML_FLAG_CHANGE);
|
||||
}
|
||||
|
||||
/* 4. Call plugin transaction start callbacks */
|
||||
if ((fn = cp->cp_api.ca_trans_begin) != NULL){
|
||||
if ((retval = fn(h, (transaction_data)td)) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' transaction_begin callback does not make clicon_err call on error",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
/* 5. Make generic validation on all new or changed data.
|
||||
Note this is only call that uses 3-values */
|
||||
if ((ret = generic_validate(h, yspec, td, &xerr)) < 0)
|
||||
goto done;
|
||||
if (ret == 0){
|
||||
if (clicon_xml2cbuf(cbret, xerr, 0, 0, -1) < 0)
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
if ((fn = cp->cp_api.ca_trans_validate) != NULL){
|
||||
if ((retval = fn(h, (transaction_data)td)) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' transaction_validate callback does not make clicon_err call on error",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if ((fn = cp->cp_api.ca_trans_complete) != NULL){
|
||||
if ((retval = fn(h, (transaction_data)td)) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' trans_complete callback does not make clicon_err call on error",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if ((fn = cp->cp_api.ca_trans_commit) != NULL){
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' trans_commit callback does not make clicon_err call on error",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if ((fn = cp->cp_api.ca_trans_end) != NULL){
|
||||
if ((retval = fn(h, (transaction_data)td)) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' trans_end callback does not make clicon_err call on error",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
retval = 1;
|
||||
done:
|
||||
return retval;
|
||||
fail:
|
||||
retval = 0;
|
||||
goto done;
|
||||
}
|
||||
#endif /* RESTART_PLUGIN_RPC */
|
||||
|
|
|
|||
|
|
@ -48,5 +48,8 @@ int from_client_commit(clicon_handle h, cxobj *xe, cbuf *cbret, void *arg, void
|
|||
int from_client_discard_changes(clicon_handle h, cxobj *xe, cbuf *cbret, void *arg, void *regarg);
|
||||
int from_client_cancel_commit(clicon_handle h, cxobj *xe, cbuf *cbret, void *arg, void *regarg);
|
||||
int from_client_validate(clicon_handle h, cxobj *xe, cbuf *cbret, void *arg, void *regarg);
|
||||
#ifdef RESTART_PLUGIN_RPC
|
||||
int from_client_restart_one(clicon_handle h, clixon_plugin *cp, cbuf *cbret);
|
||||
#endif
|
||||
|
||||
#endif /* _BACKEND_COMMIT_H_ */
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ backend_terminate(clicon_handle h)
|
|||
if ((x = clicon_conf_xml(h)) != NULL)
|
||||
xml_free(x);
|
||||
stream_publish_exit();
|
||||
clixon_plugin_exit(h);
|
||||
clixon_plugin_exit_all(h);
|
||||
/* Delete all backend plugin RPC callbacks */
|
||||
rpc_callback_delete_all(h);
|
||||
/* Delete all backend plugin upgrade callbacks */
|
||||
|
|
@ -867,7 +867,7 @@ main(int argc,
|
|||
clicon_log(LOG_NOTICE, "%s: %u %s", __PROGRAM__, getpid(), cbuf_get(cbret));
|
||||
|
||||
/* Call backend plugin_start with user -- options */
|
||||
if (clixon_plugin_start(h) < 0)
|
||||
if (clixon_plugin_start_all(h) < 0)
|
||||
goto done;
|
||||
/* -1 option to run only once */
|
||||
if (once)
|
||||
|
|
@ -886,7 +886,7 @@ main(int argc,
|
|||
|
||||
}
|
||||
/* Call plugin callbacks when in background and before dropped privileges */
|
||||
if (clixon_plugin_daemon(h) < 0)
|
||||
if (clixon_plugin_daemon_all(h) < 0)
|
||||
goto done;
|
||||
|
||||
/* Write pid-file */
|
||||
|
|
|
|||
|
|
@ -67,62 +67,150 @@
|
|||
|
||||
/*! Request plugins to reset system state
|
||||
* The system 'state' should be the same as the contents of running_db
|
||||
* @param[in] cp Plugin handle
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] db Name of database
|
||||
* @param[in] db Name of datastore
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
clixon_plugin_reset(clicon_handle h,
|
||||
char *db)
|
||||
clixon_plugin_reset_one(clixon_plugin *cp,
|
||||
clicon_handle h,
|
||||
char *db)
|
||||
{
|
||||
clixon_plugin *cp = NULL;
|
||||
plgreset_t *resetfn; /* Plugin auth */
|
||||
int retval = 1;
|
||||
|
||||
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
|
||||
if ((resetfn = cp->cp_api.ca_reset) == NULL)
|
||||
continue;
|
||||
if ((retval = resetfn(h, db)) < 0) {
|
||||
clicon_debug(1, "plugin_start() failed");
|
||||
return -1;
|
||||
int retval = -1;
|
||||
plgreset_t *fn; /* callback */
|
||||
|
||||
if ((fn = cp->cp_api.ca_reset) != NULL){
|
||||
if (fn(h, db) < 0) {
|
||||
if (clicon_errno < 0)
|
||||
clicon_log(LOG_WARNING, "%s: Internal error: Reset callback in plugin: %s returned -1 but did not make a clicon_err call",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Call all plugins reset callbacks
|
||||
* The system 'state' should be the same as the contents of running_db
|
||||
* @param[in] h Clixon handle
|
||||
* @param[in] db Name of datastore
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
clixon_plugin_reset_all(clicon_handle h,
|
||||
char *db)
|
||||
{
|
||||
int retval = -1;
|
||||
clixon_plugin *cp = NULL;
|
||||
|
||||
/* 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)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Request plugins to reset system state
|
||||
* The system 'state' should be the same as the contents of running_db
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] db Name of database
|
||||
/*! Call single plugin "post-" daemonize callback
|
||||
* @param[in] cp Plugin handle
|
||||
* @param[in] h Clixon handle
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
clixon_plugin_daemon(clicon_handle h)
|
||||
clixon_plugin_daemon_one(clixon_plugin *cp,
|
||||
clicon_handle h)
|
||||
{
|
||||
clixon_plugin *cp = NULL;
|
||||
plgdaemon_t *daemonfn; /* Plugin auth */
|
||||
int retval = 1;
|
||||
|
||||
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
|
||||
if ((daemonfn = cp->cp_api.ca_daemon) == NULL)
|
||||
continue;
|
||||
if ((retval = daemonfn(h)) < 0) {
|
||||
clicon_debug(1, "plugin_daemon() failed");
|
||||
return -1;
|
||||
int retval = -1;
|
||||
plgdaemon_t *fn; /* Daemonize plugin callback function */
|
||||
|
||||
if ((fn = cp->cp_api.ca_daemon) != NULL){
|
||||
if (fn(h) < 0) {
|
||||
if (clicon_errno < 0)
|
||||
clicon_log(LOG_WARNING, "%s: Internal error: Daemon callback in plugin: %s returned -1 but did not make a clicon_err call",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Call all plugins "post-" daemonize callbacks
|
||||
* @param[in] h Clicon handle
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
clixon_plugin_daemon_all(clicon_handle h)
|
||||
{
|
||||
int retval = -1;
|
||||
clixon_plugin *cp = NULL;
|
||||
|
||||
/* Loop through all plugins, call callbacks in each */
|
||||
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
|
||||
if (clixon_plugin_daemon_one(cp, h) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Call single backend statedata callback
|
||||
* @param[in] cp Plugin handle
|
||||
* @param[in] h clicon handle
|
||||
* @param[in] xpath String with XPATH syntax. or NULL for all
|
||||
* @retval -1 Error
|
||||
* @retval 0 Statedata callback failed
|
||||
* @retval 1 OK if callback found (and called) xp is set, otherwise xp is not set
|
||||
* @note xtop can be replaced
|
||||
*/
|
||||
static int
|
||||
clixon_plugin_statedata_one(clixon_plugin *cp,
|
||||
clicon_handle h,
|
||||
cvec *nsc,
|
||||
char *xpath,
|
||||
cxobj **xp)
|
||||
{
|
||||
int retval = -1;
|
||||
plgstatedata_t *fn; /* Plugin statedata fn */
|
||||
cxobj *x = NULL;
|
||||
|
||||
if ((fn = cp->cp_api.ca_statedata) != NULL){
|
||||
if ((x = xml_new("config", NULL, CX_ELMNT)) == NULL)
|
||||
goto done;
|
||||
if (fn(h, nsc, xpath, x) < 0){
|
||||
if (clicon_errno < 0)
|
||||
clicon_log(LOG_WARNING, "%s: Internal error: State callback in plugin: %s returned -1 but did not make a clicon_err call",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
goto fail; /* Dont quit here on user callbacks */
|
||||
}
|
||||
}
|
||||
if (xp && x)
|
||||
*xp = x;
|
||||
retval = 1;
|
||||
done:
|
||||
return retval;
|
||||
fail:
|
||||
retval = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*! Go through all backend statedata callbacks and collect state data
|
||||
* This is internal system call, plugin is invoked (does not call) this function
|
||||
* Backend plugins can register
|
||||
* @param[in] h clicon handle
|
||||
* @param[in] yspec Yang spec
|
||||
* @param[in] nsc Namespace context
|
||||
* @param[in] xpath String with XPATH syntax. or NULL for all
|
||||
* @param[in,out] xtop State XML tree is merged with existing tree.
|
||||
* @retval -1 Error
|
||||
|
|
@ -131,27 +219,31 @@ clixon_plugin_daemon(clicon_handle h)
|
|||
* @note xtop can be replaced
|
||||
*/
|
||||
int
|
||||
clixon_plugin_statedata(clicon_handle h,
|
||||
yang_stmt *yspec,
|
||||
cvec *nsc,
|
||||
char *xpath,
|
||||
cxobj **xret)
|
||||
clixon_plugin_statedata_all(clicon_handle h,
|
||||
yang_stmt *yspec,
|
||||
cvec *nsc,
|
||||
char *xpath,
|
||||
cxobj **xret)
|
||||
{
|
||||
int retval = -1;
|
||||
int ret;
|
||||
cxobj *x = NULL;
|
||||
clixon_plugin *cp = NULL;
|
||||
plgstatedata_t *fn; /* Plugin statedata fn */
|
||||
cbuf *cberr = NULL;
|
||||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
|
||||
if ((fn = cp->cp_api.ca_statedata) == NULL)
|
||||
continue;
|
||||
if ((x = xml_new("config", NULL, CX_ELMNT)) == NULL)
|
||||
if ((ret = clixon_plugin_statedata_one(cp, h, nsc, xpath, &x)) < 0)
|
||||
goto done;
|
||||
if (fn(h, nsc, xpath, x) < 0)
|
||||
goto fail; /* Dont quit here on user callbacks */
|
||||
/* if x contains no data, then continue? */
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
if (x == NULL)
|
||||
continue;
|
||||
if (xml_child_nr(x) == 0){
|
||||
xml_free(x);
|
||||
x = NULL;
|
||||
continue;
|
||||
}
|
||||
#if 1
|
||||
if (debug)
|
||||
clicon_log_xml(LOG_DEBUG, x, "%s STATE:", __FUNCTION__);
|
||||
|
|
@ -220,6 +312,27 @@ transaction_free(transaction_data_t *td)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
plugin_transaction_begin_one(clixon_plugin *cp,
|
||||
clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
|
||||
if ((fn = cp->cp_api.ca_trans_begin) != NULL){
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* The plugin_transaction routines need access to struct plugin which is local to this file */
|
||||
|
||||
/*! Call transaction_begin() in all plugins before a validate/commit.
|
||||
|
|
@ -229,24 +342,39 @@ transaction_free(transaction_data_t *td)
|
|||
* @retval -1 Error: one of the plugin callbacks returned error
|
||||
*/
|
||||
int
|
||||
plugin_transaction_begin(clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
plugin_transaction_begin_all(clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
{
|
||||
int retval = 0;
|
||||
int retval = -1;
|
||||
clixon_plugin *cp = NULL;
|
||||
trans_cb_t *fn;
|
||||
|
||||
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
|
||||
if ((fn = cp->cp_api.ca_trans_begin) == NULL)
|
||||
continue;
|
||||
if ((retval = fn(h, (transaction_data)td)) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' transaction_begin callback does not make clicon_err call on error",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
if (plugin_transaction_begin_one(cp, h, td) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
break;
|
||||
int
|
||||
plugin_transaction_validate_one(clixon_plugin *cp,
|
||||
clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
|
||||
if ((fn = cp->cp_api.ca_trans_validate) != NULL){
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -257,23 +385,39 @@ plugin_transaction_begin(clicon_handle h,
|
|||
* @retval -1 Error: one of the plugin callbacks returned validation fail
|
||||
*/
|
||||
int
|
||||
plugin_transaction_validate(clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
plugin_transaction_validate_all(clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
{
|
||||
int retval = 0;
|
||||
int retval = -1;
|
||||
clixon_plugin *cp = NULL;
|
||||
trans_cb_t *fn;
|
||||
|
||||
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
|
||||
if ((fn = cp->cp_api.ca_trans_validate) == NULL)
|
||||
continue;
|
||||
if ((retval = fn(h, (transaction_data)td)) < 0){
|
||||
if (plugin_transaction_validate_one(cp, h, td) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
plugin_transaction_complete_one(clixon_plugin *cp,
|
||||
clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
|
||||
if ((fn = cp->cp_api.ca_trans_complete) != NULL){
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' transaction_validate callback does not make clicon_err call on error",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
break;
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -286,24 +430,18 @@ plugin_transaction_validate(clicon_handle h,
|
|||
* @note Rename to transaction_complete?
|
||||
*/
|
||||
int
|
||||
plugin_transaction_complete(clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
plugin_transaction_complete_all(clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
{
|
||||
int retval = 0;
|
||||
int retval = -1;
|
||||
clixon_plugin *cp = NULL;
|
||||
trans_cb_t *fn;
|
||||
|
||||
|
||||
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
|
||||
if ((fn = cp->cp_api.ca_trans_complete) == NULL)
|
||||
continue;
|
||||
if ((retval = fn(h, (transaction_data)td)) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' trans_complete callback does not make clicon_err call on error",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
|
||||
break;
|
||||
}
|
||||
if (plugin_transaction_complete_one(cp, h, td) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -316,10 +454,10 @@ plugin_transaction_complete(clicon_handle h,
|
|||
* The revert is made in plugin before this one. Eg if error occurred in
|
||||
* plugin 2, then the revert will be made in plugins 1 and 0.
|
||||
*/
|
||||
int
|
||||
plugin_transaction_revert(clicon_handle h,
|
||||
transaction_data_t *td,
|
||||
int nr)
|
||||
static int
|
||||
plugin_transaction_revert_all(clicon_handle h,
|
||||
transaction_data_t *td,
|
||||
int nr)
|
||||
{
|
||||
int retval = 0;
|
||||
clixon_plugin *cp = NULL;
|
||||
|
|
@ -337,6 +475,27 @@ plugin_transaction_revert(clicon_handle h,
|
|||
return retval; /* ignore errors */
|
||||
}
|
||||
|
||||
int
|
||||
plugin_transaction_commit_one(clixon_plugin *cp,
|
||||
clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
|
||||
if ((fn = cp->cp_api.ca_trans_commit) != NULL){
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Call transaction_commit callbacks in all backend plugins
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] td Transaction data
|
||||
|
|
@ -347,27 +506,44 @@ plugin_transaction_revert(clicon_handle h,
|
|||
* and in reverse order.
|
||||
*/
|
||||
int
|
||||
plugin_transaction_commit(clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
plugin_transaction_commit_all(clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
{
|
||||
int retval = 0;
|
||||
int retval = -1;
|
||||
clixon_plugin *cp = NULL;
|
||||
trans_cb_t *fn;
|
||||
int i=0;
|
||||
|
||||
|
||||
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
|
||||
i++;
|
||||
if ((fn = cp->cp_api.ca_trans_commit) == NULL)
|
||||
continue;
|
||||
if ((retval = fn(h, (transaction_data)td)) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' trans_commit callback does not make clicon_err call on error",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
if (plugin_transaction_commit_one(cp, h, td) < 0){
|
||||
/* Make an effort to revert transaction */
|
||||
plugin_transaction_revert(h, td, i-1);
|
||||
break;
|
||||
plugin_transaction_revert_all(h, td, i-1);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
plugin_transaction_commit_done_one(clixon_plugin *cp,
|
||||
clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
|
||||
if ((fn = cp->cp_api.ca_trans_commit_done) != NULL){
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -379,25 +555,39 @@ plugin_transaction_commit(clicon_handle h,
|
|||
* @note no revert is done
|
||||
*/
|
||||
int
|
||||
plugin_transaction_commit_done(clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
plugin_transaction_commit_done_all(clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
{
|
||||
int retval = 0;
|
||||
int retval = -1;
|
||||
clixon_plugin *cp = NULL;
|
||||
trans_cb_t *fn;
|
||||
int i=0;
|
||||
|
||||
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
|
||||
i++;
|
||||
if ((fn = cp->cp_api.ca_trans_commit_done) == NULL)
|
||||
continue;
|
||||
if ((retval = fn(h, (transaction_data)td)) < 0){
|
||||
if (plugin_transaction_commit_done_one(cp, h, td) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
plugin_transaction_end_one(clixon_plugin *cp,
|
||||
clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
|
||||
if ((fn = cp->cp_api.ca_trans_end) != NULL){
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' trans_commit_done callback does not make clicon_err call on error",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
break;
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -408,23 +598,39 @@ plugin_transaction_commit_done(clicon_handle h,
|
|||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
plugin_transaction_end(clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
plugin_transaction_end_all(clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
{
|
||||
int retval = 0;
|
||||
int retval = -1;
|
||||
clixon_plugin *cp = NULL;
|
||||
trans_cb_t *fn;
|
||||
|
||||
|
||||
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
|
||||
if ((fn = cp->cp_api.ca_trans_end) == NULL)
|
||||
continue;
|
||||
if ((retval = fn(h, (transaction_data)td)) < 0){
|
||||
if (plugin_transaction_end_one(cp, h, td) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
plugin_transaction_abort_one(clixon_plugin *cp,
|
||||
clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
|
||||
if ((fn = cp->cp_api.ca_trans_abort) != NULL){
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' trans_end callback does not make clicon_err call on error",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
break;
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, cp->cp_name);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -435,18 +641,17 @@ plugin_transaction_end(clicon_handle h,
|
|||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
plugin_transaction_abort(clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
plugin_transaction_abort_all(clicon_handle h,
|
||||
transaction_data_t *td)
|
||||
{
|
||||
int retval = 0;
|
||||
int retval = -1;
|
||||
clixon_plugin *cp = NULL;
|
||||
trans_cb_t *fn;
|
||||
|
||||
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
|
||||
if ((fn = cp->cp_api.ca_trans_abort) == NULL)
|
||||
continue;
|
||||
fn(h, (transaction_data)td); /* dont abort on error */
|
||||
if (plugin_transaction_abort_one(cp, h, td) < 0)
|
||||
; /* dont abort on error */
|
||||
}
|
||||
retval = 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,21 +69,36 @@ typedef struct {
|
|||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
int clixon_plugin_reset(clicon_handle h, char *db);
|
||||
int clixon_plugin_reset_one(clixon_plugin *cp, clicon_handle h, char *db);
|
||||
int clixon_plugin_reset_all(clicon_handle h, char *db);
|
||||
|
||||
int clixon_plugin_daemon(clicon_handle h);
|
||||
int clixon_plugin_daemon_one(clixon_plugin *cp, clicon_handle h);
|
||||
int clixon_plugin_daemon_all(clicon_handle h);
|
||||
|
||||
int clixon_plugin_statedata_all(clicon_handle h, yang_stmt *yspec, cvec *nsc, char *xpath, cxobj **xtop);
|
||||
|
||||
int clixon_plugin_statedata(clicon_handle h, yang_stmt *yspec, cvec *nsc,
|
||||
char *xpath, cxobj **xtop);
|
||||
transaction_data_t * transaction_new(void);
|
||||
int transaction_free(transaction_data_t *);
|
||||
|
||||
int plugin_transaction_begin(clicon_handle h, transaction_data_t *td);
|
||||
int plugin_transaction_validate(clicon_handle h, transaction_data_t *td);
|
||||
int plugin_transaction_complete(clicon_handle h, transaction_data_t *td);
|
||||
int plugin_transaction_commit(clicon_handle h, transaction_data_t *td);
|
||||
int plugin_transaction_commit_done(clicon_handle h, transaction_data_t *td);
|
||||
int plugin_transaction_end(clicon_handle h, transaction_data_t *td);
|
||||
int plugin_transaction_abort(clicon_handle h, transaction_data_t *td);
|
||||
int plugin_transaction_begin_one(clixon_plugin *cp, clicon_handle h, transaction_data_t *td);
|
||||
int plugin_transaction_begin_all(clicon_handle h, transaction_data_t *td);
|
||||
|
||||
int plugin_transaction_validate_one(clixon_plugin *cp, clicon_handle h, transaction_data_t *td);
|
||||
int plugin_transaction_validate_all(clicon_handle h, transaction_data_t *td);
|
||||
|
||||
int plugin_transaction_complete_one(clixon_plugin *cp, clicon_handle h, transaction_data_t *td);
|
||||
int plugin_transaction_complete_all(clicon_handle h, transaction_data_t *td);
|
||||
|
||||
int plugin_transaction_commit_one(clixon_plugin *cp, clicon_handle h, transaction_data_t *td);
|
||||
int plugin_transaction_commit_all(clicon_handle h, transaction_data_t *td);
|
||||
|
||||
int plugin_transaction_commit_done_one(clixon_plugin *cp, clicon_handle h, transaction_data_t *td);
|
||||
int plugin_transaction_commit_done_all(clicon_handle h, transaction_data_t *td);
|
||||
|
||||
int plugin_transaction_end_one(clixon_plugin *cp, clicon_handle h, transaction_data_t *td);
|
||||
int plugin_transaction_end_all(clicon_handle h, transaction_data_t *td);
|
||||
|
||||
int plugin_transaction_abort_one(clixon_plugin *cp, clicon_handle h, transaction_data_t *td);
|
||||
int plugin_transaction_abort_all(clicon_handle h, transaction_data_t *td);
|
||||
|
||||
#endif /* _BACKEND_PLUGIN_H_ */
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ startup_extraxml(clicon_handle h,
|
|||
if (xmldb_db_reset(h, tmp_db) < 0)
|
||||
goto done;
|
||||
/* Application may define extra xml in its reset function*/
|
||||
if (clixon_plugin_reset(h, tmp_db) < 0)
|
||||
if (clixon_plugin_reset_all(h, tmp_db) < 0)
|
||||
goto done;
|
||||
/* Extra XML can also be added via file */
|
||||
if (file){
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue