Add faultd event entity
authorKrzysztof Opasiak <k.opasiak@samsung.com>
Tue, 9 May 2017 11:24:13 +0000 (13:24 +0200)
committerKrzysztof Opasiak <k.opasiak@samsung.com>
Tue, 9 May 2017 11:49:16 +0000 (13:49 +0200)
Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com>
Makefile.am
src/core/event.c [new file with mode: 0644]
src/core/event.h [new file with mode: 0644]

index 786ae4150576b190a354dab88fef407fbe1d280a..e848a5298e6457eddfc86ea545bf8684edca1c3e 100644 (file)
@@ -31,6 +31,7 @@ SED_PROCESS = \
 
 sbin_PROGRAMS = faultd
 faultd_SOURCES = \
+    src/core/event.c \
     src/core/module.c \
     src/faultd.c \
     src/util/log.c \
diff --git a/src/core/event.c b/src/core/event.c
new file mode 100644 (file)
index 0000000..c82be74
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * 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 "event.h"
+#include "module.h"
+#include "common.h"
+
+struct event_factory {
+        struct faultd_module module;
+        struct list_head types;
+};
+
+#define to_event_factory(MOD) \
+        container_of(MOD, struct event_factory, module)
+
+static int init_event_factory(struct faultd_module *module,
+                              sd_event *event_loop)
+{
+        return 0;
+}
+
+static void cleanup_event_factory(struct faultd_module *module)
+{
+        struct event_factory *efactory = to_event_factory(module);
+
+        assert(list_empty(&efactory->types));
+}
+
+static struct event_factory event_factory = {
+        .module = {
+                .name = "event_factory",
+                .type = FAULTD_MODULE_TYPE_CORE,
+
+                .init = init_event_factory,
+                .cleanup = cleanup_event_factory,
+                .node = LIST_HEAD_INIT(event_factory.module.node),
+        },
+        .types = LIST_HEAD_INIT(event_factory.types),
+};
+
+FAULTD_MODULE_REGISTER(&event_factory.module);
+
+int faultd_event_type_register(struct faultd_event_type *new)
+{
+        if (!new->name || !new->allocate_event)
+                return -EINVAL;
+
+        list_add_tail(&new->node, &event_factory.types);
+
+        return 0;
+}
+
+void faultd_event_type_unregister(struct faultd_event_type *type)
+{
+        if (list_empty(&type->node))
+                return;
+
+        list_del_init(&type->node);
+}
+
+int faultd_event_create(const char *type, void *data, struct faultd_event **ev)
+{
+        struct faultd_event_type *ev_type;
+        int ret;
+
+        if (!type)
+                return -EINVAL;
+
+        list_for_each_entry(ev_type, &event_factory.types, node)
+                if (strcmp(ev_type->name, type) == 0)
+                        break;
+        if (&ev_type->node == &event_factory.types)
+                return -ENOENT;
+
+        ret = ev_type->allocate_event(ev_type, data, ev);
+
+        return ret;
+}
+
+static void release_faultd_event(struct uref *uref)
+{
+        struct faultd_event *ev = container_of(uref, struct faultd_event, uref);
+
+        if (ev->ops.release)
+                ev->ops.release(ev);
+}
+
+int faultd_event_init(struct faultd_event_type *ev_type,
+                      struct faultd_event *ev)
+{
+        int ret;
+
+        ret = clock_gettime(CLOCK_MONOTONIC, &ev->timestamp);
+        if (ret)
+                return ret;
+
+        ev->type = ev_type;
+        ev->ops = ev_type->default_ops;
+
+        uref_init(&ev->uref, release_faultd_event);
+        INIT_LIST_HEAD(&ev->node);
+        INIT_NQUEUE_NODE(&ev->nq_node);
+
+        return 0;
+}
diff --git a/src/core/event.h b/src/core/event.h
new file mode 100644 (file)
index 0000000..949ba3b
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * 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_EVENT_H
+#define FAULTD_EVENT_H
+
+#include <time.h>
+#include <string.h>
+
+#include "uref.h"
+#include "list.h"
+#include "notify_queue.h"
+#include "module.h"
+
+struct faultd_event;
+
+struct faultd_event_ops {
+        char *(*to_string)(struct faultd_event *);
+        void (*release)(struct faultd_event *);
+};
+
+struct faultd_event_type {
+        char *name;
+
+        struct faultd_event_ops default_ops;
+
+        /* Add function to allocate event from DB */
+
+        /* Allocate event based on passed data */
+        int (*allocate_event)(struct faultd_event_type *type,
+                              void *data, struct faultd_event **);
+
+        /* To be used by event factory */
+        struct list_head node;
+};
+
+struct faultd_event {
+       struct timespec timestamp;
+
+       /* TODO: add here some id field */
+
+       struct faultd_event_type *type;
+       struct faultd_event_ops ops;
+
+       struct uref uref;
+       /* To be used by event holder */
+       struct list_head node;
+       /* To be used by event processig FW */
+       struct nqueue_node nq_node;
+};
+
+int faultd_event_type_register(struct faultd_event_type *type);
+void faultd_event_type_unregister(struct faultd_event_type *type);
+
+#define FAULTD_EVENT_TYPE_REGISTER(EVENT_TYPE, NAME)                    \
+static int event_type_ ##NAME## _init(struct faultd_module *module,     \
+                                     sd_event *event_loop)              \
+{                                                                       \
+        return faultd_event_type_register(&EVENT_TYPE);                 \
+}                                                                       \
+                                                                        \
+static void event_type_ ##NAME## _cleanup(struct faultd_module *module) \
+{                                                                       \
+        faultd_event_type_unregister(&EVENT_TYPE);                      \
+}                                                                       \
+                                                                        \
+static struct faultd_module event_type_ ##NAME## _module = {            \
+        .name = #NAME,                                                  \
+        .type = FAULTD_MODULE_TYPE_EVENT,                               \
+        .init = event_type_ ##NAME## _init,                             \
+        .cleanup = event_type_ ##NAME## _cleanup,                       \
+        .node = LIST_HEAD_INIT(event_type_ ##NAME## _module.node),      \
+};                                                                      \
+                                                                        \
+FAULTD_MODULE_REGISTER(&event_type_ ##NAME## _module)
+
+int faultd_event_create(const char *type, void *data, struct faultd_event **ev);
+
+static inline void faultd_event_ref(struct faultd_event *ev)
+{
+        uref_get(&ev->uref);
+}
+
+static inline void faultd_event_unref(struct faultd_event *ev)
+{
+        uref_put(&ev->uref);
+}
+
+static inline int faultd_event_is_of_type(struct faultd_event *ev,
+                                          const char *type)
+{
+        return strcmp(ev->type->name, type) == 0;
+}
+
+static inline char *faultd_event_to_string(struct faultd_event *ev)
+{
+        return ev->ops.to_string(ev);
+}
+
+int faultd_event_init(struct faultd_event_type *ev_type,
+                      struct faultd_event *ev);
+
+static inline void faultd_event_cleanup(struct faultd_event *ev) {}
+
+#endif /* FAULTD_EVENT_H */