Add faultd configuration 30/133530/11
authorPaweł Szewczyk <p.szewczyk@samsung.com>
Tue, 11 Jul 2017 13:11:28 +0000 (15:11 +0200)
committerPaweł Szewczyk <p.szewczyk@samsung.com>
Tue, 11 Jul 2017 14:56:42 +0000 (16:56 +0200)
Includes configuration parsing.

Change-Id: I94ab44a652635ac36a9ada4ddf4e07ba1e712de8
Signed-off-by: Paweł Szewczyk <p.szewczyk@samsung.com>
Makefile.am
src/core/faultd-config.c [new file with mode: 0644]
src/core/faultd-config.h [new file with mode: 0644]
src/core/module.c
src/core/module.h
src/faultd.c

index 01fdd27d3d725b53526bcf29c4ee32db5e73439a..c4dd6fd206f407cc0de613d23c0ea9485e88fb81 100644 (file)
@@ -8,6 +8,7 @@ AM_CPPFLAGS = \
        -DSYSCONFDIR=\""$(sysconfdir)"\" \
        -DDBDIR=\""$(dbdir)"\" \
        -DFAULTD_SERVICES_CONFIG_PATH=\""${sysconfdir}/faultd/conf.d/"\" \
+       -DFAULTD_DEFAULT_CONFIG_FILE=\""${sysconfdir}/faultd/faultd.conf"\" \
        -I${top_srcdir}/src \
        -I${top_srcdir}/src/core \
        -I${top_srcdir}/src/decision_makers \
@@ -64,6 +65,7 @@ faultd_SOURCES = \
     src/core/event_processor.c \
     src/core/module.c \
     src/core/service.c \
+    src/core/faultd-config.c \
     src/decision_makers/rv_dm.c \
     src/decision_makers/standard_fault_dm.c \
     src/decision_makers/vip_fault_dm.c \
diff --git a/src/core/faultd-config.c b/src/core/faultd-config.c
new file mode 100644 (file)
index 0000000..a781926
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * This file is part of faultd.
+ *
+ * Copyright © 2017 Samsung Electronics
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <json-c/json.h>
+
+#include "common.h"
+#include "faultd-config.h"
+#include "log.h"
+#include "module.h"
+
+static int parse_disable_modules(struct json_object *root)
+{
+       struct json_object *node;
+       const char *name;
+       struct faultd_module *module;
+       int i;
+       int len;
+
+       len = json_object_array_length(root);
+
+       for (i = 0; i < len; ++i) {
+               node = json_object_array_get_idx(root, i);
+               if (!node)
+                       return -EINVAL;
+
+               name = json_object_get_string(node);
+               if (!name)
+                       return -EINVAL;
+
+               module = faultd_get_module_by_name(name);
+               if (module) {
+                       module->disabled = 1;
+                       log_debug("Disabled %s module", name);
+               } else {
+                       log_warning("Could not find %s module", name);
+               }
+       }
+
+       return 0;
+}
+
+int faultd_parse_config(const char *config_path, struct faultd_config *c)
+{
+       struct json_object *root;
+       struct json_object *node;
+       int ret = 0;
+       json_bool json_ret;
+
+       root = json_object_from_file(config_path);
+       if (is_error(root)) {
+               log_error("Could not create object from json file %s", config_path);
+               return -EINVAL;
+       }
+
+       json_ret = json_object_object_get_ex(root, "disable_modules", &node);
+       if (json_ret) {
+               ret = parse_disable_modules(node);
+               if (ret < 0) {
+                       log_error("Could not parse configuration file %s", config_path);
+                       goto out;
+               }
+       }
+
+       c->root = root;
+       return 0;
+
+out:
+       json_object_put(root);
+       return ret;
+}
+
+void faultd_config_cleanup(struct faultd_config *c)
+{
+       if (c)
+               json_object_put(c->root);
+}
+
+int faultd_config_get_subconf(struct faultd_config *conf, const char *key, struct faultd_config **sub)
+{
+       struct faultd_config *config_node;
+       struct json_object *node;
+       json_bool ret;
+
+       ret = json_object_object_get_ex(conf->root, key, &node);
+       if (!ret)
+               return -ENOENT;
+
+       config_node = calloc(1, sizeof(*config_node));
+       if (!config_node)
+               return -ENOMEM;
+
+       if (!json_object_is_type(node, json_type_object)) {
+               log_error("%s has to be an object", key);
+               goto out;
+       }
+
+       config_node->root = json_object_get(node);
+
+       *sub = config_node;
+       return 0;
+
+out:
+       free(config_node);
+       return -EINVAL;
+}
diff --git a/src/core/faultd-config.h b/src/core/faultd-config.h
new file mode 100644 (file)
index 0000000..6a86315
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * This file is part of faultd.
+ *
+ * Copyright © 2017 Samsung Electronics
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FAULTD_CONFIG_H
+#define FAULTD_CONFIG_H
+
+#include <ejdb/ejdb.h>
+
+struct faultd_config {
+       struct json_object *root;
+};
+
+int faultd_parse_config(const char *config_path, struct faultd_config *c);
+void faultd_config_cleanup(struct faultd_config *c);
+int faultd_config_get_subconf(struct faultd_config *conf, const char *key, struct faultd_config **sub);
+
+#endif /* FAULTD_CONFIG_H */
index e56ea99714f4a0378c64923addf91923b23ff1a1..bc21a872783f4afe5708231eb96274d67a8caefc 100644 (file)
@@ -20,6 +20,7 @@
 #include <string.h>
 
 #include "common.h"
+#include "faultd-config.h"
 #include "log.h"
 #include "module.h"
 
@@ -56,11 +57,12 @@ void faultd_module_unregister(struct faultd_module *module)
        list_del(&module->node);
 }
 
-int faultd_modules_init(sd_event *event_loop)
+int faultd_modules_init(sd_event *event_loop, struct faultd_config *conf)
 {
        struct faultd_module *module, *module_to_clean;
        int i;
        int ret = 0;
+       struct faultd_config *module_conf = NULL;
 
        if (!modules[0].next)
                init_heads();
@@ -77,15 +79,30 @@ int faultd_modules_init(sd_event *event_loop)
                                continue;
                        log_debug("Initializing %s module", module->name);
 
-                       ret = module->init(module, NULL, event_loop);
-                       if (ret)
+                       ret = faultd_config_get_subconf(conf, module->name, &module_conf);
+                       if (ret < 0 && ret != -ENOENT) {
+                               log_error_errno(ret, "Could not get subconfig for %s", module->name);
                                goto err_cleanup;
+                       }
+
+                       ret = module->init(module, module_conf, event_loop);
+                       if (ret < 0) {
+                               log_error_errno(ret, "Could not initialize module %s", module->name);
+                               goto err_cleanup;
+                       }
+
+                       faultd_config_cleanup(module_conf);
+                       free(module_conf);
+                       module_conf = NULL;
                }
        }
 
        return 0;
 
 err_cleanup:
+       faultd_config_cleanup(module_conf);
+       free(module_conf);
+
        for (; i >= 0; --i) {
                if (category_disabled[i])
                        continue;
index 28b07243dbfb98aea28380438b198e6ce7d02793..f44df9e15d79919054c406c9ac3290371a75542e 100644 (file)
@@ -23,7 +23,7 @@
 #include <systemd/sd-event.h>
 
 #include "common.h"
-#include "config.h"
+#include "faultd-config.h"
 #include "list.h"
 
 #ifdef ENABLE_TESTS
@@ -49,14 +49,12 @@ enum faultd_module_type {
        FAULTD_MODULE_TYPE_MAX,
 };
 
-struct faultd_config;
-
 struct faultd_module {
        char *name;
        enum faultd_module_type type;
        bool disabled;
 
-       int (*init)(struct faultd_module *, struct faultd_config *c, sd_event *event_loop);
+       int (*init)(struct faultd_module *, struct faultd_config *config, sd_event *event_loop);
        void (*cleanup)(struct faultd_module *);
 
        struct list_head node;
@@ -65,7 +63,7 @@ struct faultd_module {
 int faultd_module_register(struct faultd_module *module);
 void faultd_module_unregister(struct faultd_module *module);
 
-int faultd_modules_init(sd_event *event_loop);
+int faultd_modules_init(sd_event *event_loop, struct faultd_config *conf);
 void faultd_modules_cleanup(void);
 
 struct faultd_module *faultd_get_module_by_name(const char *name);
index 5d92ab5c523845d8e657c608e00e7cf267d98245..7f72897bc89da6b2aee2af492701dd4c9a956999 100644 (file)
 
 #include <errno.h>
 #include <getopt.h>
+#include <json-c/json.h>
 #include <stdio.h>
 #include <poll.h>
 #include <systemd/sd-bus.h>
 #include <systemd/sd-event.h>
 #include <signal.h>
 #include <syslog.h>
+#include <unistd.h>
 
 #include "log.h"
 #include "module.h"
 #include "systemd_dbus.h"
+#include "faultd-config.h"
 
 static int terminate = 0;
+static struct faultd_config config;
 
 int sigint_handler(sd_event_source *s, const struct signalfd_siginfo *si,
                                   void *userdata);
@@ -56,12 +60,15 @@ static int parse_argv(int ac, char *av[])
                {"log-level", required_argument, NULL, ARG_LOG_LEVEL},
                {"disable-module", required_argument, NULL, 'd'},
                {"no-action", no_argument, NULL, ARG_NO_ACTION},
+               {"config-file", required_argument, NULL, 'c'},
                {}
        };
 
        struct faultd_module *module;
+       const char *config_file = FAULTD_DEFAULT_CONFIG_FILE;
+       bool using_default_config = 1;
 
-       while ((c = getopt_long(ac, av, "Dd:", options, NULL)) >= 0) {
+       while ((c = getopt_long(ac, av, "Dc:d:", options, NULL)) >= 0) {
                switch (c) {
 
                case ARG_LOG_LEVEL:
@@ -77,6 +84,12 @@ static int parse_argv(int ac, char *av[])
                        log_set_max_level(LOG_DEBUG);
                        break;
 
+               case 'c':
+                       config_file = optarg;
+                       using_default_config = 0;
+
+                       break;
+
                case 'd':
                        module = faultd_get_module_by_name(optarg);
                        if (module) {
@@ -96,6 +109,25 @@ static int parse_argv(int ac, char *av[])
                        return -EINVAL;
                }
        }
+
+       r = access(config_file, F_OK | R_OK);
+       if (r) {
+               if (!using_default_config || errno != ENOENT) {
+                       log_error("Could not access config file %s", config_file);
+                       return -errno;
+               }
+
+               log_debug("No config file");
+               config.root = json_object_new_object();
+               if (!config.root)
+                       return -ENOMEM;
+       } else {
+               log_debug("Using config file: %s", config_file);
+               r = faultd_parse_config(config_file, &config);
+               if (r < 0)
+                       return r;
+       }
+
        return 0;
 }
 
@@ -132,7 +164,7 @@ int main(int ac, char *av[])
        rc = sd_event_add_signal(loop, NULL, SIGINT, sigint_handler, loop);
 
 
-       rc = faultd_modules_init(loop);
+       rc = faultd_modules_init(loop, &config);
        if (rc < 0) {
                log_error("Failed to initialize modules %d.", rc);
                return -1;
@@ -143,6 +175,7 @@ int main(int ac, char *av[])
        sd_event_loop(loop);
 
        faultd_modules_cleanup();
+       faultd_config_cleanup(&config);
 
        sd_bus_close(bus);
        return 0;