Merge branch 'master' of https://github.com/clicon/clixon
This commit is contained in:
commit
0b0fef12cc
22 changed files with 663 additions and 249 deletions
|
|
@ -176,7 +176,6 @@ xmldb_disconnect(clicon_handle h)
|
|||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*! Copy database from db1 to db2
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] from Source database
|
||||
|
|
@ -199,7 +198,7 @@ xmldb_copy(clicon_handle h,
|
|||
cxobj *x2 = NULL; /* to */
|
||||
|
||||
/* XXX lock */
|
||||
if (clicon_option_bool(h, "CLICON_XMLDB_CACHE")){
|
||||
if (clicon_datastore_cache(h) != DATASTORE_NOCACHE){
|
||||
/* Copy in-memory cache */
|
||||
/* 1. "to" xml tree in x1 */
|
||||
if ((de1 = clicon_db_elmnt_get(h, from)) != NULL)
|
||||
|
|
@ -387,7 +386,7 @@ xmldb_delete(clicon_handle h,
|
|||
cxobj *xt = NULL;
|
||||
struct stat sb;
|
||||
|
||||
if (clicon_option_bool(h, "CLICON_XMLDB_CACHE")){
|
||||
if (clicon_datastore_cache(h) != DATASTORE_NOCACHE){
|
||||
if ((de = clicon_db_elmnt_get(h, db)) != NULL){
|
||||
if ((xt = de->de_xml) != NULL){
|
||||
xml_free(xt);
|
||||
|
|
@ -425,7 +424,7 @@ xmldb_create(clicon_handle h,
|
|||
db_elmnt *de = NULL;
|
||||
cxobj *xt = NULL;
|
||||
|
||||
if (clicon_option_bool(h, "CLICON_XMLDB_CACHE")){ /* XXX This should not really happen? */
|
||||
if (clicon_datastore_cache(h) != DATASTORE_NOCACHE){
|
||||
if ((de = clicon_db_elmnt_get(h, db)) != NULL){
|
||||
if ((xt = de->de_xml) != NULL){
|
||||
xml_free(xt);
|
||||
|
|
|
|||
|
|
@ -572,11 +572,11 @@ xmldb_get_cache(clicon_handle h,
|
|||
* @retval -1 Error
|
||||
*/
|
||||
static int
|
||||
xmldb_get1_cache(clicon_handle h,
|
||||
const char *db,
|
||||
char *xpath,
|
||||
cxobj **xtop,
|
||||
modstate_diff_t *msd)
|
||||
xmldb_get_zerocopy(clicon_handle h,
|
||||
const char *db,
|
||||
char *xpath,
|
||||
cxobj **xtop,
|
||||
modstate_diff_t *msd)
|
||||
{
|
||||
int retval = -1;
|
||||
yang_stmt *yspec;
|
||||
|
|
@ -641,16 +641,29 @@ xmldb_get1_cache(clicon_handle h,
|
|||
* @param[in] h Clicon handle
|
||||
* @param[in] db Name of database to search in (filename including dir path
|
||||
* @param[in] xpath String with XPATH syntax. or NULL for all
|
||||
* @param[in] copy Force copy. Overrides cache_zerocopy -> cache
|
||||
* @param[out] xret Single return XML tree. Free with xml_free()
|
||||
* @param[out] msd If set, return modules-state differences
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* There are two variants of the call:
|
||||
* @code
|
||||
* cxobj *xt;
|
||||
* if (xmldb_get(xh, "running", "/interfaces/interface[name="eth"]", &xt, NULL) < 0)
|
||||
* if (xmldb_get(xh, "running", "/interfaces/interface[name="eth"]", 0, &xt, NULL) < 0)
|
||||
* err;
|
||||
* # Code accessing and setting XML flags on xt, sorting, populate w yang spec,...
|
||||
* xmldb_get_clear(h, xt); # Clear tree from default values and flags
|
||||
* # (only if cache+zerocopy
|
||||
* xmldb_get_free(h, &xt); # Free tree (only if not zero-copy)
|
||||
* @endcode
|
||||
* The second variant only applies to zerocopy cases where you want to force a copy
|
||||
* since it may be too difficult to handle marked subtrees.
|
||||
* @code
|
||||
* if (xmldb_get(xh, "running", "/interfaces/interface[name="eth"]", 1, &xt, NULL) < 0)
|
||||
* err;
|
||||
* xml_free(xt);
|
||||
* @endcode
|
||||
*
|
||||
* @note if xvec is given, then purge tree, if not return whole tree.
|
||||
* @see xpath_vec
|
||||
*/
|
||||
|
|
@ -658,84 +671,83 @@ int
|
|||
xmldb_get(clicon_handle h,
|
||||
const char *db,
|
||||
char *xpath,
|
||||
int copy,
|
||||
cxobj **xret,
|
||||
modstate_diff_t *msd)
|
||||
{
|
||||
int retval = -1;
|
||||
|
||||
if (clicon_option_bool(h, "CLICON_XMLDB_CACHE"))
|
||||
switch (clicon_datastore_cache(h)){
|
||||
case DATASTORE_NOCACHE:
|
||||
/* Read from file into created/copy tree, prune non-matching xpath
|
||||
* Add default values in copy
|
||||
* Copy deleted by xmldb_free
|
||||
*/
|
||||
retval = xmldb_get_nocache(h, db, xpath, xret, msd);
|
||||
break;
|
||||
case DATASTORE_CACHE_ZEROCOPY:
|
||||
/* Get cache (file if empty) mark xpath match in original tree
|
||||
* add default values in original tree and return that.
|
||||
* Default values and markings removed in xmldb_clear
|
||||
*/
|
||||
if (!copy){
|
||||
retval = xmldb_get_zerocopy(h, db, xpath, xret, msd);
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
case DATASTORE_CACHE:
|
||||
/* Get cache (file if empty) mark xpath match and copy marked into copy
|
||||
* Add default values in copy, return copy
|
||||
* Copy deleted by xmldb_free
|
||||
*/
|
||||
retval = xmldb_get_cache(h, db, xpath, xret, msd);
|
||||
else
|
||||
retval = xmldb_get_nocache(h, db, xpath, xret, msd);
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Get content of database using xpath. return a set of matching sub-trees
|
||||
* The function returns a minimal tree that includes all sub-trees that match
|
||||
* xpath.
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] db Name of database to search in (filename including dir path
|
||||
* @param[in] xpath String with XPATH syntax. or NULL for all
|
||||
* @param[out] xret Single return XML tree. see note
|
||||
* @param[out] msd If set, return modules-state differences
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @code
|
||||
* cxobj *xt;
|
||||
* if (xmldb_get(xh, "running", "/interfaces/interface[name="eth"]", &xt, NULL) < 0)
|
||||
* err;
|
||||
* xml_free(xt);
|
||||
* @endcode
|
||||
* @note if xvec is given, then purge tree, if not return whole tree.
|
||||
* @see xmldb_get This version uses direct cache access and needs to be
|
||||
* cleanued up after use
|
||||
* @see xmldb_get1_clear Must call after use
|
||||
* @note If !CLICON_XMLDB_CACHE you need to free xret after use
|
||||
* @note If CLICON_XMLDB_CACHE mark|change flags set, need to clear after call
|
||||
*/
|
||||
int
|
||||
xmldb_get1(clicon_handle h,
|
||||
const char *db,
|
||||
char *xpath,
|
||||
cxobj **xret,
|
||||
modstate_diff_t *msd)
|
||||
{
|
||||
int retval = -1;
|
||||
|
||||
if (clicon_option_bool(h, "CLICON_XMLDB_CACHE"))
|
||||
retval = xmldb_get1_cache(h, db, xpath, xret, msd);
|
||||
else
|
||||
retval = xmldb_get_nocache(h, db, xpath, xret, msd);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Clear cached tree after accessed by xmldb_get1
|
||||
/*! Clear cached xml tree obtained with xmldb_get, if zerocopy
|
||||
*
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] dbname Name of database to search in (filename including dir path
|
||||
* @see xmldb_get1
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] db Name of datastore
|
||||
* "Clear" an xml tree means removing default values and resetting all flags.
|
||||
* @see xmldb_get
|
||||
*/
|
||||
int
|
||||
xmldb_get1_clear(clicon_handle h,
|
||||
const char *db)
|
||||
xmldb_get_clear(clicon_handle h,
|
||||
cxobj *x)
|
||||
{
|
||||
int retval = -1;
|
||||
db_elmnt *de = NULL;
|
||||
|
||||
if (!clicon_option_bool(h, "CLICON_XMLDB_CACHE"))
|
||||
goto ok; /* dont bother, tree is a copy */
|
||||
de = clicon_db_elmnt_get(h, db);
|
||||
if (de != NULL && de->de_xml != NULL){
|
||||
/* clear XML tree of defaults */
|
||||
if (xml_tree_prune_flagged(de->de_xml, XML_FLAG_DEFAULT, 1) < 0)
|
||||
goto done;
|
||||
/* clear mark and change */
|
||||
xml_apply0(de->de_xml, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset,
|
||||
(void*)(0xff));
|
||||
}
|
||||
if (clicon_datastore_cache(h) != DATASTORE_CACHE_ZEROCOPY)
|
||||
goto ok;
|
||||
if (x == NULL)
|
||||
goto ok;
|
||||
/* clear XML tree of defaults */
|
||||
if (xml_tree_prune_flagged(x, XML_FLAG_DEFAULT, 1) < 0)
|
||||
goto done;
|
||||
/* clear mark and change */
|
||||
xml_apply0(x, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset,
|
||||
(void*)(0xff));
|
||||
ok:
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
|
||||
}
|
||||
|
||||
/*! Free xml tree obtained with xmldb_get, unless zerocopy
|
||||
* @param[in] h Clixon handle
|
||||
* @param[in,out] xp Pointer to XML cache.
|
||||
* @see xmldb_get
|
||||
*/
|
||||
int
|
||||
xmldb_get_free(clicon_handle h,
|
||||
cxobj **xp)
|
||||
{
|
||||
if (*xp == NULL ||
|
||||
clicon_datastore_cache(h) == DATASTORE_CACHE_ZEROCOPY)
|
||||
return 0;
|
||||
xml_free(*xp);
|
||||
*xp = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -206,6 +206,7 @@ buf2xml(FILE *f,
|
|||
int i;
|
||||
uint32_t ind;
|
||||
cxobj *xc;
|
||||
size_t ret;
|
||||
|
||||
/* Read hdr
|
||||
* +-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
|
|
@ -216,7 +217,7 @@ buf2xml(FILE *f,
|
|||
clicon_err(OE_UNIX, errno, "fseek");
|
||||
goto done;
|
||||
}
|
||||
if (fread(hdr, sizeof(char), sizeof(hdr), f) < 0){
|
||||
if ((ret = fread(hdr, sizeof(char), sizeof(hdr), f)) != sizeof(hdr)){
|
||||
clicon_err(OE_XML, errno, "fread");
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -250,7 +251,7 @@ buf2xml(FILE *f,
|
|||
clicon_err(OE_UNIX, errno, "malloc");
|
||||
goto done;
|
||||
}
|
||||
if (fread(buf, sizeof(char), len-sizeof(hdr), f) < 0){
|
||||
if ((ret = fread(buf, sizeof(char), len-sizeof(hdr), f)) != len-sizeof(hdr)){
|
||||
clicon_err(OE_XML, errno, "fread");
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -318,7 +319,7 @@ xml2buf(FILE *f,
|
|||
int len1;
|
||||
int ptr;
|
||||
int i;
|
||||
char *buf0;
|
||||
char *buf0 = NULL;
|
||||
char *buf;
|
||||
uint32_t myindex;
|
||||
|
||||
|
|
|
|||
|
|
@ -652,8 +652,9 @@ xmldb_put(clicon_handle h,
|
|||
xml_name(x1));
|
||||
goto done;
|
||||
}
|
||||
if (clicon_option_bool(h, "CLICON_XMLDB_CACHE")){
|
||||
if ((de = clicon_db_elmnt_get(h, db)) != NULL)
|
||||
|
||||
if ((de = clicon_db_elmnt_get(h, db)) != NULL){
|
||||
if (clicon_datastore_cache(h) != DATASTORE_NOCACHE)
|
||||
x0 = de->de_xml;
|
||||
}
|
||||
/* If there is no xml x0 tree (in cache), then read it from file */
|
||||
|
|
@ -713,8 +714,9 @@ xmldb_put(clicon_handle h,
|
|||
if (xml_apply0(x0, -1, xml_sort_verify, NULL) < 0)
|
||||
clicon_log(LOG_NOTICE, "%s: verify failed #3", __FUNCTION__);
|
||||
#endif
|
||||
|
||||
/* Write back to datastore cache if first time */
|
||||
if (clicon_option_bool(h, "CLICON_XMLDB_CACHE")){
|
||||
if (clicon_datastore_cache(h) != DATASTORE_NOCACHE){
|
||||
db_elmnt de0 = {0,};
|
||||
if (de != NULL)
|
||||
de0 = *de;
|
||||
|
|
@ -770,7 +772,7 @@ xmldb_put(clicon_handle h,
|
|||
free(dbfile);
|
||||
if (cb)
|
||||
cbuf_free(cb);
|
||||
if (!clicon_option_bool(h, "CLICON_XMLDB_CACHE") && x0)
|
||||
if (x0 && clicon_datastore_cache(h) == DATASTORE_NOCACHE)
|
||||
xml_free(x0);
|
||||
return retval;
|
||||
fail:
|
||||
|
|
|
|||
|
|
@ -890,7 +890,7 @@ nacm_access_pre(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
else if (strcmp(mode, "internal")==0){
|
||||
if (xmldb_get(h, "running", "nacm", &xnacm0, NULL) < 0)
|
||||
if (xmldb_get(h, "running", "nacm", 1, &xnacm0, NULL) < 0)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -543,30 +543,25 @@ clicon_cli_genmodel_completion(clicon_handle h)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const map_str2int cli_genmodel_map[] = {
|
||||
{"NONE", GT_NONE},
|
||||
{"VARS", GT_VARS},
|
||||
{"ALL", GT_ALL},
|
||||
{NULL, -1}
|
||||
};
|
||||
|
||||
/*! How to generate and show CLI syntax: VARS|ALL
|
||||
* @see clixon-config@<date>.yang CLICON_CLI_GENMODEL_TYPE
|
||||
*/
|
||||
enum genmodel_type
|
||||
clicon_cli_genmodel_type(clicon_handle h)
|
||||
{
|
||||
char *s;
|
||||
enum genmodel_type gt = GT_ERR;
|
||||
char *str;
|
||||
|
||||
if (!clicon_option_exists(h, "CLICON_CLI_GENMODEL_TYPE")){
|
||||
gt = GT_VARS;
|
||||
goto done;
|
||||
}
|
||||
s = clicon_option_str(h, "CLICON_CLI_GENMODEL_TYPE");
|
||||
if (strcmp(s, "NONE")==0)
|
||||
gt = GT_NONE;
|
||||
if ((str = clicon_option_str(h, "CLICON_CLI_GENMODEL_TYPE")) == NULL)
|
||||
return GT_VARS;
|
||||
else
|
||||
if (strcmp(s, "VARS")==0)
|
||||
gt = GT_VARS;
|
||||
else
|
||||
if (strcmp(s, "ALL")==0)
|
||||
gt = GT_ALL;
|
||||
done:
|
||||
return gt;
|
||||
return clicon_str2int(cli_genmodel_map, str);
|
||||
}
|
||||
|
||||
/*! Get Dont include keys in cvec in cli vars callbacks
|
||||
|
|
@ -638,6 +633,28 @@ clicon_startup_mode(clicon_handle h)
|
|||
return clicon_str2int(startup_mode_map, mode);
|
||||
}
|
||||
|
||||
static const map_str2int datastore_cache_map[] = {
|
||||
{"nocache", DATASTORE_NOCACHE},
|
||||
{"cache", DATASTORE_CACHE},
|
||||
{"cache-zerocopy", DATASTORE_CACHE_ZEROCOPY},
|
||||
{NULL, -1}
|
||||
};
|
||||
|
||||
/*! How to generate and show CLI syntax: VARS|ALL
|
||||
* @see clixon-config@<date>.yang CLICON_CLI_GENMODEL_TYPE
|
||||
*/
|
||||
enum datastore_cache
|
||||
clicon_datastore_cache(clicon_handle h)
|
||||
{
|
||||
char *str;
|
||||
|
||||
if ((str = clicon_option_str(h, "CLICON_DATASTORE_CACHE")) == NULL)
|
||||
return DATASTORE_CACHE;
|
||||
else
|
||||
return clicon_str2int(datastore_cache_map, str);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------
|
||||
* Specific option access functions for non-yang options
|
||||
* Typically dynamic values and more complex datatypes,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue