#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,
* the pipe is closed but empty.
*/
ret = lttng_poll_wait_interruptible(&events, 0);
- if (ret == 0 || (LTTNG_POLL_GETEV(&events, 1) & LPOLLIN) == 0) {
+ if (ret == 0 || (LTTNG_POLL_GETEV(&events, 0) & LPOLLIN) == 0) {
/* No more notification to be read on this pipe. */
ret = 0;
goto end;
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 */
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;
}
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();
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,
end_unlock:
notification_client_list_put(client_list);
rcu_read_unlock();
+end:
return ret;
}
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;
}