From: Aleš Date: Thu, 23 Jan 2020 13:07:25 +0000 (+0100) Subject: sysrepo: C module integration to just print xpath of changed nodes X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=99a50d54bd3a424ba43addf880c76f4ebfad610b;p=thirdparty%2Fknot-resolver.git sysrepo: C module integration to just print xpath of changed nodes --- diff --git a/modules/sysrepo/callbacks.c b/modules/sysrepo/callbacks.c new file mode 100644 index 000000000..87b78f633 --- /dev/null +++ b/modules/sysrepo/callbacks.c @@ -0,0 +1,61 @@ +#include +#include + +#include "callbacks.h" +#include "conversion.h" +#include "common/sysrepo_conf.h" + + +static int kresd_change_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, +sr_event_t event, uint32_t request_id, void *private_data) +{ + if(event == SR_EV_CHANGE) + { + /* validation actions*/ + } + else if (event == SR_EV_DONE) + { + int err = SR_ERR_OK; + sr_change_oper_t oper; + sr_val_t *old_value = NULL; + sr_val_t *new_value = NULL; + sr_change_iter_t *it = NULL; + + err = sr_get_changes_iter(session, XPATH_BASE"/*/*//.", &it); + if (err != SR_ERR_OK) goto cleanup; + + while ((sr_get_change_next(session, it, &oper, &old_value, &new_value)) == SR_ERR_OK) { + + printf("%s\n", new_value->xpath); + + /* apply configuration here */ + + sr_free_val(old_value); + sr_free_val(new_value); + } + + cleanup: + sr_free_change_iter(it); + + if(err != SR_ERR_OK && err != SR_ERR_NOT_FOUND) + printf("Error: %s\n",sr_strerror(err)); + } + else if(event == SR_EV_ABORT) + { + /* abortion actions */ + } + + return SR_ERR_OK; +} + +int sysrepo_subscr_register(sr_session_ctx_t *session, sr_subscription_ctx_t **subscription) +{ + int err = SR_ERR_OK; + + err = sr_module_change_subscribe(session, YM_COMMON, XPATH_BASE, + kresd_change_cb, NULL, 0, SR_SUBSCR_NO_THREAD|SR_SUBSCR_ENABLED, subscription); + if (err != SR_ERR_OK) + return err; + + return err; +} \ No newline at end of file diff --git a/modules/sysrepo/callbacks.h b/modules/sysrepo/callbacks.h new file mode 100644 index 000000000..e12443233 --- /dev/null +++ b/modules/sysrepo/callbacks.h @@ -0,0 +1,7 @@ +#pragma once + +#include +#include + +/** Register sysrepo subscriptions */ +int sysrepo_subscr_register(sr_session_ctx_t *session, sr_subscription_ctx_t **subscription); \ No newline at end of file diff --git a/modules/sysrepo/common/helpers.c b/modules/sysrepo/common/string_helper.c similarity index 96% rename from modules/sysrepo/common/helpers.c rename to modules/sysrepo/common/string_helper.c index 3a470bee1..280de8f18 100644 --- a/modules/sysrepo/common/helpers.c +++ b/modules/sysrepo/common/string_helper.c @@ -1,6 +1,6 @@ #include #include -#include "helpers.h" +#include "string_helper.h" /// Source: https://stackoverflow.com/questions/47116974/remove-a-substring-from-a-string-in-c char *remove_substr(char *str, const char *substr) { diff --git a/modules/sysrepo/common/helpers.h b/modules/sysrepo/common/string_helper.h similarity index 100% rename from modules/sysrepo/common/helpers.h rename to modules/sysrepo/common/string_helper.h diff --git a/modules/sysrepo/common/sysrepo_conf.c b/modules/sysrepo/common/sysrepo_conf.c index 0730555c1..be9b6c0f5 100644 --- a/modules/sysrepo/common/sysrepo_conf.c +++ b/modules/sysrepo/common/sysrepo_conf.c @@ -2,16 +2,17 @@ int sysrepo_repo_config() { - /* - This function will probably be called on knot-resolver - installation or by `kres-watcher` when something - wents wrong with sysrepo. + /* + This function will probably be called on knot-resolver + installation or by `kres-watcher` when something + wents wrong with sysrepo. - Configures sysrepo: - 1. install/import YANG modules - 2. enable features - 3. import json data to startup datastore - 4. clean up any stale connections of clients that no longer exist - */ - return 0; + Configures sysrepo: + 1. install/import YANG modules + 2. enable features + 3. import json data to startup datastore + 4. clean up any stale connections of clients that no longer exist + */ + + return 0; } \ No newline at end of file diff --git a/modules/sysrepo/common/sysrepo_conf.h b/modules/sysrepo/common/sysrepo_conf.h index 8a8c57bce..a8285b7db 100644 --- a/modules/sysrepo/common/sysrepo_conf.h +++ b/modules/sysrepo/common/sysrepo_conf.h @@ -4,11 +4,12 @@ #include #include -/* sysrepo globals */ -#define YM_DIR "" -#define YM_COMMON "cznic-resolver-common" -#define YM_KRES "cznic-resolver-knot" -#define XPATH_BASE "/" YM_COMMON ":dns-resolver" - -/* Function to configure sysrepo repository */ -int sysrepo_repo_config(); \ No newline at end of file +#define YM_COMMON "cznic-resolver-common" +#define YM_KRES "cznic-resolver-knot" +#define XPATH_BASE "/" YM_COMMON ":dns-resolver" +#define XPATH_GC XPATH_BASE"/cache/"YM_KRES":garbage-collector" +#define XPATH_RPC_BASE "/"YM_COMMON + + +/** Configures sysrepo repository for usage with knot-resolver */ +int sysrepo_repo_config(); diff --git a/modules/sysrepo/conv_funcs.c b/modules/sysrepo/conv_funcs.c new file mode 100644 index 000000000..b0cc9fda4 --- /dev/null +++ b/modules/sysrepo/conv_funcs.c @@ -0,0 +1,3 @@ +#include "conv_funcs.h" + +/* Conversion functions */ \ No newline at end of file diff --git a/modules/sysrepo/conv_funcs.h b/modules/sysrepo/conv_funcs.h new file mode 100644 index 000000000..7b9637ef9 --- /dev/null +++ b/modules/sysrepo/conv_funcs.h @@ -0,0 +1 @@ +#pragma once \ No newline at end of file diff --git a/modules/sysrepo/conversion.c b/modules/sysrepo/conversion.c new file mode 100644 index 000000000..dea2cebc2 --- /dev/null +++ b/modules/sysrepo/conversion.c @@ -0,0 +1,16 @@ +#include +#include +#include +#include +#include + +#include "conversion.h" +#include "conv_funcs.h" +#include "modules/sysrepo/common/sysrepo_conf.h" + + +/** Configuration conversion table: + * sysrepo config datastore <<-->> kres config */ +static const conversion_row_t conversion_table[] = { + { NULL } +}; diff --git a/modules/sysrepo/conversion.h b/modules/sysrepo/conversion.h new file mode 100644 index 000000000..1d753c501 --- /dev/null +++ b/modules/sysrepo/conversion.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include +#include +#include + + +typedef struct conversion_row conversion_row_t; + +struct conversion_row { + const char * xpath; + /* set configuration functions + 1. prepare value on xpath for Lua function and then push it to Lua stack + 2. execute Lua function with previously pushed parameters result save on top of Lua stack + 3. get result from top of Lua stack, parse and validate it => SR_ERR_OK + */ + + /* get configuration functions + 1. prepare parametrs based on xpath for Lua function to get configured value and push it to top of Lua stack + 2. execute Lua function with previously pushed parameters result save on top of Lua stack + 3. get result from top of Lua stack, convert it to type on xpath and push it to sysrepo + */ + + /* dlete configuration functions + 1. prepare parameters based on xpath for Lua function to delete configuration, push on top of Lua stack + 2. execute Lua function to delete config, result save to top of Lua stack + 3. read result from Lua stack and confirm if it was successfull + */ +}; diff --git a/modules/sysrepo/meson.build b/modules/sysrepo/meson.build index 1808a9728..a2b5726b4 100644 --- a/modules/sysrepo/meson.build +++ b/modules/sysrepo/meson.build @@ -1,27 +1,30 @@ # C module: sysrepo sysrepo_src = files([ - 'sysrepo.c', + 'sysrepo.c', + 'callbacks.c', + 'conversion.c', + 'conv_funcs.c', ]) c_src_lint += sysrepo_src sysrepo_common_src = files([ - 'common/sysrepo_conf.c', - 'common/sysrepo_conf.h', - 'common/helpers.h', - 'common/helpers.c', + 'common/sysrepo_conf.c', + 'common/sysrepo_conf.h', + 'common/string_helper.h', + 'common/string_helper.c', ]) c_src_lint += sysrepo_common_src if build_sysrepo - sysrepo_mod = shared_module( + sysrepo_mod = shared_module( 'sysrepo', sysrepo_src, - sysrepo_common_src, + sysrepo_common_src, dependencies: [ luajit_inc, libyang, - libsysrepo, + libsysrepo, ], include_directories: mod_inc_dir, name_prefix: '', diff --git a/modules/sysrepo/sysrepo.c b/modules/sysrepo/sysrepo.c index cb7b63403..60438f420 100644 --- a/modules/sysrepo/sysrepo.c +++ b/modules/sysrepo/sysrepo.c @@ -1,3 +1,19 @@ +/* Copyright (C) 2019 CZ.NIC, z.s.p.o. + + This program 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. + + This program 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 this program. If not, see . + */ + #include #include #include @@ -5,17 +21,128 @@ #include #include "lib/module.h" +#include "common/sysrepo_conf.h" +#include "callbacks.h" + + +typedef struct el_subscription_ctx el_subscription_ctx_t; +/** Callback for our sysrepo subscriptions */ +typedef void (*el_subsription_cb)(el_subscription_ctx_t *el_subscr, int status); + +/** Context for our sysrepo subscriptions. + * might add some other fields in future */ +struct el_subscription_ctx { + sr_conn_ctx_t *connection; + sr_session_ctx_t * session; + sr_subscription_ctx_t *subscription; + el_subsription_cb callback; + uv_poll_t uv_handle; +}; + +void el_subscr_finish_closing(uv_handle_t *handle) +{ + el_subscription_ctx_t *el_subscr = handle->data; + assert(el_subscr); + free(el_subscr); +} + +/** Free a event loop subscription. */ +void el_subscription_free(el_subscription_ctx_t *el_subscr) +{ + sr_disconnect(el_subscr->connection); + uv_close((uv_handle_t *)&el_subscr->uv_handle, el_subscr_finish_closing); +} + +static void el_subscr_cb_tramp(uv_poll_t *handle, int status, int events) +{ + el_subscription_ctx_t *el_subscr = handle->data; + el_subscr->callback(el_subscr, status); +} + +/** Start a new event loop subscription. */ +static el_subscription_ctx_t * el_subscription_new(sr_subscription_ctx_t *sr_subscr, el_subsription_cb el_callback) +{ + int fd; + errno = sr_get_event_pipe(sr_subscr, &fd); + if (errno != SR_ERR_OK) return NULL; + el_subscription_ctx_t *el_subscr = malloc(sizeof(*el_subscr)); + if (!el_subscr) return NULL; + errno = uv_poll_init(uv_default_loop(), &el_subscr->uv_handle, fd); + if (errno) { + free(el_subscr); + return NULL; + } + el_subscr->subscription = sr_subscr; + el_subscr->callback = el_callback; + el_subscr->uv_handle.data = el_subscr; + errno = uv_poll_start(&el_subscr->uv_handle, UV_READABLE, el_subscr_cb_tramp); + if (errno) { + el_subscription_free(el_subscr); + return NULL; + } + return el_subscr; +} + +static void el_subscr_cb(el_subscription_ctx_t *el_subscr, int status) +{ + if (status) { + /* some error */ + return; + } + /* normal state */ + sr_process_events(el_subscr->subscription, el_subscr->session,NULL); +} KR_EXPORT -int nsid_init(struct kr_module *module) { +int sysrepo_init(struct kr_module *module) +{ + int ret = SR_ERR_OK; + sr_conn_ctx_t *sr_connection = NULL; + sr_session_ctx_t *sr_session = NULL; + sr_subscription_ctx_t *sr_subscription = NULL; + + /* connect to sysrepo */ + ret = sr_connect(0, &sr_connection); + if (ret != SR_ERR_OK) + goto cleanup; + + /* Try to recover (clean up) any stale connections of clients that no longer exist */ + ret = sr_connection_recover(sr_connection); + if (ret != SR_ERR_OK) + goto cleanup; + + /* start a new session on RUNNING datastore */ + ret = sr_session_start(sr_connection, SR_DS_RUNNING, &sr_session); + if (ret != SR_ERR_OK) + goto cleanup; + + /* register sysrepo subscriptions and callbacks*/ + ret = sysrepo_subscr_register(sr_session, &sr_subscription); + if (ret != SR_ERR_OK) + goto cleanup; + + /* add subscriptions to kres event loop */ + el_subscription_ctx_t *el_subscr = el_subscription_new(sr_subscription, el_subscr_cb); + if (!el_subscr) + goto cleanup; + + el_subscr->connection = sr_connection; + el_subscr->session = sr_session; + module->data = el_subscr; return kr_ok(); + + cleanup: + sr_disconnect(sr_connection); + return kr_error(ret); } KR_EXPORT -int nsid_deinit(struct kr_module *module) { - +int sysrepo_deinit(struct kr_module *module) +{ + el_subscription_ctx_t *el_subscr = module->data; + el_subscription_free(el_subscr); return kr_ok(); } -KR_MODULE_EXPORT(sysrepo) +KR_MODULE_EXPORT(sysrepo) \ No newline at end of file diff --git a/utils/cache_gc/main.c b/utils/cache_gc/main.c index ea9293f0e..7eeb88f93 100644 --- a/utils/cache_gc/main.c +++ b/utils/cache_gc/main.c @@ -20,9 +20,7 @@ #include #include "modules/sysrepo/common/sysrepo_conf.h" -#include "modules/sysrepo/common/helpers.h" - -#define XPATH_GC XPATH_BASE"/cache/"YM_KRES":garbage-collector" +#include "modules/sysrepo/common/string_helper.h" #endif