Add some event processor
authorKrzysztof Opasiak <k.opasiak@samsung.com>
Tue, 25 Apr 2017 14:07:13 +0000 (16:07 +0200)
committerKrzysztof Opasiak <k.opasiak@samsung.com>
Tue, 25 Apr 2017 14:07:13 +0000 (16:07 +0200)
Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com>
event_processor.c [new file with mode: 0644]
src/event_processor.h [new file with mode: 0644]

diff --git a/event_processor.c b/event_processor.c
new file mode 100644 (file)
index 0000000..2a7453a
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * 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_processor.h"
+#include "log.h"
+
+struct event_processor {
+        struct faultd_module module;
+        struct nqueue_head pending_events;
+        struct sd_event_source *pending_events_sd_source;
+        struct list_head event_handlers;
+};
+
+#define to_event_processor(MOD) \
+        container_of(MOD, struct event_processor, module)
+
+/* called each time when new event arrived */
+static int event_processor_callback(sd_event_source *s,
+                                    int fd, uint32_t revents, void *userdata)
+{
+        struct event_processor *eprocessor = userdata;
+        struct faultd_event *ev = nqueue_pop(eprocessor->pending_events,
+                                             struct faultd_event, nq_node);
+        struct faultd_event_handler *handler;
+
+        /* TODO: Here is a good place to put our event into DB */
+        {
+                char *str = faultd_event_to_string(ev);
+                log_debug("New event arrived: %s", str);
+                free(str);
+        }
+
+        list_for_each_entry(handler, &eprocessor->event_handlers, node) {
+                if (handler->event_match(handler, ev)) {
+                        nqueue_append(&handler->event_queue, &ev->nq_node);
+                        ev = NULL;
+                }
+        }
+
+        if (ev)
+                log_error("No handler event found");
+        
+        return 0;
+}
+
+static int event_processor_init(struct faultd_module *module, sd_event *event)
+{
+        struct event_processor *eprocessor = to_event_processor(module);
+        int ret;
+
+        ret = init_notify_queue_head(&eprocessor->pending_events);
+        if (ret)
+                return ret;
+
+        ret = sd_event_add_io(event, &eprocessor->pending_events_sd_source,
+                              eprocessor->pending_events->fd, EPOLLIN,
+                              event_processor_callback, eprocessor);
+        if (ret)
+                goto cleanup_queue;
+
+        return 0;
+
+cleanup_queue:
+        cleanup_notify_queue_head(&eprocessor->pending_events);
+
+        return ret;
+}
+
+static void event_processor_cleanup(struct faultd_module *module)
+{
+        struct event_processor *eprocessor = to_event_processor(module);
+
+        /* We log errors but go forward to cleanup everything we can */
+        ret = sd_event_source_set_enabled(eprocessor->pending_events_sd_source,
+                                          SD_EVENT_OFF);
+        if (ret < 0)
+                log_error("Could not disable audit event source %d", ret);
+
+        sd_event_source_unref(eprocessor->pending_events_sd_source);
+
+        /* TODO: What to do with unhandled events? */
+        while (!nqueue_empty(eprocessor->pending_events)) {
+                struct faultd_event *ev = nqueue_pop(eprocessor->pending_events,
+                                                     struct faultd_event,
+                                                     nq_node);
+                char *str = faultd_event_to_string(ev);
+                log_error("Unhandled event: %s", str);
+                free(str);
+                faultd_event_put(ev);
+        }
+}
+
+struct event_processor event_processor = {
+        .module = {
+                .name = "event_processor",
+                .type = FAULTD_MODULE_TYPE_CORE,
+
+                .init = event_processor_init,
+                .cleanup = event_processor_cleanup,
+                .node = LIST_HEAD_INIT(event_processor.module.node),
+        },
+        /* pending_events will be initialized in init() */
+        .event_handlers = LIST_HEAD_INIT(event_processor.event_handlers),
+};
+
+FAULTD_MODULE_REGISTER(&event_processor.module);
+
+int event_processor_report_event(struct faultd_event *ev)
+{
+        return nqueue_append(&event_processor->pending_events,
+                             ev->nq_node);
+}
+
+int event_processor_handler_register(struct faultd_event_handler *handler)
+{
+        if (!handler->event_match)
+                return -EINVAL;
+
+        list_add_tail(&handler->node, &event_processor->event_handlers);
+}
+
+int event_processor_handler_unregister(struct faultd_event_handler *handler)
+{
+        list_del(&handler->node);
+}
diff --git a/src/event_processor.h b/src/event_processor.h
new file mode 100644 (file)
index 0000000..d141663
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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_PROCESSOR_H
+#define FAULTD_EVENT_PROCESSOR_H
+
+#include "event.h"
+#include "notify_queue.h"
+#include "list.h"
+
+struct faultd_event_handler {
+
+        /* Would you like to handle this? */
+        int (*event_match)(struct faultd_event_handler *handler,
+                           struct faultd_event *ev);
+
+        /* 
+         * All events dedicated to this handler will
+         * be placed in this queue.
+         */
+        struct nqueue_head event_queue;
+
+        struct list_head node;
+};
+
+int event_processor_report_event(struct faultd_event *ev);
+
+int event_processor_handler_register(struct faultd_event_handler *handler);
+int event_processor_handler_unregister(struct faultd_event_handler *handler);
+
+#endif /* FAULTD_EVENT_PROCESSOR_H */