libust events: lazy probe binding
[lttng-ust.git] / libust / ltt-events.c
CommitLineData
8020ceb5
MD
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
b5234c06
MD
11#define _GNU_SOURCE
12#include <stdio.h>
13#include <urcu/list.h>
8165c8da 14#include <urcu/hlist.h>
b5234c06
MD
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>
f4681817
MD
22#include <sys/shm.h>
23#include <sys/ipc.h>
24#include <ust/lttng-events.h>
1dbfff0c 25#include <ust/usterr-signal-safe.h>
b5234c06 26#include "ust/core.h"
8020ceb5 27#include "ltt-tracer.h"
8165c8da 28#include "ltt-tracer-core.h"
b5234c06 29#include "ust/wait.h"
8d8a24c8 30#include "../libringbuffer/shm.h"
8020ceb5 31
8165c8da
MD
32typedef 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 */
39static DEFINE_MUTEX(sessions_mutex);
40
41void lock_ust(void)
42{
43 pthread_mutex_lock(&sessions_mutex);
44}
45
46void unlock_ust(void)
47{
48 pthread_mutex_unlock(&sessions_mutex);
49}
50
b5234c06
MD
51static CDS_LIST_HEAD(sessions);
52static CDS_LIST_HEAD(ltt_transport_list);
8165c8da
MD
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)
61static struct cds_hlist_head pending_probe_table[PENDING_PROBE_HASH_SIZE];
62
63struct ust_pending_probe {
64 struct ltt_event *event;
65 struct cds_hlist_node node;
66 char name[];
67};
8020ceb5
MD
68
69static void _ltt_event_destroy(struct ltt_event *event);
70static void _ltt_channel_destroy(struct ltt_channel *chan);
71static int _ltt_event_unregister(struct ltt_event *event);
72static
73int _ltt_event_metadata_statedump(struct ltt_session *session,
74 struct ltt_channel *chan,
75 struct ltt_event *event);
76static
77int _ltt_session_metadata_statedump(struct ltt_session *session);
78
8165c8da
MD
79/*
80 * called at event creation if probe is missing.
81 * called with session mutex held.
82 */
83static
84int 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 */
108static
109void 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 */
122int 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
8020ceb5
MD
154void synchronize_trace(void)
155{
8020ceb5 156 synchronize_rcu();
8020ceb5
MD
157}
158
159struct ltt_session *ltt_session_create(void)
160{
161 struct ltt_session *session;
162
b5234c06 163 session = zmalloc(sizeof(struct ltt_session));
8020ceb5
MD
164 if (!session)
165 return NULL;
1ea11eab 166 pthread_mutex_lock(&sessions_mutex);
b5234c06
MD
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);
8020ceb5
MD
172 return session;
173}
174
175void ltt_session_destroy(struct ltt_session *session)
176{
177 struct ltt_channel *chan, *tmpchan;
178 struct ltt_event *event, *tmpevent;
179 int ret;
180
b5234c06
MD
181 pthread_mutex_lock(&sessions_mutex);
182 CMM_ACCESS_ONCE(session->active) = 0;
183 cds_list_for_each_entry(event, &session->events, list) {
8020ceb5
MD
184 ret = _ltt_event_unregister(event);
185 WARN_ON(ret);
186 }
187 synchronize_trace(); /* Wait for in-flight events to complete */
b5234c06 188 cds_list_for_each_entry_safe(event, tmpevent, &session->events, list)
8020ceb5 189 _ltt_event_destroy(event);
b5234c06 190 cds_list_for_each_entry_safe(chan, tmpchan, &session->chan, list)
8020ceb5 191 _ltt_channel_destroy(chan);
b5234c06
MD
192 cds_list_del(&session->list);
193 pthread_mutex_unlock(&sessions_mutex);
194 free(session);
8020ceb5
MD
195}
196
976fe9ea 197int ltt_session_enable(struct ltt_session *session)
8020ceb5
MD
198{
199 int ret = 0;
200 struct ltt_channel *chan;
201
b5234c06 202 pthread_mutex_lock(&sessions_mutex);
8020ceb5
MD
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 */
b5234c06 212 cds_list_for_each_entry(chan, &session->chan, list) {
8020ceb5
MD
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
b5234c06
MD
221 CMM_ACCESS_ONCE(session->active) = 1;
222 CMM_ACCESS_ONCE(session->been_active) = 1;
8020ceb5 223 ret = _ltt_session_metadata_statedump(session);
4b4de73e 224 if (ret)
b5234c06 225 CMM_ACCESS_ONCE(session->active) = 0;
8020ceb5 226end:
b5234c06 227 pthread_mutex_unlock(&sessions_mutex);
8020ceb5
MD
228 return ret;
229}
230
976fe9ea 231int ltt_session_disable(struct ltt_session *session)
8020ceb5
MD
232{
233 int ret = 0;
234
b5234c06 235 pthread_mutex_lock(&sessions_mutex);
8020ceb5
MD
236 if (!session->active) {
237 ret = -EBUSY;
238 goto end;
239 }
b5234c06 240 CMM_ACCESS_ONCE(session->active) = 0;
8020ceb5 241end:
b5234c06 242 pthread_mutex_unlock(&sessions_mutex);
8020ceb5
MD
243 return ret;
244}
245
976fe9ea
MD
246int ltt_channel_enable(struct ltt_channel *channel)
247{
248 int old;
249
9beb36ba
MD
250 if (channel == channel->session->metadata)
251 return -EPERM;
b5234c06 252 old = uatomic_xchg(&channel->enabled, 1);
976fe9ea
MD
253 if (old)
254 return -EEXIST;
255 return 0;
256}
257
258int ltt_channel_disable(struct ltt_channel *channel)
259{
260 int old;
261
9beb36ba
MD
262 if (channel == channel->session->metadata)
263 return -EPERM;
b5234c06 264 old = uatomic_xchg(&channel->enabled, 0);
976fe9ea
MD
265 if (!old)
266 return -EEXIST;
267 return 0;
268}
269
270int ltt_event_enable(struct ltt_event *event)
271{
272 int old;
273
9beb36ba
MD
274 if (event->chan == event->chan->session->metadata)
275 return -EPERM;
b5234c06 276 old = uatomic_xchg(&event->enabled, 1);
976fe9ea
MD
277 if (old)
278 return -EEXIST;
279 return 0;
280}
281
282int ltt_event_disable(struct ltt_event *event)
283{
284 int old;
285
9beb36ba
MD
286 if (event->chan == event->chan->session->metadata)
287 return -EPERM;
b5234c06 288 old = uatomic_xchg(&event->enabled, 0);
976fe9ea
MD
289 if (!old)
290 return -EEXIST;
291 return 0;
292}
293
8020ceb5
MD
294static struct ltt_transport *ltt_transport_find(const char *name)
295{
296 struct ltt_transport *transport;
297
b5234c06 298 cds_list_for_each_entry(transport, &ltt_transport_list, node) {
8020ceb5
MD
299 if (!strcmp(transport->name, name))
300 return transport;
301 }
302 return NULL;
303}
304
305struct 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,
f4681817 310 unsigned int read_timer_interval)
8020ceb5
MD
311{
312 struct ltt_channel *chan;
313 struct ltt_transport *transport;
314
b5234c06 315 pthread_mutex_lock(&sessions_mutex);
8020ceb5
MD
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) {
b5234c06 320 DBG("LTTng transport %s not found\n",
8020ceb5
MD
321 transport_name);
322 goto notransport;
323 }
b5234c06 324 chan = zmalloc(sizeof(struct ltt_channel));
8020ceb5
MD
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 */
1d498196 334 transport->ops.channel_create("[lttng]", chan, buf_addr,
8020ceb5 335 subbuf_size, num_subbuf, switch_timer_interval,
8d8a24c8 336 read_timer_interval);
8020ceb5
MD
337 if (!chan->chan)
338 goto create_error;
976fe9ea 339 chan->enabled = 1;
8020ceb5 340 chan->ops = &transport->ops;
b5234c06
MD
341 cds_list_add(&chan->list, &session->chan);
342 pthread_mutex_unlock(&sessions_mutex);
8020ceb5
MD
343 return chan;
344
345create_error:
b5234c06 346 free(chan);
8020ceb5
MD
347nomem:
348notransport:
349active:
b5234c06 350 pthread_mutex_unlock(&sessions_mutex);
8020ceb5
MD
351 return NULL;
352}
353
354/*
355 * Only used internally at session destruction.
356 */
357static
358void _ltt_channel_destroy(struct ltt_channel *chan)
359{
1d498196 360 chan->ops->channel_destroy(chan);
b5234c06 361 cds_list_del(&chan->list);
8020ceb5 362 lttng_destroy_context(chan->ctx);
b5234c06 363 free(chan);
8020ceb5
MD
364}
365
366/*
367 * Supports event creation while tracing session is active.
368 */
369struct ltt_event *ltt_event_create(struct ltt_channel *chan,
b5234c06 370 struct lttng_ust_event *event_param,
8020ceb5
MD
371 void *filter)
372{
373 struct ltt_event *event;
374 int ret;
375
b5234c06 376 pthread_mutex_lock(&sessions_mutex);
8165c8da 377 if (chan->used_event_id == -1UL)
8020ceb5
MD
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 */
b5234c06 383 cds_list_for_each_entry(event, &chan->session->events, list)
8165c8da 384 if (event->desc && !strcmp(event->desc->name, event_param->name))
8020ceb5 385 goto exist;
b5234c06 386 event = zmalloc(sizeof(struct ltt_event));
8020ceb5
MD
387 if (!event)
388 goto cache_error;
389 event->chan = chan;
390 event->filter = filter;
8165c8da
MD
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++;
976fe9ea 396 event->enabled = 1;
8020ceb5
MD
397 event->instrumentation = event_param->instrumentation;
398 /* Populate ltt_event structure before tracepoint registration. */
b5234c06 399 cmm_smp_wmb();
8020ceb5 400 switch (event_param->instrumentation) {
b5234c06 401 case LTTNG_UST_TRACEPOINT:
8020ceb5 402 event->desc = ltt_event_get(event_param->name);
8165c8da
MD
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 }
8020ceb5 420 break;
8020ceb5
MD
421 default:
422 WARN_ON_ONCE(1);
423 }
8165c8da
MD
424 if (event->desc) {
425 ret = _ltt_event_metadata_statedump(chan->session, chan, event);
426 if (ret)
427 goto statedump_error;
428 }
b5234c06
MD
429 cds_list_add(&event->list, &chan->session->events);
430 pthread_mutex_unlock(&sessions_mutex);
8020ceb5
MD
431 return event;
432
433statedump_error:
8165c8da
MD
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 }
440add_pending_error:
8020ceb5 441register_error:
b5234c06 442 free(event);
8020ceb5
MD
443cache_error:
444exist:
445full:
b5234c06 446 pthread_mutex_unlock(&sessions_mutex);
8020ceb5
MD
447 return NULL;
448}
449
450/*
451 * Only used internally at session destruction.
452 */
453int _ltt_event_unregister(struct ltt_event *event)
454{
455 int ret = -EINVAL;
456
457 switch (event->instrumentation) {
b5234c06 458 case LTTNG_UST_TRACEPOINT:
8165c8da
MD
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 }
8020ceb5 469 break;
8020ceb5
MD
470 default:
471 WARN_ON_ONCE(1);
472 }
473 return ret;
474}
475
476/*
477 * Only used internally at session destruction.
478 */
479static
480void _ltt_event_destroy(struct ltt_event *event)
481{
482 switch (event->instrumentation) {
b5234c06 483 case LTTNG_UST_TRACEPOINT:
8165c8da
MD
484 if (event->desc) {
485 ltt_event_put(event->desc);
486 }
8020ceb5 487 break;
8020ceb5
MD
488 default:
489 WARN_ON_ONCE(1);
490 }
b5234c06 491 cds_list_del(&event->list);
8020ceb5 492 lttng_destroy_context(event->ctx);
b5234c06 493 free(event);
8020ceb5
MD
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 */
502int 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;
b5234c06 507 char *str = NULL;
8020ceb5
MD
508 int ret = 0, waitret;
509 size_t len, reserve_len, pos;
510 va_list ap;
511
b5234c06 512 WARN_ON_ONCE(!CMM_ACCESS_ONCE(session->active));
8020ceb5
MD
513
514 va_start(ap, fmt);
b5234c06 515 ret = vasprintf(&str, fmt, ap);
8020ceb5 516 va_end(ap);
b5234c06 517 if (ret < 0)
8020ceb5
MD
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,
1d498196 525 chan->ops->packet_avail_size(chan->chan, chan->handle),
8020ceb5
MD
526 len - pos);
527 lib_ring_buffer_ctx_init(&ctx, chan->chan, NULL, reserve_len,
1d498196 528 sizeof(char), -1, chan->handle);
8020ceb5
MD
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 */
b5234c06 535 waitret = wait_cond_interruptible_timeout(
8020ceb5
MD
536 ({
537 ret = chan->ops->event_reserve(&ctx, 0);
538 ret != -ENOBUFS || !ret;
539 }),
b5234c06 540 LTTNG_METADATA_TIMEOUT_MSEC);
b472cfc0 541 if (waitret == -ETIMEDOUT || waitret == -EINTR || ret) {
b5234c06
MD
542 DBG("LTTng: Failure to write metadata to buffers (%s)\n",
543 waitret == -EINTR ? "interrupted" :
8020ceb5 544 (ret == -ENOBUFS ? "timeout" : "I/O error"));
b5234c06 545 if (waitret == -EINTR)
8020ceb5
MD
546 ret = waitret;
547 goto end;
548 }
549 chan->ops->event_write(&ctx, &str[pos], reserve_len);
550 chan->ops->event_commit(&ctx);
551 }
552end:
b5234c06 553 free(str);
8020ceb5
MD
554 return ret;
555}
556
557static
558int _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,
403c40b4
MD
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
8020ceb5
MD
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,
403c40b4 618#ifdef __BIG_ENDIAN
8020ceb5
MD
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,
403c40b4 644#ifdef __BIG_ENDIAN
8020ceb5
MD
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,
403c40b4 664#ifdef __BIG_ENDIAN
8020ceb5
MD
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
689static
690int _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
708static
709int _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
726static
727int _ltt_event_metadata_statedump(struct ltt_session *session,
728 struct ltt_channel *chan,
729 struct ltt_event *event)
730{
731 int ret = 0;
732
b5234c06 733 if (event->metadata_dumped || !CMM_ACCESS_ONCE(session->active))
8020ceb5
MD
734 return 0;
735 if (chan == session->metadata)
736 return 0;
8165c8da
MD
737 /*
738 * Don't print events for which probe load is pending.
739 */
740 if (!event->desc)
741 return 0;
8020ceb5
MD
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;
791end:
792 return ret;
793
794}
795
796static
797int _ltt_channel_metadata_statedump(struct ltt_session *session,
798 struct ltt_channel *chan)
799{
800 int ret = 0;
801
b5234c06 802 if (chan->metadata_dumped || !CMM_ACCESS_ONCE(session->active))
8020ceb5
MD
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;
839end:
840 return ret;
841}
842
843static
844int _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 */
867static
868int _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",
1dbfff0c
MD
896 lttng_alignof(uint32_t) * CHAR_BIT,
897 lttng_alignof(uint16_t) * CHAR_BIT
8020ceb5
MD
898 );
899}
900
901/*
902 * Output metadata into this session's metadata buffers.
903 */
904static
905int _ltt_session_metadata_statedump(struct ltt_session *session)
906{
b5234c06
MD
907 unsigned char *uuid_c = session->uuid;
908 char uuid_s[37];
8020ceb5
MD
909 struct ltt_channel *chan;
910 struct ltt_event *event;
911 int ret = 0;
912
b5234c06 913 if (!CMM_ACCESS_ONCE(session->active))
8020ceb5
MD
914 return 0;
915 if (session->metadata_dumped)
916 goto skip_session;
917 if (!session->metadata) {
b5234c06 918 DBG("LTTng: attempt to start tracing, but metadata channel is not found. Operation abort.\n");
8020ceb5
MD
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",
1dbfff0c
MD
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,
8020ceb5
MD
952 CTF_VERSION_MAJOR,
953 CTF_VERSION_MINOR,
954 uuid_s,
403c40b4 955#ifdef __BIG_ENDIAN
8020ceb5
MD
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
972skip_session:
b5234c06 973 cds_list_for_each_entry(chan, &session->chan, list) {
8020ceb5
MD
974 ret = _ltt_channel_metadata_statedump(session, chan);
975 if (ret)
976 goto end;
977 }
978
b5234c06 979 cds_list_for_each_entry(event, &session->events, list) {
8020ceb5
MD
980 ret = _ltt_event_metadata_statedump(session, event->chan, event);
981 if (ret)
982 goto end;
983 }
984 session->metadata_dumped = 1;
985end:
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
b5234c06 994 * LTTng.
8020ceb5
MD
995 */
996void ltt_transport_register(struct ltt_transport *transport)
997{
b5234c06
MD
998 pthread_mutex_lock(&sessions_mutex);
999 cds_list_add_tail(&transport->node, &ltt_transport_list);
1000 pthread_mutex_unlock(&sessions_mutex);
8020ceb5 1001}
8020ceb5
MD
1002
1003/**
1004 * ltt_transport_unregister - LTT transport unregistration
1005 * @transport: transport structure
1006 */
1007void ltt_transport_unregister(struct ltt_transport *transport)
1008{
b5234c06
MD
1009 pthread_mutex_lock(&sessions_mutex);
1010 cds_list_del(&transport->node);
1011 pthread_mutex_unlock(&sessions_mutex);
8020ceb5
MD
1012}
1013
1ea11eab 1014void ltt_events_exit(void)
8020ceb5
MD
1015{
1016 struct ltt_session *session, *tmpsession;
1017
b5234c06 1018 cds_list_for_each_entry_safe(session, tmpsession, &sessions, list)
8020ceb5 1019 ltt_session_destroy(session);
8020ceb5 1020}
This page took 0.065077 seconds and 4 git commands to generate.