when_xpath memory fixes and trimmed perf

This commit is contained in:
Olof hagsand 2024-08-29 17:56:47 +02:00
parent 911594ead1
commit b0ec866544
5 changed files with 42 additions and 21 deletions

View file

@ -281,8 +281,11 @@ check_body_namespace(cxobj *x0,
* @retval 1 OK * @retval 1 OK
* @retval 0 Failed (cbret set) * @retval 0 Failed (cbret set)
* @retval -1 Error * @retval -1 Error
* XXX this code is a mess. It tries multiple methods, one after the other. The solution * XXX this code is a mess. It tries multiple methods, one after the other.
* is probably to make xpath evaluation namespace aware in combination with XML evaluation * Observations:
* (1) is enough and required by clixon/controller tests
* (1+4+6) is required by some Arista machines
* The solution is probably to make xpath evaluation namespace aware in combination with XML evaluation
* (3+4) * (3+4)
*/ */
static int static int
@ -316,9 +319,10 @@ check_when_condition(cxobj *x0p,
goto done; goto done;
if (nr != 0) if (nr != 0)
goto ok; goto ok;
/* 2. Try yang context for incoming xml */
if (xml_nsctx_node(x1p, &nnsc) < 0) if (xml_nsctx_node(x1p, &nnsc) < 0)
goto done; goto done;
/* 2. Try yang context for incoming xml */ #if 0
if ((nr = xpath_vec_bool(x1p, nsc, "%s", xpath)) < 0) if ((nr = xpath_vec_bool(x1p, nsc, "%s", xpath)) < 0)
goto done; goto done;
if (nr != 0) if (nr != 0)
@ -328,18 +332,21 @@ check_when_condition(cxobj *x0p,
goto done; goto done;
if (nr != 0) if (nr != 0)
goto ok; goto ok;
#endif
/* 4. Try xml context for existing xml */ /* 4. Try xml context for existing xml */
if ((nr = xpath_vec_bool(x0p, nnsc, "%s", xpath)) < 0) /* Try request */ if ((nr = xpath_vec_bool(x0p, nnsc, "%s", xpath)) < 0) /* Try request */
goto done; goto done;
if (nr != 0) if (nr != 0)
goto ok; goto ok;
/* 5. Try yang canonical context for incoming xml */
if (yang_when_canonical_xpath_get(y, &cxpath, &cnsc) < 0) if (yang_when_canonical_xpath_get(y, &cxpath, &cnsc) < 0)
goto done; goto done;
/* 5. Try yang canonical context for incoming xml */ #if 0
if ((nr = xpath_vec_bool(x1p, cnsc, "%s", cxpath)) < 0) if ((nr = xpath_vec_bool(x1p, cnsc, "%s", cxpath)) < 0)
goto done; goto done;
if (nr != 0) if (nr != 0)
goto ok; goto ok;
#endif
/* 6. Try yang canonical context for existing xml */ /* 6. Try yang canonical context for existing xml */
if ((nr = xpath_vec_bool(x0p, cnsc, "%s", cxpath)) < 0) if ((nr = xpath_vec_bool(x0p, cnsc, "%s", cxpath)) < 0)
goto done; goto done;
@ -361,12 +368,14 @@ check_when_condition(cxobj *x0p,
ok: ok:
retval = 1; retval = 1;
done: done:
if (cxpath)
free(cxpath);
if (cnsc)
cvec_free(cnsc);
if (nsc) if (nsc)
cvec_free(nsc); cvec_free(nsc);
if (cberr) if (cberr)
cbuf_free(cberr); cbuf_free(cberr);
if (cxpath)
free(cxpath);
if (nnsc) if (nnsc)
cvec_free(nnsc); cvec_free(nnsc);
return retval; return retval;
@ -498,6 +507,8 @@ choice_other_match(cxobj *x0,
ok: ok:
retval = 1; retval = 1;
done: done:
if (opstr)
free(opstr);
return retval; return retval;
fail: fail:
retval = 0; retval = 0;

View file

@ -1239,6 +1239,7 @@ xml_yang_validate_all(clixon_handle h,
yang_stmt *yc; /* yang child */ yang_stmt *yc; /* yang child */
yang_stmt *ye; /* yang must error-message */ yang_stmt *ye; /* yang must error-message */
char *xpath; char *xpath;
char *xpath1 = NULL;
int nr; int nr;
int ret; int ret;
cxobj *x; cxobj *x;
@ -1283,8 +1284,8 @@ xml_yang_validate_all(clixon_handle h,
goto fail; goto fail;
} }
if (yang_config(yt) != 0){ if (yang_config(yt) != 0){
ret = yang_check_when_xpath(xt, xml_parent(xt), yt, &hit, &nr, &xpath); ret = yang_check_when_xpath(xt, xml_parent(xt), yt, &hit, &nr, &xpath1);
clixon_debug(CLIXON_DBG_XPATH|CLIXON_DBG_DETAIL, "nr:%d xpath:%s return:%d", nr, xpath, ret); clixon_debug(CLIXON_DBG_XPATH|CLIXON_DBG_DETAIL, "nr:%d xpath:%s return:%d", nr, xpath1, ret);
if (ret < 0) if (ret < 0)
goto done; goto done;
@ -1296,7 +1297,7 @@ xml_yang_validate_all(clixon_handle h,
cprintf(cb, "Failed WHEN condition of %s in module %s (WHEN xpath is %s)", cprintf(cb, "Failed WHEN condition of %s in module %s (WHEN xpath is %s)",
xml_name(xt), xml_name(xt),
yang_argument_get(ys_module(yt)), yang_argument_get(ys_module(yt)),
xpath); xpath1);
if (xret && netconf_operation_failed_xml(xret, "application", if (xret && netconf_operation_failed_xml(xret, "application",
cbuf_get(cb)) < 0) cbuf_get(cb)) < 0)
goto done; goto done;
@ -1403,6 +1404,8 @@ xml_yang_validate_all(clixon_handle h,
ok: ok:
retval = 1; retval = 1;
done: done:
if (xpath1)
free(xpath1);
if (cb) if (cb)
cbuf_free(cb); cbuf_free(cb);
if (nsc) if (nsc)

View file

@ -299,7 +299,6 @@ xml_default(yang_stmt *yt,
cxobj *xc; cxobj *xc;
int top = 0; /* Top symbol (set default namespace) */ int top = 0; /* Top symbol (set default namespace) */
int create = 0; int create = 0;
char *xpath;
int nr = 0; int nr = 0;
int hit = 0; int hit = 0;
cg_var *cv; cg_var *cv;
@ -336,7 +335,7 @@ xml_default(yang_stmt *yt,
} }
if (!cv_flag(cv, V_UNSET)){ /* Default value exists */ if (!cv_flag(cv, V_UNSET)){ /* Default value exists */
/* Check when condition */ /* Check when condition */
if (yang_check_when_xpath(NULL, xt, yc, &hit, &nr, &xpath) < 0) if (yang_check_when_xpath(NULL, xt, yc, &hit, &nr, NULL) < 0)
goto done; goto done;
if (hit && nr == 0) if (hit && nr == 0)
break; /* Do not create default if xpath fails */ break; /* Do not create default if xpath fails */
@ -351,7 +350,7 @@ xml_default(yang_stmt *yt,
case Y_CONTAINER: case Y_CONTAINER:
if (yang_find(yc, Y_PRESENCE, NULL) == NULL){ if (yang_find(yc, Y_PRESENCE, NULL) == NULL){
/* Check when condition */ /* Check when condition */
if (yang_check_when_xpath(NULL, xt, yc, &hit, &nr, &xpath) < 0) if (yang_check_when_xpath(NULL, xt, yc, &hit, &nr, NULL) < 0)
goto done; goto done;
if (hit && nr == 0) if (hit && nr == 0)
break; /* Do not create default if xpath fails */ break; /* Do not create default if xpath fails */

View file

@ -2068,7 +2068,7 @@ xml_copy_marked(cxobj *x0,
* @param[in] yn Yang node * @param[in] yn Yang node
* @param[out] hit when statement found * @param[out] hit when statement found
* @param[out] nrp 1: when stmt evaluates to true * @param[out] nrp 1: when stmt evaluates to true
* @param[out] xpathp when stmts xpath * @param[out] xpathp when stmts xpath, free after use
* @retval 0 OK * @retval 0 OK
* @retval -1 Error * @retval -1 Error
* First variants of WHEN: Augmented and uses when using special info in node * First variants of WHEN: Augmented and uses when using special info in node
@ -2088,24 +2088,26 @@ yang_check_when_xpath(cxobj *xn,
cxobj *x = NULL; cxobj *x = NULL;
int nr = 0; int nr = 0;
cvec *nsc = NULL; cvec *nsc = NULL;
int xmalloc = 0; /* ugly help variable to clean temporary object */ int variant = 0; /* ugly help variable to clean temporary object */
/* First variant */
if (yang_when_canonical_xpath_get(yn, &xpath, &nsc) < 0) if (yang_when_canonical_xpath_get(yn, &xpath, &nsc) < 0)
goto done; goto done;
if (xpath != NULL){ if (xpath != NULL){
x = xp; x = xp;
*hit = 1; *hit = 1;
} }
/* Second variant */
else if ((yc = yang_find(yn, Y_WHEN, NULL)) != NULL){ else if ((yc = yang_find(yn, Y_WHEN, NULL)) != NULL){
xpath = yang_argument_get(yc); /* "when" has xpath argument */ /* "when" has xpath argument */
if ((xpath = strdup(yang_argument_get(yc))) == NULL){
clixon_err(OE_UNIX, errno, "strdup");
goto done;
}
/* Create dummy */ /* Create dummy */
if (xn == NULL){ if (xn == NULL){
if ((x = xml_new(yang_argument_get(yn), xp, CX_ELMNT)) == NULL) if ((x = xml_new(yang_argument_get(yn), xp, CX_ELMNT)) == NULL)
goto done; goto done;
xml_spec_set(x, yn); xml_spec_set(x, yn);
xmalloc++; variant = 1;
} }
else else
x = xn; x = xn;
@ -2121,12 +2123,16 @@ yang_check_when_xpath(cxobj *xn,
} }
if (nrp) if (nrp)
*nrp = nr; *nrp = nr;
if (xpathp) if (xpathp){
*xpathp = xpath; *xpathp = xpath;
xpath = NULL;
}
retval = 0; retval = 0;
done: done:
if (xmalloc) if (variant)
xml_purge(x); xml_purge(x);
if (xpath)
free(xpath);
if (nsc) if (nsc)
xml_nsctx_free(nsc); xml_nsctx_free(nsc);
return retval; return retval;

View file

@ -1147,7 +1147,7 @@ xpath_traverse_canonical(xpath_tree *xs,
* @param[in] nsc0 Input namespace context * @param[in] nsc0 Input namespace context
* @param[in] yspec Yang spec containing all modules, associated with namespaces * @param[in] yspec Yang spec containing all modules, associated with namespaces
* @param[in] exprstr Interpret strings as <prefix>:<name> (primaryexpr/literal/string) * @param[in] exprstr Interpret strings as <prefix>:<name> (primaryexpr/literal/string)
* @param[out] xpath1 Output xpath. Free after use with free * @param[out] xpath1 Output xpath. Free after use
* @param[out] nsc1 Output namespace context. Free after use with xml_nsctx_free * @param[out] nsc1 Output namespace context. Free after use with xml_nsctx_free
* @param[out] cbreason reason if retval = 0 * @param[out] cbreason reason if retval = 0
* @retval 1 OK, xpath1 and nsc1 allocated * @retval 1 OK, xpath1 and nsc1 allocated
@ -1239,6 +1239,8 @@ xpath2canonical1(const char *xpath0,
goto done; goto done;
} }
/*! Backward compatible wrapper around xpath2canonical1
*/
int int
xpath2canonical(const char *xpath0, xpath2canonical(const char *xpath0,
cvec *nsc0, cvec *nsc0,