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