Clixon config option CLICON_XMLDB_CACHE renamed to CLICON_DATASTORE_CACHE and changed type from boolean to datastore_cache

This commit is contained in:
Olof hagsand 2019-05-09 14:25:16 +02:00
parent 70221742f7
commit 99b7a1fe5b
13 changed files with 207 additions and 150 deletions

View file

@ -53,6 +53,10 @@
### API changes on existing features (you may need to change your code) ### API changes on existing features (you may need to change your code)
* Clixon config option `CLICON_XMLDB_CACHE` renamed to `CLICON_DATASTORE_CACHE` and changed type from `boolean` to `datastore_cache`
* Change code from: `clicon_option_bool(h, "CLICON_XMLDB_CACHE")` to `clicon_datastore_cache(h) == DATASTORE_CACHE`
* Type `datastore_cache` have values: nocache, cache, or cache-zerocopy
* `xmldb_get1` removed (functionality merged with `xmldb_get`)
* Non-key list now not accepted in edit-config (before only on validation) * Non-key list now not accepted in edit-config (before only on validation)
* Changed return values in internal functions * Changed return values in internal functions
* These functions are affected: `netconf_trymerge`, `startup_module_state`, `yang_modules_state_get` * These functions are affected: `netconf_trymerge`, `startup_module_state`, `yang_modules_state_get`

View file

@ -336,7 +336,10 @@ from_client_get_config(clicon_handle h,
if ((xfilter = xml_find(xe, "filter")) != NULL) if ((xfilter = xml_find(xe, "filter")) != NULL)
if ((xpath = xml_find_value(xfilter, "select"))==NULL) if ((xpath = xml_find_value(xfilter, "select"))==NULL)
xpath="/"; xpath="/";
if (xmldb_get(h, db, xpath, &xret, NULL) < 0){ /* Note xret can be pruned by nacm below (and change name),
* so zero-copy cant be used
*/
if (xmldb_get(h, db, xpath, 1, &xret, NULL) < 0){
if (netconf_operation_failed(cbret, "application", "read registry")< 0) if (netconf_operation_failed(cbret, "application", "read registry")< 0)
goto done; goto done;
goto ok; goto ok;
@ -800,14 +803,16 @@ from_client_get(clicon_handle h,
if ((xfilter = xml_find(xe, "filter")) != NULL) if ((xfilter = xml_find(xe, "filter")) != NULL)
if ((xpath = xml_find_value(xfilter, "select"))==NULL) if ((xpath = xml_find_value(xfilter, "select"))==NULL)
xpath="/"; xpath="/";
/* Get config */ /* Get config
if (xmldb_get(h, "running", xpath, &xret, NULL) < 0){ * Note xret can be pruned by nacm below and change name and
* metrged with state data, so zero-copy cant be used
*/
if (xmldb_get(h, "running", xpath, 1, &xret, NULL) < 0){
if (netconf_operation_failed(cbret, "application", "read registry")< 0) if (netconf_operation_failed(cbret, "application", "read registry")< 0)
goto done; goto done;
goto ok; goto ok;
} }
/* Get state data from plugins as defined by plugin_statedata(), if any */ /* Get state data from plugins as defined by plugin_statedata(), if any */
assert(xret);
clicon_err_reset(); clicon_err_reset();
if ((ret = client_statedata(h, xpath, &xret)) < 0) if ((ret = client_statedata(h, xpath, &xret)) < 0)
goto done; goto done;

View file

@ -182,7 +182,7 @@ startup_common(clicon_handle h,
if ((msd = modstate_diff_new()) == NULL) if ((msd = modstate_diff_new()) == NULL)
goto done; goto done;
clicon_debug(1, "Reading startup config from %s", db); clicon_debug(1, "Reading startup config from %s", db);
if (xmldb_get1(h, db, "/", &xt, msd) < 0) if (xmldb_get(h, db, "/", 0, &xt, msd) < 0)
goto done; goto done;
/* Clear flags xpath for get */ /* Clear flags xpath for get */
xml_apply0(xt, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset, xml_apply0(xt, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset,
@ -276,7 +276,7 @@ startup_validate(clicon_handle h,
if (ret == 0) if (ret == 0)
goto fail; goto fail;
/* Clear cached trees from default values and marking */ /* Clear cached trees from default values and marking */
if (xmldb_get1_clear(h, db) < 0) if (xmldb_get_clear(h, td->td_target) < 0)
goto done; goto done;
if (xtr){ if (xtr){
*xtr = td->td_target; *xtr = td->td_target;
@ -285,11 +285,7 @@ startup_validate(clicon_handle h,
retval = 1; retval = 1;
done: done:
if (td){ if (td){
if (clicon_option_bool(h, "CLICON_XMLDB_CACHE")){ xmldb_get_free(h, &td->td_target);
/* xmldb_get1 requires free only if not cache */
td->td_target = NULL;
td->td_src = NULL;
}
transaction_free(td); transaction_free(td);
} }
return retval; return retval;
@ -332,7 +328,7 @@ startup_commit(clicon_handle h,
if (plugin_transaction_commit(h, td) < 0) if (plugin_transaction_commit(h, td) < 0)
goto done; goto done;
/* Clear cached trees from default values and marking */ /* Clear cached trees from default values and marking */
if (xmldb_get1_clear(h, db) < 0) if (xmldb_get_clear(h, td->td_target) < 0)
goto done; goto done;
/* [Delete and] create running db */ /* [Delete and] create running db */
@ -356,11 +352,7 @@ startup_commit(clicon_handle h,
retval = 1; retval = 1;
done: done:
if (td){ if (td){
if (clicon_option_bool(h, "CLICON_XMLDB_CACHE")){ xmldb_get_free(h, &td->td_target);
/* xmldb_get1 requires free only if not cache */
td->td_target = NULL;
td->td_src = NULL;
}
transaction_free(td); transaction_free(td);
} }
return retval; return retval;
@ -398,7 +390,7 @@ from_validate_common(clicon_handle h,
goto done; goto done;
} }
/* This is the state we are going to */ /* This is the state we are going to */
if (xmldb_get1(h, candidate, "/", &td->td_target, NULL) < 0) if (xmldb_get(h, candidate, "/", 0, &td->td_target, NULL) < 0)
goto done; goto done;
/* Clear flags xpath for get */ /* Clear flags xpath for get */
@ -416,7 +408,7 @@ from_validate_common(clicon_handle h,
/* 2. Parse xml trees /* 2. Parse xml trees
* This is the state we are going from */ * This is the state we are going from */
if (xmldb_get1(h, "running", "/", &td->td_src, NULL) < 0) if (xmldb_get(h, "running", "/", 0, &td->td_src, NULL) < 0)
goto done; goto done;
/* Clear flags xpath for get */ /* Clear flags xpath for get */
xml_apply0(td->td_src, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset, xml_apply0(td->td_src, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset,
@ -521,9 +513,9 @@ candidate_commit(clicon_handle h,
goto done; goto done;
/* Clear cached trees from default values and marking */ /* Clear cached trees from default values and marking */
if (xmldb_get1_clear(h, candidate) < 0) if (xmldb_get_clear(h, td->td_target) < 0)
goto done; goto done;
if (xmldb_get1_clear(h, "running") < 0) if (xmldb_get_clear(h, td->td_src) < 0)
goto done; goto done;
/* Optionally write (potentially modified) tree back to candidate /* Optionally write (potentially modified) tree back to candidate
@ -559,11 +551,8 @@ candidate_commit(clicon_handle h,
if (retval < 1 && td) if (retval < 1 && td)
plugin_transaction_abort(h, td); plugin_transaction_abort(h, td);
if (td){ if (td){
if (clicon_option_bool(h, "CLICON_XMLDB_CACHE")){ xmldb_get_free(h, &td->td_target);
/* xmldb_get1 requires free only if not cache */ xmldb_get_free(h, &td->td_src);
td->td_target = NULL;
td->td_src = NULL;
}
transaction_free(td); transaction_free(td);
} }
return retval; return retval;
@ -749,9 +738,9 @@ from_client_validate(clicon_handle h,
goto ok; goto ok;
} }
/* Clear cached trees from default values and marking */ /* Clear cached trees from default values and marking */
if (xmldb_get1_clear(h, db) < 0) if (xmldb_get_clear(h, td->td_target) < 0)
goto done; goto done;
if (xmldb_get1_clear(h, "running") < 0) if (xmldb_get_clear(h, td->td_src) < 0)
goto done; goto done;
/* Optionally write (potentially modified) tree back to candidate */ /* Optionally write (potentially modified) tree back to candidate */
@ -768,11 +757,8 @@ from_client_validate(clicon_handle h,
if (retval < 0 && td) if (retval < 0 && td)
plugin_transaction_abort(h, td); plugin_transaction_abort(h, td);
if (td){ if (td){
if (clicon_option_bool(h, "CLICON_XMLDB_CACHE")){ xmldb_get_free(h, &td->td_target);
/* xmldb_get1 requires free only if not cache */ xmldb_get_free(h, &td->td_src);
td->td_target = NULL;
td->td_src = NULL;
}
transaction_free(td); transaction_free(td);
} }
return retval; return retval;

View file

@ -102,13 +102,12 @@ db_merge(clicon_handle h,
cxobj *xt = NULL; cxobj *xt = NULL;
/* Get data as xml from db1 */ /* Get data as xml from db1 */
if (xmldb_get(h, (char*)db1, NULL, &xt, NULL) < 0) if (xmldb_get(h, (char*)db1, NULL, 0, &xt, NULL) < 0)
goto done; goto done;
/* Merge xml into db2. Without commit */ /* Merge xml into db2. Without commit */
retval = xmldb_put(h, (char*)db2, OP_MERGE, xt, clicon_username_get(h), cbret); retval = xmldb_put(h, (char*)db2, OP_MERGE, xt, clicon_username_get(h), cbret);
done: done:
if (xt) xmldb_get_free(h, &xt);
xml_free(xt);
return retval; return retval;
} }
@ -270,8 +269,7 @@ startup_extraxml(clicon_handle h,
ok: ok:
retval = 1; retval = 1;
done: done:
if (xt && !clicon_option_bool(h, "CLICON_XMLDB_CACHE")) xmldb_get_free(h, &xt);
xml_free(xt);
if (xmldb_delete(h, db) != 0 && errno != ENOENT) if (xmldb_delete(h, db) != 0 && errno != ENOENT)
return -1; return -1;
return retval; return retval;

View file

@ -48,9 +48,9 @@ int xmldb_db2file(clicon_handle h, const char *db, char **filename);
int xmldb_validate_db(const char *db); int xmldb_validate_db(const char *db);
int xmldb_connect(clicon_handle h); int xmldb_connect(clicon_handle h);
int xmldb_disconnect(clicon_handle h); int xmldb_disconnect(clicon_handle h);
int xmldb_get(clicon_handle h, const char *db, char *xpath, cxobj **xtop, modstate_diff_t *msd); /* in clixon_datastore_read.[ch] */ int xmldb_get(clicon_handle h, const char *db, char *xpath, int copy, cxobj **xtop, modstate_diff_t *msd); /* in clixon_datastore_read.[ch] */
int xmldb_get1(clicon_handle h, const char *db, char *xpath, cxobj **xtop, modstate_diff_t *msd); /* in clixon_datastore_read.[ch] */ int xmldb_get_clear(clicon_handle h, cxobj *x);
int xmldb_get1_clear(clicon_handle h, const char *db); int xmldb_get_free(clicon_handle h, cxobj **xp);
int xmldb_put(clicon_handle h, const char *db, enum operation_type op, cxobj *xt, char *username, cbuf *cbret); /* in clixon_datastore_write.[ch] */ int xmldb_put(clicon_handle h, const char *db, enum operation_type op, cxobj *xt, char *username, cbuf *cbret); /* in clixon_datastore_write.[ch] */
int xmldb_copy(clicon_handle h, const char *from, const char *to); int xmldb_copy(clicon_handle h, const char *from, const char *to);
int xmldb_lock(clicon_handle h, const char *db, int pid); int xmldb_lock(clicon_handle h, const char *db, int pid);

View file

@ -73,6 +73,15 @@ enum startup_mode_t{
SM_INIT SM_INIT
}; };
/*! Datastore cache behaviour, see clixon_datastore.[ch]
* See config option type datastore_cache in clixon-config.yang
*/
enum datastore_cache{
DATASTORE_NOCACHE,
DATASTORE_CACHE,
DATASTORE_CACHE_ZEROCOPY
};
/* /*
* Prototypes * Prototypes
*/ */
@ -163,6 +172,7 @@ int clicon_sock_family(clicon_handle h);
int clicon_sock_port(clicon_handle h); int clicon_sock_port(clicon_handle h);
int clicon_autocommit(clicon_handle h); int clicon_autocommit(clicon_handle h);
int clicon_startup_mode(clicon_handle h); int clicon_startup_mode(clicon_handle h);
enum datastore_cache clicon_datastore_cache(clicon_handle h);
/*-- Specific option access functions for non-yang options --*/ /*-- Specific option access functions for non-yang options --*/
int clicon_quiet_mode(clicon_handle h); int clicon_quiet_mode(clicon_handle h);

View file

@ -176,7 +176,6 @@ xmldb_disconnect(clicon_handle h)
return retval; return retval;
} }
/*! Copy database from db1 to db2 /*! Copy database from db1 to db2
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @param[in] from Source database * @param[in] from Source database
@ -199,7 +198,7 @@ xmldb_copy(clicon_handle h,
cxobj *x2 = NULL; /* to */ cxobj *x2 = NULL; /* to */
/* XXX lock */ /* XXX lock */
if (clicon_option_bool(h, "CLICON_XMLDB_CACHE")){ if (clicon_datastore_cache(h) != DATASTORE_NOCACHE){
/* Copy in-memory cache */ /* Copy in-memory cache */
/* 1. "to" xml tree in x1 */ /* 1. "to" xml tree in x1 */
if ((de1 = clicon_db_elmnt_get(h, from)) != NULL) if ((de1 = clicon_db_elmnt_get(h, from)) != NULL)
@ -387,7 +386,7 @@ xmldb_delete(clicon_handle h,
cxobj *xt = NULL; cxobj *xt = NULL;
struct stat sb; 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 ((de = clicon_db_elmnt_get(h, db)) != NULL){
if ((xt = de->de_xml) != NULL){ if ((xt = de->de_xml) != NULL){
xml_free(xt); xml_free(xt);
@ -425,7 +424,7 @@ xmldb_create(clicon_handle h,
db_elmnt *de = NULL; db_elmnt *de = NULL;
cxobj *xt = 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 ((de = clicon_db_elmnt_get(h, db)) != NULL){
if ((xt = de->de_xml) != NULL){ if ((xt = de->de_xml) != NULL){
xml_free(xt); xml_free(xt);

View file

@ -572,7 +572,7 @@ xmldb_get_cache(clicon_handle h,
* @retval -1 Error * @retval -1 Error
*/ */
static int static int
xmldb_get1_cache(clicon_handle h, xmldb_get_zerocopy(clicon_handle h,
const char *db, const char *db,
char *xpath, char *xpath,
cxobj **xtop, cxobj **xtop,
@ -641,16 +641,29 @@ xmldb_get1_cache(clicon_handle h,
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @param[in] db Name of database to search in (filename including dir path * @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] 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] xret Single return XML tree. Free with xml_free()
* @param[out] msd If set, return modules-state differences * @param[out] msd If set, return modules-state differences
* @retval 0 OK * @retval 0 OK
* @retval -1 Error * @retval -1 Error
* There are two variants of the call:
* @code * @code
* cxobj *xt; * 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; * err;
* xml_free(xt); * xml_free(xt);
* @endcode * @endcode
*
* @note if xvec is given, then purge tree, if not return whole tree. * @note if xvec is given, then purge tree, if not return whole tree.
* @see xpath_vec * @see xpath_vec
*/ */
@ -658,84 +671,83 @@ int
xmldb_get(clicon_handle h, xmldb_get(clicon_handle h,
const char *db, const char *db,
char *xpath, char *xpath,
int copy,
cxobj **xret, cxobj **xret,
modstate_diff_t *msd) modstate_diff_t *msd)
{ {
int retval = -1; int retval = -1;
if (clicon_option_bool(h, "CLICON_XMLDB_CACHE")) switch (clicon_datastore_cache(h)){
retval = xmldb_get_cache(h, db, xpath, xret, msd); case DATASTORE_NOCACHE:
else /* Read from file into created/copy tree, prune non-matching xpath
retval = xmldb_get_nocache(h, db, xpath, xret, msd); * Add default values in copy
return retval; * Copy deleted by xmldb_free
}
/*! 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); 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);
break;
}
return retval; 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] h Clicon handle
* @param[in] dbname Name of database to search in (filename including dir path * @param[in] db Name of datastore
* @see xmldb_get1 * "Clear" an xml tree means removing default values and resetting all flags.
* @see xmldb_get
*/ */
int int
xmldb_get1_clear(clicon_handle h, xmldb_get_clear(clicon_handle h,
const char *db) cxobj *x)
{ {
int retval = -1; int retval = -1;
db_elmnt *de = NULL;
if (!clicon_option_bool(h, "CLICON_XMLDB_CACHE")) if (clicon_datastore_cache(h) != DATASTORE_CACHE_ZEROCOPY)
goto ok; /* dont bother, tree is a copy */ goto ok;
de = clicon_db_elmnt_get(h, db); if (x == NULL)
if (de != NULL && de->de_xml != NULL){ goto ok;
/* clear XML tree of defaults */ /* clear XML tree of defaults */
if (xml_tree_prune_flagged(de->de_xml, XML_FLAG_DEFAULT, 1) < 0) if (xml_tree_prune_flagged(x, XML_FLAG_DEFAULT, 1) < 0)
goto done; goto done;
/* clear mark and change */ /* clear mark and change */
xml_apply0(de->de_xml, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset, xml_apply0(x, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset,
(void*)(0xff)); (void*)(0xff));
}
ok: ok:
retval = 0; retval = 0;
done: done:
return retval; 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;
} }

View file

@ -652,8 +652,9 @@ xmldb_put(clicon_handle h,
xml_name(x1)); xml_name(x1));
goto done; 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; x0 = de->de_xml;
} }
/* If there is no xml x0 tree (in cache), then read it from file */ /* 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) if (xml_apply0(x0, -1, xml_sort_verify, NULL) < 0)
clicon_log(LOG_NOTICE, "%s: verify failed #3", __FUNCTION__); clicon_log(LOG_NOTICE, "%s: verify failed #3", __FUNCTION__);
#endif #endif
/* Write back to datastore cache if first time */ /* 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,}; db_elmnt de0 = {0,};
if (de != NULL) if (de != NULL)
de0 = *de; de0 = *de;
@ -770,7 +772,7 @@ xmldb_put(clicon_handle h,
free(dbfile); free(dbfile);
if (cb) if (cb)
cbuf_free(cb); cbuf_free(cb);
if (!clicon_option_bool(h, "CLICON_XMLDB_CACHE") && x0) if (x0 && clicon_datastore_cache(h) == DATASTORE_NOCACHE)
xml_free(x0); xml_free(x0);
return retval; return retval;
fail: fail:

View file

@ -890,7 +890,7 @@ nacm_access_pre(clicon_handle h,
goto done; goto done;
} }
else if (strcmp(mode, "internal")==0){ 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; goto done;
} }
} }

View file

@ -543,30 +543,25 @@ clicon_cli_genmodel_completion(clicon_handle h)
return 0; 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 /*! How to generate and show CLI syntax: VARS|ALL
* @see clixon-config@<date>.yang CLICON_CLI_GENMODEL_TYPE * @see clixon-config@<date>.yang CLICON_CLI_GENMODEL_TYPE
*/ */
enum genmodel_type enum genmodel_type
clicon_cli_genmodel_type(clicon_handle h) clicon_cli_genmodel_type(clicon_handle h)
{ {
char *s; char *str;
enum genmodel_type gt = GT_ERR;
if (!clicon_option_exists(h, "CLICON_CLI_GENMODEL_TYPE")){ if ((str = clicon_option_str(h, "CLICON_CLI_GENMODEL_TYPE")) == NULL)
gt = GT_VARS; return GT_VARS;
goto done;
}
s = clicon_option_str(h, "CLICON_CLI_GENMODEL_TYPE");
if (strcmp(s, "NONE")==0)
gt = GT_NONE;
else else
if (strcmp(s, "VARS")==0) return clicon_str2int(cli_genmodel_map, str);
gt = GT_VARS;
else
if (strcmp(s, "ALL")==0)
gt = GT_ALL;
done:
return gt;
} }
/*! Get Dont include keys in cvec in cli vars callbacks /*! 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); 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 * Specific option access functions for non-yang options
* Typically dynamic values and more complex datatypes, * Typically dynamic values and more complex datatypes,

View file

@ -198,11 +198,14 @@ main(int argc, char **argv)
xpath = argv[1]; xpath = argv[1];
else else
xpath = "/"; xpath = "/";
if (xmldb_get(h, db, xpath, &xt, NULL) < 0) if (xmldb_get(h, db, xpath, 1, &xt, NULL) < 0)
goto done; goto done;
clicon_xml2file(stdout, xt, 0, 0); clicon_xml2file(stdout, xt, 0, 0);
fprintf(stdout, "\n"); fprintf(stdout, "\n");
if (xt){
xml_free(xt);
xt = NULL;
}
} }
else if (strcmp(cmd, "mget")==0){ else if (strcmp(cmd, "mget")==0){
int nr; int nr;
@ -214,16 +217,18 @@ main(int argc, char **argv)
else else
xpath = "/"; xpath = "/";
for (i=0;i<nr;i++){ for (i=0;i<nr;i++){
if (xmldb_get(h, db, xpath, &xt, NULL) < 0) if (xmldb_get(h, db, xpath, 1, &xt, NULL) < 0)
goto done; goto done;
if (xt == NULL){ if (xt == NULL){
clicon_err(OE_DB, 0, "xt is NULL"); clicon_err(OE_DB, 0, "xt is NULL");
goto done; goto done;
} }
clicon_xml2file(stdout, xt, 0, 0); clicon_xml2file(stdout, xt, 0, 0);
if (xt){
xml_free(xt); xml_free(xt);
xt = NULL; xt = NULL;
} }
}
fprintf(stdout, "\n"); fprintf(stdout, "\n");
} }
else if (strcmp(cmd, "put")==0){ else if (strcmp(cmd, "put")==0){

View file

@ -80,9 +80,9 @@ module clixon-config {
} }
} }
} }
typedef xmldb_format{ typedef datastore_format{
description description
"Format of TEXT xml database format."; "Datastore format.";
type enumeration{ type enumeration{
enum xml{ enum xml{
description "Save and load xmldb as XML"; description "Save and load xmldb as XML";
@ -96,6 +96,24 @@ module clixon-config {
} }
} }
} }
typedef datastore_cache{
description
"XML configuration, ie running/candididate/ datastore cache behaviour.";
type enumeration{
enum nocache{
description "No cache always work directly with file";
}
enum cache{
description "Use in-memory cache.
Make copies when accessing internally.";
}
enum cache-zerocopy{
description "Use in-memory cache and dont copy.
Fastest but opens up for callbacks changing cache.";
}
}
}
typedef cli_genmodel_type{ typedef cli_genmodel_type{
description description
"How to generate CLI from YANG model, "How to generate CLI from YANG model,
@ -258,7 +276,8 @@ module clixon-config {
"If set, generate CLI specification for CLI completion of "If set, generate CLI specification for CLI completion of
loaded Yang modules. This CLI tree can be accessed in CLI loaded Yang modules. This CLI tree can be accessed in CLI
spec files using the tree reference syntax (eg @datamodel). spec files using the tree reference syntax (eg @datamodel).
See also CLICON_CLI_MODEL_TREENAME."; See also CLICON_CLI_MODEL_TREENAME.
(Consider boolean)";
} }
leaf CLICON_CLI_MODEL_TREENAME { leaf CLICON_CLI_MODEL_TREENAME {
type string; type string;
@ -271,7 +290,8 @@ module clixon-config {
leaf CLICON_CLI_GENMODEL_COMPLETION { leaf CLICON_CLI_GENMODEL_COMPLETION {
type int32; type int32;
default 1; default 1;
description "Generate code for CLI completion of existing db symbols"; description "Generate code for CLI completion of existing db symbols.
Consider boolean type";
} }
leaf CLICON_CLI_GENMODEL_TYPE { leaf CLICON_CLI_GENMODEL_TYPE {
type cli_genmodel_type; type cli_genmodel_type;
@ -368,16 +388,15 @@ module clixon-config {
(see datastore/ and clixon_xml_db.[ch]) (see datastore/ and clixon_xml_db.[ch])
Obsolete: Merged with libclixon in 3.10"; Obsolete: Merged with libclixon in 3.10";
} }
leaf CLICON_XMLDB_CACHE { leaf CLICON_DATASTORE_CACHE {
type boolean; type datastore_cache;
default true; default cache;
description description
"XMLDB datatsore cache. "Clixon datastore cache behaviour. There are three values: no cache,
If set, XML candidate/running parsed tree is stored in memory cache with copy, or cache without copy.";
If not set, candidate/running is always accessed via disk.";
} }
leaf CLICON_XMLDB_FORMAT { leaf CLICON_XMLDB_FORMAT {
type xmldb_format; type datastore_format;
default xml; default xml;
description "XMLDB datastore format."; description "XMLDB datastore format.";
} }