CliXoN
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
Functions | Variables
clixon_xml_db.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <limits.h>
#include <fnmatch.h>
#include <stdint.h>
#include <sys/stat.h>
#include <dirent.h>
#include <assert.h>
#include <syslog.h>
#include <curl/curl.h>
#include <cligen/cligen.h>
#include "clixon_err.h"
#include "clixon_log.h"
#include "clixon_file.h"
#include "clixon_queue.h"
#include "clixon_string.h"
#include "clixon_chunk.h"
#include "clixon_hash.h"
#include "clixon_handle.h"
#include "clixon_qdb.h"
#include "clixon_yang.h"
#include "clixon_xml.h"
#include "clixon_options.h"
#include "clixon_xsl.h"
#include "clixon_xml_parse.h"
#include "clixon_xml_db.h"

Functions

static int yang2xmlkeyfmt_1 (yang_stmt *ys, int inclkey, cbuf *cb)
 
int yang2xmlkeyfmt (yang_stmt *ys, int inclkey, char **xkfmt)
 
int xmlkeyfmt2key (char *xkfmt, cvec *cvv, char **xk)
 
int xmlkeyfmt2xpath (char *xkfmt, cvec *cvv, char **xk)
 
static int db_lock (char *db, int pid)
 
static int db_unlock (char *db)
 
static int db_unlock_all (int pid)
 
static int db_islocked (char *db)
 
static int db2file (clicon_handle h, char *db, char **filename)
 
static int append_listkeys (cbuf *ckey, cxobj *xt, yang_stmt *ys)
 
static int create_keyvalues (cxobj *x, yang_stmt *ykey, char *arg, char *keyname)
 
static int xml_tree_prune_unmarked (cxobj *xt, int *upmark)
 
static int get (char *dbname, yang_spec *ys, char *xk, char *val, cxobj *xt)
 
static int xml_sanity (cxobj *x, void *arg)
 
static int xml_default (cxobj *x, void *arg)
 
static int xml_order (cxobj *x, void *arg)
 
int xmldb_get (clicon_handle h, char *db, char *xpath, cxobj **xtop, cxobj ***xvec0, size_t *xlen0)
 
static int put (char *dbname, cxobj *xt, yang_stmt *ys, enum operation_type op, const char *xk0)
 
static int xmldb_put_xkey (clicon_handle h, char *db, enum operation_type op, char *xk, char *val)
 
static int xmldb_put_restconf_api_path (clicon_handle h, char *db, enum operation_type op, char *api_path, cxobj *xt)
 
int xmldb_put (clicon_handle h, char *db, enum operation_type op, char *api_path, cxobj *xt)
 
int xmldb_dump (FILE *f, char *dbfilename, char *rxkey)
 
int xmldb_copy (clicon_handle h, char *from, char *to)
 
int xmldb_lock (clicon_handle h, char *db, int pid)
 
int xmldb_unlock (clicon_handle h, char *db, int pid)
 
int xmldb_unlock_all (clicon_handle h, int pid)
 
int xmldb_islocked (clicon_handle h, char *db)
 
int xmldb_exists (clicon_handle h, char *db)
 
int xmldb_delete (clicon_handle h, char *db)
 
int xmldb_init (clicon_handle h, char *db)
 

Variables

static int _running_locked = 0
 
static int _candidate_locked = 0
 
static int _startup_locked = 0
 

Function Documentation

static int append_listkeys ( cbuf *  ckey,
cxobj *  xt,
yang_stmt *  ys 
)
static

Help function to append key values from an xml list to a cbuf Example, a yang node x with keys a and b results in "x/a/b"

static int create_keyvalues ( cxobj *  x,
yang_stmt *  ykey,
char *  arg,
char *  keyname 
)
static

Help function to create xml key values

Parameters
[in,out]xParent
[in]ykey
[in]arg
[in]keynameyang key name
static int db2file ( clicon_handle  h,
char *  db,
char **  filename 
)
static

Translate from symbolic database name to actual filename in file-system

Parameters
[in]hClicon handle
[in]dbSymbolic database name, eg "candidate", "running"
[out]filenameFilename. Unallocate after use with free()
Return values
0OK
-1Error
Note
Could need a way to extend which databases exists, eg to register new. The currently allowed databases are: candidate, tmp, running, result The filename reside in CLICON_XMLDB_DIR option
static int db_islocked ( char *  db)
static

returns id of locker

Return values
0Not locked
>0Id of locker
static int db_lock ( char *  db,
int  pid 
)
static

Lock database

Parameters
[in]dbDatabase name
[in]pidprocess/session-id
static int db_unlock ( char *  db)
static

Unlock database

Parameters
[in]dbDatabase name
static int db_unlock_all ( int  pid)
static

Unlock all databases locked by pid (eg process dies)

Parameters
[in]pidprocess/session-id
static int get ( char *  dbname,
yang_spec *  ys,
char *  xk,
char *  val,
cxobj *  xt 
)
static
Parameters
[in]xkxmlkey
[out]xtXML tree as result XXX cannot handle top-level list
static int put ( char *  dbname,
cxobj *  xt,
yang_stmt *  ys,
enum operation_type  op,
const char *  xk0 
)
static

Add data to database internal recursive function

Parameters
[in]dbnameName of database to search in (filename incl dir path)
[in]xtxml-node.
[in]ysYang statement corresponding to xml-node
[in]opOP_MERGE, OP_REPLACE, OP_REMOVE, etc
[in]xkey0aggregated xmlkey
Return values
0OK
-1Error
Note
XXX op only supports merge
static int xml_default ( cxobj *  x,
void *  arg 
)
static

Add default values (if not set)

static int xml_order ( cxobj *  x,
void *  arg 
)
static

Order XML children according to YANG

static int xml_sanity ( cxobj *  x,
void *  arg 
)
static

Sanitize an xml tree: xml node has matching yang_stmt pointer

static int xml_tree_prune_unmarked ( cxobj *  xt,
int *  upmark 
)
static

Prune everything that has not been marked

Parameters
[in]xtXML tree with some node marked
[out]upmarkSet if a child (recursively) has marked set. The function removes all branches that does not contain a marked child XXX: maybe key leafs should not be purged if list is not purged? XXX: consider move to clicon_xml
int xmldb_copy ( clicon_handle  h,
char *  from,
char *  to 
)

Copy database from db1 to db2

Parameters
[in]hClicon handle
[in]fromSource database copy
[in]toDestination database
Return values
-1Error
0OK
int xmldb_delete ( clicon_handle  h,
char *  db 
)

Delete database. Remove file

Parameters
[in]hClicon handle
[in]dbDatabase
Return values
-1Error
0OK
int xmldb_dump ( FILE *  f,
char *  dbfilename,
char *  rxkey 
)

Raw dump of database, just keys and values, no xml interpretation

Parameters
[in]fFile
[in]dbfileFile-name of database. This is a local file
[in]rxkeyKey regexp, eg "^.*$"
Note
This function can only be called locally.
int xmldb_exists ( clicon_handle  h,
char *  db 
)

Check if db exists

Parameters
[in]hClicon handle
[in]dbDatabase
Return values
-1Error
0No it does not exist
1Yes it exists
int xmldb_get ( clicon_handle  h,
char *  db,
char *  xpath,
cxobj **  xtop,
cxobj ***  xvec0,
size_t *  xlen0 
)

Get content of database using xpath. return a set of matching sub-trees The function returns a minimal tree that includes all sub-trees that match xpath.

Parameters
[in]dbnameName of database to search in (filename including dir path
[in]xpathString with XPATH syntax. or NULL for all
[in]yspecYang specification
[out]xtopSingle XML tree which xvec points to. Free with xml_free()
[out]xvecVector of xml trees. Free after use.
[out]xlenLength of vector.
Return values
0OK
-1Error
cxobj *xt;
cxobj **xvec;
size_t xlen;
yang_spec *yspec = clicon_dbspec_yang(h);
if (xmldb_get("running", "/interfaces/interface[name="eth"]",
&xt, &xvec, &xlen) < 0)
err;
for (i=0; i<xlen; i++){
xn = xv[i];
...
}
free(xvec);
Note
if xvec is given, then purge tree, if not return whole tree.
See Also
xpath_vec
xmldb_get
int xmldb_init ( clicon_handle  h,
char *  db 
)

Initialize database

Parameters
[in]hClicon handle
[in]dbDatabase
Return values
0OK
-1Error
int xmldb_islocked ( clicon_handle  h,
char *  db 
)

Check if database is locked

Parameters
[in]hClicon handle
[in]dbDatabase
Return values
-1Error
0Not locked
>0Id of locker
int xmldb_lock ( clicon_handle  h,
char *  db,
int  pid 
)

Lock database

Parameters
[in]hClicon handle
[in]dbDatabase
[in]pidProcess id
Return values
-1Error
0OK
int xmldb_put ( clicon_handle  h,
char *  db,
enum operation_type  op,
char *  api_path,
cxobj *  xt 
)

Modify database provided an xml tree and an operation

Parameters
[in]hCLICON handle
[in]dbrunning or candidate
[in]xtxml-tree. Top-level symbol is dummy
[in]opOP_MERGE: just add it. OP_REPLACE: first delete whole database OP_NONE: operation attribute in xml determines operation
[in]api_pathAccording to restconf (Sec 3.5.1.1 in [restconf-draft 13])
Return values
0OK
-1Error The xml may contain the "operation" attribute which defines the operation.
cxobj *xt;
if (clicon_xml_parse_str("<a>17</a>", &xt) < 0)
err;
if (xmldb_put(h, "running", OP_MERGE, NULL, xt) < 0)
err;
See Also
xmldb_put_xkey for single key
static int xmldb_put_restconf_api_path ( clicon_handle  h,
char *  db,
enum operation_type  op,
char *  api_path,
cxobj *  xt 
)
static

Modify database provided an xml tree, a restconf api_path and an operation

Parameters
[in]hCLICON handle
[in]dbrunning or candidate
[in]opOP_MERGE: just add it. OP_REPLACE: first delete whole database OP_NONE: operation attribute in xml determines operation
[in]api_pathAccording to restconf (Sec 3.5.1.1 in [restconf-draft 13])
[in]xtxml-tree. Top-level symbol is dummy
Return values
0OK
-1Error example: container top { list list1 { key "key1 key2 key3"; is referenced as /restconf/data/top/list1=a,,foo
See Also
xmldb_put
static int xmldb_put_xkey ( clicon_handle  h,
char *  db,
enum operation_type  op,
char *  xk,
char *  val 
)
static

Modify database provided an XML database key and an operation

Parameters
[in]hCLICON handle
[in]dbDatabase name
[in]opOP_MERGE, OP_REPLACE, OP_REMOVE, etc
[in]xkXML Key, eg /aa/bb=17/name
[in]valKey value, eg "17"
Return values
0OK
-1Error
if (xmldb_put_xkey(h, db, OP_MERGE, "/aa/bb=17/name", "17") < 0)
err;
See Also
xmldb_put with xml-tree, no path
int xmldb_unlock ( clicon_handle  h,
char *  db,
int  pid 
)

Unlock database

Parameters
[in]hClicon handle
[in]dbDatabase
[in]pidProcess id
Return values
-1Error
0OK
int xmldb_unlock_all ( clicon_handle  h,
int  pid 
)

Unlock all databases locked by pid (eg process dies)

int xmlkeyfmt2key ( char *  xkfmt,
cvec *  cvv,
char **  xk 
)

Transform an xml key format and a vector of values to an XML key Used for actual key, eg in clicon_rpc_change(), xmldb_put_xkey() Example: xmlkeyfmt: /aaa/s cvv: key=17 xmlkey: /aaa/17

Parameters
[in]xkfmtXML key format, eg /aaa/s
[in]cvvcligen variable vector, one for every wildchar in xkfmt
[out]xkXML key, eg /aaa/17. Free after use
Note
first and last elements of cvv are not used,..
See Also
cli_dbxml where this function is called
int xmlkeyfmt2xpath ( char *  xkfmt,
cvec *  cvv,
char **  xk 
)

Transform an xml key format and a vector of values to an XML path Used to input xmldb_get() or xmldb_get_vec Add .* in last s position. Example: xmlkeyfmt: /interface/s/address/s OLDXXX xmlkeyfmt: /interface=s/address=s cvv: name=eth0 xmlkey: /interface/[name=eth0]/address Example2: xmlkeyfmt: /ip/me/s (if key) cvv: - xmlkey: /ipv4/me/a

Parameters
[in]xkfmtXML key format
[in]cvvcligen variable vector, one for every wildchar in xkfmt
[out]xkXPATH
int yang2xmlkeyfmt ( yang_stmt *  ys,
int  inclkey,
char **  xkfmt 
)

Construct an xml key format from yang statement using wildcards for keys Recursively construct it to the top. Example: yang: container a -> list b -> key c -> leaf d xpath: /a/b=s/d

Parameters
[in]ysYang statement
[in]inclkeyIf !inclkey then dont include key leaf
[out]xkfmtXML key format. Needs to be freed after use.
static int yang2xmlkeyfmt_1 ( yang_stmt *  ys,
int  inclkey,
cbuf *  cb 
)
static

Construct an xml key format from yang statement using wildcards for keys Recursively construct it to the top. Example: yang: container a -> list b -> key c -> leaf d xpath: /a/b/s/d

Parameters
[in]ysYang statement
[in]inclkeyIf inclkey then include key leaf (eg last leaf d in ex)
[out]cbufkeyfmt

Variable Documentation

int _candidate_locked = 0
static
int _running_locked = 0
static

Database locking for candidate and running non-persistent Store an integer for running and candidate containing the session-id of the client holding the lock.

int _startup_locked = 0
static