Update readme
[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>
8a98a75d 13#include <endian.h>
b5234c06 14#include <urcu/list.h>
8165c8da 15#include <urcu/hlist.h>
b5234c06
MD
16#include <pthread.h>
17#include <urcu-bp.h>
18#include <urcu/compiler.h>
19#include <urcu/uatomic.h>
20#include <uuid/uuid.h>
4318ae1b 21#include <lttng/tracepoint.h>
b5234c06 22#include <errno.h>
f4681817
MD
23#include <sys/shm.h>
24#include <sys/ipc.h>
4318ae1b
MD
25#include <lttng/ust-events.h>
26#include <lttng/usterr-signal-safe.h>
27#include "lttng/core.h"
8020ceb5 28#include "ltt-tracer.h"
8165c8da 29#include "ltt-tracer-core.h"
4318ae1b 30#include "lttng/wait.h"
8d8a24c8 31#include "../libringbuffer/shm.h"
8020ceb5 32
8165c8da 33typedef u32 uint32_t;
4318ae1b 34#include <lttng/kcompat/jhash.h>
8165c8da
MD
35
36/*
37 * The sessions mutex is the centralized mutex across UST tracing
17dfb34b
MD
38 * control and probe registration. All operations within this file are
39 * called by the communication thread, under ust_lock protection.
8165c8da
MD
40 */
41static DEFINE_MUTEX(sessions_mutex);
42
17dfb34b 43void ust_lock(void)
8165c8da
MD
44{
45 pthread_mutex_lock(&sessions_mutex);
46}
47
17dfb34b 48void ust_unlock(void)
8165c8da
MD
49{
50 pthread_mutex_unlock(&sessions_mutex);
51}
52
b5234c06
MD
53static CDS_LIST_HEAD(sessions);
54static CDS_LIST_HEAD(ltt_transport_list);
8165c8da
MD
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)
63static struct cds_hlist_head pending_probe_table[PENDING_PROBE_HASH_SIZE];
64
65struct ust_pending_probe {
66 struct ltt_event *event;
67 struct cds_hlist_node node;
68 char name[];
69};
8020ceb5
MD
70
71static void _ltt_event_destroy(struct ltt_event *event);
72static void _ltt_channel_destroy(struct ltt_channel *chan);
73static int _ltt_event_unregister(struct ltt_event *event);
74static
75int _ltt_event_metadata_statedump(struct ltt_session *session,
76 struct ltt_channel *chan,
77 struct ltt_event *event);
78static
79int _ltt_session_metadata_statedump(struct ltt_session *session);
80
8165c8da
MD
81/*
82 * called at event creation if probe is missing.
83 * called with session mutex held.
84 */
85static
86int add_pending_probe(struct ltt_event *event, const char *name)
87{
88 struct cds_hlist_head *head;
8165c8da
MD
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 */
109static
110void 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 */
123int 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);
636c5aa4
MD
149 if (ret)
150 continue;
151 event->id = chan->free_event_id++;
8165c8da
MD
152 ret |= _ltt_event_metadata_statedump(chan->session, chan,
153 event);
154 }
155 return ret;
156}
157
8020ceb5
MD
158void synchronize_trace(void)
159{
8020ceb5 160 synchronize_rcu();
8020ceb5
MD
161}
162
163struct ltt_session *ltt_session_create(void)
164{
165 struct ltt_session *session;
166
b5234c06 167 session = zmalloc(sizeof(struct ltt_session));
8020ceb5
MD
168 if (!session)
169 return NULL;
b5234c06
MD
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);
8020ceb5
MD
174 return session;
175}
176
177void ltt_session_destroy(struct ltt_session *session)
178{
179 struct ltt_channel *chan, *tmpchan;
180 struct ltt_event *event, *tmpevent;
181 int ret;
182
b5234c06
MD
183 CMM_ACCESS_ONCE(session->active) = 0;
184 cds_list_for_each_entry(event, &session->events, list) {
8020ceb5
MD
185 ret = _ltt_event_unregister(event);
186 WARN_ON(ret);
187 }
188 synchronize_trace(); /* Wait for in-flight events to complete */
b5234c06 189 cds_list_for_each_entry_safe(event, tmpevent, &session->events, list)
8020ceb5 190 _ltt_event_destroy(event);
b5234c06 191 cds_list_for_each_entry_safe(chan, tmpchan, &session->chan, list)
8020ceb5 192 _ltt_channel_destroy(chan);
b5234c06 193 cds_list_del(&session->list);
b5234c06 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
8020ceb5
MD
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 */
b5234c06 211 cds_list_for_each_entry(chan, &session->chan, list) {
8020ceb5
MD
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
b5234c06
MD
220 CMM_ACCESS_ONCE(session->active) = 1;
221 CMM_ACCESS_ONCE(session->been_active) = 1;
8020ceb5 222 ret = _ltt_session_metadata_statedump(session);
4b4de73e 223 if (ret)
b5234c06 224 CMM_ACCESS_ONCE(session->active) = 0;
8020ceb5 225end:
8020ceb5
MD
226 return ret;
227}
228
976fe9ea 229int ltt_session_disable(struct ltt_session *session)
8020ceb5
MD
230{
231 int ret = 0;
232
8020ceb5
MD
233 if (!session->active) {
234 ret = -EBUSY;
235 goto end;
236 }
b5234c06 237 CMM_ACCESS_ONCE(session->active) = 0;
8020ceb5 238end:
8020ceb5
MD
239 return ret;
240}
241
976fe9ea
MD
242int ltt_channel_enable(struct ltt_channel *channel)
243{
244 int old;
245
9beb36ba
MD
246 if (channel == channel->session->metadata)
247 return -EPERM;
b5234c06 248 old = uatomic_xchg(&channel->enabled, 1);
976fe9ea
MD
249 if (old)
250 return -EEXIST;
251 return 0;
252}
253
254int ltt_channel_disable(struct ltt_channel *channel)
255{
256 int old;
257
9beb36ba
MD
258 if (channel == channel->session->metadata)
259 return -EPERM;
b5234c06 260 old = uatomic_xchg(&channel->enabled, 0);
976fe9ea
MD
261 if (!old)
262 return -EEXIST;
263 return 0;
264}
265
266int ltt_event_enable(struct ltt_event *event)
267{
268 int old;
269
9beb36ba
MD
270 if (event->chan == event->chan->session->metadata)
271 return -EPERM;
b5234c06 272 old = uatomic_xchg(&event->enabled, 1);
976fe9ea
MD
273 if (old)
274 return -EEXIST;
275 return 0;
276}
277
278int ltt_event_disable(struct ltt_event *event)
279{
280 int old;
281
9beb36ba
MD
282 if (event->chan == event->chan->session->metadata)
283 return -EPERM;
b5234c06 284 old = uatomic_xchg(&event->enabled, 0);
976fe9ea
MD
285 if (!old)
286 return -EEXIST;
287 return 0;
288}
289
8020ceb5
MD
290static struct ltt_transport *ltt_transport_find(const char *name)
291{
292 struct ltt_transport *transport;
293
b5234c06 294 cds_list_for_each_entry(transport, &ltt_transport_list, node) {
8020ceb5
MD
295 if (!strcmp(transport->name, name))
296 return transport;
297 }
298 return NULL;
299}
300
301struct 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,
193183fb
MD
306 unsigned int read_timer_interval,
307 int *shm_fd, int *wait_fd,
308 uint64_t *memory_map_size)
8020ceb5
MD
309{
310 struct ltt_channel *chan;
311 struct ltt_transport *transport;
312
8020ceb5
MD
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) {
b5234c06 317 DBG("LTTng transport %s not found\n",
8020ceb5
MD
318 transport_name);
319 goto notransport;
320 }
b5234c06 321 chan = zmalloc(sizeof(struct ltt_channel));
8020ceb5
MD
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 */
1d498196 331 transport->ops.channel_create("[lttng]", chan, buf_addr,
8020ceb5 332 subbuf_size, num_subbuf, switch_timer_interval,
193183fb
MD
333 read_timer_interval, shm_fd, wait_fd,
334 memory_map_size);
8020ceb5
MD
335 if (!chan->chan)
336 goto create_error;
976fe9ea 337 chan->enabled = 1;
8020ceb5 338 chan->ops = &transport->ops;
b5234c06 339 cds_list_add(&chan->list, &session->chan);
8020ceb5
MD
340 return chan;
341
342create_error:
b5234c06 343 free(chan);
8020ceb5
MD
344nomem:
345notransport:
346active:
8020ceb5
MD
347 return NULL;
348}
349
350/*
351 * Only used internally at session destruction.
352 */
353static
354void _ltt_channel_destroy(struct ltt_channel *chan)
355{
1d498196 356 chan->ops->channel_destroy(chan);
b5234c06 357 cds_list_del(&chan->list);
8020ceb5 358 lttng_destroy_context(chan->ctx);
b5234c06 359 free(chan);
8020ceb5
MD
360}
361
362/*
363 * Supports event creation while tracing session is active.
364 */
365struct ltt_event *ltt_event_create(struct ltt_channel *chan,
b5234c06 366 struct lttng_ust_event *event_param,
8020ceb5
MD
367 void *filter)
368{
369 struct ltt_event *event;
370 int ret;
371
8165c8da 372 if (chan->used_event_id == -1UL)
8020ceb5
MD
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 */
b5234c06 378 cds_list_for_each_entry(event, &chan->session->events, list)
8165c8da 379 if (event->desc && !strcmp(event->desc->name, event_param->name))
8020ceb5 380 goto exist;
b5234c06 381 event = zmalloc(sizeof(struct ltt_event));
8020ceb5
MD
382 if (!event)
383 goto cache_error;
384 event->chan = chan;
385 event->filter = filter;
8165c8da
MD
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++;
976fe9ea 391 event->enabled = 1;
8020ceb5
MD
392 event->instrumentation = event_param->instrumentation;
393 /* Populate ltt_event structure before tracepoint registration. */
b5234c06 394 cmm_smp_wmb();
8020ceb5 395 switch (event_param->instrumentation) {
b5234c06 396 case LTTNG_UST_TRACEPOINT:
8020ceb5 397 event->desc = ltt_event_get(event_param->name);
8165c8da
MD
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 }
8020ceb5 415 break;
8020ceb5
MD
416 default:
417 WARN_ON_ONCE(1);
418 }
8165c8da
MD
419 if (event->desc) {
420 ret = _ltt_event_metadata_statedump(chan->session, chan, event);
421 if (ret)
422 goto statedump_error;
423 }
b5234c06 424 cds_list_add(&event->list, &chan->session->events);
8020ceb5
MD
425 return event;
426
427statedump_error:
8165c8da
MD
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 }
434add_pending_error:
8020ceb5 435register_error:
b5234c06 436 free(event);
8020ceb5
MD
437cache_error:
438exist:
439full:
8020ceb5
MD
440 return NULL;
441}
442
443/*
444 * Only used internally at session destruction.
445 */
446int _ltt_event_unregister(struct ltt_event *event)
447{
448 int ret = -EINVAL;
449
450 switch (event->instrumentation) {
b5234c06 451 case LTTNG_UST_TRACEPOINT:
8165c8da
MD
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 }
8020ceb5 462 break;
8020ceb5
MD
463 default:
464 WARN_ON_ONCE(1);
465 }
466 return ret;
467}
468
469/*
470 * Only used internally at session destruction.
471 */
472static
473void _ltt_event_destroy(struct ltt_event *event)
474{
475 switch (event->instrumentation) {
b5234c06 476 case LTTNG_UST_TRACEPOINT:
8165c8da
MD
477 if (event->desc) {
478 ltt_event_put(event->desc);
479 }
8020ceb5 480 break;
8020ceb5
MD
481 default:
482 WARN_ON_ONCE(1);
483 }
b5234c06 484 cds_list_del(&event->list);
8020ceb5 485 lttng_destroy_context(event->ctx);
b5234c06 486 free(event);
8020ceb5
MD
487}
488
489/*
490 * We have exclusive access to our metadata buffer (protected by the
17dfb34b 491 * ust_lock), so we can do racy operations such as looking for
8020ceb5
MD
492 * remaining space left in packet and write, since mutual exclusion
493 * protects us from concurrent writes.
494 */
495int lttng_metadata_printf(struct ltt_session *session,
496 const char *fmt, ...)
497{
4cfec15c 498 struct lttng_ust_lib_ring_buffer_ctx ctx;
8020ceb5 499 struct ltt_channel *chan = session->metadata;
b5234c06 500 char *str = NULL;
8020ceb5
MD
501 int ret = 0, waitret;
502 size_t len, reserve_len, pos;
503 va_list ap;
504
b5234c06 505 WARN_ON_ONCE(!CMM_ACCESS_ONCE(session->active));
8020ceb5
MD
506
507 va_start(ap, fmt);
b5234c06 508 ret = vasprintf(&str, fmt, ap);
8020ceb5 509 va_end(ap);
b5234c06 510 if (ret < 0)
8020ceb5
MD
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,
1d498196 518 chan->ops->packet_avail_size(chan->chan, chan->handle),
8020ceb5
MD
519 len - pos);
520 lib_ring_buffer_ctx_init(&ctx, chan->chan, NULL, reserve_len,
1d498196 521 sizeof(char), -1, chan->handle);
8020ceb5
MD
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 */
b5234c06 528 waitret = wait_cond_interruptible_timeout(
8020ceb5
MD
529 ({
530 ret = chan->ops->event_reserve(&ctx, 0);
531 ret != -ENOBUFS || !ret;
532 }),
b5234c06 533 LTTNG_METADATA_TIMEOUT_MSEC);
b472cfc0 534 if (waitret == -ETIMEDOUT || waitret == -EINTR || ret) {
b5234c06
MD
535 DBG("LTTng: Failure to write metadata to buffers (%s)\n",
536 waitret == -EINTR ? "interrupted" :
8020ceb5 537 (ret == -ENOBUFS ? "timeout" : "I/O error"));
b5234c06 538 if (waitret == -EINTR)
8020ceb5
MD
539 ret = waitret;
540 goto end;
541 }
542 chan->ops->event_write(&ctx, &str[pos], reserve_len);
543 chan->ops->event_commit(&ctx);
544 }
545end:
b5234c06 546 free(str);
8020ceb5
MD
547 return ret;
548}
549
550static
551int _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,
4e2ee1f5 559 " integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s;\n",
8020ceb5
MD
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,
8a98a75d 569#if (BYTE_ORDER == BIG_ENDIAN)
403c40b4
MD
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,
8a98a75d 578 " floating_point { exp_dig = %u; mant_dig = %u; align = %u;%s } _%s;\n",
403c40b4
MD
579 field->type.u.basic._float.exp_dig,
580 field->type.u.basic._float.mant_dig,
581 field->type.u.basic._float.alignment,
8a98a75d 582#if (BYTE_ORDER == BIG_ENDIAN)
8020ceb5
MD
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,
4e2ee1f5 601 " integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[%u];\n",
8020ceb5
MD
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,
8a98a75d 611#if (BYTE_ORDER == BIG_ENDIAN)
8020ceb5
MD
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,
8a98a75d 637#if (BYTE_ORDER == BIG_ENDIAN)
8020ceb5
MD
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,
4e2ee1f5 647 " integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[ __%s_length ];\n",
8020ceb5
MD
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,
8a98a75d 657#if (BYTE_ORDER == BIG_ENDIAN)
8020ceb5
MD
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,
4e2ee1f5 670 " string%s _%s;\n",
8020ceb5
MD
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
682static
683int _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
701static
702int _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
719static
720int _ltt_event_metadata_statedump(struct ltt_session *session,
721 struct ltt_channel *chan,
722 struct ltt_event *event)
723{
724 int ret = 0;
725
b5234c06 726 if (event->metadata_dumped || !CMM_ACCESS_ONCE(session->active))
8020ceb5
MD
727 return 0;
728 if (chan == session->metadata)
729 return 0;
8165c8da
MD
730 /*
731 * Don't print events for which probe load is pending.
732 */
733 if (!event->desc)
734 return 0;
8020ceb5
MD
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;
784end:
785 return ret;
786
787}
788
789static
790int _ltt_channel_metadata_statedump(struct ltt_session *session,
791 struct ltt_channel *chan)
792{
793 int ret = 0;
794
b5234c06 795 if (chan->metadata_dumped || !CMM_ACCESS_ONCE(session->active))
8020ceb5
MD
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;
832end:
833 return ret;
834}
835
836static
837int _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 */
860static
861int _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",
1dbfff0c
MD
889 lttng_alignof(uint32_t) * CHAR_BIT,
890 lttng_alignof(uint16_t) * CHAR_BIT
8020ceb5
MD
891 );
892}
893
894/*
895 * Output metadata into this session's metadata buffers.
896 */
897static
898int _ltt_session_metadata_statedump(struct ltt_session *session)
899{
b5234c06
MD
900 unsigned char *uuid_c = session->uuid;
901 char uuid_s[37];
8020ceb5
MD
902 struct ltt_channel *chan;
903 struct ltt_event *event;
904 int ret = 0;
905
b5234c06 906 if (!CMM_ACCESS_ONCE(session->active))
8020ceb5
MD
907 return 0;
908 if (session->metadata_dumped)
909 goto skip_session;
910 if (!session->metadata) {
b5234c06 911 DBG("LTTng: attempt to start tracing, but metadata channel is not found. Operation abort.\n");
8020ceb5
MD
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",
1dbfff0c
MD
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,
8020ceb5
MD
945 CTF_VERSION_MAJOR,
946 CTF_VERSION_MINOR,
947 uuid_s,
8a98a75d 948#if (BYTE_ORDER == BIG_ENDIAN)
8020ceb5
MD
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
965skip_session:
b5234c06 966 cds_list_for_each_entry(chan, &session->chan, list) {
8020ceb5
MD
967 ret = _ltt_channel_metadata_statedump(session, chan);
968 if (ret)
969 goto end;
970 }
971
b5234c06 972 cds_list_for_each_entry(event, &session->events, list) {
8020ceb5
MD
973 ret = _ltt_event_metadata_statedump(session, event->chan, event);
974 if (ret)
975 goto end;
976 }
977 session->metadata_dumped = 1;
978end:
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
17dfb34b 987 * LTTng. Called with ust_lock held.
8020ceb5
MD
988 */
989void ltt_transport_register(struct ltt_transport *transport)
990{
b5234c06 991 cds_list_add_tail(&transport->node, &ltt_transport_list);
8020ceb5 992}
8020ceb5
MD
993
994/**
995 * ltt_transport_unregister - LTT transport unregistration
996 * @transport: transport structure
17dfb34b 997 * Called with ust_lock held.
8020ceb5
MD
998 */
999void ltt_transport_unregister(struct ltt_transport *transport)
1000{
b5234c06 1001 cds_list_del(&transport->node);
8020ceb5
MD
1002}
1003
003fedf4 1004void lttng_ust_events_exit(void)
8020ceb5
MD
1005{
1006 struct ltt_session *session, *tmpsession;
1007
b5234c06 1008 cds_list_for_each_entry_safe(session, tmpsession, &sessions, list)
8020ceb5 1009 ltt_session_destroy(session);
8020ceb5 1010}
This page took 0.065856 seconds and 4 git commands to generate.