This commit is contained in:
Olof hagsand 2016-03-07 20:55:55 +01:00
parent ca18b7f49e
commit 0a812696c2
47 changed files with 1818 additions and 1783 deletions

View file

@ -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;