optimization
This commit is contained in:
parent
14faf93eec
commit
4cb00bedfa
13 changed files with 687 additions and 320 deletions
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
## 3.4.0 (Upcoming)
|
## 3.4.0 (Upcoming)
|
||||||
|
|
||||||
* Datastore cache introduced: cache XML tree in memory for faster get access
|
* Better semantic versioning, eg MAJOR/MINOR/PATCH, where increment in PATCH does not change API.
|
||||||
|
|
||||||
|
* Datastore cache introduced: cache XML tree in memory for faster get access. Use CLICON_XMLDB_CACHE configuration option. Default is 1.
|
||||||
|
|
||||||
* Moved XML_CHILD_HASH to variable instead of constant.
|
* Moved XML_CHILD_HASH to variable instead of constant.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -617,6 +617,7 @@ main(int argc, char **argv)
|
||||||
char *sock;
|
char *sock;
|
||||||
int sockfamily;
|
int sockfamily;
|
||||||
char *xmldb_plugin;
|
char *xmldb_plugin;
|
||||||
|
int xml_cache;
|
||||||
|
|
||||||
/* In the startup, logs to stderr & syslog and debug flag set later */
|
/* In the startup, logs to stderr & syslog and debug flag set later */
|
||||||
clicon_log_init(__PROGRAM__, LOG_INFO, CLICON_LOG_STDERR|CLICON_LOG_SYSLOG);
|
clicon_log_init(__PROGRAM__, LOG_INFO, CLICON_LOG_STDERR|CLICON_LOG_SYSLOG);
|
||||||
|
|
@ -807,7 +808,8 @@ main(int argc, char **argv)
|
||||||
"or create the group and add the user to it. On linux for example:"
|
"or create the group and add the user to it. On linux for example:"
|
||||||
" sudo groupadd %s\n"
|
" sudo groupadd %s\n"
|
||||||
" sudo usermod -a -G %s user\n",
|
" sudo usermod -a -G %s user\n",
|
||||||
config_group, clicon_configfile(h), config_group, config_group);
|
config_group, clicon_configfile(h),
|
||||||
|
config_group, config_group);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -829,6 +831,9 @@ main(int argc, char **argv)
|
||||||
goto done;
|
goto done;
|
||||||
if (xmldb_setopt(h, "yangspec", clicon_dbspec_yang(h)) < 0)
|
if (xmldb_setopt(h, "yangspec", clicon_dbspec_yang(h)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
if ((xml_cache = clicon_option_bool(h, "CLICON_XMLDB_CACHE")) >= 0)
|
||||||
|
if (xmldb_setopt(h, "xml_cache", (void*)xml_cache) < 0)
|
||||||
|
goto done;
|
||||||
/* If startup mode is not defined, eg via OPTION or -s, assume old method */
|
/* If startup mode is not defined, eg via OPTION or -s, assume old method */
|
||||||
startup_mode = clicon_startup_mode(h);
|
startup_mode = clicon_startup_mode(h);
|
||||||
if (startup_mode == -1){ /* Old style, fragmented mode, phase out */
|
if (startup_mode == -1){ /* Old style, fragmented mode, phase out */
|
||||||
|
|
|
||||||
|
|
@ -837,7 +837,7 @@ save_config_file(clicon_handle h,
|
||||||
clicon_rpc_generate_error("Get configuration", xerr);
|
clicon_rpc_generate_error("Get configuration", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((f = fopen(filename, "wb")) == NULL){
|
if ((f = fopen(filename, "w")) == NULL){
|
||||||
clicon_err(OE_CFG, errno, "Creating file %s", filename);
|
clicon_err(OE_CFG, errno, "Creating file %s", filename);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -356,7 +356,7 @@ main(int argc, char **argv)
|
||||||
clicon_option_str_set(h, "CLICON_CLI_MODE", optarg);
|
clicon_option_str_set(h, "CLICON_CLI_MODE", optarg);
|
||||||
break;
|
break;
|
||||||
case 'q' : /* Quiet mode */
|
case 'q' : /* Quiet mode */
|
||||||
clicon_option_str_set(h, "CLICON_QUIET", "on");
|
clicon_quiet_mode_set(h, 1);
|
||||||
break;
|
break;
|
||||||
case 'p' : /* Print spec */
|
case 'p' : /* Print spec */
|
||||||
printspec++;
|
printspec++;
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ struct db_element{
|
||||||
* Assumes single backend
|
* Assumes single backend
|
||||||
* Experimental
|
* Experimental
|
||||||
*/
|
*/
|
||||||
static int datastore_cache = 1;
|
static int xmltree_cache = 1;
|
||||||
|
|
||||||
/*! Check struct magic number for sanity checks
|
/*! Check struct magic number for sanity checks
|
||||||
* return 0 if OK, -1 if fail.
|
* return 0 if OK, -1 if fail.
|
||||||
|
|
@ -193,7 +193,7 @@ text_disconnect(xmldb_handle xh)
|
||||||
if (th->th_dbdir)
|
if (th->th_dbdir)
|
||||||
free(th->th_dbdir);
|
free(th->th_dbdir);
|
||||||
if (th->th_dbs){
|
if (th->th_dbs){
|
||||||
if (datastore_cache){
|
if (xmltree_cache){
|
||||||
if ((keys = hash_keys(th->th_dbs, &klen)) == NULL)
|
if ((keys = hash_keys(th->th_dbs, &klen)) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
for(i = 0; i < klen; i++)
|
for(i = 0; i < klen; i++)
|
||||||
|
|
@ -264,6 +264,9 @@ text_setopt(xmldb_handle xh,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (strcmp(optname, "xml_cache") == 0){
|
||||||
|
xmltree_cache = (intptr_t)value;
|
||||||
|
}
|
||||||
else{
|
else{
|
||||||
clicon_err(OE_PLUGIN, 0, "Option %s not implemented by plugin", optname);
|
clicon_err(OE_PLUGIN, 0, "Option %s not implemented by plugin", optname);
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -389,21 +392,6 @@ xml_copy_marked(cxobj *x0,
|
||||||
* xpath.
|
* xpath.
|
||||||
* This is a clixon datastore plugin of the the xmldb api
|
* This is a clixon datastore plugin of the the xmldb api
|
||||||
* @see xmldb_get
|
* @see xmldb_get
|
||||||
#ifdef DATASTORE_CACHE
|
|
||||||
text_get 90%
|
|
||||||
clixon_xml_parse_file 74% (100x)
|
|
||||||
xml_parse 70% (100x)
|
|
||||||
clicon_xml_parseparse 70% (300x)
|
|
||||||
xml_value_append 13% (800K)
|
|
||||||
xml_new
|
|
||||||
xml_purge
|
|
||||||
clicon_xml_parselex 12% (1M)
|
|
||||||
clixon_tree_prune_flagged_sub 12% (100x)
|
|
||||||
xml_purge 12% (58000)
|
|
||||||
yang_key_match 7% (77000)
|
|
||||||
yang_arg2cvec
|
|
||||||
#endif
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
text_get(xmldb_handle xh,
|
text_get(xmldb_handle xh,
|
||||||
|
|
@ -427,7 +415,7 @@ text_get(xmldb_handle xh,
|
||||||
clicon_err(OE_YANG, ENOENT, "No yang spec");
|
clicon_err(OE_YANG, ENOENT, "No yang spec");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (datastore_cache){
|
if (xmltree_cache){
|
||||||
if ((de = hash_value(th->th_dbs, db, NULL)) != NULL)
|
if ((de = hash_value(th->th_dbs, db, NULL)) != NULL)
|
||||||
xt = de->de_xml;
|
xt = de->de_xml;
|
||||||
}
|
}
|
||||||
|
|
@ -471,11 +459,11 @@ text_get(xmldb_handle xh,
|
||||||
if (xvec != NULL)
|
if (xvec != NULL)
|
||||||
for (i=0; i<xlen; i++){
|
for (i=0; i<xlen; i++){
|
||||||
xml_flag_set(xvec[i], XML_FLAG_MARK);
|
xml_flag_set(xvec[i], XML_FLAG_MARK);
|
||||||
if (datastore_cache)
|
if (xmltree_cache)
|
||||||
xml_apply_ancestor(xvec[i], (xml_applyfn_t*)xml_flag_set, (void*)XML_FLAG_CHANGE);
|
xml_apply_ancestor(xvec[i], (xml_applyfn_t*)xml_flag_set, (void*)XML_FLAG_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (datastore_cache){
|
if (xmltree_cache){
|
||||||
/* Copy the matching parts of the (relevant) XML tree.
|
/* Copy the matching parts of the (relevant) XML tree.
|
||||||
* If cache was NULL, also write to datastore cache
|
* If cache was NULL, also write to datastore cache
|
||||||
*/
|
*/
|
||||||
|
|
@ -852,7 +840,7 @@ text_put(xmldb_handle xh,
|
||||||
xml_name(x1));
|
xml_name(x1));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (datastore_cache){
|
if (xmltree_cache){
|
||||||
if ((de = hash_value(th->th_dbs, db, NULL)) != NULL)
|
if ((de = hash_value(th->th_dbs, db, NULL)) != NULL)
|
||||||
x0 = de->de_xml;
|
x0 = de->de_xml;
|
||||||
}
|
}
|
||||||
|
|
@ -921,7 +909,7 @@ text_put(xmldb_handle xh,
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* Write back to datastore cache if first time */
|
/* Write back to datastore cache if first time */
|
||||||
if (datastore_cache){
|
if (xmltree_cache){
|
||||||
struct db_element de0 = {0,};
|
struct db_element de0 = {0,};
|
||||||
if (de != NULL)
|
if (de != NULL)
|
||||||
de0 = *de;
|
de0 = *de;
|
||||||
|
|
@ -930,7 +918,28 @@ text_put(xmldb_handle xh,
|
||||||
hash_add(th->th_dbs, db, &de0, sizeof(de0));
|
hash_add(th->th_dbs, db, &de0, sizeof(de0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (dbfile == NULL){
|
||||||
|
if (text_db2file(th, db, &dbfile) < 0)
|
||||||
|
goto done;
|
||||||
|
if (dbfile==NULL){
|
||||||
|
clicon_err(OE_XML, 0, "dbfile NULL");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if 1
|
||||||
|
if (fd != -1)
|
||||||
|
close(fd);
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
if ((f = fopen(dbfile, "w")) == NULL){
|
||||||
|
clicon_err(OE_CFG, errno, "Creating file %s", dbfile);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (xml_print(f, x0) < 0)
|
||||||
|
goto done;
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
#else
|
||||||
// output:
|
// output:
|
||||||
/* Print out top-level xml tree after modification to file */
|
/* Print out top-level xml tree after modification to file */
|
||||||
if ((cb = cbuf_new()) == NULL){
|
if ((cb = cbuf_new()) == NULL){
|
||||||
|
|
@ -942,14 +951,6 @@ text_put(xmldb_handle xh,
|
||||||
/* Reopen file in write mode */
|
/* Reopen file in write mode */
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
close(fd);
|
close(fd);
|
||||||
if (dbfile == NULL){
|
|
||||||
if (text_db2file(th, db, &dbfile) < 0)
|
|
||||||
goto done;
|
|
||||||
if (dbfile==NULL){
|
|
||||||
clicon_err(OE_XML, 0, "dbfile NULL");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((fd = open(dbfile, O_WRONLY | O_TRUNC, S_IRWXU)) < 0) {
|
if ((fd = open(dbfile, O_WRONLY | O_TRUNC, S_IRWXU)) < 0) {
|
||||||
clicon_err(OE_UNIX, errno, "open(%s)", dbfile);
|
clicon_err(OE_UNIX, errno, "open(%s)", dbfile);
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -958,6 +959,7 @@ text_put(xmldb_handle xh,
|
||||||
clicon_err(OE_UNIX, errno, "write(%s)", dbfile);
|
clicon_err(OE_UNIX, errno, "write(%s)", dbfile);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
if (dbfile)
|
if (dbfile)
|
||||||
|
|
@ -966,7 +968,7 @@ text_put(xmldb_handle xh,
|
||||||
close(fd);
|
close(fd);
|
||||||
if (cb)
|
if (cb)
|
||||||
cbuf_free(cb);
|
cbuf_free(cb);
|
||||||
if (!datastore_cache && x0)
|
if (!xmltree_cache && x0)
|
||||||
xml_free(x0);
|
xml_free(x0);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
@ -988,16 +990,38 @@ text_copy(xmldb_handle xh,
|
||||||
char *fromfile = NULL;
|
char *fromfile = NULL;
|
||||||
char *tofile = NULL;
|
char *tofile = NULL;
|
||||||
struct db_element *de = NULL;
|
struct db_element *de = NULL;
|
||||||
|
struct db_element *de2 = NULL;
|
||||||
|
|
||||||
/* XXX lock */
|
/* XXX lock */
|
||||||
if (datastore_cache){
|
if (xmltree_cache){
|
||||||
/* Just invalidate xml if exists in TO */
|
/* 1. Free xml tree in "to"
|
||||||
|
|
||||||
|
*/
|
||||||
if ((de = hash_value(th->th_dbs, to, NULL)) != NULL){
|
if ((de = hash_value(th->th_dbs, to, NULL)) != NULL){
|
||||||
if (de->de_xml != NULL){
|
if (de->de_xml != NULL){
|
||||||
xml_free(de->de_xml);
|
xml_free(de->de_xml);
|
||||||
de->de_xml = NULL;
|
de->de_xml = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* 2. Copy xml tree from "from" to "to"
|
||||||
|
* 2a) create "to" if it does not exist
|
||||||
|
*/
|
||||||
|
if ((de2 = hash_value(th->th_dbs, from, NULL)) != NULL){
|
||||||
|
if (de2->de_xml != NULL){
|
||||||
|
struct db_element de0 = {0,};
|
||||||
|
cxobj *x, *xcopy;
|
||||||
|
x = de2->de_xml;
|
||||||
|
if (de != NULL)
|
||||||
|
de0 = *de;
|
||||||
|
if ((xcopy = xml_new(xml_name(x), NULL, xml_spec(x))) == NULL)
|
||||||
|
goto done;
|
||||||
|
if (xml_copy(x, xcopy) < 0)
|
||||||
|
goto done;
|
||||||
|
de0.de_xml = xcopy;
|
||||||
|
hash_add(th->th_dbs, to, &de0, sizeof(de0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (text_db2file(th, from, &fromfile) < 0)
|
if (text_db2file(th, from, &fromfile) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -1153,7 +1177,7 @@ text_delete(xmldb_handle xh,
|
||||||
struct db_element *de = NULL;
|
struct db_element *de = NULL;
|
||||||
cxobj *xt = NULL;
|
cxobj *xt = NULL;
|
||||||
|
|
||||||
if (datastore_cache){
|
if (xmltree_cache){
|
||||||
if ((de = hash_value(th->th_dbs, db, NULL)) != NULL){
|
if ((de = hash_value(th->th_dbs, db, NULL)) != NULL){
|
||||||
if ((xt = de->de_xml) != NULL){
|
if ((xt = de->de_xml) != NULL){
|
||||||
xml_free(xt);
|
xml_free(xt);
|
||||||
|
|
@ -1192,7 +1216,7 @@ text_create(xmldb_handle xh,
|
||||||
struct db_element *de = NULL;
|
struct db_element *de = NULL;
|
||||||
cxobj *xt = NULL;
|
cxobj *xt = NULL;
|
||||||
|
|
||||||
if (datastore_cache){ /* XXX This should nt really happen? */
|
if (xmltree_cache){ /* XXX This should nt really happen? */
|
||||||
if ((de = hash_value(th->th_dbs, db, NULL)) != NULL){
|
if ((de = hash_value(th->th_dbs, db, NULL)) != NULL){
|
||||||
if ((xt = de->de_xml) != NULL){
|
if ((xt = de->de_xml) != NULL){
|
||||||
assert(xt==NULL); /* XXX */
|
assert(xt==NULL); /* XXX */
|
||||||
|
|
|
||||||
|
|
@ -74,53 +74,92 @@ enum startup_mode_t{
|
||||||
/*
|
/*
|
||||||
* Prototypes
|
* Prototypes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Print registry on file. For debugging. */
|
||||||
|
void clicon_option_dump(clicon_handle h, int dblevel);
|
||||||
/* Initialize options: set defaults, read config-file, etc */
|
/* Initialize options: set defaults, read config-file, etc */
|
||||||
int clicon_options_main(clicon_handle h);
|
int clicon_options_main(clicon_handle h);
|
||||||
|
/*! Check if a clicon option has a value */
|
||||||
void clicon_option_dump(clicon_handle h, int dblevel);
|
|
||||||
|
|
||||||
int clicon_option_exists(clicon_handle h, const char *name);
|
int clicon_option_exists(clicon_handle h, const char *name);
|
||||||
|
|
||||||
/* Get a single option via handle */
|
/* String options, default NULL */
|
||||||
char *clicon_option_str(clicon_handle h, const char *name);
|
char *clicon_option_str(clicon_handle h, const char *name);
|
||||||
int clicon_option_int(clicon_handle h, const char *name);
|
|
||||||
/* Set a single option via handle */
|
|
||||||
int clicon_option_str_set(clicon_handle h, const char *name, char *val);
|
int clicon_option_str_set(clicon_handle h, const char *name, char *val);
|
||||||
|
|
||||||
|
/* Option values gixen as int, default -1 */
|
||||||
|
int clicon_option_int(clicon_handle h, const char *name);
|
||||||
int clicon_option_int_set(clicon_handle h, const char *name, int val);
|
int clicon_option_int_set(clicon_handle h, const char *name, int val);
|
||||||
|
|
||||||
|
/* Option values gixen as bool, default false */
|
||||||
|
int clicon_option_bool(clicon_handle h, const char *name);
|
||||||
|
int clicon_option_bool_set(clicon_handle h, const char *name, int val);
|
||||||
|
|
||||||
/* Delete a single option via handle */
|
/* Delete a single option via handle */
|
||||||
int clicon_option_del(clicon_handle h, const char *name);
|
int clicon_option_del(clicon_handle h, const char *name);
|
||||||
|
|
||||||
char *clicon_configfile(clicon_handle h);
|
/*-- Standard option access functions for YANG options --*/
|
||||||
char *clicon_yang_dir(clicon_handle h);
|
static inline char *clicon_configfile(clicon_handle h){
|
||||||
char *clicon_yang_module_main(clicon_handle h);
|
return clicon_option_str(h, "CLICON_CONFIGFILE");
|
||||||
char *clicon_yang_module_revision(clicon_handle h);
|
}
|
||||||
char *clicon_backend_dir(clicon_handle h);
|
static inline char *clicon_yang_dir(clicon_handle h){
|
||||||
char *clicon_cli_dir(clicon_handle h);
|
return clicon_option_str(h, "CLICON_YANG_DIR");
|
||||||
char *clicon_clispec_dir(clicon_handle h);
|
}
|
||||||
char *clicon_netconf_dir(clicon_handle h);
|
static inline char *clicon_yang_module_main(clicon_handle h){
|
||||||
char *clicon_restconf_dir(clicon_handle h);
|
return clicon_option_str(h, "CLICON_YANG_MODULE_MAIN");
|
||||||
char *clicon_xmldb_plugin(clicon_handle h);
|
}
|
||||||
int clicon_startup_mode(clicon_handle h);
|
static inline char *clicon_yang_module_revision(clicon_handle h){
|
||||||
int clicon_sock_family(clicon_handle h);
|
return clicon_option_str(h, "CLICON_YANG_MODULE_REVISION");
|
||||||
char *clicon_sock(clicon_handle h);
|
}
|
||||||
int clicon_sock_port(clicon_handle h);
|
static inline char *clicon_backend_dir(clicon_handle h){
|
||||||
char *clicon_backend_pidfile(clicon_handle h);
|
return clicon_option_str(h, "CLICON_BACKEND_DIR");
|
||||||
char *clicon_sock_group(clicon_handle h);
|
}
|
||||||
|
static inline char *clicon_netconf_dir(clicon_handle h){
|
||||||
|
return clicon_option_str(h, "CLICON_NETCONF_DIR");
|
||||||
|
}
|
||||||
|
static inline char *clicon_restconf_dir(clicon_handle h){
|
||||||
|
return clicon_option_str(h, "CLICON_RESTCONF_DIR");
|
||||||
|
}
|
||||||
|
static inline char *clicon_cli_dir(clicon_handle h){
|
||||||
|
return clicon_option_str(h, "CLICON_CLI_DIR");
|
||||||
|
}
|
||||||
|
static inline char *clicon_clispec_dir(clicon_handle h){
|
||||||
|
return clicon_option_str(h, "CLICON_CLISPEC_DIR");
|
||||||
|
}
|
||||||
|
static inline char *clicon_cli_mode(clicon_handle h){
|
||||||
|
return clicon_option_str(h, "CLICON_CLI_MODE");
|
||||||
|
}
|
||||||
|
static inline char *clicon_sock(clicon_handle h){
|
||||||
|
return clicon_option_str(h, "CLICON_SOCK");
|
||||||
|
}
|
||||||
|
static inline char *clicon_sock_group(clicon_handle h){
|
||||||
|
return clicon_option_str(h, "CLICON_SOCK_GROUP");
|
||||||
|
}
|
||||||
|
static inline char *clicon_backend_pidfile(clicon_handle h){
|
||||||
|
return clicon_option_str(h, "CLICON_BACKEND_PIDFILE");
|
||||||
|
}
|
||||||
|
static inline char *clicon_master_plugin(clicon_handle h){
|
||||||
|
return clicon_option_str(h, "CLICON_MASTER_PLUGIN");
|
||||||
|
}
|
||||||
|
static inline char *clicon_xmldb_dir(clicon_handle h){
|
||||||
|
return clicon_option_str(h, "CLICON_XMLDB_DIR");
|
||||||
|
}
|
||||||
|
static inline char *clicon_xmldb_plugin(clicon_handle h){
|
||||||
|
return clicon_option_str(h, "CLICON_XMLDB_PLUGIN");
|
||||||
|
}
|
||||||
|
|
||||||
char *clicon_master_plugin(clicon_handle h);
|
/*-- Specific option access functions for YANG options w type conversion--*/
|
||||||
char *clicon_cli_mode(clicon_handle h);
|
|
||||||
int clicon_cli_genmodel(clicon_handle h);
|
int clicon_cli_genmodel(clicon_handle h);
|
||||||
int clicon_cli_varonly(clicon_handle h);
|
|
||||||
int clicon_cli_varonly_set(clicon_handle h, int val);
|
|
||||||
int clicon_cli_genmodel_completion(clicon_handle h);
|
int clicon_cli_genmodel_completion(clicon_handle h);
|
||||||
|
|
||||||
char *clicon_xmldb_dir(clicon_handle h);
|
|
||||||
|
|
||||||
char *clicon_quiet_mode(clicon_handle h);
|
|
||||||
enum genmodel_type clicon_cli_genmodel_type(clicon_handle h);
|
enum genmodel_type clicon_cli_genmodel_type(clicon_handle h);
|
||||||
|
int clicon_cli_varonly(clicon_handle h);
|
||||||
|
int clicon_sock_family(clicon_handle h);
|
||||||
|
int clicon_sock_port(clicon_handle h);
|
||||||
int clicon_autocommit(clicon_handle h);
|
int clicon_autocommit(clicon_handle h);
|
||||||
int clicon_autocommit_set(clicon_handle h, int val);
|
int clicon_startup_mode(clicon_handle h);
|
||||||
|
|
||||||
|
/*-- Specific option access functions for non-yang options --*/
|
||||||
|
int clicon_quiet_mode(clicon_handle h);
|
||||||
|
int clicon_quiet_mode_set(clicon_handle h, int val);
|
||||||
|
|
||||||
yang_spec * clicon_dbspec_yang(clicon_handle h);
|
yang_spec * clicon_dbspec_yang(clicon_handle h);
|
||||||
int clicon_dbspec_yang_set(clicon_handle h, struct yang_spec *ys);
|
int clicon_dbspec_yang_set(clicon_handle h, struct yang_spec *ys);
|
||||||
|
|
@ -128,16 +167,13 @@ int clicon_dbspec_yang_set(clicon_handle h, struct yang_spec *ys);
|
||||||
char *clicon_dbspec_name(clicon_handle h);
|
char *clicon_dbspec_name(clicon_handle h);
|
||||||
int clicon_dbspec_name_set(clicon_handle h, char *name);
|
int clicon_dbspec_name_set(clicon_handle h, char *name);
|
||||||
|
|
||||||
|
plghndl_t clicon_xmldb_plugin_get(clicon_handle h);
|
||||||
int clicon_xmldb_plugin_set(clicon_handle h, plghndl_t handle);
|
int clicon_xmldb_plugin_set(clicon_handle h, plghndl_t handle);
|
||||||
|
|
||||||
plghndl_t clicon_xmldb_plugin_get(clicon_handle h);
|
void *clicon_xmldb_api_get(clicon_handle h);
|
||||||
|
|
||||||
int clicon_xmldb_api_set(clicon_handle h, void *xa_api);
|
int clicon_xmldb_api_set(clicon_handle h, void *xa_api);
|
||||||
|
|
||||||
void *clicon_xmldb_api_get(clicon_handle h);
|
void *clicon_xmldb_handle_get(clicon_handle h);
|
||||||
|
|
||||||
int clicon_xmldb_handle_set(clicon_handle h, void *xh);
|
int clicon_xmldb_handle_set(clicon_handle h, void *xh);
|
||||||
|
|
||||||
void *clicon_xmldb_handle_get(clicon_handle h);
|
|
||||||
|
|
||||||
#endif /* _CLIXON_OPTIONS_H_ */
|
#endif /* _CLIXON_OPTIONS_H_ */
|
||||||
|
|
|
||||||
|
|
@ -495,6 +495,49 @@ clicon_option_int_set(clicon_handle h,
|
||||||
return clicon_option_str_set(h, name, s);
|
return clicon_option_str_set(h, name, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Get options as bool but stored as string
|
||||||
|
*
|
||||||
|
* @param h clicon handle
|
||||||
|
* @param name name of option
|
||||||
|
* @retval 0 false, or does not exist, or does not have a boolean value
|
||||||
|
* @retval 1 true
|
||||||
|
* @code
|
||||||
|
* if (clicon_option_exists(h, "X")
|
||||||
|
* return clicon_option_bool(h, "X");
|
||||||
|
* else
|
||||||
|
* return 0; # default false?
|
||||||
|
* @endcode
|
||||||
|
* Note that 0 can be both error and false.
|
||||||
|
* This means that it should be used together with clicon_option_exists() and
|
||||||
|
* supply a default value as shown in the example.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
clicon_option_bool(clicon_handle h,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
if ((s = clicon_option_str(h, name)) == NULL)
|
||||||
|
return 0;
|
||||||
|
if (strcmp(s,"true")==0)
|
||||||
|
return 1;
|
||||||
|
return 0; /* Hopefully false, but anything else than "true" */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Set option given as bool
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
clicon_option_bool_set(clicon_handle h,
|
||||||
|
const char *name,
|
||||||
|
int val)
|
||||||
|
{
|
||||||
|
char s[64];
|
||||||
|
|
||||||
|
if (snprintf(s, sizeof(s)-1, "%u", val) < 0)
|
||||||
|
return -1;
|
||||||
|
return clicon_option_str_set(h, name, s);
|
||||||
|
}
|
||||||
|
|
||||||
/*! Delete option
|
/*! Delete option
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
|
|
@ -507,146 +550,18 @@ clicon_option_del(clicon_handle h,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------
|
/*-----------------------------------------------------------------
|
||||||
* Specific option access functions.
|
* Specific option access functions for YANG configuration variables.
|
||||||
* These should be commonly accessible for all users of clicon lib
|
* Sometimes overridden by command-line options,
|
||||||
|
* such as -f for CLICON_CONFIGFILE
|
||||||
|
* @see yang/clixon-config@<date>.yang
|
||||||
|
* You can always use the basic access functions, such as
|
||||||
|
* clicon_option_str[_set]
|
||||||
|
* But sometimes there are type conversions, etc which makes it more
|
||||||
|
* convenient to make wrapper functions. Or not?
|
||||||
*-----------------------------------------------------------------*/
|
*-----------------------------------------------------------------*/
|
||||||
|
|
||||||
char *
|
|
||||||
clicon_configfile(clicon_handle h)
|
|
||||||
{
|
|
||||||
return clicon_option_str(h, "CLICON_CONFIGFILE");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! YANG database specification directory */
|
|
||||||
char *
|
|
||||||
clicon_yang_dir(clicon_handle h)
|
|
||||||
{
|
|
||||||
return clicon_option_str(h, "CLICON_YANG_DIR");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! YANG main module or absolute file name */
|
|
||||||
char *
|
|
||||||
clicon_yang_module_main(clicon_handle h)
|
|
||||||
{
|
|
||||||
return clicon_option_str(h, "CLICON_YANG_MODULE_MAIN");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! YANG revision */
|
|
||||||
char *
|
|
||||||
clicon_yang_module_revision(clicon_handle h)
|
|
||||||
{
|
|
||||||
return clicon_option_str(h, "CLICON_YANG_MODULE_REVISION");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Directory of backend plugins. If null, no plugins are loaded */
|
|
||||||
char *
|
|
||||||
clicon_backend_dir(clicon_handle h)
|
|
||||||
{
|
|
||||||
return clicon_option_str(h, "CLICON_BACKEND_DIR");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* contains .so files CLICON_CLI_DIR */
|
|
||||||
char *
|
|
||||||
clicon_cli_dir(clicon_handle h)
|
|
||||||
{
|
|
||||||
return clicon_option_str(h, "CLICON_CLI_DIR");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* contains .cli files - CLICON_CLISPEC_DIR */
|
|
||||||
char *
|
|
||||||
clicon_clispec_dir(clicon_handle h)
|
|
||||||
{
|
|
||||||
return clicon_option_str(h, "CLICON_CLISPEC_DIR");
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
clicon_netconf_dir(clicon_handle h)
|
|
||||||
{
|
|
||||||
return clicon_option_str(h, "CLICON_NETCONF_DIR");
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
clicon_restconf_dir(clicon_handle h)
|
|
||||||
{
|
|
||||||
return clicon_option_str(h, "CLICON_RESTCONF_DIR");
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
clicon_xmldb_plugin(clicon_handle h)
|
|
||||||
{
|
|
||||||
return clicon_option_str(h, "CLICON_XMLDB_PLUGIN");
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
clicon_startup_mode(clicon_handle h)
|
|
||||||
{
|
|
||||||
char *mode;
|
|
||||||
if ((mode = clicon_option_str(h, "CLICON_STARTUP_MODE")) == NULL)
|
|
||||||
return -1;
|
|
||||||
return clicon_str2int(startup_mode_map, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Get family of backend socket: AF_UNIX, AF_INET or AF_INET6 */
|
|
||||||
int
|
|
||||||
clicon_sock_family(clicon_handle h)
|
|
||||||
{
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
if ((s = clicon_option_str(h, "CLICON_SOCK_FAMILY")) == NULL)
|
|
||||||
return AF_UNIX;
|
|
||||||
else if (strcmp(s, "IPv4")==0)
|
|
||||||
return AF_INET;
|
|
||||||
else if (strcmp(s, "IPv6")==0)
|
|
||||||
return AF_INET6;
|
|
||||||
else
|
|
||||||
return AF_UNIX; /* default */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Get information about socket: unix domain filepath, or addr:path */
|
|
||||||
char *
|
|
||||||
clicon_sock(clicon_handle h)
|
|
||||||
{
|
|
||||||
return clicon_option_str(h, "CLICON_SOCK");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Get port for backend socket in case of AF_INET or AF_INET6 */
|
|
||||||
int
|
|
||||||
clicon_sock_port(clicon_handle h)
|
|
||||||
{
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
if ((s = clicon_option_str(h, "CLICON_SOCK_PORT")) == NULL)
|
|
||||||
return -1;
|
|
||||||
return atoi(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
clicon_backend_pidfile(clicon_handle h)
|
|
||||||
{
|
|
||||||
return clicon_option_str(h, "CLICON_BACKEND_PIDFILE");
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
clicon_sock_group(clicon_handle h)
|
|
||||||
{
|
|
||||||
return clicon_option_str(h, "CLICON_SOCK_GROUP");
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
clicon_master_plugin(clicon_handle h)
|
|
||||||
{
|
|
||||||
return clicon_option_str(h, "CLICON_MASTER_PLUGIN");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Return initial clicon cli mode */
|
|
||||||
char *
|
|
||||||
clicon_cli_mode(clicon_handle h)
|
|
||||||
{
|
|
||||||
return clicon_option_str(h, "CLICON_CLI_MODE");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Whether to generate CLIgen syntax from datamodel or not (0 or 1)
|
/*! Whether to generate CLIgen syntax from datamodel or not (0 or 1)
|
||||||
* Must be used with a previous clicon_option_exists().
|
* Must be used with a previous clicon_option_exists().
|
||||||
|
* @see clixon-config@<date>.yang CLICON_CLI_GENMODEL
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clicon_cli_genmodel(clicon_handle h)
|
clicon_cli_genmodel(clicon_handle h)
|
||||||
|
|
@ -659,7 +574,23 @@ clicon_cli_genmodel(clicon_handle h)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! How to generate and show CLI syntax: VARS|ALL */
|
/*! Generate code for CLI completion of existing db symbols
|
||||||
|
* @see clixon-config@<date>.yang CLICON_CLI_GENMODEL_COMPLETION
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
clicon_cli_genmodel_completion(clicon_handle h)
|
||||||
|
{
|
||||||
|
char const *opt = "CLICON_CLI_GENMODEL_COMPLETION";
|
||||||
|
|
||||||
|
if (clicon_option_exists(h, opt))
|
||||||
|
return clicon_option_int(h, opt);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! How to generate and show CLI syntax: VARS|ALL
|
||||||
|
* @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)
|
||||||
{
|
{
|
||||||
|
|
@ -683,32 +614,8 @@ clicon_cli_genmodel_type(clicon_handle h)
|
||||||
return gt;
|
return gt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Get Dont include keys in cvec in cli vars callbacks
|
||||||
/* eg -q option, dont print notifications on stdout */
|
* @see clixon-config@<date>.yang CLICON_CLI_VARONLY
|
||||||
char *
|
|
||||||
clicon_quiet_mode(clicon_handle h)
|
|
||||||
{
|
|
||||||
return clicon_option_str(h, "CLICON_QUIET");
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
clicon_autocommit(clicon_handle h)
|
|
||||||
{
|
|
||||||
char const *opt = "CLICON_AUTOCOMMIT";
|
|
||||||
|
|
||||||
if (clicon_option_exists(h, opt))
|
|
||||||
return clicon_option_int(h, opt);
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
clicon_autocommit_set(clicon_handle h, int val)
|
|
||||||
{
|
|
||||||
return clicon_option_int_set(h, "CLICON_AUTOCOMMIT", val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Dont include keys in cvec in cli vars callbacks
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clicon_cli_varonly(clicon_handle h)
|
clicon_cli_varonly(clicon_handle h)
|
||||||
|
|
@ -721,16 +628,43 @@ clicon_cli_varonly(clicon_handle h)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Get family of backend socket: AF_UNIX, AF_INET or AF_INET6
|
||||||
|
* @see clixon-config@<date>.yang CLICON_SOCK_FAMILY
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
clicon_cli_varonly_set(clicon_handle h, int val)
|
clicon_sock_family(clicon_handle h)
|
||||||
{
|
{
|
||||||
return clicon_option_int_set(h, "CLICON_CLI_VARONLY", val);
|
char *s;
|
||||||
|
|
||||||
|
if ((s = clicon_option_str(h, "CLICON_SOCK_FAMILY")) == NULL)
|
||||||
|
return AF_UNIX;
|
||||||
|
else if (strcmp(s, "IPv4")==0)
|
||||||
|
return AF_INET;
|
||||||
|
else if (strcmp(s, "IPv6")==0)
|
||||||
|
return AF_INET6;
|
||||||
|
else
|
||||||
|
return AF_UNIX; /* default */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Get port for backend socket in case of AF_INET or AF_INET6
|
||||||
|
* @see clixon-config@<date>.yang CLICON_SOCK_PORT
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
clicon_cli_genmodel_completion(clicon_handle h)
|
clicon_sock_port(clicon_handle h)
|
||||||
{
|
{
|
||||||
char const *opt = "CLICON_CLI_GENMODEL_COMPLETION";
|
char *s;
|
||||||
|
|
||||||
|
if ((s = clicon_option_str(h, "CLICON_SOCK_PORT")) == NULL)
|
||||||
|
return -1;
|
||||||
|
return atoi(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Set if all configuration changes are committed automatically
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
clicon_autocommit(clicon_handle h)
|
||||||
|
{
|
||||||
|
char const *opt = "CLICON_AUTOCOMMIT";
|
||||||
|
|
||||||
if (clicon_option_exists(h, opt))
|
if (clicon_option_exists(h, opt))
|
||||||
return clicon_option_int(h, opt);
|
return clicon_option_int(h, opt);
|
||||||
|
|
@ -738,11 +672,36 @@ clicon_cli_genmodel_completion(clicon_handle h)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Where are "running" and "candidate" databases? */
|
/*! Which method to boot/start clicon backen
|
||||||
char *
|
*/
|
||||||
clicon_xmldb_dir(clicon_handle h)
|
int
|
||||||
|
clicon_startup_mode(clicon_handle h)
|
||||||
{
|
{
|
||||||
return clicon_option_str(h, "CLICON_XMLDB_DIR");
|
char *mode;
|
||||||
|
if ((mode = clicon_option_str(h, "CLICON_STARTUP_MODE")) == NULL)
|
||||||
|
return -1;
|
||||||
|
return clicon_str2int(startup_mode_map, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------
|
||||||
|
* Specific option access functions for non-yang options
|
||||||
|
* Typically dynamic values and more complex datatypes,
|
||||||
|
* Such as handles to plugins, API:s and parsed structures
|
||||||
|
*--------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* eg -q option, dont print notifications on stdout */
|
||||||
|
int
|
||||||
|
clicon_quiet_mode(clicon_handle h)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
if ((s = clicon_option_str(h, "CLICON_QUIET")) == NULL)
|
||||||
|
return 0; /* default */
|
||||||
|
return atoi(s);
|
||||||
|
}
|
||||||
|
int
|
||||||
|
clicon_quiet_mode_set(clicon_handle h, int val)
|
||||||
|
{
|
||||||
|
return clicon_option_int_set(h, "CLICON_QUIET", val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Get YANG specification
|
/*! Get YANG specification
|
||||||
|
|
@ -796,6 +755,19 @@ clicon_dbspec_name_set(clicon_handle h, char *name)
|
||||||
return clicon_option_str_set(h, "dbspec_name", name);
|
return clicon_option_str_set(h, "dbspec_name", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Get xmldb datastore plugin handle, as used by dlopen/dlsym/dlclose */
|
||||||
|
plghndl_t
|
||||||
|
clicon_xmldb_plugin_get(clicon_handle h)
|
||||||
|
{
|
||||||
|
clicon_hash_t *cdat = clicon_data(h);
|
||||||
|
size_t len;
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
if ((p = hash_value(cdat, "xmldb_plugin", &len)) != NULL)
|
||||||
|
return *(plghndl_t*)p;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*! Set xmldb datastore plugin handle, as used by dlopen/dlsym/dlclose */
|
/*! Set xmldb datastore plugin handle, as used by dlopen/dlsym/dlclose */
|
||||||
int
|
int
|
||||||
clicon_xmldb_plugin_set(clicon_handle h,
|
clicon_xmldb_plugin_set(clicon_handle h,
|
||||||
|
|
@ -808,16 +780,20 @@ clicon_xmldb_plugin_set(clicon_handle h,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Get xmldb datastore plugin handle, as used by dlopen/dlsym/dlclose */
|
/*! Get XMLDB API struct pointer
|
||||||
plghndl_t
|
* @param[in] h Clicon handle
|
||||||
clicon_xmldb_plugin_get(clicon_handle h)
|
* @retval xa XMLDB API struct
|
||||||
|
* @note xa is really of type struct xmldb_api*
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
clicon_xmldb_api_get(clicon_handle h)
|
||||||
{
|
{
|
||||||
clicon_hash_t *cdat = clicon_data(h);
|
clicon_hash_t *cdat = clicon_data(h);
|
||||||
size_t len;
|
size_t len;
|
||||||
void *p;
|
void *xa;
|
||||||
|
|
||||||
if ((p = hash_value(cdat, "xmldb_plugin", &len)) != NULL)
|
if ((xa = hash_value(cdat, "xmldb_api", &len)) != NULL)
|
||||||
return *(plghndl_t*)p;
|
return *(void**)xa;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -840,20 +816,19 @@ clicon_xmldb_api_set(clicon_handle h,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Get XMLDB API struct pointer
|
/*! Get XMLDB storage handle
|
||||||
* @param[in] h Clicon handle
|
* @param[in] h Clicon handle
|
||||||
* @retval xa XMLDB API struct
|
* @retval xh XMLDB storage handle. If not connected return NULL
|
||||||
* @note xa is really of type struct xmldb_api*
|
|
||||||
*/
|
*/
|
||||||
void *
|
void *
|
||||||
clicon_xmldb_api_get(clicon_handle h)
|
clicon_xmldb_handle_get(clicon_handle h)
|
||||||
{
|
{
|
||||||
clicon_hash_t *cdat = clicon_data(h);
|
clicon_hash_t *cdat = clicon_data(h);
|
||||||
size_t len;
|
size_t len;
|
||||||
void *xa;
|
void *xh;
|
||||||
|
|
||||||
if ((xa = hash_value(cdat, "xmldb_api", &len)) != NULL)
|
if ((xh = hash_value(cdat, "xmldb_handle", &len)) != NULL)
|
||||||
return *(void**)xa;
|
return *(void**)xh;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -873,18 +848,4 @@ clicon_xmldb_handle_set(clicon_handle h,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Get XMLDB storage handle
|
|
||||||
* @param[in] h Clicon handle
|
|
||||||
* @retval xh XMLDB storage handle. If not connected return NULL
|
|
||||||
*/
|
|
||||||
void *
|
|
||||||
clicon_xmldb_handle_get(clicon_handle h)
|
|
||||||
{
|
|
||||||
clicon_hash_t *cdat = clicon_data(h);
|
|
||||||
size_t len;
|
|
||||||
void *xh;
|
|
||||||
|
|
||||||
if ((xh = hash_value(cdat, "xmldb_handle", &len)) != NULL)
|
|
||||||
return *(void**)xh;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,7 @@ pidfile_write(char *pidfile)
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
||||||
/* Here, there should be no old agent and no pidfile */
|
/* Here, there should be no old agent and no pidfile */
|
||||||
if ((f = fopen(pidfile, "wb")) == NULL){
|
if ((f = fopen(pidfile, "w")) == NULL){
|
||||||
if (errno == EACCES)
|
if (errno == EACCES)
|
||||||
clicon_err(OE_DEMON, errno, "Creating pid-file %s (Try run as root?)", pidfile);
|
clicon_err(OE_DEMON, errno, "Creating pid-file %s (Try run as root?)", pidfile);
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@
|
||||||
* Constants
|
* Constants
|
||||||
*/
|
*/
|
||||||
#define BUFLEN 1024 /* Size of xml read buffer */
|
#define BUFLEN 1024 /* Size of xml read buffer */
|
||||||
|
#define XML_INDENT 3 /* maybe we should set this programmatically? */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Types
|
* Types
|
||||||
|
|
@ -104,7 +105,7 @@ static const map_str2int xsmap[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Hash for XML trees list entries
|
/* Hash for XML trees list entries
|
||||||
* Experimental
|
* Experimental XXX DOES NOT WORK
|
||||||
*/
|
*/
|
||||||
int xml_child_hash = 0;
|
int xml_child_hash = 0;
|
||||||
|
|
||||||
|
|
@ -442,7 +443,7 @@ xml_child_each(cxobj *xparent,
|
||||||
xn = xparent->x_childvec[i];
|
xn = xparent->x_childvec[i];
|
||||||
if (xn == NULL)
|
if (xn == NULL)
|
||||||
continue;
|
continue;
|
||||||
if (type != CX_ERROR && xml_type(xn) != type)
|
if (type != CX_ERROR && xn->x_type != type)
|
||||||
continue;
|
continue;
|
||||||
break; /* this is next object after previous */
|
break; /* this is next object after previous */
|
||||||
}
|
}
|
||||||
|
|
@ -931,27 +932,89 @@ xml_free(cxobj *x)
|
||||||
* @param[in] level how many spaces to insert before each line
|
* @param[in] level how many spaces to insert before each line
|
||||||
* @param[in] prettyprint insert \n and spaces tomake the xml more readable.
|
* @param[in] prettyprint insert \n and spaces tomake the xml more readable.
|
||||||
* @see clicon_xml2cbuf
|
* @see clicon_xml2cbuf
|
||||||
|
* One can use clicon_xml2cbuf to get common code, but using fprintf is
|
||||||
|
* much faster than using cbuf and then printing that,...
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clicon_xml2file(FILE *f,
|
clicon_xml2file(FILE *f,
|
||||||
cxobj *xn,
|
cxobj *x,
|
||||||
int level,
|
int level,
|
||||||
int prettyprint)
|
int prettyprint)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
cbuf *cb = NULL;
|
char *name;
|
||||||
|
char *namespace;
|
||||||
|
cxobj *xc;
|
||||||
|
int hasbody;
|
||||||
|
int haselement;
|
||||||
|
|
||||||
if ((cb = cbuf_new()) == NULL){
|
name = xml_name(x);
|
||||||
clicon_err(OE_XML, errno, "cbuf_new");
|
namespace = xml_namespace(x);
|
||||||
|
switch(xml_type(x)){
|
||||||
|
case CX_BODY:
|
||||||
|
fprintf(f, "%s", xml_value(x));
|
||||||
|
break;
|
||||||
|
case CX_ATTR:
|
||||||
|
fprintf(f, " ");
|
||||||
|
if (namespace)
|
||||||
|
fprintf(f, "%s:", namespace);
|
||||||
|
fprintf(f, "%s=\"%s\"", name, xml_value(x));
|
||||||
|
break;
|
||||||
|
case CX_ELMNT:
|
||||||
|
fprintf(f, "%*s<", prettyprint?(level*XML_INDENT):0, "");
|
||||||
|
if (namespace)
|
||||||
|
fprintf(f, "%s:", namespace);
|
||||||
|
fprintf(f, "%s", name);
|
||||||
|
hasbody = 0;
|
||||||
|
haselement = 0;
|
||||||
|
xc = NULL;
|
||||||
|
/* print attributes only */
|
||||||
|
while ((xc = xml_child_each(x, xc, -1)) != NULL) {
|
||||||
|
switch (xc->x_type){
|
||||||
|
case CX_ATTR:
|
||||||
|
if (clicon_xml2file(f, xc, level+1, prettyprint) <0)
|
||||||
|
goto done;
|
||||||
|
break;
|
||||||
|
case CX_BODY:
|
||||||
|
hasbody=1;
|
||||||
|
break;
|
||||||
|
case CX_ELMNT:
|
||||||
|
haselement=1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Check for special case <a/> instead of <a></a>:
|
||||||
|
* Ie, no CX_BODY or CX_ELMNT child.
|
||||||
|
*/
|
||||||
|
if (hasbody==0 && haselement==0)
|
||||||
|
fprintf(f, "/>");
|
||||||
|
else{
|
||||||
|
fprintf(f, ">");
|
||||||
|
if (prettyprint && hasbody == 0)
|
||||||
|
fprintf(f, "\n");
|
||||||
|
xc = NULL;
|
||||||
|
while ((xc = xml_child_each(x, xc, -1)) != NULL) {
|
||||||
|
if (xml_type(xc) != CX_ATTR)
|
||||||
|
if (clicon_xml2file(f, xc, level+1, prettyprint) <0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (clicon_xml2cbuf(cb, xn, level, prettyprint) < 0)
|
if (prettyprint && hasbody==0)
|
||||||
goto done;
|
fprintf(f, "%*s", level*XML_INDENT, "");
|
||||||
fprintf(f, "%s", cbuf_get(cb));
|
fprintf(f, "</");
|
||||||
|
if (namespace)
|
||||||
|
fprintf(f, "%s:", namespace);
|
||||||
|
fprintf(f, "%s>", name);
|
||||||
|
}
|
||||||
|
if (prettyprint)
|
||||||
|
fprintf(f, "\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}/* switch */
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
if (cb)
|
|
||||||
cbuf_free(cb);
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -971,7 +1034,6 @@ xml_print(FILE *f,
|
||||||
return clicon_xml2file(f, xn, 0, 1);
|
return clicon_xml2file(f, xn, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define XML_INDENT 3 /* maybe we should set this programmatically? */
|
|
||||||
|
|
||||||
/*! Print an XML tree structure to a cligen buffer
|
/*! Print an XML tree structure to a cligen buffer
|
||||||
*
|
*
|
||||||
|
|
@ -987,7 +1049,7 @@ xml_print(FILE *f,
|
||||||
* goto err;
|
* goto err;
|
||||||
* cbuf_free(cb);
|
* cbuf_free(cb);
|
||||||
* @endcode
|
* @endcode
|
||||||
* See also clicon_xml2file
|
* @see clicon_xml2file
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clicon_xml2cbuf(cbuf *cb,
|
clicon_xml2cbuf(cbuf *cb,
|
||||||
|
|
@ -995,48 +1057,67 @@ clicon_xml2cbuf(cbuf *cb,
|
||||||
int level,
|
int level,
|
||||||
int prettyprint)
|
int prettyprint)
|
||||||
{
|
{
|
||||||
|
int retval = -1;
|
||||||
cxobj *xc;
|
cxobj *xc;
|
||||||
char *name;
|
char *name;
|
||||||
|
int hasbody;
|
||||||
|
int haselement;
|
||||||
|
char *namespace;
|
||||||
|
|
||||||
name = xml_name(x);
|
name = xml_name(x);
|
||||||
|
namespace = xml_namespace(x);
|
||||||
switch(xml_type(x)){
|
switch(xml_type(x)){
|
||||||
case CX_BODY:
|
case CX_BODY:
|
||||||
cprintf(cb, "%s", xml_value(x));
|
cprintf(cb, "%s", xml_value(x));
|
||||||
break;
|
break;
|
||||||
case CX_ATTR:
|
case CX_ATTR:
|
||||||
cprintf(cb, " ");
|
cprintf(cb, " ");
|
||||||
if (xml_namespace(x))
|
if (namespace)
|
||||||
cprintf(cb, "%s:", xml_namespace(x));
|
cprintf(cb, "%s:", namespace);
|
||||||
cprintf(cb, "%s=\"%s\"", name, xml_value(x));
|
cprintf(cb, "%s=\"%s\"", name, xml_value(x));
|
||||||
break;
|
break;
|
||||||
case CX_ELMNT:
|
case CX_ELMNT:
|
||||||
cprintf(cb, "%*s<", prettyprint?(level*XML_INDENT):0, "");
|
cprintf(cb, "%*s<", prettyprint?(level*XML_INDENT):0, "");
|
||||||
if (xml_namespace(x))
|
if (namespace)
|
||||||
cprintf(cb, "%s:", xml_namespace(x));
|
cprintf(cb, "%s:", namespace);
|
||||||
cprintf(cb, "%s", name);
|
cprintf(cb, "%s", name);
|
||||||
|
hasbody = 0;
|
||||||
|
haselement = 0;
|
||||||
xc = NULL;
|
xc = NULL;
|
||||||
/* print attributes only */
|
/* print attributes only */
|
||||||
while ((xc = xml_child_each(x, xc, CX_ATTR)) != NULL)
|
while ((xc = xml_child_each(x, xc, -1)) != NULL)
|
||||||
clicon_xml2cbuf(cb, xc, level+1, prettyprint);
|
switch (xc->x_type){
|
||||||
|
case CX_ATTR:
|
||||||
|
if (clicon_xml2cbuf(cb, xc, level+1, prettyprint) < 0)
|
||||||
|
goto done;
|
||||||
|
break;
|
||||||
|
case CX_BODY:
|
||||||
|
hasbody=1;
|
||||||
|
break;
|
||||||
|
case CX_ELMNT:
|
||||||
|
haselement=1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check for special case <a/> instead of <a></a> */
|
/* Check for special case <a/> instead of <a></a> */
|
||||||
if (xml_body(x)==NULL && xml_child_nr_type(x, CX_ELMNT)==0)
|
if (hasbody==0 && haselement==0)
|
||||||
cprintf(cb, "/>");
|
cprintf(cb, "/>");
|
||||||
else{
|
else{
|
||||||
cprintf(cb, ">");
|
cprintf(cb, ">");
|
||||||
if (prettyprint && xml_body(x)==NULL)
|
if (prettyprint && hasbody == 0)
|
||||||
cprintf(cb, "\n");
|
cprintf(cb, "\n");
|
||||||
xc = NULL;
|
xc = NULL;
|
||||||
while ((xc = xml_child_each(x, xc, -1)) != NULL) {
|
while ((xc = xml_child_each(x, xc, -1)) != NULL)
|
||||||
if (xml_type(xc) == CX_ATTR)
|
if (xml_type(xc) != CX_ATTR)
|
||||||
continue;
|
if (clicon_xml2cbuf(cb, xc, level+1, prettyprint) < 0)
|
||||||
else
|
goto done;
|
||||||
clicon_xml2cbuf(cb, xc, level+1, prettyprint);
|
if (prettyprint && hasbody == 0)
|
||||||
}
|
|
||||||
if (prettyprint && xml_body(x)==NULL)
|
|
||||||
cprintf(cb, "%*s", level*XML_INDENT, "");
|
cprintf(cb, "%*s", level*XML_INDENT, "");
|
||||||
cprintf(cb, "</");
|
cprintf(cb, "</");
|
||||||
if (xml_namespace(x))
|
if (namespace)
|
||||||
cprintf(cb, "%s:", xml_namespace(x));
|
cprintf(cb, "%s:", namespace);
|
||||||
cprintf(cb, "%s>", name);
|
cprintf(cb, "%s>", name);
|
||||||
}
|
}
|
||||||
if (prettyprint)
|
if (prettyprint)
|
||||||
|
|
@ -1045,7 +1126,9 @@ clicon_xml2cbuf(cbuf *cb,
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}/* switch */
|
}/* switch */
|
||||||
return 0;
|
retval = 0;
|
||||||
|
done:
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Basic xml parsing function.
|
/*! Basic xml parsing function.
|
||||||
|
|
|
||||||
|
|
@ -86,18 +86,21 @@ echo "$clixon_netconf -qf $clixon_cf -y $fyang"
|
||||||
new "netconf edit large config"
|
new "netconf edit large config"
|
||||||
expecteof_file "time -p $clixon_netconf -qf $clixon_cf -y $fyang" "$fconfig" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof_file "time -p $clixon_netconf -qf $clixon_cf -y $fyang" "$fconfig" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
echo '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' | $clixon_netconf -qf $clixon_cf -y $fyang
|
#echo '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' | $clixon_netconf -qf $clixon_cf -y $fyang
|
||||||
|
|
||||||
new "netconf edit large config again"
|
new "netconf edit large config again"
|
||||||
expecteof_file "time -p $clixon_netconf -qf $clixon_cf -y $fyang" "$fconfig" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof_file "time -p $clixon_netconf -qf $clixon_cf -y $fyang" "$fconfig" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
echo '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' | $clixon_netconf -qf $clixon_cf -y $fyang
|
#echo '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' | $clixon_netconf -qf $clixon_cf -y $fyang
|
||||||
|
|
||||||
rm $fconfig
|
rm $fconfig
|
||||||
|
|
||||||
new "netconf commit large config"
|
new "netconf commit large config"
|
||||||
expecteof "time -p $clixon_netconf -qf $clixon_cf -y $fyang" "<rpc><commit><source><candidate/></source></commit></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "time -p $clixon_netconf -qf $clixon_cf -y $fyang" "<rpc><commit><source><candidate/></source></commit></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
new "netconf commit same config again"
|
||||||
|
expecteof "time -p $clixon_netconf -qf $clixon_cf -y $fyang" "<rpc><commit><source><candidate/></source></commit></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf add one small config"
|
new "netconf add one small config"
|
||||||
expecteof "time -p $clixon_netconf -qf $clixon_cf -y $fyang" "<rpc><edit-config><target><candidate/></target><config><x><y><a>x</a><b>y</b></y></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "time -p $clixon_netconf -qf $clixon_cf -y $fyang" "<rpc><edit-config><target><candidate/></target><config><x><y><a>x</a><b>y</b></y></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
|
@ -107,9 +110,6 @@ time -p for (( i=0; i<$req; i++ )); do
|
||||||
echo "<rpc><edit-config><target><candidate/></target><config><x><y><a>$rnd</a><b>$rnd</b></y></x></config></edit-config></rpc>]]>]]>"
|
echo "<rpc><edit-config><target><candidate/></target><config><x><y><a>$rnd</a><b>$rnd</b></y></x></config></edit-config></rpc>]]>]]>"
|
||||||
done | $clixon_netconf -qf $clixon_cf -y $fyang > /dev/null
|
done | $clixon_netconf -qf $clixon_cf -y $fyang > /dev/null
|
||||||
|
|
||||||
new "netconf commit small config"
|
|
||||||
expecteof "time -p $clixon_netconf -qf $clixon_cf -y $fyang" "<rpc><commit><source><candidate/></source></commit></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
|
||||||
|
|
||||||
new "netconf get large config"
|
new "netconf get large config"
|
||||||
expecteof "time -p $clixon_netconf -qf $clixon_cf -y $fyang" "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><x><y><a>0</a><b>0</b></y><y><a>1</a><b>1</b>"
|
expecteof "time -p $clixon_netconf -qf $clixon_cf -y $fyang" "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><x><y><a>0</a><b>0</b></y><y><a>1</a><b>1</b>"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ bindir = @bindir@
|
||||||
includedir = @includedir@
|
includedir = @includedir@
|
||||||
datarootdir = @datarootdir@
|
datarootdir = @datarootdir@
|
||||||
|
|
||||||
YANGSPECS = clixon-config@2017-07-02.yang
|
YANGSPECS = clixon-config@2017-12-03.yang
|
||||||
YANGSPECS += ietf-netconf@2011-06-01.yang
|
YANGSPECS += ietf-netconf@2011-06-01.yang
|
||||||
|
|
||||||
APPNAME = clixon # subdir ehere these files are installed
|
APPNAME = clixon # subdir ehere these files are installed
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@
|
||||||
|
|
||||||
***** END LICENSE BLOCK *****";
|
***** END LICENSE BLOCK *****";
|
||||||
|
|
||||||
revision 2017-11-12 {
|
revision 2017-07-02 {
|
||||||
description
|
description
|
||||||
"Added startup config";
|
"Added startup config";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
256
yang/clixon-config@2017-12-03.yang
Normal file
256
yang/clixon-config@2017-12-03.yang
Normal file
|
|
@ -0,0 +1,256 @@
|
||||||
|
module clixon-config {
|
||||||
|
|
||||||
|
prefix cc;
|
||||||
|
|
||||||
|
organization
|
||||||
|
"Clicon / Clixon";
|
||||||
|
|
||||||
|
contact
|
||||||
|
"Olof Hagsand <olof@hagsand.se>";
|
||||||
|
|
||||||
|
description
|
||||||
|
"Clixon configuration file
|
||||||
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
Copyright (C) 2009-2017 Olof Hagsand and Benny Holmgren
|
||||||
|
|
||||||
|
This file is part of CLIXON
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the \"License\");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an \"AS IS\" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
Alternatively, the contents of this file may be used under the terms of
|
||||||
|
the GNU General Public License Version 3 or later (the \"GPL\"),
|
||||||
|
in which case the provisions of the GPL are applicable instead
|
||||||
|
of those above. If you wish to allow use of your version of this file only
|
||||||
|
under the terms of the GPL, and not to allow others to
|
||||||
|
use your version of this file under the terms of Apache License version 2,
|
||||||
|
indicate your decision by deleting the provisions above and replace them with
|
||||||
|
the notice and other provisions required by the GPL. If you do not delete
|
||||||
|
the provisions above, a recipient may use your version of this file under
|
||||||
|
the terms of any one of the Apache License version 2 or the GPL.
|
||||||
|
|
||||||
|
***** END LICENSE BLOCK *****";
|
||||||
|
|
||||||
|
revision 2017-12-03 {
|
||||||
|
description
|
||||||
|
"Added startup config for Clixon 1.3.3 and xmldb_cache in 1.4.0";
|
||||||
|
}
|
||||||
|
typedef startup_mode{
|
||||||
|
description
|
||||||
|
"Which method to boot/start clicon backend.
|
||||||
|
The methods differ in how they reach a running state
|
||||||
|
Which source database to commit from, if any.";
|
||||||
|
type enumeration{
|
||||||
|
enum none{
|
||||||
|
description
|
||||||
|
"Do not touch running state
|
||||||
|
Typically after crash when running state and db are synched";
|
||||||
|
}
|
||||||
|
enum init{
|
||||||
|
description
|
||||||
|
"Initialize running state.
|
||||||
|
Start with a completely clean running state";
|
||||||
|
}
|
||||||
|
enum running{
|
||||||
|
description
|
||||||
|
"Commit running db configuration into running state
|
||||||
|
After reboot if a persistent running db exists";
|
||||||
|
}
|
||||||
|
enum startup{
|
||||||
|
description
|
||||||
|
"Commit startup configuration into running state
|
||||||
|
After reboot when no persistent running db exists";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
container config {
|
||||||
|
leaf CLICON_CONFIGFILE{
|
||||||
|
type string;
|
||||||
|
description
|
||||||
|
"Location of configuration-file for default values (this file)";
|
||||||
|
}
|
||||||
|
leaf CLICON_YANG_DIR {
|
||||||
|
type string;
|
||||||
|
mandatory true;
|
||||||
|
description
|
||||||
|
"Location of YANG module and submodule files.";
|
||||||
|
}
|
||||||
|
leaf CLICON_YANG_MODULE_MAIN {
|
||||||
|
type string;
|
||||||
|
default "clicon";
|
||||||
|
description
|
||||||
|
"Option used to construct initial yang file:
|
||||||
|
<module>[@<revision>]";
|
||||||
|
}
|
||||||
|
leaf CLICON_YANG_MODULE_REVISION {
|
||||||
|
type string;
|
||||||
|
description
|
||||||
|
"Option used to construct initial yang file:
|
||||||
|
<module>[@<revision>]";
|
||||||
|
}
|
||||||
|
leaf CLICON_BACKEND_DIR {
|
||||||
|
type string;
|
||||||
|
description
|
||||||
|
"Location of backend .so plugins. Load all .so
|
||||||
|
plugins in this dir as backend plugins";
|
||||||
|
}
|
||||||
|
leaf CLICON_NETCONF_DIR {
|
||||||
|
type string;
|
||||||
|
description "Location of netconf (frontend) .so plugins";
|
||||||
|
}
|
||||||
|
leaf CLICON_RESTCONF_DIR {
|
||||||
|
type string;
|
||||||
|
description
|
||||||
|
"Location of restconf (frontend) .so plugins. Load all .so
|
||||||
|
plugins in this dir as restconf code plugins";
|
||||||
|
}
|
||||||
|
leaf CLICON_RESTCONF_PATH {
|
||||||
|
type string;
|
||||||
|
default "/www-data/fastcgi_restconf.sock";
|
||||||
|
description
|
||||||
|
"FastCGI unix socket. Should be specified in webserver
|
||||||
|
Eg in nginx: fastcgi_pass unix:/www-data/clicon_restconf.sock";
|
||||||
|
}
|
||||||
|
leaf CLICON_CLI_DIR {
|
||||||
|
type string;
|
||||||
|
description
|
||||||
|
"Location of cli frontend .so plugins. Load all .so
|
||||||
|
plugins in this dir as CLI object plugins";
|
||||||
|
}
|
||||||
|
leaf CLICON_CLISPEC_DIR {
|
||||||
|
type string;
|
||||||
|
description
|
||||||
|
"Location of frontend .cli cligen spec files. Load all .cli
|
||||||
|
files in this dir as CLI specification files";
|
||||||
|
}
|
||||||
|
leaf CLICON_CLISPEC_FILE {
|
||||||
|
type string;
|
||||||
|
description "Specific frontend .cli cligen spec file.";
|
||||||
|
}
|
||||||
|
leaf CLICON_CLI_MODE {
|
||||||
|
type string;
|
||||||
|
default "base";
|
||||||
|
description
|
||||||
|
"Startup CLI mode. This should match a CLICON_MODE set in
|
||||||
|
one of the clispec files";
|
||||||
|
}
|
||||||
|
leaf CLICON_CLI_GENMODEL {
|
||||||
|
type int32;
|
||||||
|
default 1;
|
||||||
|
description
|
||||||
|
"Generate code for CLI completion of existing db symbols.
|
||||||
|
Example: Add name=\"myspec\" in datamodel spec and reference
|
||||||
|
as @myspec";
|
||||||
|
}
|
||||||
|
leaf CLICON_CLI_GENMODEL_COMPLETION {
|
||||||
|
type int32;
|
||||||
|
default 1;
|
||||||
|
description "Generate code for CLI completion of existing db symbols";
|
||||||
|
}
|
||||||
|
leaf CLICON_CLI_GENMODEL_TYPE {
|
||||||
|
type string;
|
||||||
|
default "VARS";
|
||||||
|
description "How to generate and show CLI syntax: VARS|ALL";
|
||||||
|
}
|
||||||
|
leaf CLICON_CLI_VARONLY {
|
||||||
|
type int32;
|
||||||
|
default 1;
|
||||||
|
description
|
||||||
|
"Dont include keys in cvec in cli vars callbacks,
|
||||||
|
ie a & k in 'a <b> k <c>' ignored";
|
||||||
|
}
|
||||||
|
leaf CLICON_CLI_LINESCROLLING {
|
||||||
|
type int32;
|
||||||
|
default 1;
|
||||||
|
description
|
||||||
|
"Set to 0 if you want CLI to wrap to next line.
|
||||||
|
Set to 1 if you want CLI to scroll sideways when approaching
|
||||||
|
right margin";
|
||||||
|
}
|
||||||
|
leaf CLICON_SOCK_FAMILY {
|
||||||
|
type string;
|
||||||
|
default "UNIX";
|
||||||
|
description
|
||||||
|
"Address family for communicating with clixon_backend
|
||||||
|
(UNIX|IPv4|IPv6)";
|
||||||
|
}
|
||||||
|
leaf CLICON_SOCK {
|
||||||
|
type string;
|
||||||
|
mandatory true;
|
||||||
|
description
|
||||||
|
"If family above is AF_UNIX: Unix socket for communicating
|
||||||
|
with clixon_backend. If family is AF_INET: IPv4 address";
|
||||||
|
}
|
||||||
|
leaf CLICON_SOCK_PORT {
|
||||||
|
type int32;
|
||||||
|
default 4535;
|
||||||
|
description
|
||||||
|
"Inet socket port for communicating with clixon_backend
|
||||||
|
(only IPv4|IPv6)";
|
||||||
|
}
|
||||||
|
leaf CLICON_SOCK_GROUP {
|
||||||
|
type string;
|
||||||
|
default "clicon";
|
||||||
|
description "Group membership to access clixon_backend unix socket";
|
||||||
|
}
|
||||||
|
leaf CLICON_BACKEND_PIDFILE {
|
||||||
|
type string;
|
||||||
|
mandatory true;
|
||||||
|
description "Process-id file of backend daemon";
|
||||||
|
}
|
||||||
|
leaf CLICON_AUTOCOMMIT {
|
||||||
|
type int32;
|
||||||
|
default 0;
|
||||||
|
description
|
||||||
|
"Set if all configuration changes are committed automatically
|
||||||
|
on every edit change. Explicit commit commands unnecessary";
|
||||||
|
}
|
||||||
|
leaf CLICON_MASTER_PLUGIN {
|
||||||
|
type string;
|
||||||
|
default "master";
|
||||||
|
description
|
||||||
|
"Name of master plugin (both frontend and backend).
|
||||||
|
Master plugin has special callbacks for frontends.
|
||||||
|
See clicon user manual for more info. (Obsolete?)";
|
||||||
|
}
|
||||||
|
leaf CLICON_XMLDB_DIR {
|
||||||
|
type string;
|
||||||
|
mandatory true;
|
||||||
|
description
|
||||||
|
"Directory where \"running\", \"candidate\" and \"startup\" are placed";
|
||||||
|
}
|
||||||
|
leaf CLICON_XMLDB_PLUGIN {
|
||||||
|
type string;
|
||||||
|
mandatory true;
|
||||||
|
description
|
||||||
|
"XMLDB datastore plugin filename
|
||||||
|
(see datastore/ and clixon_xml_db.[ch])";
|
||||||
|
}
|
||||||
|
leaf CLICON_XMLDB_CACHE {
|
||||||
|
type boolean;
|
||||||
|
default true;
|
||||||
|
description
|
||||||
|
"XMLDB datastore cache.
|
||||||
|
If set, XML parsed tree is stored in memory";
|
||||||
|
}
|
||||||
|
leaf CLICON_USE_STARTUP_CONFIG {
|
||||||
|
type int32;
|
||||||
|
default 0;
|
||||||
|
description
|
||||||
|
"Enabled uses \"startup\" configuration on boot. It is called
|
||||||
|
startup_db and exists in XMLDB_DIR.
|
||||||
|
NOTE: Obsolete with 1.3.3 and CLICON_STARTUP_MODE";
|
||||||
|
}
|
||||||
|
leaf CLICON_STARTUP_MODE {
|
||||||
|
type startup_mode;
|
||||||
|
description "Which method to boot/start clicon backend";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue