return run_command_no_wait(handle, &cmd);
}
+/*
+ * Takes ownership of the payload if present.
+ */
LTTNG_HIDDEN
-struct lttng_event_notifier_notification *
-lttng_event_notifier_notification_create(uint64_t tracer_token,
- enum lttng_domain_type domain)
+struct lttng_event_notifier_notification *lttng_event_notifier_notification_create(
+ uint64_t tracer_token,
+ enum lttng_domain_type domain,
+ char *payload,
+ size_t payload_size)
{
struct lttng_event_notifier_notification *notification = NULL;
assert(domain != LTTNG_DOMAIN_NONE);
+ assert((payload && payload_size) || (!payload && !payload_size));
- notification = zmalloc(
- sizeof(struct lttng_event_notifier_notification));
+ notification = zmalloc(sizeof(struct lttng_event_notifier_notification));
if (notification == NULL) {
ERR("[notification-thread] Error allocating notification");
goto end;
notification->tracer_token = tracer_token;
notification->type = domain;
+ notification->capture_buffer = payload;
+ notification->capture_buf_size = payload_size;
end:
return notification;
return;
}
+ free(notification->capture_buffer);
free(notification);
}
#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,
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;
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_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;
}
struct lttng_event_notifier_notification {
uint64_t tracer_token;
enum lttng_domain_type type;
+ size_t capture_buf_size;
+ char *capture_buffer;
};
struct notification_client_list_element {
notification_client_id id,
enum client_transmission_status transmission_status);
+/*
+ * Takes ownership of the payload if present.
+ */
LTTNG_HIDDEN
struct lttng_event_notifier_notification *lttng_event_notifier_notification_create(
uint64_t tracer_token,
- enum lttng_domain_type domain);
+ enum lttng_domain_type domain,
+ char *payload,
+ size_t payload_size);
LTTNG_HIDDEN
void lttng_event_notifier_notification_destroy(