]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
sysrepo: C module integration to just print xpath of changed nodes
authorAleš <ales.mrazek@nic.cz>
Thu, 23 Jan 2020 13:07:25 +0000 (14:07 +0100)
committerAleš <ales.mrazek@nic.cz>
Thu, 23 Jan 2020 13:07:25 +0000 (14:07 +0100)
13 files changed:
modules/sysrepo/callbacks.c [new file with mode: 0644]
modules/sysrepo/callbacks.h [new file with mode: 0644]
modules/sysrepo/common/string_helper.c [moved from modules/sysrepo/common/helpers.c with 96% similarity]
modules/sysrepo/common/string_helper.h [moved from modules/sysrepo/common/helpers.h with 100% similarity]
modules/sysrepo/common/sysrepo_conf.c
modules/sysrepo/common/sysrepo_conf.h
modules/sysrepo/conv_funcs.c [new file with mode: 0644]
modules/sysrepo/conv_funcs.h [new file with mode: 0644]
modules/sysrepo/conversion.c [new file with mode: 0644]
modules/sysrepo/conversion.h [new file with mode: 0644]
modules/sysrepo/meson.build
modules/sysrepo/sysrepo.c
utils/cache_gc/main.c

diff --git a/modules/sysrepo/callbacks.c b/modules/sysrepo/callbacks.c
new file mode 100644 (file)
index 0000000..87b78f6
--- /dev/null
@@ -0,0 +1,61 @@
+#include <libyang/libyang.h>
+#include <sysrepo.h>
+
+#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 (file)
index 0000000..e124432
--- /dev/null
@@ -0,0 +1,7 @@
+#pragma once
+
+#include <libyang/libyang.h>
+#include <sysrepo.h>
+
+/** Register sysrepo subscriptions */
+int sysrepo_subscr_register(sr_session_ctx_t *session, sr_subscription_ctx_t **subscription);
\ No newline at end of file
similarity index 96%
rename from modules/sysrepo/common/helpers.c
rename to modules/sysrepo/common/string_helper.c
index 3a470bee1d5272783449c759c109749d383c5558..280de8f1812c510ebc1fc56183772ae112817beb 100644 (file)
@@ -1,6 +1,6 @@
 #include <stdlib.h>
 #include <string.h>
-#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) {
index 0730555c14dee61a27ca4e089acde868f81f9864..be9b6c0f5c579f16014b682832a728f38a6a4546 100644 (file)
@@ -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
index 8a8c57bced117f7fd8ec65472d2eadce41a731fd..a8285b7db5d9a0e88b4d78f565808eac74f8edd4 100644 (file)
@@ -4,11 +4,12 @@
 #include <sysrepo.h>
 #include <libyang/libyang.h>
 
-/* 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 (file)
index 0000000..b0cc9fd
--- /dev/null
@@ -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 (file)
index 0000000..7b9637e
--- /dev/null
@@ -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 (file)
index 0000000..dea2ceb
--- /dev/null
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <lua.h>
+#include <sysrepo.h>
+
+#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 (file)
index 0000000..1d753c5
--- /dev/null
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <lua.h>
+#include <sysrepo.h>
+
+
+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
+        */
+};
index 1808a97289a98fc86e53a3ea4dddad71cdb7536e..a2b5726b4823009ffecb9cf4efb13e1dded7755e 100644 (file)
@@ -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: '',
index cb7b634033a9bcc1276c7a7e6528209f6f9c861b..60438f42051cf95a3c15d2f01e6a7d06b31806e5 100644 (file)
@@ -1,3 +1,19 @@
+/*  Copyright (C) 2019 CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+
+       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 <https://www.gnu.org/licenses/>.
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <uv.h>
 #include <sysrepo.h>
 
 #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
index ab95300a6f24d3d9715730cea728236b5993cce8..8387dbe2f37cb40b91a2bb542d023d24cd70ad0a 100644 (file)
@@ -19,9 +19,7 @@
 #include <libyang/libyang.h>
 
 #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