Includes configuration parsing.
Change-Id: I94ab44a652635ac36a9ada4ddf4e07ba1e712de8
Signed-off-by: Paweł Szewczyk <p.szewczyk@samsung.com>
-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 \
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 \
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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 */
#include <string.h>
#include "common.h"
+#include "faultd-config.h"
#include "log.h"
#include "module.h"
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();
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;
#include <systemd/sd-event.h>
#include "common.h"
-#include "config.h"
+#include "faultd-config.h"
#include "list.h"
#ifdef ENABLE_TESTS
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;
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);
#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);
{"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:
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) {
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;
}
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;
sd_event_loop(loop);
faultd_modules_cleanup();
+ faultd_config_cleanup(&config);
sd_bus_close(bus);
return 0;