double predicates in xpath; leaks; grideye debug

This commit is contained in:
Olof hagsand 2016-03-26 10:47:58 +01:00
parent c1c1670a74
commit 741fb97a9f
13 changed files with 453 additions and 242 deletions

View file

@ -244,7 +244,7 @@ from_client_xmlput(clicon_handle h,
cvec *cvv = NULL;
char *str = NULL;
char *xml = NULL;
cxobj *xt;
cxobj *xt = NULL;
int piddb;
if (clicon_msg_xmlput_decode(msg,
@ -283,6 +283,8 @@ from_client_xmlput(clicon_handle h,
free(str);
if (cvv)
cvec_free (cvv);
if (xt)
xml_free(xt);
return retval;
}

View file

@ -112,51 +112,41 @@ generic_validate(yang_spec *yspec,
return retval;
}
/*! Do a diff between candidate and running, then start a commit transaction
*
* The code reverts changes if the commit fails. But if the revert
* fails, we just ignore the errors and proceed. Maybe we should
* do something more drastic?
* @param[in] h Clicon handle
*/
int
candidate_commit(clicon_handle h,
char *candidate)
/*! Common code of candidate_validate and candidate_commit
*/
static int
validate_common(clicon_handle h,
char *candidate,
transaction_data_t *td)
{
int retval = -1;
int i;
cxobj *xn;
void *firsterr = NULL;
yang_spec *yspec;
transaction_data_t *td = NULL;
int retval = -1;
yang_spec *yspec;
int i;
cxobj *xn;
if ((yspec = clicon_dbspec_yang(h)) == NULL){
clicon_err(OE_FATAL, 0, "No DB_SPEC");
goto done;
}
/* 1. Start transaction */
if ((td = transaction_new()) == NULL)
goto done;
/* 2. Parse xml trees */
/* 2. Parse xml trees */
if (xmldb_get(h, "running", "/", 0, &td->td_src, NULL, NULL) < 0)
goto done;
if (xmldb_get(h, candidate, "/", 0, &td->td_target, NULL, 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;
/* 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;
if (debug)
transaction_print(stderr, td);
/* Mark as changed in tree */
@ -183,19 +173,45 @@ candidate_commit(clicon_handle h,
/* 4. Call plugin transaction start callbacks */
if (plugin_transaction_begin(h, td) < 0)
goto done;
goto done;
/* 5. Make generic validation on all new or changed data. */
if (generic_validate(yspec, td) < 0)
goto done;
goto done;
/* 6. Call plugin transaction validate callbacks */
if (plugin_transaction_validate(h, td) < 0)
goto done;
if (plugin_transaction_validate(h, td) < 0)
goto done;
/* 7. Call plugin transaction complete callbacks */
if (plugin_transaction_complete(h, td) < 0)
goto done;
/* 7. Call plugin transaction complete callbacks */
if (plugin_transaction_complete(h, td) < 0)
goto done;
retval = 0;
done:
return retval;
}
/*! Do a diff between candidate and running, then start a commit transaction
*
* The code reverts changes if the commit fails. But if the revert
* fails, we just ignore the errors and proceed. Maybe we should
* do something more drastic?
* @param[in] h Clicon handle
*/
int
candidate_commit(clicon_handle h,
char *candidate)
{
int retval = -1;
transaction_data_t *td = NULL;
/* 1. Start transaction */
if ((td = transaction_new()) == NULL)
goto done;
/* Common steps (with validate) */
if (validate_common(h, candidate, td) < 0)
goto done;
/* 7. Call plugin transaction commit callbacks */
if (plugin_transaction_commit(h, td) < 0)
@ -214,7 +230,6 @@ candidate_commit(clicon_handle h,
clicon_log(LOG_NOTICE, "Error in rollback, trying to continue");
goto done;
}
retval = 0;
done:
/* In case of failure, call plugin transaction termination callbacks */
@ -222,8 +237,6 @@ candidate_commit(clicon_handle h,
plugin_transaction_abort(h, td);
if (td)
transaction_free(td);
if (firsterr)
clicon_err_restore(firsterr);
return retval;
}
@ -237,73 +250,15 @@ candidate_validate(clicon_handle h,
char *candidate)
{
int retval = -1;
yang_spec *yspec;
transaction_data_t *td = NULL;
int i;
cxobj *xn;
if ((yspec = clicon_dbspec_yang(h)) == NULL){
clicon_err(OE_FATAL, 0, "No DB_SPEC");
goto done;
}
/* 1. Start transaction */
if ((td = transaction_new()) == NULL)
goto done;
/* 2. Parse xml trees */
if (xmldb_get(h, "running", "/", 0, &td->td_src, NULL, NULL) < 0)
/* Common steps (with commit) */
if (validate_common(h, candidate, td) < 0)
goto done;
if (xmldb_get(h, "candidate", "/", 0, &td->td_target, NULL, 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;
if (debug)
transaction_print(stderr, td);
/* 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);
}
for (i=0; i<td->td_alen; i++){ /* Also down */
xn = td->td_avec[i];
xml_flag_set(xn, XML_FLAG_ADD);
}
for (i=0; i<td->td_clen; i++){ /* Also up */
xn = td->td_scvec[i];
xml_flag_set(xn, XML_FLAG_CHANGE);
xn = td->td_tcvec[i];
xml_flag(xn, XML_FLAG_CHANGE);
}
/* 4. Call plugin start transaction callbacks */
if (plugin_transaction_begin(h, td) < 0)
goto done;
/* 5. Make generic validation on all new or changed data. */
if (generic_validate(yspec, td) < 0)
goto done;
/* 6. Call plugin validate transaction callbacks */
if (plugin_transaction_validate(h, td) < 0)
goto done;
/* 7. Call plugin complete transaction callbacks */
if (plugin_transaction_complete(h, td) < 0)
goto done;
retval = 0;
done:

View file

@ -632,6 +632,15 @@ plugin_transaction_complete(clicon_handle h,
return retval;
}
/*! Revert a commit
* @param[in] h CLICON handle
* @param[in] td Transaction data
* @param[in] nr The plugin where an error occured.
* @retval 0 OK
* @retval -1 Error
* 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,
@ -651,10 +660,11 @@ plugin_transaction_revert(clicon_handle h,
tr.td_dvec = td->td_avec;
tr.td_alen = td->td_dlen;
tr.td_avec = td->td_dvec;
tr.td_clen = td->td_clen;
tr.td_scvec = td->td_tcvec;
tr.td_tcvec = td->td_scvec;
for (i = nr-1; i; i--){
for (i = nr-1; i>=0; i--){
p = &plugins[i];
if (p->p_trans_commit)
if ((p->p_trans_commit)(h, (transaction_data)&tr) < 0){

View file

@ -167,6 +167,7 @@ backend_notify_xml(clicon_handle h,
cbuf *cb = NULL;
struct handle_subscription *hs;
clicon_debug(1, "%s %s", __FUNCTION__, stream);
/* Now go thru all clients(sessions), and all subscriptions and find matches */
for (ce = backend_client_list(h); ce; ce = ce->ce_next)
for (su = ce->ce_subscription; su; su = su->su_next)
@ -185,8 +186,6 @@ backend_notify_xml(clicon_handle h,
}
}
/* Then go thru all global (handle) subscriptions and find matches */
/* XXX: x contains name==dk-ore, but filter is
id==/[userid=d2d5e46c-c6f9-42f3-9a69-fb52fe60940d] */
hs = NULL;
while ((hs = subscription_each(h, hs)) != NULL){
if (hs->hs_format != MSG_NOTIFY_XML)