2 * SPDX-License-Identifier: LGPL-2.1-only
4 * Copyright (C) 2020 Francis Deslauriers <francis.deslauriers@efficios.com>
13 #include <lttng/ust-endian.h>
14 #include "common/logging.h"
15 #include <urcu/rculist.h>
17 #include "lttng-tracer-core.h"
18 #include "lib/lttng-ust/events.h"
19 #include "common/msgpack/msgpack.h"
20 #include "lttng-bytecode.h"
21 #include "common/patient.h"
24 * We want this write to be atomic AND non-blocking, meaning that we
25 * want to write either everything OR nothing.
26 * According to `pipe(7)`, writes that are less than `PIPE_BUF` bytes must be
27 * atomic, so we bound the capture buffer size to the `PIPE_BUF` minus the size
28 * of the notification struct we are sending alongside the capture buffer.
30 #define CAPTURE_BUFFER_SIZE \
31 (PIPE_BUF - sizeof(struct lttng_ust_abi_event_notifier_notification) - 1)
33 #define MSG_WRITE_NIL_LEN 1
35 struct lttng_event_notifier_notification
{
37 uint64_t event_notifier_token
;
38 uint8_t capture_buf
[CAPTURE_BUFFER_SIZE
];
39 struct lttng_msgpack_writer writer
;
44 int capture_enum(struct lttng_msgpack_writer
*writer
,
45 struct lttng_interpreter_output
*output
)
49 ret
= lttng_msgpack_begin_map(writer
, 2);
53 ret
= lttng_msgpack_write_str(writer
, "type");
57 ret
= lttng_msgpack_write_str(writer
, "enum");
61 ret
= lttng_msgpack_write_str(writer
, "value");
66 switch (output
->type
) {
67 case LTTNG_INTERPRETER_TYPE_SIGNED_ENUM
:
68 ret
= lttng_msgpack_write_signed_integer(writer
, output
->u
.s
);
73 case LTTNG_INTERPRETER_TYPE_UNSIGNED_ENUM
:
74 ret
= lttng_msgpack_write_signed_integer(writer
, output
->u
.u
);
80 CRIT("Unknown enum output type\n");
85 ret
= lttng_msgpack_end_map(writer
);
91 int64_t capture_sequence_element_signed(uint8_t *ptr
,
92 const struct lttng_ust_type_integer
*integer_type
)
95 unsigned int size
= integer_type
->size
;
96 bool byte_order_reversed
= integer_type
->reverse_byte_order
;
105 tmp
= *(int16_t *) ptr
;
106 if (byte_order_reversed
)
107 tmp
= lttng_ust_bswap_16(tmp
);
115 tmp
= *(int32_t *) ptr
;
116 if (byte_order_reversed
)
117 tmp
= lttng_ust_bswap_32(tmp
);
125 tmp
= *(int64_t *) ptr
;
126 if (byte_order_reversed
)
127 tmp
= lttng_ust_bswap_64(tmp
);
133 CRIT("Unknown sequence element size\n");
141 uint64_t capture_sequence_element_unsigned(uint8_t *ptr
,
142 const struct lttng_ust_type_integer
*integer_type
)
145 unsigned int size
= integer_type
->size
;
146 bool byte_order_reversed
= integer_type
->reverse_byte_order
;
155 tmp
= *(uint16_t *) ptr
;
156 if (byte_order_reversed
)
157 tmp
= lttng_ust_bswap_16(tmp
);
165 tmp
= *(uint32_t *) ptr
;
166 if (byte_order_reversed
)
167 tmp
= lttng_ust_bswap_32(tmp
);
175 tmp
= *(uint64_t *) ptr
;
176 if (byte_order_reversed
)
177 tmp
= lttng_ust_bswap_64(tmp
);
183 CRIT("Unknown sequence element size\n");
191 int capture_sequence(struct lttng_msgpack_writer
*writer
,
192 struct lttng_interpreter_output
*output
)
194 const struct lttng_ust_type_integer
*integer_type
;
195 const struct lttng_ust_type_common
*nested_type
;
200 ret
= lttng_msgpack_begin_array(writer
, output
->u
.sequence
.nr_elem
);
204 ptr
= (uint8_t *) output
->u
.sequence
.ptr
;
205 nested_type
= output
->u
.sequence
.nested_type
;
206 switch (nested_type
->type
) {
207 case lttng_ust_type_integer
:
208 integer_type
= lttng_ust_get_type_integer(nested_type
);
210 case lttng_ust_type_enum
:
211 /* Treat enumeration as an integer. */
212 integer_type
= lttng_ust_get_type_integer(lttng_ust_get_type_enum(nested_type
)->container_type
);
215 CRIT("Capture of array of non-integer are not supported\n");
219 signedness
= integer_type
->signedness
;
220 for (i
= 0; i
< output
->u
.sequence
.nr_elem
; i
++) {
222 ret
= lttng_msgpack_write_signed_integer(writer
,
223 capture_sequence_element_signed(ptr
, integer_type
));
225 ret
= lttng_msgpack_write_unsigned_integer(writer
,
226 capture_sequence_element_unsigned(ptr
, integer_type
));
233 * We assume that alignment is smaller or equal to the size.
234 * This currently holds true but if it changes in the future,
235 * we will want to change the pointer arithmetic below to
236 * take into account that the next element might be further
239 assert(integer_type
->alignment
<= integer_type
->size
);
241 /* Size is in number of bits. */
242 ptr
+= (integer_type
->size
/ CHAR_BIT
) ;
245 ret
= lttng_msgpack_end_array(writer
);
251 int notification_init(struct lttng_event_notifier_notification
*notif
,
252 const struct lttng_ust_event_notifier
*event_notifier
)
254 struct lttng_msgpack_writer
*writer
= ¬if
->writer
;
257 notif
->event_notifier_token
= event_notifier
->priv
->parent
.user_token
;
258 notif
->notification_fd
= event_notifier
->priv
->group
->notification_fd
;
259 notif
->has_captures
= false;
261 if (event_notifier
->priv
->num_captures
> 0) {
262 lttng_msgpack_writer_init(writer
, notif
->capture_buf
,
263 CAPTURE_BUFFER_SIZE
);
265 ret
= lttng_msgpack_begin_array(writer
, event_notifier
->priv
->num_captures
);
269 notif
->has_captures
= true;
276 int notification_append_capture(
277 struct lttng_event_notifier_notification
*notif
,
278 struct lttng_interpreter_output
*output
)
280 struct lttng_msgpack_writer
*writer
= ¬if
->writer
;
283 switch (output
->type
) {
284 case LTTNG_INTERPRETER_TYPE_S64
:
285 ret
= lttng_msgpack_write_signed_integer(writer
, output
->u
.s
);
287 case LTTNG_INTERPRETER_TYPE_U64
:
288 ret
= lttng_msgpack_write_unsigned_integer(writer
, output
->u
.u
);
290 case LTTNG_INTERPRETER_TYPE_DOUBLE
:
291 ret
= lttng_msgpack_write_double(writer
, output
->u
.d
);
293 case LTTNG_INTERPRETER_TYPE_STRING
:
294 ret
= lttng_msgpack_write_str(writer
, output
->u
.str
.str
);
296 case LTTNG_INTERPRETER_TYPE_SEQUENCE
:
297 ret
= capture_sequence(writer
, output
);
299 case LTTNG_INTERPRETER_TYPE_SIGNED_ENUM
:
300 case LTTNG_INTERPRETER_TYPE_UNSIGNED_ENUM
:
301 ret
= capture_enum(writer
, output
);
304 CRIT("Unknown capture output type\n");
311 int notification_append_empty_capture(
312 struct lttng_event_notifier_notification
*notif
)
314 return lttng_msgpack_write_nil(¬if
->writer
);
317 static void record_error(const struct lttng_ust_event_notifier
*event_notifier
)
319 struct lttng_event_notifier_group
*event_notifier_group
=
320 event_notifier
->priv
->group
;
321 struct lttng_counter
*error_counter
;
322 size_t dimension_index
[1];
325 error_counter
= CMM_LOAD_SHARED(event_notifier_group
->error_counter
);
327 * load-acquire paired with store-release orders creation of the
328 * error counter and setting error_counter_len before the
329 * error_counter is used.
330 * Currently a full memory barrier is used, which could be
331 * turned into acquire-release barriers.
334 /* This group may not have an error counter attached to it. */
338 dimension_index
[0] = event_notifier
->priv
->error_counter_index
;
339 ret
= event_notifier_group
->error_counter
->ops
->counter_add(
340 error_counter
->counter
, dimension_index
, 1);
346 void notification_send(struct lttng_event_notifier_notification
*notif
,
347 const struct lttng_ust_event_notifier
*event_notifier
)
352 struct lttng_ust_abi_event_notifier_notification ust_notif
= {0};
357 ust_notif
.token
= event_notifier
->priv
->parent
.user_token
;
360 * Prepare sending the notification from multiple buffers using an
361 * array of `struct iovec`. The first buffer of the vector is
362 * notification structure itself and is always present.
364 iov
[0].iov_base
= &ust_notif
;
365 iov
[0].iov_len
= sizeof(ust_notif
);
367 if (notif
->has_captures
) {
369 * If captures were requested, the second buffer of the array
370 * is the capture buffer.
372 assert(notif
->writer
.buffer
);
373 content_len
= notif
->writer
.write_pos
- notif
->writer
.buffer
;
375 assert(content_len
> 0 && content_len
<= CAPTURE_BUFFER_SIZE
);
377 iov
[1].iov_base
= notif
->capture_buf
;
378 iov
[1].iov_len
= content_len
;
386 * Update the capture buffer size so that receiver of the buffer will
387 * know how much to expect.
389 ust_notif
.capture_buf_size
= content_len
;
391 /* Send all the buffers. */
392 ret
= ust_patient_writev(notif
->notification_fd
, iov
, iovec_count
);
394 if (errno
== EAGAIN
) {
395 record_error(event_notifier
);
396 DBG("Cannot send event_notifier notification without blocking: %s",
399 DBG("Error to sending event notifier notification: %s",
407 * Validate that the buffer has enough room to hold empty capture fields.
410 bool validate_buffer_len(struct lttng_event_notifier_notification
*notif
, size_t captures_left
)
412 if (notif
->writer
.end_write_pos
- notif
->writer
.write_pos
< MSG_WRITE_NIL_LEN
* captures_left
)
417 void lttng_event_notifier_notification_send(
418 const struct lttng_ust_event_notifier
*event_notifier
,
419 const char *stack_data
,
420 struct lttng_ust_probe_ctx
*probe_ctx
,
421 struct lttng_ust_notification_ctx
*notif_ctx
)
424 * This function is called from the probe, we must do dynamic
425 * allocation in this context.
427 struct lttng_event_notifier_notification notif
= {0};
428 size_t captures_left
;
430 if (notification_init(¬if
, event_notifier
))
433 captures_left
= event_notifier
->priv
->num_captures
;
434 if (!validate_buffer_len(¬if
, captures_left
))
437 if (caa_unlikely(notif_ctx
->eval_capture
)) {
438 struct lttng_ust_bytecode_runtime
*capture_bc_runtime
;
441 * Iterate over all the capture bytecodes. If the interpreter
442 * functions returns successfully, append the value of the
443 * `output` parameter to the capture buffer. If the interpreter
444 * fails, append an empty capture to the buffer.
446 cds_list_for_each_entry_rcu(capture_bc_runtime
,
447 &event_notifier
->priv
->capture_bytecode_runtime_head
, node
) {
448 struct lttng_interpreter_output output
;
452 lttng_msgpack_save_writer_pos(¬if
.writer
, &save_pos
);
453 if (capture_bc_runtime
->interpreter_func(capture_bc_runtime
,
454 stack_data
, probe_ctx
, &output
) == LTTNG_UST_BYTECODE_INTERPRETER_OK
)
455 ret
= notification_append_capture(¬if
, &output
);
456 if (ret
|| !validate_buffer_len(¬if
, captures_left
)) {
458 * On append capture error or if the generated
459 * buffer data would not leave enough room to
460 * write empty capture fields for the remaining
461 * fields, skip the field capture by restoring
462 * the msgpack writer position and writing an
463 * empty capture field.
465 lttng_msgpack_restore_writer_pos(¬if
.writer
, save_pos
);
466 ret
= notification_append_empty_capture(¬if
);
468 CRIT("Not enough space for empty capture field\n");
473 if (notif
.has_captures
&& lttng_msgpack_end_array(¬if
.writer
))
477 * Send the notification (including the capture buffer) to the
480 notification_send(¬if
, event_notifier
);
484 record_error(event_notifier
);