Move include/ust/ to include/lttng/
[lttng-ust.git] / libust / ltt-events.c
1 /*
2 * ltt-events.c
3 *
4 * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 *
6 * Holds LTTng per-session event registry.
7 *
8 * Dual LGPL v2.1/GPL v2 license.
9 */
10
11 #define _GNU_SOURCE
12 #include <stdio.h>
13 #include <endian.h>
14 #include <urcu/list.h>
15 #include <urcu/hlist.h>
16 #include <pthread.h>
17 #include <urcu-bp.h>
18 #include <urcu/compiler.h>
19 #include <urcu/uatomic.h>
20 #include <uuid/uuid.h>
21 #include <lttng/tracepoint.h>
22 #include <errno.h>
23 #include <sys/shm.h>
24 #include <sys/ipc.h>
25 #include <lttng/ust-events.h>
26 #include <lttng/usterr-signal-safe.h>
27 #include "lttng/core.h"
28 #include "ltt-tracer.h"
29 #include "ltt-tracer-core.h"
30 #include "lttng/wait.h"
31 #include "../libringbuffer/shm.h"
32
33 typedef u32 uint32_t;
34 #include <lttng/kcompat/jhash.h>
35
36 /*
37 * The sessions mutex is the centralized mutex across UST tracing
38 * control and probe registration. All operations within this file are
39 * called by the communication thread, under ust_lock protection.
40 */
41 static DEFINE_MUTEX(sessions_mutex);
42
43 void ust_lock(void)
44 {
45 pthread_mutex_lock(&sessions_mutex);
46 }
47
48 void ust_unlock(void)
49 {
50 pthread_mutex_unlock(&sessions_mutex);
51 }
52
53 static CDS_LIST_HEAD(sessions);
54 static CDS_LIST_HEAD(ltt_transport_list);
55
56 /*
57 * Pending probes hash table, containing the registered ltt events for
58 * which tracepoint probes are still missing. Protected by the sessions
59 * mutex.
60 */
61 #define PENDING_PROBE_HASH_BITS 6
62 #define PENDING_PROBE_HASH_SIZE (1 << PENDING_PROBE_HASH_BITS)
63 static struct cds_hlist_head pending_probe_table[PENDING_PROBE_HASH_SIZE];
64
65 struct ust_pending_probe {
66 struct ltt_event *event;
67 struct cds_hlist_node node;
68 char name[];
69 };
70
71 static void _ltt_event_destroy(struct ltt_event *event);
72 static void _ltt_channel_destroy(struct ltt_channel *chan);
73 static int _ltt_event_unregister(struct ltt_event *event);
74 static
75 int _ltt_event_metadata_statedump(struct ltt_session *session,
76 struct ltt_channel *chan,
77 struct ltt_event *event);
78 static
79 int _ltt_session_metadata_statedump(struct ltt_session *session);
80
81 /*
82 * called at event creation if probe is missing.
83 * called with session mutex held.
84 */
85 static
86 int add_pending_probe(struct ltt_event *event, const char *name)
87 {
88 struct cds_hlist_head *head;
89 struct ust_pending_probe *e;
90 size_t name_len = strlen(name) + 1;
91 u32 hash = jhash(name, name_len - 1, 0);
92
93 head = &pending_probe_table[hash & (PENDING_PROBE_HASH_SIZE - 1)];
94 e = zmalloc(sizeof(struct ust_pending_probe) + name_len);
95 if (!e)
96 return -ENOMEM;
97 memcpy(&e->name[0], name, name_len);
98 cds_hlist_add_head(&e->node, head);
99 e->event = event;
100 event->pending_probe = e;
101 return 0;
102 }
103
104 /*
105 * remove a pending probe. called when at event teardown and when an
106 * event is fixed (probe is loaded).
107 * called with session mutex held.
108 */
109 static
110 void remove_pending_probe(struct ust_pending_probe *e)
111 {
112 if (!e)
113 return;
114 cds_hlist_del(&e->node);
115 free(e);
116 }
117
118 /*
119 * Called at library load: connect the probe on the events pending on
120 * probe load.
121 * called with session mutex held.
122 */
123 int pending_probe_fix_events(const struct lttng_event_desc *desc)
124 {
125 struct cds_hlist_head *head;
126 struct cds_hlist_node *node, *p;
127 struct ust_pending_probe *e;
128 const char *name = desc->name;
129 size_t name_len = strlen(name) + 1;
130 u32 hash = jhash(name, name_len - 1, 0);
131 int ret = 0;
132
133 head = &pending_probe_table[hash & (PENDING_PROBE_HASH_SIZE - 1)];
134 cds_hlist_for_each_entry_safe(e, node, p, head, node) {
135 struct ltt_event *event;
136 struct ltt_channel *chan;
137
138 if (strcmp(name, e->name))
139 continue;
140 event = e->event;
141 chan = event->chan;
142 assert(!event->desc);
143 event->desc = desc;
144 event->pending_probe = NULL;
145 remove_pending_probe(e);
146 ret |= __tracepoint_probe_register(name,
147 event->desc->probe_callback,
148 event);
149 if (ret)
150 continue;
151 event->id = chan->free_event_id++;
152 ret |= _ltt_event_metadata_statedump(chan->session, chan,
153 event);
154 }
155 return ret;
156 }
157
158 void synchronize_trace(void)
159 {
160 synchronize_rcu();
161 }
162
163 struct ltt_session *ltt_session_create(void)
164 {
165 struct ltt_session *session;
166
167 session = zmalloc(sizeof(struct ltt_session));
168 if (!session)
169 return NULL;
170 CDS_INIT_LIST_HEAD(&session->chan);
171 CDS_INIT_LIST_HEAD(&session->events);
172 uuid_generate(session->uuid);
173 cds_list_add(&session->list, &sessions);
174 return session;
175 }
176
177 void ltt_session_destroy(struct ltt_session *session)
178 {
179 struct ltt_channel *chan, *tmpchan;
180 struct ltt_event *event, *tmpevent;
181 int ret;
182
183 CMM_ACCESS_ONCE(session->active) = 0;
184 cds_list_for_each_entry(event, &session->events, list) {
185 ret = _ltt_event_unregister(event);
186 WARN_ON(ret);
187 }
188 synchronize_trace(); /* Wait for in-flight events to complete */
189 cds_list_for_each_entry_safe(event, tmpevent, &session->events, list)
190 _ltt_event_destroy(event);
191 cds_list_for_each_entry_safe(chan, tmpchan, &session->chan, list)
192 _ltt_channel_destroy(chan);
193 cds_list_del(&session->list);
194 free(session);
195 }
196
197 int ltt_session_enable(struct ltt_session *session)
198 {
199 int ret = 0;
200 struct ltt_channel *chan;
201
202 if (session->active) {
203 ret = -EBUSY;
204 goto end;
205 }
206
207 /*
208 * Snapshot the number of events per channel to know the type of header
209 * we need to use.
210 */
211 cds_list_for_each_entry(chan, &session->chan, list) {
212 if (chan->header_type)
213 continue; /* don't change it if session stop/restart */
214 if (chan->free_event_id < 31)
215 chan->header_type = 1; /* compact */
216 else
217 chan->header_type = 2; /* large */
218 }
219
220 CMM_ACCESS_ONCE(session->active) = 1;
221 CMM_ACCESS_ONCE(session->been_active) = 1;
222 ret = _ltt_session_metadata_statedump(session);
223 if (ret)
224 CMM_ACCESS_ONCE(session->active) = 0;
225 end:
226 return ret;
227 }
228
229 int ltt_session_disable(struct ltt_session *session)
230 {
231 int ret = 0;
232
233 if (!session->active) {
234 ret = -EBUSY;
235 goto end;
236 }
237 CMM_ACCESS_ONCE(session->active) = 0;
238 end:
239 return ret;
240 }
241
242 int ltt_channel_enable(struct ltt_channel *channel)
243 {
244 int old;
245
246 if (channel == channel->session->metadata)
247 return -EPERM;
248 old = uatomic_xchg(&channel->enabled, 1);
249 if (old)
250 return -EEXIST;
251 return 0;
252 }
253
254 int ltt_channel_disable(struct ltt_channel *channel)
255 {
256 int old;
257
258 if (channel == channel->session->metadata)
259 return -EPERM;
260 old = uatomic_xchg(&channel->enabled, 0);
261 if (!old)
262 return -EEXIST;
263 return 0;
264 }
265
266 int ltt_event_enable(struct ltt_event *event)
267 {
268 int old;
269
270 if (event->chan == event->chan->session->metadata)
271 return -EPERM;
272 old = uatomic_xchg(&event->enabled, 1);
273 if (old)
274 return -EEXIST;
275 return 0;
276 }
277
278 int ltt_event_disable(struct ltt_event *event)
279 {
280 int old;
281
282 if (event->chan == event->chan->session->metadata)
283 return -EPERM;
284 old = uatomic_xchg(&event->enabled, 0);
285 if (!old)
286 return -EEXIST;
287 return 0;
288 }
289
290 static struct ltt_transport *ltt_transport_find(const char *name)
291 {
292 struct ltt_transport *transport;
293
294 cds_list_for_each_entry(transport, &ltt_transport_list, node) {
295 if (!strcmp(transport->name, name))
296 return transport;
297 }
298 return NULL;
299 }
300
301 struct ltt_channel *ltt_channel_create(struct ltt_session *session,
302 const char *transport_name,
303 void *buf_addr,
304 size_t subbuf_size, size_t num_subbuf,
305 unsigned int switch_timer_interval,
306 unsigned int read_timer_interval,
307 int *shm_fd, int *wait_fd,
308 uint64_t *memory_map_size)
309 {
310 struct ltt_channel *chan;
311 struct ltt_transport *transport;
312
313 if (session->been_active)
314 goto active; /* Refuse to add channel to active session */
315 transport = ltt_transport_find(transport_name);
316 if (!transport) {
317 DBG("LTTng transport %s not found\n",
318 transport_name);
319 goto notransport;
320 }
321 chan = zmalloc(sizeof(struct ltt_channel));
322 if (!chan)
323 goto nomem;
324 chan->session = session;
325 chan->id = session->free_chan_id++;
326 /*
327 * Note: the channel creation op already writes into the packet
328 * headers. Therefore the "chan" information used as input
329 * should be already accessible.
330 */
331 transport->ops.channel_create("[lttng]", chan, buf_addr,
332 subbuf_size, num_subbuf, switch_timer_interval,
333 read_timer_interval, shm_fd, wait_fd,
334 memory_map_size);
335 if (!chan->chan)
336 goto create_error;
337 chan->enabled = 1;
338 chan->ops = &transport->ops;
339 cds_list_add(&chan->list, &session->chan);
340 return chan;
341
342 create_error:
343 free(chan);
344 nomem:
345 notransport:
346 active:
347 return NULL;
348 }
349
350 /*
351 * Only used internally at session destruction.
352 */
353 static
354 void _ltt_channel_destroy(struct ltt_channel *chan)
355 {
356 chan->ops->channel_destroy(chan);
357 cds_list_del(&chan->list);
358 lttng_destroy_context(chan->ctx);
359 free(chan);
360 }
361
362 /*
363 * Supports event creation while tracing session is active.
364 */
365 struct ltt_event *ltt_event_create(struct ltt_channel *chan,
366 struct lttng_ust_event *event_param,
367 void *filter)
368 {
369 struct ltt_event *event;
370 int ret;
371
372 if (chan->used_event_id == -1UL)
373 goto full;
374 /*
375 * This is O(n^2) (for each event, the loop is called at event
376 * creation). Might require a hash if we have lots of events.
377 */
378 cds_list_for_each_entry(event, &chan->session->events, list)
379 if (event->desc && !strcmp(event->desc->name, event_param->name))
380 goto exist;
381 event = zmalloc(sizeof(struct ltt_event));
382 if (!event)
383 goto cache_error;
384 event->chan = chan;
385 event->filter = filter;
386 /*
387 * used_event_id counts the maximum number of event IDs that can
388 * register if all probes register.
389 */
390 chan->used_event_id++;
391 event->enabled = 1;
392 event->instrumentation = event_param->instrumentation;
393 /* Populate ltt_event structure before tracepoint registration. */
394 cmm_smp_wmb();
395 switch (event_param->instrumentation) {
396 case LTTNG_UST_TRACEPOINT:
397 event->desc = ltt_event_get(event_param->name);
398 if (event->desc) {
399 ret = __tracepoint_probe_register(event_param->name,
400 event->desc->probe_callback,
401 event);
402 if (ret)
403 goto register_error;
404 event->id = chan->free_event_id++;
405 } else {
406 /*
407 * If the probe is not present, event->desc stays NULL,
408 * waiting for the probe to register, and the event->id
409 * stays unallocated.
410 */
411 ret = add_pending_probe(event, event_param->name);
412 if (ret)
413 goto add_pending_error;
414 }
415 break;
416 default:
417 WARN_ON_ONCE(1);
418 }
419 if (event->desc) {
420 ret = _ltt_event_metadata_statedump(chan->session, chan, event);
421 if (ret)
422 goto statedump_error;
423 }
424 cds_list_add(&event->list, &chan->session->events);
425 return event;
426
427 statedump_error:
428 if (event->desc) {
429 WARN_ON_ONCE(__tracepoint_probe_unregister(event_param->name,
430 event->desc->probe_callback,
431 event));
432 ltt_event_put(event->desc);
433 }
434 add_pending_error:
435 register_error:
436 free(event);
437 cache_error:
438 exist:
439 full:
440 return NULL;
441 }
442
443 /*
444 * Only used internally at session destruction.
445 */
446 int _ltt_event_unregister(struct ltt_event *event)
447 {
448 int ret = -EINVAL;
449
450 switch (event->instrumentation) {
451 case LTTNG_UST_TRACEPOINT:
452 if (event->desc) {
453 ret = __tracepoint_probe_unregister(event->desc->name,
454 event->desc->probe_callback,
455 event);
456 if (ret)
457 return ret;
458 } else {
459 remove_pending_probe(event->pending_probe);
460 ret = 0;
461 }
462 break;
463 default:
464 WARN_ON_ONCE(1);
465 }
466 return ret;
467 }
468
469 /*
470 * Only used internally at session destruction.
471 */
472 static
473 void _ltt_event_destroy(struct ltt_event *event)
474 {
475 switch (event->instrumentation) {
476 case LTTNG_UST_TRACEPOINT:
477 if (event->desc) {
478 ltt_event_put(event->desc);
479 }
480 break;
481 default:
482 WARN_ON_ONCE(1);
483 }
484 cds_list_del(&event->list);
485 lttng_destroy_context(event->ctx);
486 free(event);
487 }
488
489 /*
490 * We have exclusive access to our metadata buffer (protected by the
491 * ust_lock), so we can do racy operations such as looking for
492 * remaining space left in packet and write, since mutual exclusion
493 * protects us from concurrent writes.
494 */
495 int lttng_metadata_printf(struct ltt_session *session,
496 const char *fmt, ...)
497 {
498 struct lttng_ust_lib_ring_buffer_ctx ctx;
499 struct ltt_channel *chan = session->metadata;
500 char *str = NULL;
501 int ret = 0, waitret;
502 size_t len, reserve_len, pos;
503 va_list ap;
504
505 WARN_ON_ONCE(!CMM_ACCESS_ONCE(session->active));
506
507 va_start(ap, fmt);
508 ret = vasprintf(&str, fmt, ap);
509 va_end(ap);
510 if (ret < 0)
511 return -ENOMEM;
512
513 len = strlen(str);
514 pos = 0;
515
516 for (pos = 0; pos < len; pos += reserve_len) {
517 reserve_len = min_t(size_t,
518 chan->ops->packet_avail_size(chan->chan, chan->handle),
519 len - pos);
520 lib_ring_buffer_ctx_init(&ctx, chan->chan, NULL, reserve_len,
521 sizeof(char), -1, chan->handle);
522 /*
523 * We don't care about metadata buffer's records lost
524 * count, because we always retry here. Report error if
525 * we need to bail out after timeout or being
526 * interrupted.
527 */
528 waitret = wait_cond_interruptible_timeout(
529 ({
530 ret = chan->ops->event_reserve(&ctx, 0);
531 ret != -ENOBUFS || !ret;
532 }),
533 LTTNG_METADATA_TIMEOUT_MSEC);
534 if (waitret == -ETIMEDOUT || waitret == -EINTR || ret) {
535 DBG("LTTng: Failure to write metadata to buffers (%s)\n",
536 waitret == -EINTR ? "interrupted" :
537 (ret == -ENOBUFS ? "timeout" : "I/O error"));
538 if (waitret == -EINTR)
539 ret = waitret;
540 goto end;
541 }
542 chan->ops->event_write(&ctx, &str[pos], reserve_len);
543 chan->ops->event_commit(&ctx);
544 }
545 end:
546 free(str);
547 return ret;
548 }
549
550 static
551 int _ltt_field_statedump(struct ltt_session *session,
552 const struct lttng_event_field *field)
553 {
554 int ret = 0;
555
556 switch (field->type.atype) {
557 case atype_integer:
558 ret = lttng_metadata_printf(session,
559 " integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s;\n",
560 field->type.u.basic.integer.size,
561 field->type.u.basic.integer.alignment,
562 field->type.u.basic.integer.signedness,
563 (field->type.u.basic.integer.encoding == lttng_encode_none)
564 ? "none"
565 : (field->type.u.basic.integer.encoding == lttng_encode_UTF8)
566 ? "UTF8"
567 : "ASCII",
568 field->type.u.basic.integer.base,
569 #if (BYTE_ORDER == BIG_ENDIAN)
570 field->type.u.basic.integer.reverse_byte_order ? " byte_order = le;" : "",
571 #else
572 field->type.u.basic.integer.reverse_byte_order ? " byte_order = be;" : "",
573 #endif
574 field->name);
575 break;
576 case atype_float:
577 ret = lttng_metadata_printf(session,
578 " floating_point { exp_dig = %u; mant_dig = %u; align = %u;%s } _%s;\n",
579 field->type.u.basic._float.exp_dig,
580 field->type.u.basic._float.mant_dig,
581 field->type.u.basic._float.alignment,
582 #if (BYTE_ORDER == BIG_ENDIAN)
583 field->type.u.basic.integer.reverse_byte_order ? " byte_order = le;" : "",
584 #else
585 field->type.u.basic.integer.reverse_byte_order ? " byte_order = be;" : "",
586 #endif
587 field->name);
588 break;
589 case atype_enum:
590 ret = lttng_metadata_printf(session,
591 " %s %s;\n",
592 field->type.u.basic.enumeration.name,
593 field->name);
594 break;
595 case atype_array:
596 {
597 const struct lttng_basic_type *elem_type;
598
599 elem_type = &field->type.u.array.elem_type;
600 ret = lttng_metadata_printf(session,
601 " integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[%u];\n",
602 elem_type->u.basic.integer.size,
603 elem_type->u.basic.integer.alignment,
604 elem_type->u.basic.integer.signedness,
605 (elem_type->u.basic.integer.encoding == lttng_encode_none)
606 ? "none"
607 : (elem_type->u.basic.integer.encoding == lttng_encode_UTF8)
608 ? "UTF8"
609 : "ASCII",
610 elem_type->u.basic.integer.base,
611 #if (BYTE_ORDER == BIG_ENDIAN)
612 elem_type->u.basic.integer.reverse_byte_order ? " byte_order = le;" : "",
613 #else
614 elem_type->u.basic.integer.reverse_byte_order ? " byte_order = be;" : "",
615 #endif
616 field->name, field->type.u.array.length);
617 break;
618 }
619 case atype_sequence:
620 {
621 const struct lttng_basic_type *elem_type;
622 const struct lttng_basic_type *length_type;
623
624 elem_type = &field->type.u.sequence.elem_type;
625 length_type = &field->type.u.sequence.length_type;
626 ret = lttng_metadata_printf(session,
627 " integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } __%s_length;\n",
628 length_type->u.basic.integer.size,
629 (unsigned int) length_type->u.basic.integer.alignment,
630 length_type->u.basic.integer.signedness,
631 (length_type->u.basic.integer.encoding == lttng_encode_none)
632 ? "none"
633 : ((length_type->u.basic.integer.encoding == lttng_encode_UTF8)
634 ? "UTF8"
635 : "ASCII"),
636 length_type->u.basic.integer.base,
637 #if (BYTE_ORDER == BIG_ENDIAN)
638 length_type->u.basic.integer.reverse_byte_order ? " byte_order = le;" : "",
639 #else
640 length_type->u.basic.integer.reverse_byte_order ? " byte_order = be;" : "",
641 #endif
642 field->name);
643 if (ret)
644 return ret;
645
646 ret = lttng_metadata_printf(session,
647 " integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[ __%s_length ];\n",
648 elem_type->u.basic.integer.size,
649 (unsigned int) elem_type->u.basic.integer.alignment,
650 elem_type->u.basic.integer.signedness,
651 (elem_type->u.basic.integer.encoding == lttng_encode_none)
652 ? "none"
653 : ((elem_type->u.basic.integer.encoding == lttng_encode_UTF8)
654 ? "UTF8"
655 : "ASCII"),
656 elem_type->u.basic.integer.base,
657 #if (BYTE_ORDER == BIG_ENDIAN)
658 elem_type->u.basic.integer.reverse_byte_order ? " byte_order = le;" : "",
659 #else
660 elem_type->u.basic.integer.reverse_byte_order ? " byte_order = be;" : "",
661 #endif
662 field->name,
663 field->name);
664 break;
665 }
666
667 case atype_string:
668 /* Default encoding is UTF8 */
669 ret = lttng_metadata_printf(session,
670 " string%s _%s;\n",
671 field->type.u.basic.string.encoding == lttng_encode_ASCII ?
672 " { encoding = ASCII; }" : "",
673 field->name);
674 break;
675 default:
676 WARN_ON_ONCE(1);
677 return -EINVAL;
678 }
679 return ret;
680 }
681
682 static
683 int _ltt_context_metadata_statedump(struct ltt_session *session,
684 struct lttng_ctx *ctx)
685 {
686 int ret = 0;
687 int i;
688
689 if (!ctx)
690 return 0;
691 for (i = 0; i < ctx->nr_fields; i++) {
692 const struct lttng_ctx_field *field = &ctx->fields[i];
693
694 ret = _ltt_field_statedump(session, &field->event_field);
695 if (ret)
696 return ret;
697 }
698 return ret;
699 }
700
701 static
702 int _ltt_fields_metadata_statedump(struct ltt_session *session,
703 struct ltt_event *event)
704 {
705 const struct lttng_event_desc *desc = event->desc;
706 int ret = 0;
707 int i;
708
709 for (i = 0; i < desc->nr_fields; i++) {
710 const struct lttng_event_field *field = &desc->fields[i];
711
712 ret = _ltt_field_statedump(session, field);
713 if (ret)
714 return ret;
715 }
716 return ret;
717 }
718
719 static
720 int _ltt_event_metadata_statedump(struct ltt_session *session,
721 struct ltt_channel *chan,
722 struct ltt_event *event)
723 {
724 int ret = 0;
725
726 if (event->metadata_dumped || !CMM_ACCESS_ONCE(session->active))
727 return 0;
728 if (chan == session->metadata)
729 return 0;
730 /*
731 * Don't print events for which probe load is pending.
732 */
733 if (!event->desc)
734 return 0;
735
736 ret = lttng_metadata_printf(session,
737 "event {\n"
738 " name = %s;\n"
739 " id = %u;\n"
740 " stream_id = %u;\n",
741 event->desc->name,
742 event->id,
743 event->chan->id);
744 if (ret)
745 goto end;
746
747 if (event->ctx) {
748 ret = lttng_metadata_printf(session,
749 " context := struct {\n");
750 if (ret)
751 goto end;
752 }
753 ret = _ltt_context_metadata_statedump(session, event->ctx);
754 if (ret)
755 goto end;
756 if (event->ctx) {
757 ret = lttng_metadata_printf(session,
758 " };\n");
759 if (ret)
760 goto end;
761 }
762
763 ret = lttng_metadata_printf(session,
764 " fields := struct {\n"
765 );
766 if (ret)
767 goto end;
768
769 ret = _ltt_fields_metadata_statedump(session, event);
770 if (ret)
771 goto end;
772
773 /*
774 * LTTng space reservation can only reserve multiples of the
775 * byte size.
776 */
777 ret = lttng_metadata_printf(session,
778 " };\n"
779 "};\n\n");
780 if (ret)
781 goto end;
782
783 event->metadata_dumped = 1;
784 end:
785 return ret;
786
787 }
788
789 static
790 int _ltt_channel_metadata_statedump(struct ltt_session *session,
791 struct ltt_channel *chan)
792 {
793 int ret = 0;
794
795 if (chan->metadata_dumped || !CMM_ACCESS_ONCE(session->active))
796 return 0;
797 if (chan == session->metadata)
798 return 0;
799
800 WARN_ON_ONCE(!chan->header_type);
801 ret = lttng_metadata_printf(session,
802 "stream {\n"
803 " id = %u;\n"
804 " event.header := %s;\n"
805 " packet.context := struct packet_context;\n",
806 chan->id,
807 chan->header_type == 1 ? "struct event_header_compact" :
808 "struct event_header_large");
809 if (ret)
810 goto end;
811
812 if (chan->ctx) {
813 ret = lttng_metadata_printf(session,
814 " event.context := struct {\n");
815 if (ret)
816 goto end;
817 }
818 ret = _ltt_context_metadata_statedump(session, chan->ctx);
819 if (ret)
820 goto end;
821 if (chan->ctx) {
822 ret = lttng_metadata_printf(session,
823 " };\n");
824 if (ret)
825 goto end;
826 }
827
828 ret = lttng_metadata_printf(session,
829 "};\n\n");
830
831 chan->metadata_dumped = 1;
832 end:
833 return ret;
834 }
835
836 static
837 int _ltt_stream_packet_context_declare(struct ltt_session *session)
838 {
839 return lttng_metadata_printf(session,
840 "struct packet_context {\n"
841 " uint64_t timestamp_begin;\n"
842 " uint64_t timestamp_end;\n"
843 " uint32_t events_discarded;\n"
844 " uint32_t content_size;\n"
845 " uint32_t packet_size;\n"
846 " uint32_t cpu_id;\n"
847 "};\n\n"
848 );
849 }
850
851 /*
852 * Compact header:
853 * id: range: 0 - 30.
854 * id 31 is reserved to indicate an extended header.
855 *
856 * Large header:
857 * id: range: 0 - 65534.
858 * id 65535 is reserved to indicate an extended header.
859 */
860 static
861 int _ltt_event_header_declare(struct ltt_session *session)
862 {
863 return lttng_metadata_printf(session,
864 "struct event_header_compact {\n"
865 " enum : uint5_t { compact = 0 ... 30, extended = 31 } id;\n"
866 " variant <id> {\n"
867 " struct {\n"
868 " uint27_t timestamp;\n"
869 " } compact;\n"
870 " struct {\n"
871 " uint32_t id;\n"
872 " uint64_t timestamp;\n"
873 " } extended;\n"
874 " } v;\n"
875 "} align(%u);\n"
876 "\n"
877 "struct event_header_large {\n"
878 " enum : uint16_t { compact = 0 ... 65534, extended = 65535 } id;\n"
879 " variant <id> {\n"
880 " struct {\n"
881 " uint32_t timestamp;\n"
882 " } compact;\n"
883 " struct {\n"
884 " uint32_t id;\n"
885 " uint64_t timestamp;\n"
886 " } extended;\n"
887 " } v;\n"
888 "} align(%u);\n\n",
889 lttng_alignof(uint32_t) * CHAR_BIT,
890 lttng_alignof(uint16_t) * CHAR_BIT
891 );
892 }
893
894 /*
895 * Output metadata into this session's metadata buffers.
896 */
897 static
898 int _ltt_session_metadata_statedump(struct ltt_session *session)
899 {
900 unsigned char *uuid_c = session->uuid;
901 char uuid_s[37];
902 struct ltt_channel *chan;
903 struct ltt_event *event;
904 int ret = 0;
905
906 if (!CMM_ACCESS_ONCE(session->active))
907 return 0;
908 if (session->metadata_dumped)
909 goto skip_session;
910 if (!session->metadata) {
911 DBG("LTTng: attempt to start tracing, but metadata channel is not found. Operation abort.\n");
912 return -EPERM;
913 }
914
915 snprintf(uuid_s, sizeof(uuid_s),
916 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
917 uuid_c[0], uuid_c[1], uuid_c[2], uuid_c[3],
918 uuid_c[4], uuid_c[5], uuid_c[6], uuid_c[7],
919 uuid_c[8], uuid_c[9], uuid_c[10], uuid_c[11],
920 uuid_c[12], uuid_c[13], uuid_c[14], uuid_c[15]);
921
922 ret = lttng_metadata_printf(session,
923 "typealias integer { size = 8; align = %u; signed = false; } := uint8_t;\n"
924 "typealias integer { size = 16; align = %u; signed = false; } := uint16_t;\n"
925 "typealias integer { size = 32; align = %u; signed = false; } := uint32_t;\n"
926 "typealias integer { size = 64; align = %u; signed = false; } := uint64_t;\n"
927 "typealias integer { size = 5; align = 1; signed = false; } := uint5_t;\n"
928 "typealias integer { size = 27; align = 1; signed = false; } := uint27_t;\n"
929 "\n"
930 "trace {\n"
931 " major = %u;\n"
932 " minor = %u;\n"
933 " uuid = \"%s\";\n"
934 " byte_order = %s;\n"
935 " packet.header := struct {\n"
936 " uint32_t magic;\n"
937 " uint8_t uuid[16];\n"
938 " uint32_t stream_id;\n"
939 " };\n"
940 "};\n\n",
941 lttng_alignof(uint8_t) * CHAR_BIT,
942 lttng_alignof(uint16_t) * CHAR_BIT,
943 lttng_alignof(uint32_t) * CHAR_BIT,
944 lttng_alignof(uint64_t) * CHAR_BIT,
945 CTF_VERSION_MAJOR,
946 CTF_VERSION_MINOR,
947 uuid_s,
948 #if (BYTE_ORDER == BIG_ENDIAN)
949 "be"
950 #else
951 "le"
952 #endif
953 );
954 if (ret)
955 goto end;
956
957 ret = _ltt_stream_packet_context_declare(session);
958 if (ret)
959 goto end;
960
961 ret = _ltt_event_header_declare(session);
962 if (ret)
963 goto end;
964
965 skip_session:
966 cds_list_for_each_entry(chan, &session->chan, list) {
967 ret = _ltt_channel_metadata_statedump(session, chan);
968 if (ret)
969 goto end;
970 }
971
972 cds_list_for_each_entry(event, &session->events, list) {
973 ret = _ltt_event_metadata_statedump(session, event->chan, event);
974 if (ret)
975 goto end;
976 }
977 session->metadata_dumped = 1;
978 end:
979 return ret;
980 }
981
982 /**
983 * ltt_transport_register - LTT transport registration
984 * @transport: transport structure
985 *
986 * Registers a transport which can be used as output to extract the data out of
987 * LTTng. Called with ust_lock held.
988 */
989 void ltt_transport_register(struct ltt_transport *transport)
990 {
991 cds_list_add_tail(&transport->node, &ltt_transport_list);
992 }
993
994 /**
995 * ltt_transport_unregister - LTT transport unregistration
996 * @transport: transport structure
997 * Called with ust_lock held.
998 */
999 void ltt_transport_unregister(struct ltt_transport *transport)
1000 {
1001 cds_list_del(&transport->node);
1002 }
1003
1004 void lttng_ust_events_exit(void)
1005 {
1006 struct ltt_session *session, *tmpsession;
1007
1008 cds_list_for_each_entry_safe(session, tmpsession, &sessions, list)
1009 ltt_session_destroy(session);
1010 }
This page took 0.050264 seconds and 4 git commands to generate.