diff options
author | Konrad Kuchciak <k.kuchciak@samsung.com> | 2017-09-06 16:51:48 +0200 |
---|---|---|
committer | Konrad Kuchciak <k.kuchciak@samsung.com> | 2017-09-14 09:53:06 +0200 |
commit | 9ffa47d0303b40d5213f87da4cfcd2174c54c8bb (patch) | |
tree | ecb6276b9e9842a73e26344323ac9cd7ef9c5f1f | |
parent | be8af647b995654c3e61dcfc964e5765bd8e16e8 (diff) | |
download | faultd-9ffa47d0303b40d5213f87da4cfcd2174c54c8bb.tar.gz faultd-9ffa47d0303b40d5213f87da4cfcd2174c54c8bb.tar.bz2 faultd-9ffa47d0303b40d5213f87da4cfcd2174c54c8bb.zip |
Allow events to be handled by more than one handler
Change-Id: Ie069de32e88bdee7eeacfc19e68bc627b12bfb89
Signed-off-by: Konrad Kuchciak <k.kuchciak@samsung.com>
-rw-r--r-- | src/action/action_executed_handler.c | 4 | ||||
-rw-r--r-- | src/action/action_executor.c | 26 | ||||
-rw-r--r-- | src/action/service_recover.c | 3 | ||||
-rw-r--r-- | src/action/service_restart.c | 3 | ||||
-rw-r--r-- | src/action/system_reboot.c | 3 | ||||
-rw-r--r-- | src/action/system_reboot_to_recovery.c | 3 | ||||
-rw-r--r-- | src/core/event.c | 38 | ||||
-rw-r--r-- | src/core/event.h | 13 | ||||
-rw-r--r-- | src/core/event_processor.c | 33 | ||||
-rw-r--r-- | src/decision_makers/rv_dm.c | 4 | ||||
-rw-r--r-- | src/decision_makers/standard_fault_dm.c | 4 | ||||
-rw-r--r-- | src/decision_makers/vip_fault_dm.c | 4 |
12 files changed, 88 insertions, 50 deletions
diff --git a/src/action/action_executed_handler.c b/src/action/action_executed_handler.c index 58e499b..d19093c 100644 --- a/src/action/action_executed_handler.c +++ b/src/action/action_executed_handler.c @@ -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; diff --git a/src/action/action_executor.c b/src/action/action_executor.c index 5e4e91a..ac4d3ea 100644 --- a/src/action/action_executor.c +++ b/src/action/action_executor.c @@ -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); diff --git a/src/action/service_recover.c b/src/action/service_recover.c index a34d15e..e603495 100644 --- a/src/action/service_recover.c +++ b/src/action/service_recover.c @@ -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; diff --git a/src/action/service_restart.c b/src/action/service_restart.c index 5d284fb..dc14dfe 100644 --- a/src/action/service_restart.c +++ b/src/action/service_restart.c @@ -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; diff --git a/src/action/system_reboot.c b/src/action/system_reboot.c index 8f49ec9..a62b48b 100644 --- a/src/action/system_reboot.c +++ b/src/action/system_reboot.c @@ -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; /* diff --git a/src/action/system_reboot_to_recovery.c b/src/action/system_reboot_to_recovery.c index d2335d6..f9e188d 100644 --- a/src/action/system_reboot_to_recovery.c +++ b/src/action/system_reboot_to_recovery.c @@ -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; diff --git a/src/core/event.c b/src/core/event.c index 37a6966..5c9e200 100644 --- a/src/core/event.c +++ b/src/core/event.c @@ -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; +} diff --git a/src/core/event.h b/src/core/event.h index 8b40730..6405d66 100644 --- a/src/core/event.h +++ b/src/core/event.h @@ -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 */ diff --git a/src/core/event_processor.c b/src/core/event_processor.c index 7ef9b0b..863f9f7 100644 --- a/src/core/event_processor.c +++ b/src/core/event_processor.c @@ -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); diff --git a/src/decision_makers/rv_dm.c b/src/decision_makers/rv_dm.c index 7934189..2d1d33e 100644 --- a/src/decision_makers/rv_dm.c +++ b/src/decision_makers/rv_dm.c @@ -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 = { diff --git a/src/decision_makers/standard_fault_dm.c b/src/decision_makers/standard_fault_dm.c index da47e96..8901e92 100644 --- a/src/decision_makers/standard_fault_dm.c +++ b/src/decision_makers/standard_fault_dm.c @@ -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; diff --git a/src/decision_makers/vip_fault_dm.c b/src/decision_makers/vip_fault_dm.c index 31207d0..d2e067c 100644 --- a/src/decision_makers/vip_fault_dm.c +++ b/src/decision_makers/vip_fault_dm.c @@ -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, |