sessiond: notification-thread: Missing action executor status handling
[lttng-tools.git] / src / bin / lttng-sessiond / notification-thread-events.c
index 747902612d93059705cd9d987cde39e1cc757a31..ccd285a8103d6a344bcb3344abbd982f079a0c13 100644 (file)
@@ -21,6 +21,8 @@
 #include <common/macros.h>
 #include <lttng/condition/condition.h>
 #include <lttng/action/action-internal.h>
+#include <lttng/action/group-internal.h>
+#include <lttng/domain-internal.h>
 #include <lttng/notification/notification-internal.h>
 #include <lttng/condition/condition-internal.h>
 #include <lttng/condition/buffer-usage-internal.h>
@@ -48,6 +50,9 @@
 #define CLIENT_POLL_MASK_IN (LPOLLIN | LPOLLERR | LPOLLHUP | LPOLLRDHUP)
 #define CLIENT_POLL_MASK_IN_OUT (CLIENT_POLL_MASK_IN | LPOLLOUT)
 
+/* The tracers currently limit the capture size to PIPE_BUF (4kb on linux). */
+#define MAX_CAPTURE_SIZE (PIPE_BUF)
+
 enum lttng_object_type {
        LTTNG_OBJECT_TYPE_UNKNOWN,
        LTTNG_OBJECT_TYPE_NONE,
@@ -4244,10 +4249,12 @@ struct lttng_event_notifier_notification *recv_one_event_notifier_notification(
        int ret;
        uint64_t token;
        struct lttng_event_notifier_notification *notification = NULL;
+       char *capture_buffer = NULL;
+       size_t capture_buffer_size;
        void *reception_buffer;
        size_t reception_size;
 
-       struct lttng_ust_event_notifier_notification ust_notification;
+       struct lttng_ust_abi_event_notifier_notification ust_notification;
        struct lttng_kernel_event_notifier_notification kernel_notification;
 
        /* Init lttng_event_notifier_notification */
@@ -4280,17 +4287,55 @@ struct lttng_event_notifier_notification *recv_one_event_notifier_notification(
        switch(domain) {
        case LTTNG_DOMAIN_UST:
                token = ust_notification.token;
+               capture_buffer_size = ust_notification.capture_buf_size;
                break;
        case LTTNG_DOMAIN_KERNEL:
                token = kernel_notification.token;
+               capture_buffer_size = 0;
                break;
        default:
                abort();
        }
 
-       notification = lttng_event_notifier_notification_create(
-                       token, domain);
+       if (capture_buffer_size == 0) {
+               capture_buffer = NULL;
+               goto skip_capture;
+       }
+
+       if (capture_buffer_size > MAX_CAPTURE_SIZE) {
+               ERR("[notification-thread] Event notifier has a capture payload size which exceeds the maximum allowed size: capture_payload_size = %zu bytes, max allowed size = %d bytes",
+                               capture_buffer_size, MAX_CAPTURE_SIZE);
+               goto end;
+       }
+
+       capture_buffer = zmalloc(capture_buffer_size);
+       if (!capture_buffer) {
+               ERR("[notification-thread] Failed to allocate capture buffer");
+               goto end;
+       }
+
+       /* Fetch additional payload (capture). */
+       ret = lttng_read(notification_pipe_read_fd, capture_buffer, capture_buffer_size);
+       if (ret != capture_buffer_size) {
+               ERR("[notification-thread] Failed to read from event source pipe (fd = %i)",
+                               notification_pipe_read_fd);
+               goto end;
+       }
+
+skip_capture:
+       notification = lttng_event_notifier_notification_create(token, domain,
+                       capture_buffer, capture_buffer_size);
+       if (notification == NULL) {
+               goto end;
+       }
+
+       /*
+        * Ownership transfered to the lttng_event_notifier_notification object.
+        */
+       capture_buffer = NULL;
+
 end:
+       free(capture_buffer);
        return notification;
 }
 
@@ -4307,6 +4352,7 @@ int dispatch_one_event_notifier_notification(struct notification_thread_state *s
        struct notification_client_list *client_list = NULL;
        const char *trigger_name;
        int ret;
+       unsigned int capture_count = 0;
 
        /* Find triggers associated with this token. */
        rcu_read_lock();
@@ -4339,14 +4385,34 @@ int dispatch_one_event_notifier_notification(struct notification_thread_state *s
        trigger_status = lttng_trigger_get_name(element->trigger, &trigger_name);
        assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
 
+       if (lttng_condition_event_rule_get_capture_descriptor_count(
+                           lttng_trigger_get_const_condition(element->trigger),
+                           &capture_count) != LTTNG_CONDITION_STATUS_OK) {
+               ERR("Failed to get capture count");
+               ret = -1;
+               goto end;
+       }
+
+       if (!notification->capture_buffer && capture_count != 0) {
+               ERR("Expected capture but capture buffer is null");
+               ret = -1;
+               goto end;
+       }
+
        evaluation = lttng_evaluation_event_rule_create(
-                       trigger_name);
+                       container_of(lttng_trigger_get_const_condition(
+                                                    element->trigger),
+                                       struct lttng_condition_event_rule,
+                                       parent),
+                       trigger_name,
+                       notification->capture_buffer,
+                       notification->capture_buf_size, false);
+
        if (evaluation == NULL) {
                ERR("[notification-thread] Failed to create event rule hit evaluation while creating and enqueuing action executor job");
                ret = -1;
                goto end_unlock;
        }
-
        client_list = get_client_list_from_condition(state,
                        lttng_trigger_get_const_condition(element->trigger));
        executor_status = action_executor_enqueue(state->executor,
@@ -4404,6 +4470,7 @@ next_client:
                pthread_mutex_unlock(&client_list->lock);
                break;
        }
+       case ACTION_EXECUTOR_STATUS_INVALID:
        case ACTION_EXECUTOR_STATUS_ERROR:
                /* Fatal error, shut down everything. */
                ERR("Fatal error encoutered while enqueuing action to the action executor");
@@ -4417,6 +4484,7 @@ next_client:
 end_unlock:
        notification_client_list_put(client_list);
        rcu_read_unlock();
+end:
        return ret;
 }
 
@@ -4425,14 +4493,14 @@ int handle_one_event_notifier_notification(
                struct notification_thread_state *state,
                int pipe, enum lttng_domain_type domain)
 {
-       int ret;
+       int ret = 0;
        struct lttng_event_notifier_notification *notification = NULL;
 
        notification = recv_one_event_notifier_notification(pipe, domain);
        if (notification == NULL) {
+               /* Reception failed, don't consider it fatal. */
                ERR("[notification-thread] Error receiving an event notifier notification from tracer: fd = %i, domain = %s",
                                pipe, lttng_domain_type_str(domain));
-               ret = -1;
                goto end;
        }
 
This page took 0.029336 seconds and 4 git commands to generate.