Add modules infrastructure
authorKrzysztof Opasiak <k.opasiak@samsung.com>
Mon, 8 May 2017 20:58:22 +0000 (22:58 +0200)
committerKrzysztof Opasiak <k.opasiak@samsung.com>
Wed, 10 May 2017 18:42:59 +0000 (20:42 +0200)
Add some infrastructure to make faultd a modular daemon.

Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com>
src/core/module.c [new file with mode: 0644]
src/core/module.h [new file with mode: 0644]

diff --git a/src/core/module.c b/src/core/module.c
new file mode 100644 (file)
index 0000000..ebbda82
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * 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 "module.h"
+#include "log.h"
+#include "common.h"
+
+static struct list_head modules[FAULTD_MODULE_TYPE_MAX];
+
+static void init_heads(void)
+{
+       unsigned i;
+
+       for (i = 0; i < ARRAY_SIZE(modules); ++i)
+               INIT_LIST_HEAD(modules + i);
+}
+
+int faultd_module_register(struct faultd_module *module)
+{
+       if (!module->name || !module->init) {
+               log_error("Missing module name or init()");
+               return -EINVAL;
+       }
+
+       if (!modules[0].next)
+               init_heads();
+
+       list_add_tail(&module->node, modules + module->type);
+
+       return 0;
+}
+
+void faultd_module_unregister(struct faultd_module *module)
+{
+       list_del(&module->node);
+}
+
+int faultd_modules_init(sd_event *event_loop)
+{
+       struct faultd_module *module, *module_to_clean;
+       int i;
+       int ret = 0;
+
+       if (!modules[0].next)
+               init_heads();
+
+       for (i = 0; i < (int)(ARRAY_SIZE(modules)); ++i) {
+               log_debug("Initializing modules category %d", i);
+               list_for_each_entry(module, modules + i, node) {
+                       log_debug("Initializing %s module", module->name);
+
+                       ret = module->init(module, event_loop);
+                       if (ret)
+                               goto err_cleanup;
+               }
+       }
+
+       return 0;
+
+err_cleanup:
+       for (; i >= 0; --i) {
+               log_debug("Cleaning up modules category %d", i);
+               /* From first element of the list... */
+               for (module_to_clean = list_first_entry(modules + i,
+                                                                                               struct faultd_module,
+                                                                                               node);
+                        /* iterate as long as modules has been initialized */
+                        module_to_clean != module &&
+                                &module_to_clean->node != (modules + i);
+                        /* move to next one */
+                        module_to_clean = list_next_entry(module_to_clean, node)) {
+                       log_debug("Cleaning up %s module",
+                                         module_to_clean->name);
+                       module_to_clean->cleanup(module_to_clean);
+               }
+       }
+
+       return ret;
+}
+
+void faultd_modules_cleanup()
+{
+       struct faultd_module *module;
+       int i;
+
+       for (i = FAULTD_MODULE_TYPE_MAX - 1; i >= 0; --i) {
+               log_debug("Cleaning up modules category %d", i);
+               list_for_each_entry(module, modules + i, node) {
+                       log_debug("Cleaning up %s module", module->name);
+
+                       module->cleanup(module);
+               }
+       }
+}
diff --git a/src/core/module.h b/src/core/module.h
new file mode 100644 (file)
index 0000000..14af97b
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 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_MODULE_H
+#define FAULTD_MODULE_H
+
+#include <time.h>
+#include <systemd/sd-event.h>
+
+#include "list.h"
+#include "common.h"
+
+/* Order in this enum is also order of initialization */
+enum faultd_module_type {
+       FAULTD_MODULE_TYPE_MIN = 0,
+       FAULTD_MODULE_TYPE_UNCATEGORIZED = FAULTD_MODULE_TYPE_MIN,
+       FAULTD_MODULE_TYPE_CORE,
+       FAULTD_MODULE_TYPE_EVENT,
+       FAULTD_MODULE_TYPE_ACTION_EXECUTOR,
+       FAULTD_MODULE_TYPE_DECISION_MAKER,
+       FAULTD_MODULE_TYPE_LISTENER,
+       FAULTD_MODULE_TYPE_MAX,
+};
+
+struct faultd_module {
+       char *name;
+       enum faultd_module_type type;
+
+       int (*init)(struct faultd_module *, 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);
+void faultd_modules_cleanup(void);
+
+#ifndef __CONSTRUCTOR__
+#define __CONSTRUCTOR__ __attribute__((constructor))
+#endif
+
+#ifndef __DESTRUCTOR__
+#define __DESTRUCTOR__ __attribute__((destructor))
+#endif
+
+#define FAULTD_MODULE_REGISTER(module)                         \
+       static void __CONSTRUCTOR__ module_init(void)   \
+       {                                                                                               \
+               faultd_module_register(module);                         \
+       }                                                                                               \
+       static void __DESTRUCTOR__ module_cleanup(void) \
+       {                                                                                               \
+               faultd_module_unregister(module);                       \
+       }
+
+#endif /* FAULTD_MODULE_H */