Allow events to be handled by more than one handler 66/148366/8
authorKonrad Kuchciak <k.kuchciak@samsung.com>
Wed, 6 Sep 2017 14:51:48 +0000 (16:51 +0200)
committerKonrad Kuchciak <k.kuchciak@samsung.com>
Thu, 14 Sep 2017 07:53:06 +0000 (09:53 +0200)
Change-Id: Ie069de32e88bdee7eeacfc19e68bc627b12bfb89
Signed-off-by: Konrad Kuchciak <k.kuchciak@samsung.com>
12 files changed:
src/action/action_executed_handler.c
src/action/action_executor.c
src/action/service_recover.c
src/action/service_restart.c
src/action/system_reboot.c
src/action/system_reboot_to_recovery.c
src/core/event.c
src/core/event.h
src/core/event_processor.c
src/decision_makers/rv_dm.c
src/decision_makers/standard_fault_dm.c
src/decision_makers/vip_fault_dm.c

index 58e499b1c84a64e5f1fea021b300b6c19194341e..d19093c811b3ee122d877d70967f572eeda97761 100644 (file)
@@ -30,9 +30,7 @@ static int ae_event_match(struct faultd_event_handler *handler,
 
 static int ae_handle_event(struct faultd_event_handler *handler)
 {
-       struct faultd_event *ev = nqueue_pop(&handler->event_queue,
-                                                                                struct faultd_event,
-                                                                                nq_node);
+       struct faultd_event *ev = pop_faultd_event(&handler->event_queue);
 
        faultd_event_unref(ev);
        return 0;
index 5e4e91ad7d8439c4591198e302cfce4348cee42b..ac4d3ea0095204f506ce2234456ee59e34bc92df 100644 (file)
@@ -37,29 +37,35 @@ static int ae_event_match(struct faultd_event_handler *handler,
 
 static int ae_execute_action(struct faultd_event_handler *handler)
 {
-       struct faultd_event *ev = nqueue_pop(&handler->event_queue,
-                                                                                struct faultd_event,
-                                                                                nq_node);
+       struct faultd_event *ev = pop_faultd_event(&handler->event_queue);
        struct decision_made_event *dm_ev = to_decision_made_event(ev);
        struct action_executor *ae = container_of(handler, struct action_executor,
                                                                                          handler);
        struct faultd_action *action;
+       int ret = -1;
 
        list_for_each_entry(action, &ae->builtin_actions, node)
                if (strcmp(action->action_id , dm_ev->action) == 0) {
-                       nqueue_append(&action->execution_queue, &ev->nq_node);
-                       dm_ev = NULL;
+                       ret = append_faultd_event(&action->execution_queue, ev);
+                       if (ret) {
+                               log_error("Unable to append event to the queue");
+                               ret = 0;
+                               goto cleanup;
+                       }
                        break;
                }
 
        /* TODO: Here is a good place to insert plugin search */
 
-       if (dm_ev) {
+       if (ret) {
                log_error("No implementation of %s action.", dm_ev->action);
-               faultd_event_unref(ev);
+               ret = 0;
+               goto cleanup;
        }
 
-       return 0;
+cleanup:
+       faultd_event_unref(ev);
+       return ret;
 }
 
 static struct action_executor action_executor = {
@@ -129,9 +135,7 @@ void action_executor_action_unregister(struct faultd_action *act)
 
        /* TODO: What to do with all pending executions? */
        while (!nqueue_empty(&act->execution_queue)) {
-               struct faultd_event *ev = nqueue_pop(&act->execution_queue,
-                                                                                        struct faultd_event,
-                                                                                        nq_node);
+               struct faultd_event *ev = pop_faultd_event(&act->execution_queue);
                char *str = faultd_event_to_string(ev);
 
                log_error("Unhandled event: %s", str);
index a34d15e595076ecb99baaef4781f3e92ac668948..e60349556fab00c6b681145263228b30ce064e85 100644 (file)
@@ -25,8 +25,7 @@
 
 static int recover_service(struct faultd_action *action)
 {
-       struct faultd_event *ev = nqueue_pop(&action->execution_queue,
-                                                                                struct faultd_event, nq_node);
+       struct faultd_event *ev = pop_faultd_event(&action->execution_queue);
        struct decision_made_event *dm_ev = to_decision_made_event(ev);
        char *service_path = NULL;
        int ret;
index 5d284fb58452163f73c7be16d7c60061c0ffbe54..dc14dfe3f67cf4144c9f4c0660e056211caaa192 100644 (file)
@@ -25,8 +25,7 @@
 
 static int restart_service(struct faultd_action *action)
 {
-       struct faultd_event *ev = nqueue_pop(&action->execution_queue,
-                                                                                struct faultd_event, nq_node);
+       struct faultd_event *ev = pop_faultd_event(&action->execution_queue);
        struct decision_made_event *dm_ev = to_decision_made_event(ev);
        char *service_path = NULL;
        int ret;
index 8f49ec9bc30e127b8a79cc378cfc8380e627f9cb..a62b48b9ddd2fa5267912d46fa3a0f5a8790becb 100644 (file)
@@ -24,8 +24,7 @@
 
 static int reboot_system(struct faultd_action *action)
 {
-       struct faultd_event *ev = nqueue_pop(&action->execution_queue,
-                                                                                struct faultd_event, nq_node);
+       struct faultd_event *ev = pop_faultd_event(&action->execution_queue);
        int ret;
 
        /*
index d2335d6c943ff214f19bb35de52fac082b8a0217..f9e188d1213baf8b8093c1b7b5fef19164f7242d 100644 (file)
@@ -31,8 +31,7 @@
 
 static int reboot_system_to_recovery(struct faultd_action *action)
 {
-       struct faultd_event *ev = nqueue_pop(&action->execution_queue,
-                                                                                struct faultd_event, nq_node);
+       struct faultd_event *ev = pop_faultd_event(&action->execution_queue);
        mode_t prev_umask;
        FILE *rp_file;
        size_t n_wrte;
index 37a69666bf9a6dc7aba616d7edd60348e87320a9..5c9e2008416ce4f96d80d26f4e7ef4b812f39c45 100644 (file)
@@ -166,7 +166,8 @@ int faultd_event_init_internal(struct faultd_event_type *ev_type,
 
        uref_init(&ev->uref, release_faultd_event);
        INIT_LIST_HEAD(&ev->node);
-       INIT_NQUEUE_NODE(&ev->nq_node);
+       INIT_NQUEUE_NODE(&ev->event_queue_node.node);
+       ev->event_queue_node.ev = ev;
 
        return 0;
 }
@@ -220,3 +221,38 @@ cleanup:
 
        return ret;
 }
+
+int append_faultd_event(struct nqueue_head *head, struct faultd_event *ev)
+{
+       struct eq_node *event_queue_node;
+
+       if (list_empty(&ev->event_queue_node.node)) {
+               event_queue_node = &ev->event_queue_node;
+       } else {
+               event_queue_node = malloc(sizeof(*event_queue_node));
+               if (!event_queue_node) {
+                       log_error("Unable to allocate memory");
+                       return -ENOMEM;
+               }
+               event_queue_node->ev = ev;
+       }
+
+       faultd_event_ref(ev);
+
+       return nqueue_append(head, &event_queue_node->node);
+}
+
+struct faultd_event *pop_faultd_event(struct nqueue_head *head)
+{
+       struct eq_node *event_queue_node = nqueue_pop(head,
+                                                                                                 struct eq_node,
+                                                                                                 node);
+       struct faultd_event *ev = event_queue_node->ev;
+
+       if (event_queue_node == &ev->event_queue_node)
+               INIT_NQUEUE_NODE(&ev->event_queue_node.node);
+       else
+               free(event_queue_node);
+
+       return ev;
+}
index 8b40730d6e2d5a530e965fe998ed31079e0f598c..6405d669f49e5e88e0c5e310ad20fa70a2d3e76b 100644 (file)
@@ -60,6 +60,11 @@ struct faultd_event_type {
        struct list_head node;
 };
 
+struct eq_node {
+       struct faultd_event *ev;
+       struct nqueue_node node;
+};
+
 struct faultd_event {
        struct timespec timestamp;
        struct system_booted_event *boot_event;
@@ -72,8 +77,9 @@ struct faultd_event {
        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;
+       /* To be used by event processor */
+       struct eq_node event_queue_node;
+
        faultd_oid_t oid;
 };
 
@@ -143,4 +149,7 @@ int faultd_event_deserialize_internal(const struct faultd_object *in, struct fau
 void set_boot_event(struct system_booted_event *sb_ev);
 struct system_booted_event *get_boot_event(void);
 
+int append_faultd_event(struct nqueue_head *head, struct faultd_event *ev);
+struct faultd_event *pop_faultd_event(struct nqueue_head *head);
+
 #endif /* FAULTD_EVENT_H */
index 7ef9b0b31d5fd8f7d93fcf08111e2a40ae3a19c9..863f9f75ae67dc1f1e7e02b250811707e3c321e8 100644 (file)
@@ -38,9 +38,9 @@ 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 *ev = pop_faultd_event(&eprocessor->pending_events);
        struct faultd_event_handler *handler;
+       int ret = -1;
 
        /* TODO: Here is a good place to put our event into DB */
        {
@@ -51,18 +51,24 @@ static int event_processor_callback(sd_event_source *s,
 
        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;
-                       break;
+                       ret = append_faultd_event(&handler->event_queue, ev);
+                       if (ret) {
+                               log_error("Unable to append event to the queue");
+                               ret = 0;
+                               goto cleanup;
+                       }
                }
        }
 
-       if (ev) {
+       if (ret) {
                log_error("No handler for event found");
-               faultd_event_unref(ev);
+               ret = 0;
+               goto cleanup;
        }
 
-       return 0;
+cleanup:
+       faultd_event_unref(ev);
+       return ret;
 }
 
 static int event_processor_init(struct faultd_module *module,
@@ -106,9 +112,7 @@ static void event_processor_cleanup(struct faultd_module *module)
 
        /* 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);
+               struct faultd_event *ev = pop_faultd_event(&eprocessor->pending_events);
                char *str = faultd_event_to_string(ev);
                log_error("Unhandled event: %s", str);
                free(str);
@@ -154,8 +158,7 @@ int event_processor_report_event(struct faultd_event *ev)
 unref_obj:
        faultd_object_unref(obj);
 
-       return nqueue_append(&event_processor.pending_events,
-                                                &ev->nq_node);
+       return append_faultd_event(&event_processor.pending_events, ev);
 }
 
 static int event_processor_handler_callback(sd_event_source *s, int fd,
@@ -208,9 +211,7 @@ void event_processor_handler_unregister(struct faultd_event_handler *handler)
 
        /* TODO: What to do with unhandled events? */
        while (!nqueue_empty(&handler->event_queue)) {
-               struct faultd_event *ev = nqueue_pop(&event_processor.pending_events,
-                                                                                        struct faultd_event,
-                                                                                        nq_node);
+               struct faultd_event *ev = pop_faultd_event(&event_processor.pending_events);
                char *str = faultd_event_to_string(ev);
 
                log_error("Unhandled event: %s", str);
index 79341895b3b7d74457b8e38d634e50aefde4cfd9..2d1d33ec02144c6a8a787f93bc78586b7dd06ed9 100644 (file)
@@ -42,9 +42,7 @@ static int rv_event_match(struct faultd_event_handler *handler,
  */
 static int rv_make_decision(struct faultd_event_handler *handler)
 {
-       struct faultd_event *ev = nqueue_pop(&handler->event_queue,
-                                                                                struct faultd_event,
-                                                                                nq_node);
+       struct faultd_event *ev = pop_faultd_event(&handler->event_queue);
        struct resource_violation_event *rv_ev = to_resource_violation_event(ev);
        struct faultd_event *new_ev;
        struct dm_event_data ev_data = {
index da47e96c15475dfc396b0c28ba08e50d99a433e2..8901e92a669c362862c621e334d04f51f7dda44f 100644 (file)
@@ -41,9 +41,7 @@ static int sf_event_match(struct faultd_event_handler *handler,
 
 static int sf_make_decision(struct faultd_event_handler *handler)
 {
-       struct faultd_event *ev = nqueue_pop(&handler->event_queue,
-                                                                                struct faultd_event,
-                                                                                nq_node);
+       struct faultd_event *ev = pop_faultd_event(&handler->event_queue);
        struct service_failed_event *sf_ev = to_service_failed_event(ev);
        struct system_booted_event *boot_event;
        struct faultd_event *new_ev;
index 31207d05851cef71a8da48e765f8514d53149775..d2e067ced098397f6bd94ef05cc1a43cf8ba065d 100644 (file)
@@ -38,9 +38,7 @@ static int vf_event_match(struct faultd_event_handler *handler,
 
 static int vf_make_decision(struct faultd_event_handler *handler)
 {
-       struct faultd_event *ev = nqueue_pop(&handler->event_queue,
-                                                                                struct faultd_event,
-                                                                                nq_node);
+       struct faultd_event *ev = pop_faultd_event(&handler->event_queue);
        struct faultd_event *new_ev;
        struct dm_event_data ev_data = {
                .reason = ev,