diff --git a/CHANGELOG b/CHANGELOG index 0db1efeb..2aa49340 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -29,6 +29,10 @@ # # ***** END LICENSE BLOCK ***** +- Netconf startup configuration support. Set CLICON_USE_STARTUP_CONFIG to 1 to + enable. Eg, if backend_main is started with -CIr startup will be copied to + running. +- Added ".." as valid step in xpath - Use restconf format for internal xmldb keys. Eg /a/b=3,4 - List keys with special characters are RFC 3986 encoded. - Changed example to use multiple cli callbacks diff --git a/apps/backend/backend_commit.c b/apps/backend/backend_commit.c index b8d826ab..ba798b1e 100644 --- a/apps/backend/backend_commit.c +++ b/apps/backend/backend_commit.c @@ -297,16 +297,10 @@ from_client_commit(clicon_handle h, int retval = -1; char *candidate; char *running; - uint32_t snapshot; - uint32_t startup; - char *archive_dir; - char *startup_config; if (clicon_msg_commit_decode(msg, &candidate, &running, - &snapshot, - &startup, label) < 0) goto err; @@ -325,30 +319,6 @@ from_client_commit(clicon_handle h, goto err; } clicon_debug(1, "Commit %s", candidate); - if (snapshot){ - if ((archive_dir = clicon_archive_dir(h)) == NULL){ - clicon_err(OE_PLUGIN, 0, "snapshot set and clicon_archive_dir not defined"); - goto err; - } - if (config_snapshot(h, running, archive_dir) < 0) - goto err; - } - - if (startup){ - if ((archive_dir = clicon_archive_dir(h)) == NULL){ - clicon_err(OE_PLUGIN, 0, "startup set but clicon_archive_dir not defined"); - goto err; - } - if ((startup_config = clicon_startup_config(h)) == NULL){ - clicon_err(OE_PLUGIN, 0, "startup set but startup_config not defined"); - goto err; - } - if (clicon_file_copy("snapshot", "startup") < 0){ - clicon_err(OE_PROTO, errno, "%s: Error when creating startup", - __FUNCTION__); - goto err; - } - } retval = 0; if (send_msg_ok(s) < 0) goto done; diff --git a/apps/backend/backend_main.c b/apps/backend/backend_main.c index 05dff9db..03fe3b06 100644 --- a/apps/backend/backend_main.c +++ b/apps/backend/backend_main.c @@ -72,7 +72,7 @@ #include "backend_handle.h" /* Command line options to be passed to getopt(3) */ -#define BACKEND_OPTS "hD:f:d:Fzu:P:1IRCc::rg:ptx:" +#define BACKEND_OPTS "hD:f:d:Fzu:P:1IRCc:rg:ptx:" /*! Terminate. Cannot use h after this */ static int @@ -121,7 +121,6 @@ usage(char *argv0, clicon_handle h) char *plgdir = clicon_backend_dir(h); char *confsock = clicon_sock(h); char *confpid = clicon_backend_pidfile(h); - char *startup = clicon_startup_config(h); char *group = clicon_sock_group(h); fprintf(stderr, "usage:%s\n" @@ -138,8 +137,7 @@ usage(char *argv0, clicon_handle h) " -I\t\tInitialize running state database\n" " -R\t\tCall plugin_reset() in plugins to reset system state in running db (use with -I)\n" " -C\t\tCall plugin_reset() in plugins to reset system state in candidate db (use with -I)\n" - " -c []\tLoad specified application config. Default is\n" - " \t\"CLICON_STARTUP_CONFIG\" = %s\n" + " -c \tLoad specified application config.\n" " -r\t\tReload running database\n" " -p \t\tPrint database yang specification\n" " -t \t\tPrint alternate spec translation (eg if YANG print KEY, if KEY print YANG)\n" @@ -149,7 +147,6 @@ usage(char *argv0, clicon_handle h) plgdir ? plgdir : "none", confsock ? confsock : "none", confpid ? confpid : "none", - startup ? startup : "none", group ? group : "none" ); exit(-1); @@ -415,11 +412,7 @@ main(int argc, char **argv) reset_state_candidate++; break; case 'c': /* Load application config */ - app_config_file = optarg ? optarg : clicon_startup_config(h); - if (app_config_file == NULL) { - fprintf(stderr, "Option \"CLICON_STARTUP_CONFIG\" not set\n"); - return -1; - } + app_config_file = optarg; break; case 'r': /* Reload running */ reload_running++; @@ -510,6 +503,19 @@ main(int argc, char **argv) if (yang_spec_main(h, stdout, printspec) < 0) goto done; + /* First check for starup config + XXX the options below have become out-of-hand. + Too complex, need to simplify*/ + if (clicon_option_int(h, "CLICON_USE_STARTUP_CONFIG") > 0){ + if (xmldb_exists(h, "startup") == 1){ + /* copy startup config -> running */ + if (xmldb_copy(h, "startup", "running") < 0) + goto done; + } + else + if (rundb_init(h) < 0) + goto done; + } /* If running exists and reload_running set, make a copy to candidate */ if (reload_running){ if (xmldb_exists(h, "running") != 1){ @@ -549,14 +555,13 @@ main(int argc, char **argv) *(argv-1) = tmp; if (reload_running){ - if (candidate_commit(h, "candidate") < 0) - goto done; + /* This could be afailed validation, and we should not fail for that */ + (void)candidate_commit(h, "candidate"); } /* Have we specified a config file to load? eg - -c - -r replace running (obsolete) - */ + * -c [] + */ if (app_config_file) if (rundb_main(h, app_config_file) < 0) goto done; diff --git a/apps/cli/cli_common.c b/apps/cli/cli_common.c index b655f40e..aca4669d 100644 --- a/apps/cli/cli_common.c +++ b/apps/cli/cli_common.c @@ -257,7 +257,7 @@ cli_dbxmlv(clicon_handle h, if (clicon_rpc_change(h, "candidate", op, xk, str) < 0) goto done; if (clicon_autocommit(h)) { - if (clicon_rpc_commit(h, "candidate", "running", 0, 0) < 0) + if (clicon_rpc_commit(h, "candidate", "running") < 0) goto done; } retval = 0; @@ -456,7 +456,7 @@ cli_quitv(clicon_handle h, } /*! Generic commit callback - * @param[in] arg If 1, then snapshot and copy to startup config + * @param[in] argv No arguments expected */ int cli_commitv(clicon_handle h, @@ -464,21 +464,10 @@ cli_commitv(clicon_handle h, cvec *argv) { int retval = -1; - int snapshot; - if (cvec_len(argv) > 1){ - clicon_err(OE_PLUGIN, 0, "%s: Requires 0 or 1 element. If given: snapshot flag 0|1", __FUNCTION__); - goto done; - } - if (cvec_len(argv)) - snapshot = cv_int32_get(cvec_i(argv, 0)); - else - snapshot = 0; if ((retval = clicon_rpc_commit(h, "candidate", - "running", - snapshot, /* snapshot */ - snapshot)) < 0){ /* startup */ + "running")) < 0){ /* startup */ cli_output(stderr, "Commit failed. Edit and try again or discard changes"); goto done; } @@ -702,8 +691,8 @@ load_config_filev(clicon_handle h, * Utility function used by cligen spec file * @param[in] h CLICON handle * @param[in] cvv variable vector (containing ) - * @param[in] arg a string: " " - * is running or candidate + * @param[in] argv a string: " " + * is running, candidate, or startup * is name of cligen variable in the "cvv" vector containing file name * Note that "filename" is local on client filesystem not backend. * The function can run without a local database @@ -735,23 +724,11 @@ save_config_filev(clicon_handle h, goto done; } -#if 0 - if (arg == NULL || (str = cv_string_get(arg)) == NULL){ - clicon_err(OE_PLUGIN, 0, "%s: requires string argument", __FUNCTION__); - goto done; - } - if ((vec = clicon_strsplit(str, " ", &nvec, __FUNCTION__)) == NULL){ - clicon_err(OE_PLUGIN, errno, "clicon_strsplit"); - goto done; - } - if (nvec != 2){ - clicon_err(OE_PLUGIN, 0, "Arg syntax is "); - goto done; - } -#endif dbstr = cv_string_get(cvec_i(argv, 0)); varstr = cv_string_get(cvec_i(argv, 1)); - if (strcmp(dbstr, "running") != 0 && strcmp(dbstr, "candidate") != 0) { + if (strcmp(dbstr, "running") != 0 && + strcmp(dbstr, "candidate") != 0 && + strcmp(dbstr, "startup") != 0) { clicon_err(OE_PLUGIN, 0, "No such db name: %s", dbstr); goto done; } @@ -799,7 +776,9 @@ delete_allv(clicon_handle h, goto done; } dbstr = cv_string_get(cvec_i(argv, 0)); - if (strcmp(dbstr, "running") != 0 && strcmp(dbstr, "candidate") != 0){ + if (strcmp(dbstr, "running") != 0 && + strcmp(dbstr, "candidate") != 0 && + strcmp(dbstr, "startup") != 0){ clicon_err(OE_PLUGIN, 0, "No such db name: %s", dbstr); goto done; } @@ -822,6 +801,22 @@ discard_changesv(clicon_handle h, return clicon_rpc_copy(h, "running", "candidate"); } +/*! Copy from one database to another, eg running->startup + * @param[in] argv a string: " " Copy from db1 to db2 + */ +int +db_copy(clicon_handle h, + cvec *cvv, + cvec *argv) +{ + char *db1; + char *db2; + + db1 = cv_string_get(cvec_i(argv, 0)); + db2 = cv_string_get(cvec_i(argv, 1)); + return clicon_rpc_copy(h, db1, db2); +} + /* These are strings that can be used as 3rd argument to cli_setlog */ static const char *SHOWAS_TXT = "txt"; static const char *SHOWAS_XML = "xml"; diff --git a/apps/cli/cli_show.c b/apps/cli/cli_show.c index 0b006126..f25eb2b4 100644 --- a/apps/cli/cli_show.c +++ b/apps/cli/cli_show.c @@ -126,7 +126,8 @@ expandv_dbvar(void *h, } dbstr = cv_string_get(cv); if (strcmp(dbstr, "running") != 0 && - strcmp(dbstr, "candidate") != 0){ + strcmp(dbstr, "candidate") != 0 && + strcmp(dbstr, "startup") != 0){ clicon_err(OE_PLUGIN, 0, "No such db name: %s", dbstr); goto done; } @@ -407,7 +408,7 @@ xml2csv(FILE *f, cxobj *x, cvec *cvv) * @param[in] arg A string: [] * @param[out] xt Configuration as xml tree. * Format of arg: - * "running", "candidate" + * "running", "candidate", "startup" * xpath expression * optional name of variable in cvv. If set, xpath must have a '%s' * @code @@ -440,7 +441,9 @@ show_confv_as(clicon_handle h, } /* Dont get attr here, take it from arg instead */ db = cv_string_get(cvec_i(argv, 0)); - if (strcmp(db, "running") != 0 && strcmp(db, "candidate") != 0) { + if (strcmp(db, "running") != 0 && + strcmp(db, "candidate") != 0 && + strcmp(db, "startup") != 0) { clicon_err(OE_PLUGIN, 0, "No such db name: %s", db); goto done; } @@ -703,8 +706,8 @@ show_confv_as_csv(clicon_handle h, */ int show_confv_xpath(clicon_handle h, - cvec *cvv, - cvec *argv) + cvec *cvv, + cvec *argv) { int retval = -1; char *str; @@ -721,7 +724,9 @@ show_confv_xpath(clicon_handle h, } str = cv_string_get(cvec_i(argv, 0)); /* Dont get attr here, take it from arg instead */ - if (strcmp(str, "running") != 0 && strcmp(str, "candidate") != 0){ + if (strcmp(str, "running") != 0 && + strcmp(str, "candidate") != 0 && + strcmp(str, "startup") != 0){ clicon_err(OE_PLUGIN, 0, "No such db name: %s", str); goto done; } @@ -790,7 +795,8 @@ expand_dbvar(void *h, } dbstr = vec[0]; if (strcmp(dbstr, "running") != 0 && - strcmp(dbstr, "candidate") != 0){ + strcmp(dbstr, "candidate") != 0 && + strcmp(dbstr, "startup") != 0){ clicon_err(OE_PLUGIN, 0, "No such db name: %s", dbstr); goto done; } @@ -869,7 +875,7 @@ expand_dbvar(void *h, * @param[in] arg A string: [] * @param[out] xt Configuration as xml tree. * Format of arg: - * "running", "candidate" + * "running", "candidate", "startup" * xpath expression * optional name of variable in cvv. If set, xpath must have a '%s' * @code @@ -909,7 +915,9 @@ show_conf_as(clicon_handle h, } /* Dont get attr here, take it from arg instead */ db = vec[0]; - if (strcmp(db, "running") != 0 && strcmp(db, "candidate") != 0) { + if (strcmp(db, "running") != 0 && + strcmp(db, "candidate") != 0 && + strcmp(db, "startup") != 0) { clicon_err(OE_PLUGIN, 0, "No such db name: %s", db); goto done; } @@ -1178,7 +1186,9 @@ show_conf_xpath(clicon_handle h, goto done; } /* Dont get attr here, take it from arg instead */ - if (strcmp(str, "running") != 0 && strcmp(str, "candidate") != 0){ + if (strcmp(str, "running") != 0 && + strcmp(str, "candidate") != 0 && + strcmp(str, "startup") != 0){ clicon_err(OE_PLUGIN, 0, "No such db name: %s", str); goto done; } diff --git a/apps/dbctrl/dbctrl_main.c b/apps/dbctrl/dbctrl_main.c index ebc1b01f..e8ea26cd 100644 --- a/apps/dbctrl/dbctrl_main.c +++ b/apps/dbctrl/dbctrl_main.c @@ -88,7 +88,7 @@ usage(char *argv0) "\t-h\t\tHelp\n" "\t-D\t\tDebug\n" "\t-S\t\tLog on syslog\n" - "\t-d \tDatabase name (default: running)\n" + "\t-d \t\tDatabase name (default: running)\n" "\t-p\t\tDump database on stdout\n" "\t-b\t\tBrief output, just print keys. Combine with -p or -m\n" "\t-n \" \" Add database entry\n" diff --git a/apps/netconf/netconf_hello.c b/apps/netconf/netconf_hello.c index 3157c4c4..128ef9cc 100644 --- a/apps/netconf/netconf_hello.c +++ b/apps/netconf/netconf_hello.c @@ -120,9 +120,7 @@ netconf_create_hello(cbuf *xf, /* msg buffer */ cprintf(xf, "urn:ietf:params:xml:ns:netconf:capability:validate:1.0\n"); cprintf(xf, "urn:ietf:params:netconf:capability:xpath:1.0\n"); cprintf(xf, "urn:ietf:params:netconf:capability:notification:1.0\n"); - - -// cprintf(xf, "urn:rnr:rnrapi:1:0"); + cprintf(xf, "urn:ietf:params:netconf:capability:startup:1.0\n"); cprintf(xf, ""); cprintf(xf, "%lu", 42+session_id); cprintf(xf, ""); diff --git a/apps/netconf/netconf_lib.c b/apps/netconf/netconf_lib.c index 098d2071..3cd5e094 100644 --- a/apps/netconf/netconf_lib.c +++ b/apps/netconf/netconf_lib.c @@ -204,6 +204,9 @@ netconf_get_target(clicon_handle h, else if (xpath_first(x, "running") != NULL) target = "running"; + else + if (xpath_first(x, "startup") != NULL) + target = "startup"; } return target; diff --git a/apps/netconf/netconf_rpc.c b/apps/netconf/netconf_rpc.c index 030e597d..92471ee8 100644 --- a/apps/netconf/netconf_rpc.c +++ b/apps/netconf/netconf_rpc.c @@ -247,11 +247,11 @@ netconf_get_config(clicon_handle h, cbuf *cb_err, cxobj *xorig) { - cxobj *xfilter; /* filter */ - int retval = -1; - char *source; + cxobj *xfilter; /* filter */ + int retval = -1; + char *source; enum filter_option foption = FILTER_SUBTREE; - char *ftype = NULL; + char *ftype = NULL; if ((source = netconf_get_target(h, xn, "source")) == NULL){ netconf_create_rpc_error(cb_err, xorig, @@ -568,7 +568,7 @@ netconf_delete_config(clicon_handle h, "target"); goto done; } - if (strcmp(target, "candidate")){ + if (strcmp(target, "running") == 0){ netconf_create_rpc_error(cb_err, xorig, "bad-element", "protocol", @@ -577,7 +577,7 @@ netconf_delete_config(clicon_handle h, "target"); goto done; } - if (clicon_rpc_change(h, "candidate", + if (clicon_rpc_change(h, target, OP_REMOVE, "/", "") < 0){ netconf_create_rpc_error(cb_err, xorig, @@ -745,8 +745,7 @@ netconf_commit(clicon_handle h, { int retval = -1; - if (clicon_rpc_commit(h, "candidate", "running", - 0, 0) < 0){ + if (clicon_rpc_commit(h, "candidate", "running") < 0){ netconf_create_rpc_error(cb_err, xorig, "operation-failed", "protocol", "error", diff --git a/apps/restconf/restconf_main.c b/apps/restconf/restconf_main.c index 6a260aa4..4306569a 100644 --- a/apps/restconf/restconf_main.c +++ b/apps/restconf/restconf_main.c @@ -273,8 +273,7 @@ api_data_delete(clicon_handle h, api_path, "") < 0) goto done; - if (clicon_rpc_commit(h, "candidate", "running", - 0, 0) < 0) + if (clicon_rpc_commit(h, "candidate", "running") < 0) goto done; FCGX_SetExitStatus(201, r->out); FCGX_FPrintF(r->out, "Content-Type: text/plain\r\n"); @@ -348,8 +347,7 @@ api_data_put(clicon_handle h, api_path, cbuf_get(cbx)) < 0) goto done; - if (clicon_rpc_commit(h, "candidate", "running", - 0, 0) < 0) + if (clicon_rpc_commit(h, "candidate", "running") < 0) goto done; FCGX_SetExitStatus(201, r->out); /* Created */ FCGX_FPrintF(r->out, "Content-Type: text/plain\r\n"); diff --git a/clixon.conf.cpp.cpp b/clixon.conf.cpp.cpp index a3823ad3..dc801198 100644 --- a/clixon.conf.cpp.cpp +++ b/clixon.conf.cpp.cpp @@ -77,8 +77,8 @@ CLICON_CLISPEC_DIR libdir/APPNAME/clispec # are saved chronologically CLICON_ARCHIVE_DIR localstatedir/APPNAME/archive -# XXX Name of startup configuration file (in XML) -CLICON_STARTUP_CONFIG localstatedir/APPNAME/startup-config +# Enabled uses "startup" configuration on boot +CLICON_USE_STARTUP_CONFIG 0 # Address family for communicating with clixon_backend (UNIX|IPv4|IPv6) CLICON_SOCK_FAMILY UNIX @@ -118,7 +118,7 @@ CLICON_BACKEND_PIDFILE localstatedir/APPNAME/APPNAME.pidfile # How to generate and show CLI syntax: VARS|ALL # CLICON_CLI_GENMODEL_TYPE VARS -# Directory where "running" and "candidate" are placed +# Directory where "running", "candidate" and "startup" are placed CLICON_XMLDB_DIR localstatedir/APPNAME # Set if xmldb runs in a separate process (clixon_xmldb). @@ -149,3 +149,4 @@ CLICON_CLIGEN_EXPAND_SINGLE_ARG 0 # And change predefined callbacks, eg cli_commit -> cli_commitv in all cli files CLICON_CLIGEN_CALLBACK_SINGLE_ARG 1 + diff --git a/example/routing_cli.cli b/example/routing_cli.cli index ec1eac7a..a96bd4e6 100644 --- a/example/routing_cli.cli +++ b/example/routing_cli.cli @@ -10,10 +10,11 @@ set @datamodel:ietf-ip, cli_mergev(); delete("Delete a configuration item") @datamodel:ietf-ip, cli_delv(); validate("Validate changes"), cli_validatev(); -commit("Commit the changes"), cli_commitv((int32)0); # snapshot +commit("Commit the changes"), cli_commitv(); quit("Quit Hello"), cli_quitv(); delete("Delete a configuration item") all("Delete whole candidate configuration"), delete_allv("candidate"); +startup("Store running as startup config"), db_copy("running","startup"); no("Negate or remove") debug("Debugging parts of the system"), cli_debug_cliv((int32)0); debug("Debugging parts of the system"), cli_debug_cliv((int32)1);{ level("Set debug level: 1..n") ("Set debug level (0..n)"), cli_debug_cliv(); @@ -22,7 +23,7 @@ debug("Debugging parts of the system"), cli_debug_cliv((int32)1);{ discard("Discard edits (rollback 0)"), discard_changesv(); show("Show a particular state of the system"){ - xpath("Show configuration") ("XPATH expression"), show_confv_xpath("candidate"); + xpath("Show configuration") ("XPATH expression"), show_confv_xpath("candidate","/"); compare("Compare candidate and running databases"), compare_dbsv((int32)0);{ xml("Show comparison in xml"), compare_dbsv((int32)0); text("Show comparison in text"), compare_dbsv((int32)1); diff --git a/lib/clixon/clixon_options.h b/lib/clixon/clixon_options.h index ec5c97b2..0d339514 100644 --- a/lib/clixon/clixon_options.h +++ b/lib/clixon/clixon_options.h @@ -95,7 +95,6 @@ char *clicon_clispec_dir(clicon_handle h); char *clicon_netconf_dir(clicon_handle h); char *clicon_restconf_dir(clicon_handle h); char *clicon_archive_dir(clicon_handle h); -char *clicon_startup_config(clicon_handle h); int clicon_sock_family(clicon_handle h); char *clicon_sock(clicon_handle h); int clicon_sock_port(clicon_handle h); diff --git a/lib/clixon/clixon_proto_client.h b/lib/clixon/clixon_proto_client.h index c4a774ea..1b6d0e09 100644 --- a/lib/clixon/clixon_proto_client.h +++ b/lib/clixon/clixon_proto_client.h @@ -40,8 +40,7 @@ #ifndef _CLIXON_PROTO_CLIENT_H_ #define _CLIXON_PROTO_CLIENT_H_ -int clicon_rpc_commit(clicon_handle h, char *from, char *to, - int snapshot, int startup); +int clicon_rpc_commit(clicon_handle h, char *from, char *to); int clicon_rpc_validate(clicon_handle h, char *db); int clicon_rpc_change(clicon_handle h, char *db, enum operation_type op, char *key, char *val); diff --git a/lib/clixon/clixon_proto_encode.h b/lib/clixon/clixon_proto_encode.h index fa58b140..5d4f9e22 100644 --- a/lib/clixon/clixon_proto_encode.h +++ b/lib/clixon/clixon_proto_encode.h @@ -44,13 +44,11 @@ */ struct clicon_msg * clicon_msg_commit_encode(char *dbsrc, char *dbdst, - uint32_t snapshot, uint32_t startup, const char *label); int clicon_msg_commit_decode(struct clicon_msg *msg, char **dbsrc, char **dbdst, - uint32_t *snapshot, uint32_t *startup, const char *label); struct clicon_msg * diff --git a/lib/src/clixon_options.c b/lib/src/clixon_options.c index 56cb9419..f1432007 100644 --- a/lib/src/clixon_options.c +++ b/lib/src/clixon_options.c @@ -241,10 +241,6 @@ clicon_option_sanity(clicon_hash_t *copt) clicon_err(OE_UNIX, 0, "CLICON_ARCHIVE_DIR not defined in config file"); goto done; } - if (!hash_lookup(copt, "CLICON_STARTUP_CONFIG")){ - clicon_err(OE_UNIX, 0, "CLICON_STARTUP_CONFIG not defined in config file"); - goto done; - } if (!hash_lookup(copt, "CLICON_SOCK")){ clicon_err(OE_UNIX, 0, "CLICON_SOCK not defined in config file"); goto done; @@ -461,12 +457,6 @@ clicon_archive_dir(clicon_handle h) return clicon_option_str(h, "CLICON_ARCHIVE_DIR"); } -char * -clicon_startup_config(clicon_handle h) -{ - return clicon_option_str(h, "CLICON_STARTUP_CONFIG"); -} - /* get family of backend socket: AF_UNIX, AF_INET or AF_INET6 */ int clicon_sock_family(clicon_handle h) diff --git a/lib/src/clixon_proto_client.c b/lib/src/clixon_proto_client.c index f0b78e4c..ffc0ab79 100644 --- a/lib/src/clixon_proto_client.c +++ b/lib/src/clixon_proto_client.c @@ -128,22 +128,17 @@ clicon_rpc_msg(clicon_handle h, * @param[in] h CLICON handle * @param[in] from name of 'from' database (eg "candidate") * @param[in] db name of 'to' database (eg "running") - * @param[in] snapshot Make a snapshot copy of db state - * @param[in] startup Make a copy to startup. * @retval 0 Copy current->candidate */ int clicon_rpc_commit(clicon_handle h, char *from, - char *to, - int snapshot, - int startup) + char *to) { int retval = -1; struct clicon_msg *msg; - if ((msg=clicon_msg_commit_encode(from, to, snapshot, startup, - __FUNCTION__)) == NULL) + if ((msg=clicon_msg_commit_encode(from, to, __FUNCTION__)) == NULL) goto done; if (clicon_rpc_msg(h, msg, NULL, NULL, NULL, __FUNCTION__) < 0) goto done; diff --git a/lib/src/clixon_proto_encode.c b/lib/src/clixon_proto_encode.c index a03eec9c..ee7fa34e 100644 --- a/lib/src/clixon_proto_encode.c +++ b/lib/src/clixon_proto_encode.c @@ -73,18 +73,16 @@ struct clicon_msg * clicon_msg_commit_encode(char *dbsrc, char *dbdst, - uint32_t snapshot, uint32_t startup, const char *label) { struct clicon_msg *msg; uint16_t len; int hdrlen = sizeof(*msg); int p; - uint32_t tmp; - clicon_debug(2, "%s: snapshot: %d startup: %d dbsrc: %s dbdst: %s", + clicon_debug(2, "%s: dbsrc: %s dbdst: %s", __FUNCTION__, - snapshot, startup, dbsrc, dbdst); + dbsrc, dbdst); p = 0; len = sizeof(*msg) + 2*sizeof(uint32_t) + strlen(dbsrc) + 1 + strlen(dbdst) + 1; @@ -97,12 +95,6 @@ clicon_msg_commit_encode(char *dbsrc, char *dbdst, msg->op_type = htons(CLICON_MSG_COMMIT); msg->op_len = htons(len); /* body */ - tmp = htonl(snapshot); - memcpy(msg->op_body+p, &tmp, sizeof(uint32_t)); - p += sizeof(uint32_t); - tmp = htonl(startup); - memcpy(msg->op_body+p, &tmp, sizeof(uint32_t)); - p += sizeof(uint32_t); strncpy(msg->op_body+p, dbsrc, len-p-hdrlen); p += strlen(dbsrc)+1; strncpy(msg->op_body+p, dbdst, len-p-hdrlen); @@ -113,20 +105,12 @@ clicon_msg_commit_encode(char *dbsrc, char *dbdst, int clicon_msg_commit_decode(struct clicon_msg *msg, char **dbsrc, char **dbdst, - uint32_t *snapshot, uint32_t *startup, const char *label) { int p; - uint32_t tmp; p = 0; /* body */ - memcpy(&tmp, msg->op_body+p, sizeof(uint32_t)); - *snapshot = ntohl(tmp); - p += sizeof(uint32_t); - memcpy(&tmp, msg->op_body+p, sizeof(uint32_t)); - *startup = ntohl(tmp); - p += sizeof(uint32_t); if ((*dbsrc = chunk_sprintf(label, "%s", msg->op_body+p)) == NULL){ clicon_err(OE_PROTO, errno, "%s: chunk_sprintf", __FUNCTION__); @@ -139,9 +123,7 @@ clicon_msg_commit_decode(struct clicon_msg *msg, return -1; } p += strlen(*dbdst)+1; - clicon_debug(2, "%s: snapshot: %d startup: %d dbsrc: %s dbdst: %s", - __FUNCTION__, - *snapshot, *startup, *dbsrc, *dbdst); + clicon_debug(2, "%s: dbsrc: %s dbdst: %s", __FUNCTION__, *dbsrc, *dbdst); return 0; } diff --git a/lib/src/clixon_xml_db.c b/lib/src/clixon_xml_db.c index ec2feb26..25a51577 100644 --- a/lib/src/clixon_xml_db.c +++ b/lib/src/clixon_xml_db.c @@ -414,6 +414,7 @@ xmlkeyfmt2xpath(char *xkfmt, */ static int _running_locked = 0; static int _candidate_locked = 0; +static int _startup_locked = 0; /*! Lock database */ @@ -425,6 +426,8 @@ db_lock(char *db, _running_locked = pid; else if (strcmp("candidate", db) == 0) _candidate_locked = pid; + else if (strcmp("startup", db) == 0) + _startup_locked = pid; clicon_debug(1, "%s: locked by %u", db, pid); return 0; } @@ -438,6 +441,8 @@ db_unlock(char *db) _running_locked = 0; else if (strcmp("candidate", db) == 0) _candidate_locked = 0; + else if (strcmp("startup", db) == 0) + _startup_locked = 0; return 0; } @@ -452,6 +457,8 @@ db_islocked(char *db) return (_running_locked); else if (strcmp("candidate", db) == 0) return(_candidate_locked); + else if (strcmp("startup", db) == 0) + return(_startup_locked); return 0; } @@ -485,6 +492,7 @@ db2file(clicon_handle h, } if (strcmp(db, "running") != 0 && strcmp(db, "candidate") != 0 && + strcmp(db, "startup") != 0 && strcmp(db, "tmp") != 0){ clicon_err(OE_XML, 0, "Unexpected database: %s", db); goto done; @@ -1016,8 +1024,10 @@ xmldb_get_local(clicon_handle h, if (xvec != NULL) for (i=0; i "a" "b[/c]" "d" */ esc = 0; @@ -358,12 +358,12 @@ xpath_parse(char *xpath, else if (strncmp(s,"descendant-or-self::", strlen("descendant-or-self::"))==0){ xpath_element_new(A_DESCENDANT_OR_SELF, s+strlen("descendant-or-self::"), &xpnext); } - else if (strncmp(s,".", strlen("."))==0) - xpath_element_new(A_SELF, s+strlen("."), &xpnext); + else if (strncmp(s,".", strlen(s))==0) /* abbreviatedstep */ + xpath_element_new(A_SELF, NULL, &xpnext); else if (strncmp(s,"self::", strlen("self::"))==0) xpath_element_new(A_SELF, s+strlen("self::"), &xpnext); - else if (strncmp(s,"..", strlen(".."))==0) - xpath_element_new(A_PARENT, s+strlen(".."), &xpnext); + else if (strncmp(s,"..", strlen(s))==0) /* abbreviatedstep */ + xpath_element_new(A_PARENT, NULL, &xpnext); else if (strncmp(s,"parent::", strlen("parent::"))==0) xpath_element_new(A_PARENT, s+strlen("parent::"), &xpnext); else if (strncmp(s,"ancestor::", strlen("ancestor::"))==0)