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