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>
Wed, 10 May 2017 18:42:59 +0000 (20:42 +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..186b526
--- /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..3c000be
--- /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 */