xmldb
This commit is contained in:
parent
ca18b7f49e
commit
0a812696c2
47 changed files with 1818 additions and 1783 deletions
|
|
@ -54,7 +54,7 @@ INCLUDES = -I. -I$(top_srcdir)/lib/src -I$(top_srcdir)/lib -I$(top_srcdir)/inclu
|
|||
|
||||
# Not accessible from plugin
|
||||
APPSRC = backend_main.c backend_socket.c backend_client.c \
|
||||
backend_lock.c backend_commit.c backend_plugin.c
|
||||
backend_commit.c backend_plugin.c
|
||||
|
||||
APPOBJ = $(APPSRC:.c=.o)
|
||||
APPL = clixon_backend
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@
|
|||
#include <clixon/clixon.h>
|
||||
|
||||
#include "backend_commit.h"
|
||||
#include "backend_lock.h"
|
||||
#include "backend_plugin.h"
|
||||
#include "backend_client.h"
|
||||
#include "backend_handle.h"
|
||||
|
|
@ -163,7 +162,6 @@ backend_client_rm(clicon_handle h,
|
|||
return backend_client_delete(h, ce); /* actually purge it */
|
||||
}
|
||||
|
||||
|
||||
/*! Internal message: Change entry set/delete in database xmldb variant
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] s Socket where request arrived, and where replies are sent
|
||||
|
|
@ -183,15 +181,14 @@ from_client_change(clicon_handle h,
|
|||
int retval = -1;
|
||||
uint32_t len;
|
||||
char *xk;
|
||||
char *dbname;
|
||||
char *db;
|
||||
enum operation_type op;
|
||||
char *str = NULL;
|
||||
char *candidate_db;
|
||||
char *val=NULL;
|
||||
yang_spec *yspec;
|
||||
int piddb;
|
||||
|
||||
if (clicon_msg_change_decode(msg,
|
||||
&dbname,
|
||||
&db,
|
||||
&op,
|
||||
&xk,
|
||||
&val,
|
||||
|
|
@ -201,25 +198,17 @@ from_client_change(clicon_handle h,
|
|||
clicon_err_reason);
|
||||
goto done;
|
||||
}
|
||||
if ((candidate_db = clicon_candidate_db(h)) == NULL){
|
||||
send_msg_err(s, 0, 0, "candidate db not set");
|
||||
goto done;
|
||||
}
|
||||
/* candidate is locked by other client */
|
||||
if (strcmp(dbname, candidate_db) == 0 &&
|
||||
db_islocked(h) &&
|
||||
pid != db_islocked(h)){
|
||||
send_msg_err(s, OE_DB, 0,
|
||||
"lock failed: locked by %d", db_islocked(h));
|
||||
goto done;
|
||||
if (strcmp(db, "candidate") == 0){
|
||||
piddb = xmldb_islocked(h, db);
|
||||
if (piddb && pid != piddb){
|
||||
send_msg_err(s, OE_DB, 0,
|
||||
"lock failed: locked by %d", piddb);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update database */
|
||||
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
||||
clicon_err(OE_XML, 0, "yang spec not found");
|
||||
goto done;
|
||||
}
|
||||
if (xmldb_put_xkey(dbname, xk, val, yspec, op) < 0){
|
||||
if (xmldb_put_xkey(h, db, xk, val, op) < 0){
|
||||
send_msg_err(s, clicon_errno, clicon_suberrno,
|
||||
clicon_err_reason);
|
||||
goto done;
|
||||
|
|
@ -233,8 +222,6 @@ from_client_change(clicon_handle h,
|
|||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*! Internal message: Change entries as XML
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] s Socket where request arrived, and where replies are sent
|
||||
|
|
@ -252,19 +239,16 @@ from_client_xmlput(clicon_handle h,
|
|||
const char *label)
|
||||
{
|
||||
int retval = -1;
|
||||
char *dbname;
|
||||
char *db;
|
||||
enum operation_type op;
|
||||
cvec *cvv = NULL;
|
||||
char *str = NULL;
|
||||
char *xml = NULL;
|
||||
yang_spec *ys;
|
||||
char *candidate_db;
|
||||
cxobj *xt;
|
||||
int piddb;
|
||||
|
||||
if ((ys = clicon_dbspec_yang(h)) == NULL)
|
||||
goto done;
|
||||
if (clicon_msg_xmlput_decode(msg,
|
||||
&dbname,
|
||||
&db,
|
||||
&op,
|
||||
&xml,
|
||||
label) < 0){
|
||||
|
|
@ -272,24 +256,21 @@ from_client_xmlput(clicon_handle h,
|
|||
clicon_err_reason);
|
||||
goto done;
|
||||
}
|
||||
if ((candidate_db = clicon_candidate_db(h)) == NULL){
|
||||
send_msg_err(s, 0, 0, "candidate db not set");
|
||||
goto done;
|
||||
}
|
||||
/* candidate is locked by other client */
|
||||
if (strcmp(dbname, candidate_db) == 0 &&
|
||||
db_islocked(h) &&
|
||||
pid != db_islocked(h)){
|
||||
send_msg_err(s, OE_DB, 0,
|
||||
"lock failed: locked by %d", db_islocked(h));
|
||||
goto done;
|
||||
if (strcmp(db, "candidate") == 0){
|
||||
piddb = xmldb_islocked(h, db);
|
||||
if (piddb && pid != piddb){
|
||||
send_msg_err(s, OE_DB, 0,
|
||||
"lock failed: locked by %d", piddb);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (clicon_xml_parse_string(&xml, &xt) < 0){
|
||||
send_msg_err(s, clicon_errno, clicon_suberrno,
|
||||
clicon_err_reason);
|
||||
goto done;
|
||||
}
|
||||
if (xmldb_put(dbname, xt, ys, op) < 0){
|
||||
if (xmldb_put(h, db, xt, op) < 0){
|
||||
send_msg_err(s, clicon_errno, clicon_suberrno,
|
||||
clicon_err_reason);
|
||||
goto done;
|
||||
|
|
@ -312,7 +293,7 @@ from_client_xmlput(clicon_handle h,
|
|||
*/
|
||||
int
|
||||
config_snapshot(clicon_handle h,
|
||||
char *dbname,
|
||||
char *db,
|
||||
char *dir)
|
||||
{
|
||||
int retval = -1;
|
||||
|
|
@ -322,7 +303,6 @@ config_snapshot(clicon_handle h,
|
|||
int i;
|
||||
FILE *f = NULL;
|
||||
cxobj *xn;
|
||||
yang_spec *yspec = clicon_dbspec_yang(h);
|
||||
|
||||
if (stat(dir, &st) < 0){
|
||||
clicon_err(OE_CFG, errno, "%s: stat(%s): %s\n",
|
||||
|
|
@ -354,7 +334,7 @@ config_snapshot(clicon_handle h,
|
|||
clicon_err(OE_CFG, errno, "Creating file %s", filename0);
|
||||
return -1;
|
||||
}
|
||||
if (xmldb_get(dbname, "/", yspec, &xn) < 0)
|
||||
if (xmldb_get(h, db, "/", 0, &xn, NULL, NULL) < 0)
|
||||
goto done;
|
||||
if (clicon_xml2file(f, xn, 0, 1) < 0)
|
||||
goto done;
|
||||
|
|
@ -389,7 +369,6 @@ from_client_save(clicon_handle h,
|
|||
uint32_t snapshot;
|
||||
FILE *f = NULL;
|
||||
cxobj *xn = NULL;
|
||||
yang_spec *yspec;
|
||||
|
||||
if (clicon_msg_save_decode(msg,
|
||||
&db,
|
||||
|
|
@ -400,6 +379,10 @@ from_client_save(clicon_handle h,
|
|||
clicon_err_reason);
|
||||
goto done;
|
||||
}
|
||||
if (strcmp(db, "running") != 0 && strcmp(db, "candidate") != 0){
|
||||
clicon_err(OE_XML, 0, "Expected running or candidate, got %s", db);
|
||||
goto done;
|
||||
}
|
||||
if (snapshot){
|
||||
if ((archive_dir = clicon_archive_dir(h)) == NULL){
|
||||
clicon_err(OE_PLUGIN, 0, "snapshot set and clicon_archive_dir not defined");
|
||||
|
|
@ -417,8 +400,7 @@ from_client_save(clicon_handle h,
|
|||
clicon_err(OE_CFG, errno, "Creating file %s", filename);
|
||||
return -1;
|
||||
}
|
||||
yspec = clicon_dbspec_yang(h);
|
||||
if (xmldb_get(db, "/", yspec, &xn) < 0)
|
||||
if (xmldb_get(h, db, "/", 0, &xn, NULL, NULL) < 0)
|
||||
goto done;
|
||||
if (clicon_xml2file(f, xn, 0, 1) < 0)
|
||||
goto done;
|
||||
|
|
@ -453,40 +435,41 @@ from_client_load(clicon_handle h,
|
|||
{
|
||||
char *filename = NULL;
|
||||
int retval = -1;
|
||||
char *dbname = NULL;
|
||||
char *db = NULL;
|
||||
int replace = 0;
|
||||
char *candidate_db;
|
||||
int fd = -1;
|
||||
cxobj *xt = NULL;
|
||||
cxobj *xn;
|
||||
yang_spec *yspec;
|
||||
int piddb;
|
||||
|
||||
if (clicon_msg_load_decode(msg,
|
||||
&replace,
|
||||
&dbname,
|
||||
&db,
|
||||
&filename,
|
||||
label) < 0){
|
||||
send_msg_err(s, clicon_errno, clicon_suberrno,
|
||||
clicon_err_reason);
|
||||
goto done;
|
||||
}
|
||||
if ((candidate_db = clicon_candidate_db(h)) == NULL){
|
||||
send_msg_err(s, 0, 0, "candidate db not set");
|
||||
if (strcmp(db, "running") != 0 && strcmp(db, "candidate") != 0){
|
||||
clicon_err(OE_XML, 0, "Expected running or candidate, got %s", db);
|
||||
goto done;
|
||||
}
|
||||
/* candidate is locked by other client */
|
||||
if (strcmp(dbname, candidate_db) == 0 &&
|
||||
db_islocked(h) &&
|
||||
pid != db_islocked(h)){
|
||||
send_msg_err(s, OE_DB, 0, "lock failed: locked by %d", db_islocked(h));
|
||||
goto done;
|
||||
if (strcmp(db, "candidate") == 0){
|
||||
piddb = xmldb_islocked(h, db);
|
||||
if (piddb && pid != piddb){
|
||||
send_msg_err(s, OE_DB, 0,
|
||||
"lock failed: locked by %d", piddb);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (replace){
|
||||
if (unlink(dbname) < 0){
|
||||
if (xmldb_delete(h, db) < 0){
|
||||
send_msg_err(s, OE_UNIX, 0, "rm %s %s", filename, strerror(errno));
|
||||
goto done;
|
||||
}
|
||||
if (xmldb_init(dbname) < 0)
|
||||
if (xmldb_init(h, db) < 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
|
@ -501,9 +484,8 @@ from_client_load(clicon_handle h,
|
|||
clicon_err_reason);
|
||||
goto done;
|
||||
}
|
||||
yspec = clicon_dbspec_yang(h);
|
||||
if ((xn = xml_child_i(xt, 0)) != NULL){
|
||||
if (xmldb_put(dbname, xn, yspec, replace?OP_REPLACE:OP_MERGE) < 0){
|
||||
if (xmldb_put(h, db, xn, replace?OP_REPLACE:OP_MERGE) < 0){
|
||||
send_msg_err(s, clicon_errno, clicon_suberrno,
|
||||
clicon_err_reason);
|
||||
goto done;
|
||||
|
|
@ -520,270 +502,6 @@ from_client_load(clicon_handle h,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*! Internal message: Initialize database
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] s Socket where request arrived, and where replies are sent
|
||||
* @param[in] pid Unix process id
|
||||
* @param[in] msg Message
|
||||
* @param[in] label Memory chunk
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error. Send error message back to client.
|
||||
*/
|
||||
static int
|
||||
from_client_initdb(clicon_handle h,
|
||||
int s,
|
||||
int pid,
|
||||
struct clicon_msg *msg,
|
||||
const char *label)
|
||||
{
|
||||
char *filename1;
|
||||
int retval = -1;
|
||||
char *candidate_db;
|
||||
|
||||
if (clicon_msg_initdb_decode(msg,
|
||||
&filename1,
|
||||
label) < 0){
|
||||
send_msg_err(s, clicon_errno, clicon_suberrno,
|
||||
clicon_err_reason);
|
||||
goto done;
|
||||
}
|
||||
if ((candidate_db = clicon_candidate_db(h)) == NULL){
|
||||
send_msg_err(s, 0, 0, "candidate db not set");
|
||||
goto done;
|
||||
}
|
||||
/* candidate is locked by other client */
|
||||
if (strcmp(filename1, candidate_db) == 0 &&
|
||||
db_islocked(h) &&
|
||||
pid != db_islocked(h)){
|
||||
send_msg_err(s, OE_DB, 0, "lock failed: locked by %d", db_islocked(h));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (xmldb_init(filename1) < 0)
|
||||
goto done;
|
||||
/* Change mode if shared candidate. XXXX full rights for all is no good */
|
||||
if (strcmp(filename1, candidate_db) == 0)
|
||||
chmod(filename1, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
|
||||
|
||||
if (send_msg_ok(s) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Internal message: Remove file
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] s Socket where request arrived, and where replies are sent
|
||||
* @param[in] pid Unix process id
|
||||
* @param[in] msg Message
|
||||
* @param[in] label Memory chunk
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error. Send error message back to client.
|
||||
*/
|
||||
static int
|
||||
from_client_rm(clicon_handle h,
|
||||
int s,
|
||||
int pid,
|
||||
struct clicon_msg *msg,
|
||||
const char *label)
|
||||
{
|
||||
char *filename1;
|
||||
int retval = -1;
|
||||
char *candidate_db;
|
||||
|
||||
if (clicon_msg_rm_decode(msg,
|
||||
&filename1,
|
||||
label) < 0){
|
||||
send_msg_err(s, clicon_errno, clicon_suberrno,
|
||||
clicon_err_reason);
|
||||
goto done;
|
||||
}
|
||||
if ((candidate_db = clicon_candidate_db(h)) == NULL){
|
||||
send_msg_err(s, 0, 0, "candidate db not set");
|
||||
goto done;
|
||||
}
|
||||
/* candidate is locked by other client */
|
||||
if (strcmp(filename1, candidate_db) == 0 &&
|
||||
db_islocked(h) &&
|
||||
pid != db_islocked(h)){
|
||||
send_msg_err(s, OE_DB, 0, "lock failed: locked by %d", db_islocked(h));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (unlink(filename1) < 0){
|
||||
send_msg_err(s, OE_UNIX, 0, "rm %s %s", filename1, strerror(errno));
|
||||
goto done;
|
||||
}
|
||||
if (send_msg_ok(s) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Internal message: Copy file from file1 to file2
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] s Socket where request arrived, and where replies are sent
|
||||
* @param[in] pid Unix process id
|
||||
* @param[in] msg Message
|
||||
* @param[in] label Memory chunk
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error. Send error message back to client.
|
||||
*/
|
||||
static int
|
||||
from_client_copy(clicon_handle h,
|
||||
int s,
|
||||
int pid,
|
||||
struct clicon_msg *msg,
|
||||
const char *label)
|
||||
{
|
||||
char *filename1;
|
||||
char *filename2;
|
||||
int retval = -1;
|
||||
char *candidate_db;
|
||||
|
||||
if (clicon_msg_copy_decode(msg,
|
||||
&filename1,
|
||||
&filename2,
|
||||
label) < 0){
|
||||
send_msg_err(s, clicon_errno, clicon_suberrno,
|
||||
clicon_err_reason);
|
||||
goto done;
|
||||
}
|
||||
if ((candidate_db = clicon_candidate_db(h)) == NULL){
|
||||
send_msg_err(s, 0, 0, "candidate db not set");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* candidate is locked by other client */
|
||||
if (strcmp(filename2, candidate_db) == 0 &&
|
||||
db_islocked(h) &&
|
||||
pid != db_islocked(h)){
|
||||
send_msg_err(s, OE_DB, 0, "lock failed: locked by %d", db_islocked(h));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (file_cp(filename1, filename2) < 0){
|
||||
send_msg_err(s, OE_UNIX, errno, "copy %s to %s", filename1, filename2);
|
||||
goto done;
|
||||
}
|
||||
/* Change mode if shared candidate. XXXX full rights for all is no good */
|
||||
if (strcmp(filename2, candidate_db) == 0)
|
||||
chmod(filename2, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
|
||||
if (send_msg_ok(s) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Internal message: Lock database
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] s Client socket where request arrived, and where replies are sent
|
||||
* @param[in] pid Client unix process id
|
||||
* @param[in] msg Message
|
||||
* @param[in] label Memory chunk
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error. Send error message back to client.
|
||||
*/
|
||||
static int
|
||||
from_client_lock(clicon_handle h,
|
||||
int s,
|
||||
int pid,
|
||||
struct clicon_msg *msg,
|
||||
const char *label)
|
||||
{
|
||||
char *db;
|
||||
int retval = -1;
|
||||
char *candidate_db;
|
||||
|
||||
|
||||
if (clicon_msg_lock_decode(msg,
|
||||
&db,
|
||||
label) < 0){
|
||||
send_msg_err(s, clicon_errno, clicon_suberrno,
|
||||
clicon_err_reason);
|
||||
goto done;
|
||||
}
|
||||
if ((candidate_db = clicon_candidate_db(h)) == NULL){
|
||||
send_msg_err(s, 0, 0, "candidate db not set");
|
||||
goto done;
|
||||
}
|
||||
if (strcmp(db, candidate_db)){
|
||||
send_msg_err(s, OE_DB, 0, "can not lock %s, only %s",
|
||||
db, candidate_db);
|
||||
goto done;
|
||||
}
|
||||
if (db_islocked(h)){
|
||||
if (pid == db_islocked(h))
|
||||
;
|
||||
else{
|
||||
send_msg_err(s, OE_DB, 0, "lock failed: locked by %d", db_islocked(h));
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else
|
||||
db_lock(h, pid);
|
||||
if (send_msg_ok(s) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Internal message: Unlock database
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] s Client socket where request arrived, and where replies are sent
|
||||
* @param[in] pid Client unix process id
|
||||
* @param[in] msg Message
|
||||
* @param[in] label Memory chunk
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error. Send error message back to client.
|
||||
*/
|
||||
static int
|
||||
from_client_unlock(clicon_handle h,
|
||||
int s,
|
||||
int pid,
|
||||
struct clicon_msg *msg,
|
||||
const char *label)
|
||||
{
|
||||
char *db;
|
||||
int retval = -1;
|
||||
char *candidate_db;
|
||||
|
||||
if (clicon_msg_unlock_decode(msg,
|
||||
&db,
|
||||
label) < 0){
|
||||
send_msg_err(s, clicon_errno, clicon_suberrno,
|
||||
clicon_err_reason);
|
||||
goto done;
|
||||
}
|
||||
if ((candidate_db = clicon_candidate_db(h)) == NULL){
|
||||
send_msg_err(s, 0, 0, "candidate db not set");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (strcmp(db, candidate_db)){
|
||||
send_msg_err(s, OE_DB, 0, "can not unlock %s, only %s",
|
||||
db, clicon_candidate_db(h));
|
||||
goto done;
|
||||
}
|
||||
if (db_islocked(h)){
|
||||
if (pid == db_islocked(h))
|
||||
db_unlock(h);
|
||||
else{
|
||||
send_msg_err(s, OE_DB, 0, "unlock failed: locked by %d", db_islocked(h));
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (send_msg_ok(s) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Internal message: Kill session (Kill the process)
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] s Client socket where request arrived, and where replies are sent
|
||||
|
|
@ -798,9 +516,10 @@ from_client_kill(clicon_handle h,
|
|||
struct clicon_msg *msg,
|
||||
const char *label)
|
||||
{
|
||||
uint32_t pid; /* other pid */
|
||||
int retval = -1;
|
||||
int retval = -1;
|
||||
uint32_t pid; /* other pid */
|
||||
struct client_entry *ce;
|
||||
char *db = "running"; /* XXX */
|
||||
|
||||
if (clicon_msg_kill_decode(msg,
|
||||
&pid,
|
||||
|
|
@ -823,8 +542,8 @@ from_client_kill(clicon_handle h,
|
|||
}
|
||||
if (1 || (kill (pid, 0) != 0 && errno == ESRCH)){ /* Nothing there */
|
||||
/* clear from locks */
|
||||
if (db_islocked(h) == pid)
|
||||
db_unlock(h);
|
||||
if (xmldb_islocked(h, db) == pid)
|
||||
xmldb_unlock(h, db, pid);
|
||||
}
|
||||
else{ /* failed to kill client */
|
||||
send_msg_err(s, OE_DB, 0, "failed to kill %d", pid);
|
||||
|
|
@ -1017,26 +736,6 @@ from_client(int s, void* arg)
|
|||
if (from_client_load(h, ce->ce_s, ce->ce_pid, msg, __FUNCTION__) < 0)
|
||||
goto done;
|
||||
break;
|
||||
case CLICON_MSG_RM:
|
||||
if (from_client_rm(h, ce->ce_s, ce->ce_pid, msg, __FUNCTION__) < 0)
|
||||
goto done;
|
||||
break;
|
||||
case CLICON_MSG_INITDB:
|
||||
if (from_client_initdb(h, ce->ce_s, ce->ce_pid, msg, __FUNCTION__) < 0)
|
||||
goto done;
|
||||
break;
|
||||
case CLICON_MSG_COPY:
|
||||
if (from_client_copy(h, ce->ce_s, ce->ce_pid, msg, __FUNCTION__) < 0)
|
||||
goto done;
|
||||
break;
|
||||
case CLICON_MSG_LOCK:
|
||||
if (from_client_lock(h, ce->ce_s, ce->ce_pid, msg, __FUNCTION__) < 0)
|
||||
goto done;
|
||||
break;
|
||||
case CLICON_MSG_UNLOCK:
|
||||
if (from_client_unlock(h, ce->ce_s, ce->ce_pid, msg, __FUNCTION__) < 0)
|
||||
goto done;
|
||||
break;
|
||||
case CLICON_MSG_KILL:
|
||||
if (from_client_kill(h, ce->ce_s, msg, __FUNCTION__) < 0)
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -117,18 +117,14 @@ generic_validate(yang_spec *yspec,
|
|||
* fails, we just ignore the errors and proceed. Maybe we should
|
||||
* do something more drastic?
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] running The current database. The original backend state
|
||||
* @param[in] candidate: The candidate database. The wanted backend state
|
||||
*/
|
||||
int
|
||||
candidate_commit(clicon_handle h,
|
||||
char *candidate,
|
||||
char *running)
|
||||
char *candidate)
|
||||
{
|
||||
int retval = -1;
|
||||
int i;
|
||||
cxobj *xn;
|
||||
struct stat sb;
|
||||
void *firsterr = NULL;
|
||||
yang_spec *yspec;
|
||||
transaction_data_t *td = NULL;
|
||||
|
|
@ -137,24 +133,15 @@ candidate_commit(clicon_handle h,
|
|||
clicon_err(OE_FATAL, 0, "No DB_SPEC");
|
||||
goto done;
|
||||
}
|
||||
/* Sanity checks that databases exists. */
|
||||
if (stat(running, &sb) < 0){
|
||||
clicon_err(OE_DB, errno, "%s", running);
|
||||
goto done;
|
||||
}
|
||||
if (stat(candidate, &sb) < 0){
|
||||
clicon_err(OE_DB, errno, "%s", candidate);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* 1. Start transaction */
|
||||
if ((td = transaction_new()) == NULL)
|
||||
goto done;
|
||||
|
||||
/* 2. Parse xml trees */
|
||||
if (xmldb_get(running, "/", yspec, &td->td_src) < 0)
|
||||
if (xmldb_get(h, "running", "/", 0, &td->td_src, NULL, NULL) < 0)
|
||||
goto done;
|
||||
if (xmldb_get(candidate, "/", yspec, &td->td_target) < 0)
|
||||
if (xmldb_get(h, candidate, "/", 0, &td->td_target, NULL, NULL) < 0)
|
||||
goto done;
|
||||
|
||||
/* 3. Compute differences */
|
||||
|
|
@ -212,18 +199,15 @@ candidate_commit(clicon_handle h,
|
|||
goto done;
|
||||
|
||||
/* 8. Success: Copy candidate to running */
|
||||
if (file_cp(candidate, running) < 0){
|
||||
clicon_err(OE_UNIX, errno, "file_cp(candidate; running)");
|
||||
if (xmldb_copy(h, candidate, "running") < 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* 9. Call plugin transaction end callbacks */
|
||||
plugin_transaction_end(h, td);
|
||||
|
||||
/* 8. Copy running back to running in case end functions updated running */
|
||||
if (file_cp(running, candidate) < 0){
|
||||
/* 8. Copy running back to candidate in case end functions updated running */
|
||||
if (xmldb_copy(h, "running", candidate) < 0){
|
||||
/* ignore errors or signal major setback ? */
|
||||
clicon_err(OE_UNIX, errno, "file_cp(running, candidate)");
|
||||
clicon_log(LOG_NOTICE, "Error in rollback, trying to continue");
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -243,16 +227,13 @@ candidate_commit(clicon_handle h,
|
|||
/*! Do a diff between candidate and running, then start a validate transaction
|
||||
*
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] running The current database. The original backend state
|
||||
* @param[in] candidate: The candidate database. The wanted backend state
|
||||
*/
|
||||
int
|
||||
candidate_validate(clicon_handle h,
|
||||
char *candidate,
|
||||
char *running)
|
||||
{
|
||||
char *candidate)
|
||||
{
|
||||
int retval = -1;
|
||||
struct stat sb;
|
||||
yang_spec *yspec;
|
||||
transaction_data_t *td = NULL;
|
||||
int i;
|
||||
|
|
@ -262,24 +243,15 @@ candidate_validate(clicon_handle h,
|
|||
clicon_err(OE_FATAL, 0, "No DB_SPEC");
|
||||
goto done;
|
||||
}
|
||||
/* Sanity checks that databases exists. */
|
||||
if (stat(running, &sb) < 0){
|
||||
clicon_err(OE_DB, errno, "%s", running);
|
||||
goto done;
|
||||
}
|
||||
if (stat(candidate, &sb) < 0){
|
||||
clicon_err(OE_DB, errno, "%s", candidate);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* 1. Start transaction */
|
||||
if ((td = transaction_new()) == NULL)
|
||||
goto done;
|
||||
|
||||
/* 2. Parse xml trees */
|
||||
if (xmldb_get(running, "/", yspec, &td->td_src) < 0)
|
||||
if (xmldb_get(h, "running", "/", 0, &td->td_src, NULL, NULL) < 0)
|
||||
goto done;
|
||||
if (xmldb_get(candidate, "/", yspec, &td->td_target) < 0)
|
||||
if (xmldb_get(h, "candidate", "/", 0, &td->td_target, NULL, NULL) < 0)
|
||||
goto done;
|
||||
|
||||
/* 3. Compute differences */
|
||||
|
|
@ -346,25 +318,36 @@ candidate_validate(clicon_handle h,
|
|||
* the commit has succeeded but an error message is returned.
|
||||
*/
|
||||
int
|
||||
from_client_commit(clicon_handle h,
|
||||
int s,
|
||||
from_client_commit(clicon_handle h,
|
||||
int s,
|
||||
struct clicon_msg *msg,
|
||||
const char *label)
|
||||
const char *label)
|
||||
{
|
||||
int retval = -1;
|
||||
char *candidate;
|
||||
char *running;
|
||||
uint32_t snapshot;
|
||||
uint32_t startup;
|
||||
char *snapshot_0;
|
||||
char *archive_dir;
|
||||
char *startup_config;
|
||||
|
||||
if (clicon_msg_commit_decode(msg, &candidate, &running,
|
||||
&snapshot, &startup, label) < 0)
|
||||
if (clicon_msg_commit_decode(msg,
|
||||
&candidate,
|
||||
&running,
|
||||
&snapshot,
|
||||
&startup,
|
||||
label) < 0)
|
||||
goto err;
|
||||
|
||||
if (candidate_commit(h, candidate, running) < 0){
|
||||
if (strcmp(candidate, "candidate") && strcmp(candidate, "tmp")){
|
||||
clicon_err(OE_PLUGIN, 0, "candidate is not \"candidate\" or tmp");
|
||||
goto err;
|
||||
}
|
||||
if (strcmp(running, "running")){
|
||||
clicon_err(OE_PLUGIN, 0, "running db is not \"running\"");
|
||||
goto err;
|
||||
}
|
||||
if (candidate_commit(h, "candidate") < 0){
|
||||
clicon_debug(1, "Commit %s failed", candidate);
|
||||
retval = 0; /* We ignore errors from commit, but maybe
|
||||
we should fail on fatal errors? */
|
||||
|
|
@ -389,8 +372,7 @@ from_client_commit(clicon_handle h,
|
|||
clicon_err(OE_PLUGIN, 0, "startup set but startup_config not defined");
|
||||
goto err;
|
||||
}
|
||||
snapshot_0 = chunk_sprintf(__FUNCTION__, "%s/0", archive_dir);
|
||||
if (file_cp(snapshot_0, startup_config) < 0){
|
||||
if (clicon_file_copy("snapshot", "startup") < 0){
|
||||
clicon_err(OE_PROTO, errno, "%s: Error when creating startup",
|
||||
__FUNCTION__);
|
||||
goto err;
|
||||
|
|
@ -412,32 +394,31 @@ from_client_commit(clicon_handle h,
|
|||
|
||||
|
||||
|
||||
/*
|
||||
* Call backend plugin
|
||||
/*! Handle an incoming validate message from a client.
|
||||
*/
|
||||
int
|
||||
from_client_validate(clicon_handle h,
|
||||
int s,
|
||||
from_client_validate(clicon_handle h,
|
||||
int s,
|
||||
struct clicon_msg *msg,
|
||||
const char *label)
|
||||
const char *label)
|
||||
{
|
||||
char *dbname;
|
||||
char *running_db;
|
||||
int retval = -1;
|
||||
int retval = -1;
|
||||
char *candidate;
|
||||
|
||||
if (clicon_msg_validate_decode(msg, &dbname, label) < 0){
|
||||
if (clicon_msg_validate_decode(msg,
|
||||
&candidate,
|
||||
label) < 0){
|
||||
send_msg_err(s, clicon_errno, clicon_suberrno,
|
||||
clicon_err_reason);
|
||||
goto err;
|
||||
}
|
||||
|
||||
clicon_debug(1, "Validate %s", dbname);
|
||||
if ((running_db = clicon_running_db(h)) == NULL){
|
||||
clicon_err(OE_FATAL, 0, "running db not set");
|
||||
goto err;
|
||||
if (strcmp(candidate, "candidate") != 0 && strcmp(candidate, "tmp") != 0){
|
||||
clicon_err(OE_PLUGIN, 0, "candidate is not \"candidate\" or tmp");
|
||||
goto err;
|
||||
}
|
||||
if (candidate_validate(h, dbname, running_db) < 0){
|
||||
clicon_debug(1, "Validate %s failed", dbname);
|
||||
clicon_debug(1, "Validate %s", candidate);
|
||||
if (candidate_validate(h, candidate) < 0){
|
||||
clicon_debug(1, "Validate %s failed", candidate);
|
||||
retval = 0; /* We ignore errors from commit, but maybe
|
||||
we should fail on fatal errors? */
|
||||
goto err;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,6 @@
|
|||
*/
|
||||
int from_client_validate(clicon_handle h, int s, struct clicon_msg *msg, const char *label);
|
||||
int from_client_commit(clicon_handle h, int s, struct clicon_msg *msg, const char *label);
|
||||
int candidate_commit(clicon_handle h, char *candidate, char *running);
|
||||
int candidate_commit(clicon_handle h, char *candidate);
|
||||
|
||||
#endif /* _BACKEND_COMMIT_H_ */
|
||||
|
|
|
|||
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
*
|
||||
Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren
|
||||
|
||||
This file is part of CLIXON.
|
||||
|
||||
CLIXON is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CLIXON is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CLIXON; see the file LICENSE. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "clixon_config.h" /* generated by config & autoconf */
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <assert.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
/* cligen */
|
||||
#include <cligen/cligen.h>
|
||||
|
||||
/* clicon */
|
||||
#include <clixon/clixon.h>
|
||||
|
||||
#include "backend_lock.h"
|
||||
|
||||
/*
|
||||
* Easy way out: store an integer for candidate db which contains
|
||||
* the session-id of the client holding the lock.
|
||||
* more general: any database
|
||||
* we dont make any sanity check on who is locking.
|
||||
*/
|
||||
static int _db_locked = 0;
|
||||
|
||||
/*
|
||||
* db_lock
|
||||
*/
|
||||
int
|
||||
db_lock(clicon_handle h, int id)
|
||||
{
|
||||
_db_locked = id;
|
||||
clicon_debug(1, "%s: lock db by %u", __FUNCTION__, id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* db_unlock
|
||||
*/
|
||||
int
|
||||
db_unlock(clicon_handle h)
|
||||
{
|
||||
if (!_db_locked )
|
||||
return 0;
|
||||
_db_locked = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* db_islocked
|
||||
* returns id of locker
|
||||
*/
|
||||
int
|
||||
db_islocked(clicon_handle h)
|
||||
{
|
||||
return _db_locked;
|
||||
}
|
||||
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
*
|
||||
Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren
|
||||
|
||||
This file is part of CLIXON.
|
||||
|
||||
CLIXON is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CLIXON is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CLIXON; see the file LICENSE. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Database logical lock functions.
|
||||
* Only one lock (candidate_db)
|
||||
* Not persistent (needs another db)
|
||||
*/
|
||||
|
||||
#ifndef _BACKEND_LOCK_H_
|
||||
#define _BACKEND_LOCK_H_
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
int db_lock(clicon_handle h, int id);
|
||||
int db_unlock(clicon_handle h);
|
||||
int db_islocked(clicon_handle h);
|
||||
|
||||
#endif /* _BACKEND_LOCK_H_ */
|
||||
|
|
@ -59,9 +59,9 @@
|
|||
#include "backend_handle.h"
|
||||
|
||||
/* Command line options to be passed to getopt(3) */
|
||||
#define BACKEND_OPTS "hD:f:d:Fzu:P:1IRCc::rg:pt"
|
||||
#define BACKEND_OPTS "hD:f:d:Fzu:P:1IRCc::rg:ptx:"
|
||||
|
||||
/* Cannot use h after this */
|
||||
/*! Terminate. Cannot use h after this */
|
||||
static int
|
||||
config_terminate(clicon_handle h)
|
||||
{
|
||||
|
|
@ -85,10 +85,8 @@ config_terminate(clicon_handle h)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
config_sig_term
|
||||
Unlink pidfile and quit
|
||||
*/
|
||||
/*! Unlink pidfile and quit
|
||||
*/
|
||||
static void
|
||||
config_sig_term(int arg)
|
||||
{
|
||||
|
|
@ -130,7 +128,8 @@ usage(char *argv0, clicon_handle h)
|
|||
" -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"
|
||||
" -g <group>\tClient membership required to this group (default: %s)\n",
|
||||
" -g <group>\tClient membership required to this group (default: %s)\n"
|
||||
" -x <status>\tSet CLICON_XMLDB_RPC to 0 or 1.\n",
|
||||
argv0,
|
||||
plgdir ? plgdir : "none",
|
||||
confsock ? confsock : "none",
|
||||
|
|
@ -138,19 +137,16 @@ usage(char *argv0, clicon_handle h)
|
|||
startup ? startup : "none",
|
||||
group ? group : "none"
|
||||
);
|
||||
exit(0);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
static int
|
||||
rundb_init(clicon_handle h, char *running_db)
|
||||
rundb_init(clicon_handle h)
|
||||
{
|
||||
if (unlink(running_db) != 0 && errno != ENOENT) {
|
||||
clicon_err(OE_UNIX, errno, "unlink");
|
||||
if (xmldb_delete(h, "running") != 0 && errno != ENOENT)
|
||||
return -1;
|
||||
}
|
||||
if (xmldb_init(running_db) < 0)
|
||||
if (xmldb_init(h, "running") < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -164,19 +160,16 @@ rundb_init(clicon_handle h, char *running_db)
|
|||
*/
|
||||
static int
|
||||
rundb_main(clicon_handle h,
|
||||
char *app_config_file,
|
||||
char *running_db)
|
||||
char *app_config_file)
|
||||
{
|
||||
char *tmp = NULL;
|
||||
int retval = -1;
|
||||
int fd = -1;
|
||||
yang_spec *yspec;
|
||||
cxobj *xt = NULL;
|
||||
cxobj *xn;
|
||||
|
||||
if ((tmp = clicon_tmpfile(__FUNCTION__)) == NULL)
|
||||
if (xmldb_init(h, "tmp") < 0)
|
||||
goto done;
|
||||
if (file_cp(running_db, tmp) < 0){
|
||||
if (xmldb_copy(h, "running", "tmp") < 0){
|
||||
clicon_err(OE_UNIX, errno, "file copy");
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -186,16 +179,15 @@ rundb_main(clicon_handle h,
|
|||
}
|
||||
if (clicon_xml_parse_file(fd, &xt, "</clicon>") < 0)
|
||||
goto done;
|
||||
yspec = clicon_dbspec_yang(h);
|
||||
if ((xn = xml_child_i(xt, 0)) != NULL)
|
||||
if (xmldb_put(tmp, xn, yspec, OP_MERGE) < 0)
|
||||
if (xmldb_put(h, "tmp", xn, OP_MERGE) < 0)
|
||||
goto done;
|
||||
if (candidate_commit(h, tmp, running_db) < 0)
|
||||
if (candidate_commit(h, "tmp") < 0)
|
||||
goto done;
|
||||
if (xmldb_delete(h, "tmp") < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
if (tmp)
|
||||
unlink(tmp);
|
||||
if (xt)
|
||||
xml_free(xt);
|
||||
if (fd != -1)
|
||||
|
|
@ -204,31 +196,24 @@ done:
|
|||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
candb_reset(clicon_handle h, char *running_db)
|
||||
candb_reset(clicon_handle h)
|
||||
{
|
||||
int retval = -1;
|
||||
char *tmp = NULL;
|
||||
|
||||
if ((tmp = clicon_tmpfile(__FUNCTION__)) == NULL)
|
||||
goto done;
|
||||
if (file_cp(running_db, tmp) < 0){
|
||||
if (xmldb_copy(h, "running", "tmp") < 0){
|
||||
clicon_err(OE_UNIX, errno, "file copy");
|
||||
goto done;
|
||||
}
|
||||
/* Request plugins to reset system state, eg initiate running from system
|
||||
* -R
|
||||
*/
|
||||
if (plugin_reset_state(h, tmp) < 0)
|
||||
if (plugin_reset_state(h, "tmp") < 0)
|
||||
goto done;
|
||||
if (candidate_commit(h, tmp, running_db) < 0)
|
||||
if (candidate_commit(h, "tmp") < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
if (tmp)
|
||||
unlink(tmp);
|
||||
unchunk_group(__FUNCTION__);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -299,8 +284,6 @@ main(int argc, char **argv)
|
|||
int foreground;
|
||||
int once;
|
||||
int init_rundb;
|
||||
char *running_db;
|
||||
char *candidate_db;
|
||||
int reload_running;
|
||||
int reset_state_running;
|
||||
int reset_state_candidate;
|
||||
|
|
@ -431,6 +414,14 @@ main(int argc, char **argv)
|
|||
case 't' : /* Print alternative dbspec format (eg if YANG, print KEY) */
|
||||
printalt++;
|
||||
break;
|
||||
case 'x' : /* set xmldb rpc on */
|
||||
{
|
||||
int i;
|
||||
if (sscanf(optarg, "%d", &i) != 1)
|
||||
usage(argv[0], h);
|
||||
clicon_option_int_set(h, "CLICON_XMLDB_RPC", i);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage(argv[0], h);
|
||||
break;
|
||||
|
|
@ -462,7 +453,7 @@ main(int argc, char **argv)
|
|||
unlink(pidfile);
|
||||
if (sockfamily==AF_UNIX && lstat(sock, &st) == 0)
|
||||
unlink(sock);
|
||||
exit(0);
|
||||
exit(0); /* OK */
|
||||
}
|
||||
else
|
||||
if (pid){
|
||||
|
|
@ -500,31 +491,21 @@ main(int argc, char **argv)
|
|||
if (yang_spec_main(h, stdout, printspec) < 0)
|
||||
goto done;
|
||||
|
||||
if ((running_db = clicon_running_db(h)) == NULL){
|
||||
clicon_err(OE_FATAL, 0, "running db not set");
|
||||
goto done;
|
||||
}
|
||||
if ((candidate_db = clicon_candidate_db(h)) == NULL){
|
||||
clicon_err(OE_FATAL, 0, "candidate db not set");
|
||||
goto done;
|
||||
}
|
||||
/* If running exists and reload_running set, make a copy to candidate */
|
||||
if (reload_running){
|
||||
if (stat(running_db, &st) && errno == ENOENT){
|
||||
if (xmldb_exists(h, "running") != 1){
|
||||
clicon_log(LOG_NOTICE, "%s: -r (reload running) option given but no running_db found, proceeding without", __PROGRAM__);
|
||||
reload_running = 0; /* void it, so we dont commit candidate below */
|
||||
}
|
||||
else
|
||||
if (file_cp(running_db, candidate_db) < 0){
|
||||
clicon_err(OE_UNIX, errno, "FATAL: file_cp");
|
||||
if (xmldb_copy(h, "running", "candidate") < 0)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
/* Init running db
|
||||
* -I
|
||||
* -I or if it isnt there
|
||||
*/
|
||||
if (init_rundb || (stat(running_db, &st) && errno == ENOENT))
|
||||
if (rundb_init(h, running_db) < 0)
|
||||
if (init_rundb || xmldb_exists(h, "running") != 1)
|
||||
if (rundb_init(h) < 0)
|
||||
goto done;
|
||||
|
||||
/* Initialize plugins
|
||||
|
|
@ -533,12 +514,12 @@ main(int argc, char **argv)
|
|||
goto done;
|
||||
|
||||
if (reset_state_candidate){
|
||||
if (candb_reset(h, running_db) < 0)
|
||||
if (candb_reset(h) < 0)
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
if (reset_state_running){
|
||||
if (plugin_reset_state(h, running_db) < 0)
|
||||
if (plugin_reset_state(h, "running") < 0)
|
||||
goto done;
|
||||
}
|
||||
/* Call plugin_start */
|
||||
|
|
@ -549,7 +530,7 @@ main(int argc, char **argv)
|
|||
*(argv-1) = tmp;
|
||||
|
||||
if (reload_running){
|
||||
if (candidate_commit(h, candidate_db, running_db) < 0)
|
||||
if (candidate_commit(h, "candidate") < 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
|
@ -558,17 +539,16 @@ main(int argc, char **argv)
|
|||
-r replace running (obsolete)
|
||||
*/
|
||||
if (app_config_file)
|
||||
if (rundb_main(h, app_config_file, running_db) < 0)
|
||||
if (rundb_main(h, app_config_file) < 0)
|
||||
goto done;
|
||||
|
||||
/* Initiate the shared candidate. Maybe we should not do this? */
|
||||
if (file_cp(running_db, candidate_db) < 0){
|
||||
clicon_err(OE_UNIX, errno, "FATAL: file_cp");
|
||||
if (xmldb_copy(h, "running", "candidate") < 0)
|
||||
goto done;
|
||||
}
|
||||
#ifdef OBSOLETE
|
||||
/* XXX Hack for now. Change mode so that we all can write. Security issue*/
|
||||
chmod(candidate_db, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
|
||||
|
||||
#endif
|
||||
if (once)
|
||||
goto done;
|
||||
|
||||
|
|
@ -579,7 +559,7 @@ main(int argc, char **argv)
|
|||
clicon_log_init(__PROGRAM__, debug?LOG_DEBUG:LOG_INFO, CLICON_LOG_SYSLOG);
|
||||
if (daemon(0, 0) < 0){
|
||||
fprintf(stderr, "config: daemon");
|
||||
exit(0);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
/* Write pid-file */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue