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

View file

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

View file

@ -299,7 +299,6 @@ xml_default(yang_stmt *yt,
cxobj *xc;
int top = 0; /* Top symbol (set default namespace) */
int create = 0;
char *xpath;
int nr = 0;
int hit = 0;
cg_var *cv;
@ -336,7 +335,7 @@ xml_default(yang_stmt *yt,
}
if (!cv_flag(cv, V_UNSET)){ /* Default value exists */
/* 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;
if (hit && nr == 0)
break; /* Do not create default if xpath fails */
@ -351,7 +350,7 @@ xml_default(yang_stmt *yt,
case Y_CONTAINER:
if (yang_find(yc, Y_PRESENCE, NULL) == NULL){
/* 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;
if (hit && nr == 0)
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[out] hit when statement found
* @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 -1 Error
* 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;
int nr = 0;
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)
goto done;
if (xpath != NULL){
x = xp;
*hit = 1;
}
/* Second variant */
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 */
if (xn == NULL){
if ((x = xml_new(yang_argument_get(yn), xp, CX_ELMNT)) == NULL)
goto done;
xml_spec_set(x, yn);
xmalloc++;
variant = 1;
}
else
x = xn;
@ -2121,12 +2123,16 @@ yang_check_when_xpath(cxobj *xn,
}
if (nrp)
*nrp = nr;
if (xpathp)
if (xpathp){
*xpathp = xpath;
xpath = NULL;
}
retval = 0;
done:
if (xmalloc)
if (variant)
xml_purge(x);
if (xpath)
free(xpath);
if (nsc)
xml_nsctx_free(nsc);
return retval;

View file

@ -1147,7 +1147,7 @@ xpath_traverse_canonical(xpath_tree *xs,
* @param[in] nsc0 Input namespace context
* @param[in] yspec Yang spec containing all modules, associated with namespaces
* @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] cbreason reason if retval = 0
* @retval 1 OK, xpath1 and nsc1 allocated
@ -1239,6 +1239,8 @@ xpath2canonical1(const char *xpath0,
goto done;
}
/*! Backward compatible wrapper around xpath2canonical1
*/
int
xpath2canonical(const char *xpath0,
cvec *nsc0,