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;
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 = {
/* 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);
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;
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;
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;
/*
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;
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;
}
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;
+}
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;
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;
};
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 */
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 */
{
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,
/* 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);
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,
/* 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);
*/
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 = {
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;
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,