Initial implementation of NETCONF confirmed-commit
This commit is contained in:
parent
954e5d56fd
commit
284316b646
16 changed files with 1375 additions and 26 deletions
|
|
@ -76,5 +76,6 @@ int xmldb_modified_set(clicon_handle h, const char *db, int value);
|
|||
int xmldb_empty_get(clicon_handle h, const char *db);
|
||||
int xmldb_dump(clicon_handle h, FILE *f, cxobj *xt);
|
||||
int xmldb_print(clicon_handle h, FILE *f);
|
||||
int xmldb_rename(clicon_handle h, const char *db, const char *newdb, const char *suffix);
|
||||
|
||||
#endif /* _CLIXON_DATASTORE_H */
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
* t
|
||||
*
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
|
||||
|
|
@ -63,7 +64,7 @@ int clicon_rpc_get_pageable_list(clicon_handle h, char *datastore, char *xpath,
|
|||
int clicon_rpc_close_session(clicon_handle h);
|
||||
int clicon_rpc_kill_session(clicon_handle h, uint32_t session_id);
|
||||
int clicon_rpc_validate(clicon_handle h, char *db);
|
||||
int clicon_rpc_commit(clicon_handle h);
|
||||
int clicon_rpc_commit(clicon_handle h, int confirmed, int cancel, uint32_t timeout, char *persist, char *persist_id);
|
||||
int clicon_rpc_discard_changes(clicon_handle h);
|
||||
int clicon_rpc_create_subscription(clicon_handle h, char *stream, char *filter, int *s);
|
||||
int clicon_rpc_debug(clicon_handle h, int level);
|
||||
|
|
|
|||
|
|
@ -418,10 +418,18 @@ xmldb_delete(clicon_handle h,
|
|||
if (xmldb_db2file(h, db, &filename) < 0)
|
||||
goto done;
|
||||
if (lstat(filename, &sb) == 0)
|
||||
if (truncate(filename, 0) < 0){
|
||||
clicon_err(OE_DB, errno, "truncate %s", filename);
|
||||
goto done;
|
||||
}
|
||||
// TODO this had been changed from unlink to truncate some time ago. It was changed back for confirmed-commit
|
||||
// as the presence of the rollback_db at startup triggers loading of the rollback rather than the startup
|
||||
// configuration. It might not be sufficient to check for a truncated file. Needs more review, switching back
|
||||
// to unlink temporarily.
|
||||
// if (truncate(filename, 0) < 0){
|
||||
// clicon_err(OE_DB, errno, "truncate %s", filename);
|
||||
// goto done;
|
||||
// }
|
||||
if (unlink(filename) < 0) {
|
||||
clicon_err(OE_UNIX, errno, "unlink %s: %s", filename, strerror(errno));
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (filename)
|
||||
|
|
@ -594,3 +602,64 @@ xmldb_print(clicon_handle h,
|
|||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Rename an XML database
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] db Database name
|
||||
* @param[in] newdb New Database name; if NULL, then same as new
|
||||
* @param[in] suffix Suffix to append to new database name
|
||||
* @retval -1 Error
|
||||
* @retval 0 OK
|
||||
* @note if newdb and suffix are null, OK is returned as it is a no-op
|
||||
*/
|
||||
int
|
||||
xmldb_rename(clicon_handle h,
|
||||
const char *db,
|
||||
const char *newdb,
|
||||
const char *suffix)
|
||||
{
|
||||
char *old;
|
||||
char *fname;
|
||||
int retval = -1;
|
||||
|
||||
if ((xmldb_db2file(h, db, &old)) < 0) {
|
||||
goto done;
|
||||
};
|
||||
|
||||
if (newdb == NULL && suffix == NULL)
|
||||
// no-op
|
||||
goto done;
|
||||
|
||||
newdb = newdb == NULL ? old : newdb;
|
||||
suffix = suffix == NULL ? "" : suffix;
|
||||
|
||||
size_t size = strlen(newdb) + strlen(suffix);
|
||||
|
||||
if ((fname = malloc(size + 1)) == NULL) {
|
||||
clicon_err(OE_UNIX, errno, "malloc: %s", strerror(errno));
|
||||
goto done;
|
||||
};
|
||||
|
||||
int actual = 0;
|
||||
if ((actual = snprintf(fname, size, "%s%s", newdb, suffix)) < size) {
|
||||
clicon_err(OE_UNIX, 0, "snprintf wrote fewer bytes (%d) than requested (%zu)", actual, size);
|
||||
goto done;
|
||||
};
|
||||
|
||||
if ((rename(old, fname)) < 0) {
|
||||
clicon_err(OE_UNIX, errno, "rename: %s", strerror(errno));
|
||||
goto done;
|
||||
};
|
||||
|
||||
|
||||
retval = 0;
|
||||
|
||||
done:
|
||||
if (old)
|
||||
free(old);
|
||||
|
||||
if (fname)
|
||||
free(fname);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,6 +83,10 @@
|
|||
#include "clixon_netconf_lib.h"
|
||||
#include "clixon_proto_client.h"
|
||||
|
||||
#define PERSIST_ID_XML_FMT "<persist-id>%s</persist-id>"
|
||||
#define PERSIST_XML_FMT "<persist>%s</persist>"
|
||||
#define TIMEOUT_XML_FMT "<confirm-timeout>%u</confirm-timeout>"
|
||||
|
||||
/*! Connect to internal netconf socket
|
||||
*/
|
||||
int
|
||||
|
|
@ -1266,7 +1270,12 @@ clicon_rpc_validate(clicon_handle h,
|
|||
* @retval -1 Error and logged to syslog
|
||||
*/
|
||||
int
|
||||
clicon_rpc_commit(clicon_handle h)
|
||||
clicon_rpc_commit(clicon_handle h,
|
||||
int confirmed,
|
||||
int cancel,
|
||||
uint32_t timeout,
|
||||
char *persist,
|
||||
char *persist_id)
|
||||
{
|
||||
int retval = -1;
|
||||
struct clicon_msg *msg = NULL;
|
||||
|
|
@ -1274,15 +1283,65 @@ clicon_rpc_commit(clicon_handle h)
|
|||
cxobj *xerr;
|
||||
char *username;
|
||||
uint32_t session_id;
|
||||
|
||||
char *persist_id_xml = NULL;
|
||||
char *persist_xml = NULL;
|
||||
char *timeout_xml = NULL;
|
||||
|
||||
if (persist_id) {
|
||||
if ((persist_id_xml = malloc(strlen(persist_id) + strlen(PERSIST_ID_XML_FMT) + 1)) == NULL) {
|
||||
clicon_err(OE_UNIX, 0, "malloc: %s", strerror(errno));
|
||||
}
|
||||
sprintf(persist_id_xml, PERSIST_ID_XML_FMT, persist_id);
|
||||
}
|
||||
|
||||
if (persist) {
|
||||
if ((persist_xml = malloc(strlen(persist) + strlen(PERSIST_XML_FMT) + 1)) == NULL) {
|
||||
clicon_err(OE_UNIX, 0, "malloc: %s", strerror(errno));
|
||||
};
|
||||
sprintf(persist_xml, PERSIST_XML_FMT, persist);
|
||||
}
|
||||
|
||||
if (timeout > 0) {
|
||||
|
||||
/* timeout is a uint32_t, so max value is 2^32, a 10-digit number, we'll just always malloc for a string that
|
||||
* may be that large rather than calculate the string length
|
||||
*/
|
||||
|
||||
if ((timeout_xml = malloc(10 + 1 + strlen(TIMEOUT_XML_FMT))) == NULL) {
|
||||
clicon_err(OE_UNIX, 0, "malloc: %s", strerror(errno));
|
||||
};
|
||||
sprintf(timeout_xml, TIMEOUT_XML_FMT, timeout);
|
||||
}
|
||||
|
||||
|
||||
if (session_id_check(h, &session_id) < 0)
|
||||
goto done;
|
||||
username = clicon_username_get(h);
|
||||
if ((msg = clicon_msg_encode(session_id,
|
||||
"<rpc xmlns=\"%s\" username=\"%s\" %s><commit/></rpc>",
|
||||
NETCONF_BASE_NAMESPACE,
|
||||
username?username:"",
|
||||
NETCONF_MESSAGE_ID_ATTR)) == NULL)
|
||||
if (cancel) {
|
||||
msg = clicon_msg_encode(session_id,
|
||||
"<rpc xmlns=\"%s\" username=\"%s\" %s><cancel-commit>%s</cancel-commit></rpc>",
|
||||
NETCONF_BASE_NAMESPACE,
|
||||
username ? username : "",
|
||||
NETCONF_MESSAGE_ID_ATTR,
|
||||
persist_id ? persist_id_xml : "");
|
||||
} else if (confirmed) {
|
||||
msg = clicon_msg_encode(session_id,
|
||||
"<rpc xmlns=\"%s\" username=\"%s\" %s><commit><confirmed/>%s%s%s</commit></rpc>",
|
||||
NETCONF_BASE_NAMESPACE,
|
||||
username ? username : "",
|
||||
NETCONF_MESSAGE_ID_ATTR,
|
||||
timeout ? timeout_xml : "",
|
||||
persist_id ? persist_id_xml : "",
|
||||
persist ? persist_xml : "");
|
||||
} else {
|
||||
msg = clicon_msg_encode(session_id,
|
||||
"<rpc xmlns=\"%s\" username=\"%s\" %s><commit>%s</commit></rpc>",
|
||||
NETCONF_BASE_NAMESPACE,
|
||||
username ? username : "",
|
||||
NETCONF_MESSAGE_ID_ATTR,
|
||||
persist ? persist_xml : "");
|
||||
}
|
||||
if (msg == NULL)
|
||||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret) < 0)
|
||||
goto done;
|
||||
|
|
@ -1296,6 +1355,12 @@ clicon_rpc_commit(clicon_handle h)
|
|||
xml_free(xret);
|
||||
if (msg)
|
||||
free(msg);
|
||||
if (persist_id_xml)
|
||||
free(persist_id_xml);
|
||||
if (persist_xml)
|
||||
free(persist_xml);
|
||||
if (timeout_xml)
|
||||
free(timeout_xml);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -1479,7 +1544,7 @@ clicon_rpc_restconf_debug(clicon_handle h,
|
|||
clicon_err(OE_XML, 0, "rpc error"); /* XXX extract info from rpc-error */
|
||||
goto done;
|
||||
}
|
||||
if ((retval = clicon_rpc_commit(h)) < 0)
|
||||
if ((retval = clicon_rpc_commit(h, 0, 0, 0, NULL, NULL)) < 0)
|
||||
goto done;
|
||||
done:
|
||||
if (msg)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue