datastore handles

This commit is contained in:
Olof hagsand 2017-04-15 19:42:35 +02:00
parent d8fa7bc033
commit 540cd96e74
21 changed files with 286 additions and 146 deletions

View file

@ -52,6 +52,7 @@
#include "clixon_handle.h"
#include "clixon_err.h"
#include "clixon_yang.h"
#include "clixon_plugin.h"
#include "clixon_options.h"
#define CLICON_MAGIC 0x99aafabe
@ -66,7 +67,6 @@ struct clicon_handle {
int ch_magic; /* magic (HDR) */
clicon_hash_t *ch_copt; /* clicon option list (HDR) */
clicon_hash_t *ch_data; /* internal clicon data (HDR) */
void *ch_xmldb; /* XMLDB storage handle, uie xmldb_handle */
};
/*! Internal call to allocate a CLICON handle.
@ -166,30 +166,3 @@ clicon_data(clicon_handle h)
return ch->ch_data;
}
/*! Set or reset XMLDB storage handle
* @param[in] h Clicon handle
* @param[in] xh XMLDB storage handle. If NULL reset it
* @note Just keep note of it, dont allocate it or so.
*/
int
clicon_handle_xmldb_set(clicon_handle h,
void *xh)
{
struct clicon_handle *ch = handle(h);
ch->ch_xmldb = xh;
return 0;
}
/*! Get XMLDB storage handle
* @param[in] h Clicon handle
* @retval xh XMLDB storage handle. If not connected return NULL
*/
void *
clicon_handle_xmldb_get(clicon_handle h)
{
struct clicon_handle *ch = handle(h);
return ch->ch_xmldb;
}

View file

@ -200,8 +200,8 @@ hash_value(clicon_hash_t *hash,
/*! Copy value and add hash entry.
*
* @param[in] hash Hash table
* @param[in] key New variable name
* @param[in] val New variable value
* @param[in] key Variable name
* @param[in] val Variable value
* @param[in] vlen Length of variable value
* @retval variable New hash structure on success
* @retval NULL Failure
@ -212,8 +212,9 @@ hash_add(clicon_hash_t *hash,
void *val,
size_t vlen)
{
void *newval;
clicon_hash_t h, new = NULL;
void *newval;
clicon_hash_t h;
clicon_hash_t new = NULL;
/* If variable exist, don't allocate a new. just replace value */
h = hash_lookup (hash, key);

View file

@ -63,6 +63,7 @@
#include "clixon_handle.h"
#include "clixon_log.h"
#include "clixon_yang.h"
#include "clixon_plugin.h"
#include "clixon_options.h"
/*
@ -625,12 +626,12 @@ clicon_dbspec_yang(clicon_handle h)
return NULL;
}
/*
* Set dbspec (YANG variant)
/*! Set yang database specification
* ys must be a malloced pointer
*/
int
clicon_dbspec_yang_set(clicon_handle h, struct yang_spec *ys)
clicon_dbspec_yang_set(clicon_handle h,
struct yang_spec *ys)
{
clicon_hash_t *cdat = clicon_data(h);
@ -642,8 +643,7 @@ clicon_dbspec_yang_set(clicon_handle h, struct yang_spec *ys)
return 0;
}
/*
* Get dbspec name as read from spec. Can be used in CLI '@' syntax.
/*! Get dbspec name as read from spec. Can be used in CLI '@' syntax.
* XXX: this we muśt change,...
*/
char *
@ -654,11 +654,103 @@ clicon_dbspec_name(clicon_handle h)
return clicon_option_str(h, "dbspec_name");
}
/*
* Set dbspec name as read from spec. Can be used in CLI '@' syntax.
/*! Set dbspec name as read from spec. Can be used in CLI '@' syntax.
*/
int
clicon_dbspec_name_set(clicon_handle h, char *name)
{
return clicon_option_str_set(h, "dbspec_name", name);
}
/*! Set xmldb datastore plugin handle, as used by dlopen/dlsym/dlclose */
int
clicon_xmldb_plugin_set(clicon_handle h,
plghndl_t handle)
{
clicon_hash_t *cdat = clicon_data(h);
if (hash_add(cdat, "xmldb_plugin", &handle, sizeof(void*)) == NULL)
return -1;
return 0;
}
/*! Get xmldb datastore plugin handle, as used by dlopen/dlsym/dlclose */
plghndl_t
clicon_xmldb_plugin_get(clicon_handle h)
{
clicon_hash_t *cdat = clicon_data(h);
size_t len;
void *p;
if ((p = hash_value(cdat, "xmldb_plugin", &len)) != NULL)
return *(plghndl_t*)p;
return NULL;
}
/*! Set or reset XMLDB API struct pointer
* @param[in] h Clicon handle
* @param[in] xa XMLDB API struct
* @note xa is really of type struct xmldb_api*
*/
int
clicon_xmldb_api_set(clicon_handle h,
void *xa)
{
clicon_hash_t *cdat = clicon_data(h);
/* It is the pointer to xa_api that should be copied by hash,
so we send a ptr to the ptr to indicate what to copy.
*/
if (hash_add(cdat, "xmldb_api", &xa, sizeof(void*)) == NULL)
return -1;
return 0;
}
/*! Get XMLDB API struct pointer
* @param[in] h Clicon handle
* @retval xa XMLDB API struct
* @note xa is really of type struct xmldb_api*
*/
void *
clicon_xmldb_api_get(clicon_handle h)
{
clicon_hash_t *cdat = clicon_data(h);
size_t len;
void *xa;
if ((xa = hash_value(cdat, "xmldb_api", &len)) != NULL)
return *(void**)xa;
return NULL;
}
/*! Set or reset XMLDB storage handle
* @param[in] h Clicon handle
* @param[in] xh XMLDB storage handle. If NULL reset it
* @note Just keep note of it, dont allocate it or so.
*/
int
clicon_xmldb_handle_set(clicon_handle h,
void *xh)
{
clicon_hash_t *cdat = clicon_data(h);
if (hash_add(cdat, "xmldb_handle", &xh, sizeof(void*)) == NULL)
return -1;
return 0;
}
/*! Get XMLDB storage handle
* @param[in] h Clicon handle
* @retval xh XMLDB storage handle. If not connected return NULL
*/
void *
clicon_xmldb_handle_get(clicon_handle h)
{
clicon_hash_t *cdat = clicon_data(h);
size_t len;
void *xh;
if ((xh = hash_value(cdat, "xmldb_handle", &len)) != NULL)
return *(void**)xh;
return NULL;
}

View file

@ -93,9 +93,9 @@ clicon_find_func(clicon_handle h, char *plugin, char *func)
* @param[in] dlflags See man(3) dlopen
*/
plghndl_t
plugin_load (clicon_handle h,
char *file,
int dlflags)
plugin_load(clicon_handle h,
char *file,
int dlflags)
{
char *error;
void *handle = NULL;

View file

@ -60,6 +60,7 @@
#include "clixon_hash.h"
#include "clixon_handle.h"
#include "clixon_yang.h"
#include "clixon_plugin.h"
#include "clixon_options.h"
#include "clixon_xml.h"
#include "clixon_xsl.h"

View file

@ -59,17 +59,15 @@
#include "clixon_handle.h"
#include "clixon_xml.h"
#include "clixon_yang.h"
#include "clixon_plugin.h"
#include "clixon_options.h"
#include "clixon_xml_db.h"
static struct xmldb_api *_xa_api = NULL;
/*! Load a specific plugin, call its init function and add it to plugins list
/*! Load an xmldb storage plugin according to filename
* If init function fails (not found, wrong version, etc) print a log and dont
* add it.
* @param[in] name Filename (complete path) of plugin
* @param[in] h CLicon handle
* @param[in] filename Actual filename with path
* @param[out] plugin Plugin data structure for invoking. Dealloc with free
*/
int
xmldb_plugin_load(clicon_handle h,
@ -78,8 +76,9 @@ xmldb_plugin_load(clicon_handle h,
int retval = -1;
char *dlerrcode;
plugin_init_t *initfun;
void *handle = NULL;
plghndl_t handle = NULL;
char *error;
struct xmldb_api *xa = NULL;
dlerror(); /* Clear any existing error */
if ((handle = dlopen(filename, RTLD_NOW|RTLD_GLOBAL)) == NULL) {
@ -94,21 +93,27 @@ xmldb_plugin_load(clicon_handle h,
XMLDB_PLUGIN_INIT_FN, dlerrcode);
goto fail;
}
if ((_xa_api = initfun(XMLDB_API_VERSION)) == NULL) {
if ((xa = initfun(XMLDB_API_VERSION)) == NULL) {
clicon_log(LOG_WARNING, "%s: failed when running init function %s: %s",
filename, XMLDB_PLUGIN_INIT_FN, errno?strerror(errno):"");
goto fail;
}
if (_xa_api->xa_version != XMLDB_API_VERSION){
if (xa->xa_version != XMLDB_API_VERSION){
clicon_log(LOG_WARNING, "%s: Unexpected plugin version number: %d",
filename, _xa_api->xa_version);
filename, xa->xa_version);
goto fail;
}
if (_xa_api->xa_magic != XMLDB_API_MAGIC){
if (xa->xa_magic != XMLDB_API_MAGIC){
clicon_log(LOG_WARNING, "%s: Wrong plugin magic number: %x",
filename, _xa_api->xa_magic);
filename, xa->xa_magic);
goto fail;
}
/* Add plugin */
if (clicon_xmldb_plugin_set(h, handle) < 0)
goto done;
/* Add API */
if (clicon_xmldb_api_set(h, xa) < 0)
goto done;
clicon_log(LOG_WARNING, "xmldb plugin %s loaded", filename);
retval = 0;
done:
@ -120,11 +125,41 @@ xmldb_plugin_load(clicon_handle h,
goto done;
}
/*! XXX: fixme */
/*! Unload the xmldb storage plugin */
int
xmldb_plugin_unload(clicon_handle h)
{
return 0;
int retval = -1;
plghndl_t handle;
struct xmldb_api *xa;
xmldb_handle xh;
char *error;
if ((handle = clicon_xmldb_plugin_get(h)) == NULL){
clicon_err(OE_PLUGIN, errno, "No plugin handle");
goto done;
}
/* If connected storage handle then disconnect */
if ((xh = clicon_xmldb_handle_get(h)) != NULL)
xmldb_disconnect(h); /* sets xmldb handle to NULL */
/* Deregister api */
if ((xa = clicon_xmldb_api_get(h)) != NULL){
/* Call plugin_exit */
if (xa->xa_plugin_exit_fn != NULL)
xa->xa_plugin_exit_fn();
/* Deregister API (it is allocated in plugin) */
clicon_xmldb_api_set(h, NULL);
}
/* Unload plugin */
dlerror(); /* Clear any existing error */
if (dlclose(handle) != 0) {
error = (char*)dlerror();
clicon_err(OE_PLUGIN, errno, "dlclose: %s\n", error ? error : "Unknown error");
/* Just report no -1 return*/
}
retval = 0;
done:
return retval;
}
/*! Connect to a datastore plugin
@ -139,21 +174,21 @@ xmldb_plugin_unload(clicon_handle h)
int
xmldb_connect(clicon_handle h)
{
int retval = -1;
xmldb_handle xh;
int retval = -1;
xmldb_handle xh;
struct xmldb_api *xa;
if (_xa_api == NULL){
if ((xa = clicon_xmldb_api_get(h)) == NULL){
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_connect_fn == NULL){
if (xa->xa_connect_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
}
if ((xh = _xa_api->xa_connect_fn()) == NULL)
if ((xh = xa->xa_connect_fn()) == NULL)
goto done;
clicon_handle_xmldb_set(h, xh);
clicon_xmldb_handle_set(h, xh);
retval = 0;
done:
return retval;
@ -168,22 +203,23 @@ xmldb_disconnect(clicon_handle h)
{
int retval = -1;
xmldb_handle xh;
struct xmldb_api *xa;
if (_xa_api == NULL){
if ((xa = clicon_xmldb_api_get(h)) == NULL){
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_disconnect_fn == NULL){
if (xa->xa_disconnect_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
}
if ((xh = clicon_handle_xmldb_get(h)) == NULL){
if ((xh = clicon_xmldb_handle_get(h)) == NULL){
clicon_err(OE_DB, 0, "Already disconnected from datastore plugin");
goto done;
}
if (_xa_api->xa_disconnect_fn(xh) < 0)
if (xa->xa_disconnect_fn(xh) < 0)
goto done;
clicon_handle_xmldb_set(h, NULL);
clicon_xmldb_handle_set(h, NULL);
retval = 0;
done:
return retval;
@ -203,20 +239,21 @@ xmldb_getopt(clicon_handle h,
{
int retval = -1;
xmldb_handle xh;
struct xmldb_api *xa;
if (_xa_api == NULL){
if ((xa = clicon_xmldb_api_get(h)) == NULL){
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_getopt_fn == NULL){
if (xa->xa_getopt_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
}
if ((xh = clicon_handle_xmldb_get(h)) == NULL){
if ((xh = clicon_xmldb_handle_get(h)) == NULL){
clicon_err(OE_DB, 0, "Not connected to datastore plugin");
goto done;
}
retval = _xa_api->xa_getopt_fn(xh, optname, value);
retval = xa->xa_getopt_fn(xh, optname, value);
done:
return retval;
}
@ -235,20 +272,21 @@ xmldb_setopt(clicon_handle h,
{
int retval = -1;
xmldb_handle xh;
struct xmldb_api *xa;
if (_xa_api == NULL){
if ((xa = clicon_xmldb_api_get(h)) == NULL){
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_setopt_fn == NULL){
if (xa->xa_setopt_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
}
if ((xh = clicon_handle_xmldb_get(h)) == NULL){
if ((xh = clicon_xmldb_handle_get(h)) == NULL){
clicon_err(OE_DB, 0, "Not connected to datastore plugin");
goto done;
}
retval = _xa_api->xa_setopt_fn(xh, optname, value);
retval = xa->xa_setopt_fn(xh, optname, value);
done:
return retval;
}
@ -293,20 +331,22 @@ xmldb_get(clicon_handle h,
{
int retval = -1;
xmldb_handle xh;
struct xmldb_api *xa;
if (_xa_api == NULL){
if ((xa = clicon_xmldb_api_get(h)) == NULL){
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_get_fn == NULL){
if (xa->xa_get_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
}
if ((xh = clicon_handle_xmldb_get(h)) == NULL){
if ((xh = clicon_xmldb_handle_get(h)) == NULL){
clicon_err(OE_DB, 0, "Not connected to datastore plugin");
goto done;
}
retval = _xa_api->xa_get_fn(xh, db, xpath, xtop, xvec, xlen);
clicon_log(LOG_WARNING, "%s: db:%s xpath:%s", __FUNCTION__, db, xpath);
retval = xa->xa_get_fn(xh, db, xpath, xtop, xvec, xlen);
done:
return retval;
}
@ -341,20 +381,30 @@ xmldb_put(clicon_handle h,
{
int retval = -1;
xmldb_handle xh;
struct xmldb_api *xa;
if (_xa_api == NULL){
if ((xa = clicon_xmldb_api_get(h)) == NULL){
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_put_fn == NULL){
if (xa->xa_put_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
}
if ((xh = clicon_handle_xmldb_get(h)) == NULL){
if ((xh = clicon_xmldb_handle_get(h)) == NULL){
clicon_err(OE_DB, 0, "Not connected to datastore plugin");
goto done;
}
retval = _xa_api->xa_put_fn(xh, db, op, api_path, xt);
{
cbuf *cb = cbuf_new();
if (clicon_xml2cbuf(cb, xt, 0, 0) < 0)
goto done;
clicon_log(LOG_WARNING, "%s: db:%s op:%d api_path:%s xml:%s", __FUNCTION__,
db, op, api_path, cbuf_get(cb));
cbuf_free(cb);
}
retval = xa->xa_put_fn(xh, db, op, api_path, xt);
done:
return retval;
}
@ -373,20 +423,21 @@ xmldb_copy(clicon_handle h,
{
int retval = -1;
xmldb_handle xh;
struct xmldb_api *xa;
if (_xa_api == NULL){
if ((xa = clicon_xmldb_api_get(h)) == NULL){
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_copy_fn == NULL){
if (xa->xa_copy_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
}
if ((xh = clicon_handle_xmldb_get(h)) == NULL){
if ((xh = clicon_xmldb_handle_get(h)) == NULL){
clicon_err(OE_DB, 0, "Not connected to datastore plugin");
goto done;
}
retval = _xa_api->xa_copy_fn(xh, from, to);
retval = xa->xa_copy_fn(xh, from, to);
done:
return retval;
}
@ -405,20 +456,21 @@ xmldb_lock(clicon_handle h,
{
int retval = -1;
xmldb_handle xh;
struct xmldb_api *xa;
if (_xa_api == NULL){
if ((xa = clicon_xmldb_api_get(h)) == NULL){
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_lock_fn == NULL){
if (xa->xa_lock_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
}
if ((xh = clicon_handle_xmldb_get(h)) == NULL){
if ((xh = clicon_xmldb_handle_get(h)) == NULL){
clicon_err(OE_DB, 0, "Not connected to datastore plugin");
goto done;
}
retval = _xa_api->xa_lock_fn(xh, db, pid);
retval = xa->xa_lock_fn(xh, db, pid);
done:
return retval;
}
@ -438,20 +490,21 @@ xmldb_unlock(clicon_handle h,
{
int retval = -1;
xmldb_handle xh;
struct xmldb_api *xa;
if (_xa_api == NULL){
if ((xa = clicon_xmldb_api_get(h)) == NULL){
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_unlock_fn == NULL){
if (xa->xa_unlock_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
}
if ((xh = clicon_handle_xmldb_get(h)) == NULL){
if ((xh = clicon_xmldb_handle_get(h)) == NULL){
clicon_err(OE_DB, 0, "Not connected to datastore plugin");
goto done;
}
retval = _xa_api->xa_unlock_fn(xh, db, pid);
retval = xa->xa_unlock_fn(xh, db, pid);
done:
return retval;
}
@ -468,20 +521,21 @@ xmldb_unlock_all(clicon_handle h,
{
int retval = -1;
xmldb_handle xh;
struct xmldb_api *xa;
if (_xa_api == NULL){
if ((xa = clicon_xmldb_api_get(h)) == NULL){
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_unlock_all_fn == NULL){
if (xa->xa_unlock_all_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
}
if ((xh = clicon_handle_xmldb_get(h)) == NULL){
if ((xh = clicon_xmldb_handle_get(h)) == NULL){
clicon_err(OE_DB, 0, "Not connected to datastore plugin");
goto done;
}
retval =_xa_api->xa_unlock_all_fn(xh, pid);
retval =xa->xa_unlock_all_fn(xh, pid);
done:
return retval;
}
@ -499,20 +553,21 @@ xmldb_islocked(clicon_handle h,
{
int retval = -1;
xmldb_handle xh;
struct xmldb_api *xa;
if (_xa_api == NULL){
if ((xa = clicon_xmldb_api_get(h)) == NULL){
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_islocked_fn == NULL){
if (xa->xa_islocked_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
}
if ((xh = clicon_handle_xmldb_get(h)) == NULL){
if ((xh = clicon_xmldb_handle_get(h)) == NULL){
clicon_err(OE_DB, 0, "Not connected to datastore plugin");
goto done;
}
retval =_xa_api->xa_islocked_fn(xh, db);
retval =xa->xa_islocked_fn(xh, db);
done:
return retval;
}
@ -530,20 +585,21 @@ xmldb_exists(clicon_handle h,
{
int retval = -1;
xmldb_handle xh;
struct xmldb_api *xa;
if (_xa_api == NULL){
if ((xa = clicon_xmldb_api_get(h)) == NULL){
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_exists_fn == NULL){
if (xa->xa_exists_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
}
if ((xh = clicon_handle_xmldb_get(h)) == NULL){
if ((xh = clicon_xmldb_handle_get(h)) == NULL){
clicon_err(OE_DB, 0, "Not connected to datastore plugin");
goto done;
}
retval = _xa_api->xa_exists_fn(xh, db);
retval = xa->xa_exists_fn(xh, db);
done:
return retval;
}
@ -560,20 +616,21 @@ xmldb_delete(clicon_handle h,
{
int retval = -1;
xmldb_handle xh;
struct xmldb_api *xa;
if (_xa_api == NULL){
if ((xa = clicon_xmldb_api_get(h)) == NULL){
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_delete_fn == NULL){
if (xa->xa_delete_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
}
if ((xh = clicon_handle_xmldb_get(h)) == NULL){
if ((xh = clicon_xmldb_handle_get(h)) == NULL){
clicon_err(OE_DB, 0, "Not connected to datastore plugin");
goto done;
}
retval = _xa_api->xa_delete_fn(xh, db);
retval = xa->xa_delete_fn(xh, db);
done:
return retval;
}
@ -590,20 +647,21 @@ xmldb_init(clicon_handle h,
{
int retval = -1;
xmldb_handle xh;
struct xmldb_api *xa;
if (_xa_api == NULL){
if ((xa = clicon_xmldb_api_get(h)) == NULL){
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_init_fn == NULL){
if (xa->xa_init_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
}
if ((xh = clicon_handle_xmldb_get(h)) == NULL){
if ((xh = clicon_xmldb_handle_get(h)) == NULL){
clicon_err(OE_DB, 0, "Not connected to datastore plugin");
goto done;
}
retval = _xa_api->xa_init_fn(xh, db);
retval = xa->xa_init_fn(xh, db);
done:
return retval;
}

View file

@ -79,6 +79,7 @@
#include "clixon_string.h"
#include "clixon_yang.h"
#include "clixon_yang_type.h"
#include "clixon_plugin.h"
#include "clixon_options.h"
#include "clixon_xml.h"
#include "clixon_xsl.h"

View file

@ -66,6 +66,7 @@
#include "clixon_file.h"
#include "clixon_yang.h"
#include "clixon_hash.h"
#include "clixon_plugin.h"
#include "clixon_options.h"
#include "clixon_yang_type.h"
#include "clixon_yang_parse.h"

View file

@ -63,6 +63,7 @@
#include "clixon_handle.h"
#include "clixon_yang.h"
#include "clixon_hash.h"
#include "clixon_plugin.h"
#include "clixon_options.h"
#include "clixon_yang.h"
#include "clixon_yang_type.h"