Cleanup: add lttng_/lttng-/LTTNG_ prefixes
[lttng-ust.git] / liblttng-ust / lttng-events.c
1 /*
2 * lttng-events.c
3 *
4 * Holds LTTng per-session event registry.
5 *
6 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; only
11 * version 2.1 of the License.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #define _GNU_SOURCE
24 #include <stdio.h>
25 #include <urcu/list.h>
26 #include <urcu/hlist.h>
27 #include <pthread.h>
28 #include <errno.h>
29 #include <sys/shm.h>
30 #include <sys/ipc.h>
31 #include <stdint.h>
32 #include <stddef.h>
33 #include <inttypes.h>
34 #include <time.h>
35 #include <lttng/ust-endian.h>
36 #include "clock.h"
37
38 #include <urcu-bp.h>
39 #include <urcu/compiler.h>
40 #include <urcu/uatomic.h>
41 #include <urcu/arch.h>
42
43 #include <lttng/tracepoint.h>
44 #include <lttng/ust-events.h>
45
46 #include <usterr-signal-safe.h>
47 #include <helper.h>
48 #include "error.h"
49 #include "compat.h"
50 #include "lttng-ust-uuid.h"
51
52 #include "tracepoint-internal.h"
53 #include "lttng-tracer.h"
54 #include "lttng-tracer-core.h"
55 #include "wait.h"
56 #include "../libringbuffer/shm.h"
57 #include "jhash.h"
58
59 /*
60 * The sessions mutex is the centralized mutex across UST tracing
61 * control and probe registration. All operations within this file are
62 * called by the communication thread, under ust_lock protection.
63 */
64 static pthread_mutex_t sessions_mutex = PTHREAD_MUTEX_INITIALIZER;
65
66 void ust_lock(void)
67 {
68 pthread_mutex_lock(&sessions_mutex);
69 }
70
71 void ust_unlock(void)
72 {
73 pthread_mutex_unlock(&sessions_mutex);
74 }
75
76 static CDS_LIST_HEAD(sessions);
77
78 /*
79 * Wildcard list, containing the active wildcards.
80 * Protected by ust lock.
81 */
82 static CDS_LIST_HEAD(wildcard_list);
83
84 /*
85 * Pending probes hash table, containing the registered ltt events for
86 * which tracepoint probes are still missing. Protected by the sessions
87 * mutex.
88 */
89 #define PENDING_PROBE_HASH_BITS 6
90 #define PENDING_PROBE_HASH_SIZE (1 << PENDING_PROBE_HASH_BITS)
91 static struct cds_hlist_head pending_probe_table[PENDING_PROBE_HASH_SIZE];
92
93 struct ust_pending_probe {
94 struct lttng_event *event;
95 struct cds_hlist_node node;
96 enum lttng_ust_loglevel_type loglevel_type;
97 int loglevel;
98 char name[];
99 };
100
101 static void _lttng_event_destroy(struct lttng_event *event);
102 static void _lttng_wildcard_destroy(struct session_wildcard *sw);
103 static void _lttng_channel_destroy(struct lttng_channel *chan);
104 static int _lttng_event_unregister(struct lttng_event *event);
105 static
106 int _lttng_event_metadata_statedump(struct lttng_session *session,
107 struct lttng_channel *chan,
108 struct lttng_event *event);
109 static
110 int _lttng_session_metadata_statedump(struct lttng_session *session);
111
112 int lttng_loglevel_match(const struct lttng_event_desc *desc,
113 enum lttng_ust_loglevel_type req_type,
114 int req_loglevel)
115 {
116 int ev_loglevel;
117
118 if (req_type == LTTNG_UST_LOGLEVEL_ALL)
119 return 1;
120 if (!desc->loglevel)
121 ev_loglevel = TRACE_DEFAULT;
122 else
123 ev_loglevel = *(*desc->loglevel);
124 switch (req_type) {
125 case LTTNG_UST_LOGLEVEL_RANGE:
126 if (ev_loglevel <= req_loglevel || req_loglevel == -1)
127 return 1;
128 else
129 return 0;
130 case LTTNG_UST_LOGLEVEL_SINGLE:
131 if (ev_loglevel == req_loglevel || req_loglevel == -1)
132 return 1;
133 else
134 return 0;
135 case LTTNG_UST_LOGLEVEL_ALL:
136 default:
137 return 1;
138 }
139 }
140
141 /*
142 * Return wildcard for a given event name if the event name match the
143 * one of the wildcards.
144 * Must be called with ust lock held.
145 * Returns NULL if not present.
146 */
147 static
148 struct wildcard_entry *match_wildcard(const struct lttng_event_desc *desc)
149 {
150 struct wildcard_entry *e;
151
152 cds_list_for_each_entry(e, &wildcard_list, list) {
153 /* If only contain '*' */
154 if (strlen(e->name) == 1)
155 goto possible_match;
156 /* Compare excluding final '*' */
157 if (!strncmp(desc->name, e->name, strlen(e->name) - 1))
158 goto possible_match;
159 continue; /* goto next, no match */
160 possible_match:
161 if (lttng_loglevel_match(desc,
162 e->loglevel_type,
163 e->loglevel)) {
164 return e;
165 }
166 /* no match, loop to next */
167 }
168 return NULL;
169 }
170
171 /*
172 * called at event creation if probe is missing.
173 * called with session mutex held.
174 */
175 static
176 int add_pending_probe(struct lttng_event *event, const char *name,
177 enum lttng_ust_loglevel_type loglevel_type,
178 int loglevel)
179 {
180 struct cds_hlist_head *head;
181 struct ust_pending_probe *e;
182 size_t name_len = strlen(name) + 1;
183 uint32_t hash;
184
185 if (name_len > LTTNG_UST_SYM_NAME_LEN) {
186 WARN("Truncating tracepoint name %s which exceeds size limits of %u chars", name, LTTNG_UST_SYM_NAME_LEN);
187 name_len = LTTNG_UST_SYM_NAME_LEN;
188 }
189 hash = jhash(name, name_len - 1, 0);
190 head = &pending_probe_table[hash & (PENDING_PROBE_HASH_SIZE - 1)];
191 e = zmalloc(sizeof(struct ust_pending_probe) + name_len);
192 if (!e)
193 return -ENOMEM;
194 memcpy(&e->name[0], name, name_len);
195 e->name[name_len - 1] = '\0';
196 e->loglevel_type = loglevel_type;
197 e->loglevel = loglevel;
198 cds_hlist_add_head(&e->node, head);
199 e->event = event;
200 event->pending_probe = e;
201 return 0;
202 }
203
204 /*
205 * remove a pending probe. called when at event teardown and when an
206 * event is fixed (probe is loaded).
207 * called with session mutex held.
208 */
209 static
210 void remove_pending_probe(struct ust_pending_probe *e)
211 {
212 if (!e)
213 return;
214 cds_hlist_del(&e->node);
215 free(e);
216 }
217
218 /*
219 * Called at library load: connect the probe on the events pending on
220 * probe load.
221 * called with session mutex held.
222 */
223 int pending_probe_fix_events(const struct lttng_event_desc *desc)
224 {
225 struct cds_hlist_head *head;
226 struct cds_hlist_node *node, *p;
227 struct ust_pending_probe *e;
228 const char *name = desc->name;
229 int ret = 0;
230 struct lttng_ust_event event_param;
231 size_t name_len = strlen(name) + 1;
232 uint32_t hash;
233
234 /* Wildcard */
235 {
236 struct wildcard_entry *wildcard;
237
238 //FIXME: should iterate on all match for filter.
239 //FIXME: should re-use pending event if present rather
240 //than create duplicate.
241 wildcard = match_wildcard(desc);
242 if (strcmp(desc->name, "lttng_ust:metadata") && wildcard) {
243 struct session_wildcard *sw;
244
245 cds_list_for_each_entry(sw, &wildcard->session_list,
246 session_list) {
247 struct lttng_event *ev;
248 int ret;
249
250 memcpy(&event_param, &sw->event_param,
251 sizeof(event_param));
252 strncpy(event_param.name,
253 desc->name,
254 sizeof(event_param.name));
255 event_param.name[sizeof(event_param.name) - 1] = '\0';
256 /* create event */
257 ret = lttng_event_create(sw->chan,
258 &event_param, &ev);
259 if (ret) {
260 DBG("Error creating event");
261 continue;
262 }
263 cds_list_add(&ev->wildcard_list,
264 &sw->events);
265 lttng_filter_event_link_wildcard_bytecode(ev,
266 sw);
267 }
268 }
269 }
270
271 if (name_len > LTTNG_UST_SYM_NAME_LEN) {
272 WARN("Truncating tracepoint name %s which exceeds size limits of %u chars", name, LTTNG_UST_SYM_NAME_LEN);
273 name_len = LTTNG_UST_SYM_NAME_LEN;
274 }
275 hash = jhash(name, name_len - 1, 0);
276 head = &pending_probe_table[hash & (PENDING_PROBE_HASH_SIZE - 1)];
277 cds_hlist_for_each_entry_safe(e, node, p, head, node) {
278 struct lttng_event *event;
279 struct lttng_channel *chan;
280
281 if (!lttng_loglevel_match(desc,
282 e->loglevel_type,
283 e->loglevel)) {
284 continue;
285 }
286 if (strncmp(name, e->name, LTTNG_UST_SYM_NAME_LEN - 1)) {
287 continue;
288 }
289 /* TODO: wildcard same as pending event: duplicate */
290 /* TODO: Should apply filter though */
291 event = e->event;
292 chan = event->chan;
293 assert(!event->desc);
294 event->desc = desc;
295 event->pending_probe = NULL;
296 remove_pending_probe(e);
297 ret |= __tracepoint_probe_register(name,
298 event->desc->probe_callback,
299 event, event->desc->signature);
300 if (ret)
301 continue;
302 event->id = chan->free_event_id++;
303 ret |= _lttng_event_metadata_statedump(chan->session, chan,
304 event);
305 lttng_filter_event_link_bytecode(event);
306 }
307 return ret;
308 }
309
310 void synchronize_trace(void)
311 {
312 synchronize_rcu();
313 }
314
315 struct lttng_session *lttng_session_create(void)
316 {
317 struct lttng_session *session;
318 int ret;
319
320 session = zmalloc(sizeof(struct lttng_session));
321 if (!session)
322 return NULL;
323 CDS_INIT_LIST_HEAD(&session->chan);
324 CDS_INIT_LIST_HEAD(&session->events);
325 CDS_INIT_LIST_HEAD(&session->wildcards);
326 ret = lttng_ust_uuid_generate(session->uuid);
327 if (ret != 0) {
328 session->uuid[0] = '\0';
329 }
330 cds_list_add(&session->list, &sessions);
331 return session;
332 }
333
334 void lttng_session_destroy(struct lttng_session *session)
335 {
336 struct lttng_channel *chan, *tmpchan;
337 struct lttng_event *event, *tmpevent;
338 struct session_wildcard *wildcard, *tmpwildcard;
339 int ret;
340
341 CMM_ACCESS_ONCE(session->active) = 0;
342 cds_list_for_each_entry(event, &session->events, list) {
343 ret = _lttng_event_unregister(event);
344 WARN_ON(ret);
345 }
346 synchronize_trace(); /* Wait for in-flight events to complete */
347 cds_list_for_each_entry_safe(wildcard, tmpwildcard, &session->wildcards, list)
348 _lttng_wildcard_destroy(wildcard);
349 cds_list_for_each_entry_safe(event, tmpevent, &session->events, list)
350 _lttng_event_destroy(event);
351 cds_list_for_each_entry_safe(chan, tmpchan, &session->chan, list)
352 _lttng_channel_destroy(chan);
353 cds_list_del(&session->list);
354 free(session);
355 }
356
357 int lttng_session_enable(struct lttng_session *session)
358 {
359 int ret = 0;
360 struct lttng_channel *chan;
361
362 if (session->active) {
363 ret = -EBUSY;
364 goto end;
365 }
366
367 /*
368 * Snapshot the number of events per channel to know the type of header
369 * we need to use.
370 */
371 cds_list_for_each_entry(chan, &session->chan, list) {
372 if (chan->header_type)
373 continue; /* don't change it if session stop/restart */
374 if (chan->free_event_id < 31)
375 chan->header_type = 1; /* compact */
376 else
377 chan->header_type = 2; /* large */
378 }
379
380 CMM_ACCESS_ONCE(session->active) = 1;
381 CMM_ACCESS_ONCE(session->been_active) = 1;
382 ret = _lttng_session_metadata_statedump(session);
383 if (ret)
384 CMM_ACCESS_ONCE(session->active) = 0;
385 end:
386 return ret;
387 }
388
389 int lttng_session_disable(struct lttng_session *session)
390 {
391 int ret = 0;
392
393 if (!session->active) {
394 ret = -EBUSY;
395 goto end;
396 }
397 CMM_ACCESS_ONCE(session->active) = 0;
398 end:
399 return ret;
400 }
401
402 int lttng_channel_enable(struct lttng_channel *channel)
403 {
404 int old;
405
406 if (channel == channel->session->metadata)
407 return -EPERM;
408 old = uatomic_xchg(&channel->enabled, 1);
409 if (old)
410 return -EEXIST;
411 return 0;
412 }
413
414 int lttng_channel_disable(struct lttng_channel *channel)
415 {
416 int old;
417
418 if (channel == channel->session->metadata)
419 return -EPERM;
420 old = uatomic_xchg(&channel->enabled, 0);
421 if (!old)
422 return -EEXIST;
423 return 0;
424 }
425
426 int lttng_event_enable(struct lttng_event *event)
427 {
428 int old;
429
430 if (event->chan == event->chan->session->metadata)
431 return -EPERM;
432 old = uatomic_xchg(&event->enabled, 1);
433 if (old)
434 return -EEXIST;
435 return 0;
436 }
437
438 int lttng_event_disable(struct lttng_event *event)
439 {
440 int old;
441
442 if (event->chan == event->chan->session->metadata)
443 return -EPERM;
444 old = uatomic_xchg(&event->enabled, 0);
445 if (!old)
446 return -EEXIST;
447 return 0;
448 }
449
450 struct lttng_channel *lttng_channel_create(struct lttng_session *session,
451 const char *transport_name,
452 void *buf_addr,
453 size_t subbuf_size, size_t num_subbuf,
454 unsigned int switch_timer_interval,
455 unsigned int read_timer_interval,
456 int **shm_fd, int **wait_fd,
457 uint64_t **memory_map_size,
458 struct lttng_channel *chan_priv_init)
459 {
460 struct lttng_channel *chan = NULL;
461 struct lttng_transport *transport;
462
463 if (session->been_active)
464 goto active; /* Refuse to add channel to active session */
465 transport = lttng_transport_find(transport_name);
466 if (!transport) {
467 DBG("LTTng transport %s not found\n",
468 transport_name);
469 goto notransport;
470 }
471 chan_priv_init->id = session->free_chan_id++;
472 chan_priv_init->session = session;
473 /*
474 * Note: the channel creation op already writes into the packet
475 * headers. Therefore the "chan" information used as input
476 * should be already accessible.
477 */
478 chan = transport->ops.channel_create(transport_name, buf_addr,
479 subbuf_size, num_subbuf, switch_timer_interval,
480 read_timer_interval, shm_fd, wait_fd,
481 memory_map_size, chan_priv_init);
482 if (!chan)
483 goto create_error;
484 chan->enabled = 1;
485 chan->ops = &transport->ops;
486 cds_list_add(&chan->list, &session->chan);
487 return chan;
488
489 create_error:
490 notransport:
491 active:
492 return NULL;
493 }
494
495 /*
496 * Only used internally at session destruction.
497 */
498 static
499 void _lttng_channel_destroy(struct lttng_channel *chan)
500 {
501 cds_list_del(&chan->list);
502 lttng_destroy_context(chan->ctx);
503 chan->ops->channel_destroy(chan);
504 }
505
506 /*
507 * Supports event creation while tracing session is active.
508 */
509 int lttng_event_create(struct lttng_channel *chan,
510 struct lttng_ust_event *event_param,
511 struct lttng_event **_event)
512 {
513 const struct lttng_event_desc *desc = NULL; /* silence gcc */
514 struct lttng_event *event;
515 int ret = 0;
516
517 if (chan->used_event_id == -1U) {
518 ret = -ENOMEM;
519 goto full;
520 }
521 //FIXME: re-use event if already registered by wildcard or
522 //if we have a pending probe.... (CHECK)
523 /*
524 * This is O(n^2) (for each event, the loop is called at event
525 * creation). Might require a hash if we have lots of events.
526 */
527 cds_list_for_each_entry(event, &chan->session->events, list) {
528 if (event->desc && !strncmp(event->desc->name,
529 event_param->name,
530 LTTNG_UST_SYM_NAME_LEN - 1)) {
531 ret = -EEXIST;
532 goto exist;
533 }
534 }
535
536 /*
537 * Check if loglevel match. Refuse to connect event if not.
538 */
539 if (event_param->instrumentation == LTTNG_UST_TRACEPOINT) {
540 desc = lttng_event_get(event_param->name);
541 if (desc) {
542 if (!lttng_loglevel_match(desc,
543 event_param->loglevel_type,
544 event_param->loglevel)) {
545 ret = -EPERM;
546 goto no_loglevel_match;
547 }
548 }
549 /*
550 * If descriptor is not there, it will be added to
551 * pending probes.
552 */
553 }
554 event = zmalloc(sizeof(struct lttng_event));
555 if (!event) {
556 ret = -ENOMEM;
557 goto cache_error;
558 }
559 event->chan = chan;
560 /*
561 * used_event_id counts the maximum number of event IDs that can
562 * register if all probes register.
563 */
564 chan->used_event_id++;
565 event->enabled = 1;
566 CDS_INIT_LIST_HEAD(&event->filter_bytecode);
567 CDS_INIT_LIST_HEAD(&event->bytecode_runtime);
568 event->instrumentation = event_param->instrumentation;
569 /* Populate lttng_event structure before tracepoint registration. */
570 cmm_smp_wmb();
571 switch (event_param->instrumentation) {
572 case LTTNG_UST_TRACEPOINT:
573 event->desc = desc;
574 if (event->desc) {
575 ret = __tracepoint_probe_register(event_param->name,
576 event->desc->probe_callback,
577 event, event->desc->signature);
578 if (ret)
579 goto register_error;
580 event->id = chan->free_event_id++;
581 } else {
582 /*
583 * If the probe is not present, event->desc stays NULL,
584 * waiting for the probe to register, and the event->id
585 * stays unallocated.
586 */
587 ret = add_pending_probe(event, event_param->name,
588 event_param->loglevel_type,
589 event_param->loglevel);
590 if (ret)
591 goto add_pending_error;
592 }
593 break;
594 default:
595 WARN_ON_ONCE(1);
596 }
597 if (event->desc) {
598 ret = _lttng_event_metadata_statedump(chan->session, chan, event);
599 if (ret)
600 goto statedump_error;
601 }
602 cds_list_add(&event->list, &chan->session->events);
603 *_event = event;
604 return 0;
605
606 statedump_error:
607 if (event->desc) {
608 WARN_ON_ONCE(__tracepoint_probe_unregister(event_param->name,
609 event->desc->probe_callback,
610 event));
611 lttng_event_put(event->desc);
612 }
613 add_pending_error:
614 register_error:
615 free(event);
616 cache_error:
617 no_loglevel_match:
618 exist:
619 full:
620 return ret;
621 }
622
623 /*
624 * Only used internally at session destruction.
625 */
626 int _lttng_event_unregister(struct lttng_event *event)
627 {
628 int ret = -EINVAL;
629
630 switch (event->instrumentation) {
631 case LTTNG_UST_TRACEPOINT:
632 if (event->desc) {
633 ret = __tracepoint_probe_unregister(event->desc->name,
634 event->desc->probe_callback,
635 event);
636 if (ret)
637 return ret;
638 } else {
639 remove_pending_probe(event->pending_probe);
640 ret = 0;
641 }
642 break;
643 default:
644 WARN_ON_ONCE(1);
645 }
646 return ret;
647 }
648
649 /*
650 * Only used internally at session destruction.
651 */
652 static
653 void _lttng_event_destroy(struct lttng_event *event)
654 {
655 switch (event->instrumentation) {
656 case LTTNG_UST_TRACEPOINT:
657 if (event->desc) {
658 lttng_event_put(event->desc);
659 }
660 break;
661 default:
662 WARN_ON_ONCE(1);
663 }
664 cds_list_del(&event->list);
665 lttng_destroy_context(event->ctx);
666 lttng_free_event_filter_runtime(event);
667 lttng_free_event_filter_bytecode(event);
668 free(event);
669 }
670
671 /*
672 * We have exclusive access to our metadata buffer (protected by the
673 * ust_lock), so we can do racy operations such as looking for
674 * remaining space left in packet and write, since mutual exclusion
675 * protects us from concurrent writes.
676 */
677 int lttng_metadata_printf(struct lttng_session *session,
678 const char *fmt, ...)
679 {
680 struct lttng_ust_lib_ring_buffer_ctx ctx;
681 struct lttng_channel *chan = session->metadata;
682 char *str = NULL;
683 int ret = 0, waitret;
684 size_t len, reserve_len, pos;
685 va_list ap;
686
687 WARN_ON_ONCE(!CMM_ACCESS_ONCE(session->active));
688
689 va_start(ap, fmt);
690 ret = vasprintf(&str, fmt, ap);
691 va_end(ap);
692 if (ret < 0)
693 return -ENOMEM;
694
695 len = strlen(str);
696 pos = 0;
697
698 for (pos = 0; pos < len; pos += reserve_len) {
699 reserve_len = min_t(size_t,
700 chan->ops->packet_avail_size(chan->chan, chan->handle),
701 len - pos);
702 lib_ring_buffer_ctx_init(&ctx, chan->chan, NULL, reserve_len,
703 sizeof(char), -1, chan->handle);
704 /*
705 * We don't care about metadata buffer's records lost
706 * count, because we always retry here. Report error if
707 * we need to bail out after timeout or being
708 * interrupted.
709 */
710 waitret = wait_cond_interruptible_timeout(
711 ({
712 ret = chan->ops->event_reserve(&ctx, 0);
713 ret != -ENOBUFS || !ret;
714 }),
715 LTTNG_METADATA_TIMEOUT_MSEC);
716 if (waitret == -ETIMEDOUT || waitret == -EINTR || ret) {
717 DBG("LTTng: Failure to write metadata to buffers (%s)\n",
718 waitret == -EINTR ? "interrupted" :
719 (ret == -ENOBUFS ? "timeout" : "I/O error"));
720 if (waitret == -EINTR)
721 ret = waitret;
722 goto end;
723 }
724 chan->ops->event_write(&ctx, &str[pos], reserve_len);
725 chan->ops->event_commit(&ctx);
726 }
727 end:
728 free(str);
729 return ret;
730 }
731
732 static
733 int _lttng_field_statedump(struct lttng_session *session,
734 const struct lttng_event_field *field)
735 {
736 int ret = 0;
737
738 if (field->nowrite)
739 return 0;
740
741 switch (field->type.atype) {
742 case atype_integer:
743 ret = lttng_metadata_printf(session,
744 " integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s;\n",
745 field->type.u.basic.integer.size,
746 field->type.u.basic.integer.alignment,
747 field->type.u.basic.integer.signedness,
748 (field->type.u.basic.integer.encoding == lttng_encode_none)
749 ? "none"
750 : (field->type.u.basic.integer.encoding == lttng_encode_UTF8)
751 ? "UTF8"
752 : "ASCII",
753 field->type.u.basic.integer.base,
754 #if (BYTE_ORDER == BIG_ENDIAN)
755 field->type.u.basic.integer.reverse_byte_order ? " byte_order = le;" : "",
756 #else
757 field->type.u.basic.integer.reverse_byte_order ? " byte_order = be;" : "",
758 #endif
759 field->name);
760 break;
761 case atype_float:
762 ret = lttng_metadata_printf(session,
763 " floating_point { exp_dig = %u; mant_dig = %u; align = %u;%s } _%s;\n",
764 field->type.u.basic._float.exp_dig,
765 field->type.u.basic._float.mant_dig,
766 field->type.u.basic._float.alignment,
767 #if (BYTE_ORDER == BIG_ENDIAN)
768 field->type.u.basic.integer.reverse_byte_order ? " byte_order = le;" : "",
769 #else
770 field->type.u.basic.integer.reverse_byte_order ? " byte_order = be;" : "",
771 #endif
772 field->name);
773 break;
774 case atype_enum:
775 ret = lttng_metadata_printf(session,
776 " %s %s;\n",
777 field->type.u.basic.enumeration.name,
778 field->name);
779 break;
780 case atype_array:
781 {
782 const struct lttng_basic_type *elem_type;
783
784 elem_type = &field->type.u.array.elem_type;
785 ret = lttng_metadata_printf(session,
786 " integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[%u];\n",
787 elem_type->u.basic.integer.size,
788 elem_type->u.basic.integer.alignment,
789 elem_type->u.basic.integer.signedness,
790 (elem_type->u.basic.integer.encoding == lttng_encode_none)
791 ? "none"
792 : (elem_type->u.basic.integer.encoding == lttng_encode_UTF8)
793 ? "UTF8"
794 : "ASCII",
795 elem_type->u.basic.integer.base,
796 #if (BYTE_ORDER == BIG_ENDIAN)
797 elem_type->u.basic.integer.reverse_byte_order ? " byte_order = le;" : "",
798 #else
799 elem_type->u.basic.integer.reverse_byte_order ? " byte_order = be;" : "",
800 #endif
801 field->name, field->type.u.array.length);
802 break;
803 }
804 case atype_sequence:
805 {
806 const struct lttng_basic_type *elem_type;
807 const struct lttng_basic_type *length_type;
808
809 elem_type = &field->type.u.sequence.elem_type;
810 length_type = &field->type.u.sequence.length_type;
811 ret = lttng_metadata_printf(session,
812 " integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } __%s_length;\n",
813 length_type->u.basic.integer.size,
814 (unsigned int) length_type->u.basic.integer.alignment,
815 length_type->u.basic.integer.signedness,
816 (length_type->u.basic.integer.encoding == lttng_encode_none)
817 ? "none"
818 : ((length_type->u.basic.integer.encoding == lttng_encode_UTF8)
819 ? "UTF8"
820 : "ASCII"),
821 length_type->u.basic.integer.base,
822 #if (BYTE_ORDER == BIG_ENDIAN)
823 length_type->u.basic.integer.reverse_byte_order ? " byte_order = le;" : "",
824 #else
825 length_type->u.basic.integer.reverse_byte_order ? " byte_order = be;" : "",
826 #endif
827 field->name);
828 if (ret)
829 return ret;
830
831 ret = lttng_metadata_printf(session,
832 " integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[ __%s_length ];\n",
833 elem_type->u.basic.integer.size,
834 (unsigned int) elem_type->u.basic.integer.alignment,
835 elem_type->u.basic.integer.signedness,
836 (elem_type->u.basic.integer.encoding == lttng_encode_none)
837 ? "none"
838 : ((elem_type->u.basic.integer.encoding == lttng_encode_UTF8)
839 ? "UTF8"
840 : "ASCII"),
841 elem_type->u.basic.integer.base,
842 #if (BYTE_ORDER == BIG_ENDIAN)
843 elem_type->u.basic.integer.reverse_byte_order ? " byte_order = le;" : "",
844 #else
845 elem_type->u.basic.integer.reverse_byte_order ? " byte_order = be;" : "",
846 #endif
847 field->name,
848 field->name);
849 break;
850 }
851
852 case atype_string:
853 /* Default encoding is UTF8 */
854 ret = lttng_metadata_printf(session,
855 " string%s _%s;\n",
856 field->type.u.basic.string.encoding == lttng_encode_ASCII ?
857 " { encoding = ASCII; }" : "",
858 field->name);
859 break;
860 default:
861 WARN_ON_ONCE(1);
862 return -EINVAL;
863 }
864 return ret;
865 }
866
867 static
868 int _lttng_context_metadata_statedump(struct lttng_session *session,
869 struct lttng_ctx *ctx)
870 {
871 int ret = 0;
872 int i;
873
874 if (!ctx)
875 return 0;
876 for (i = 0; i < ctx->nr_fields; i++) {
877 const struct lttng_ctx_field *field = &ctx->fields[i];
878
879 ret = _lttng_field_statedump(session, &field->event_field);
880 if (ret)
881 return ret;
882 }
883 return ret;
884 }
885
886 static
887 int _lttng_fields_metadata_statedump(struct lttng_session *session,
888 struct lttng_event *event)
889 {
890 const struct lttng_event_desc *desc = event->desc;
891 int ret = 0;
892 int i;
893
894 for (i = 0; i < desc->nr_fields; i++) {
895 const struct lttng_event_field *field = &desc->fields[i];
896
897 ret = _lttng_field_statedump(session, field);
898 if (ret)
899 return ret;
900 }
901 return ret;
902 }
903
904 static
905 int _lttng_event_metadata_statedump(struct lttng_session *session,
906 struct lttng_channel *chan,
907 struct lttng_event *event)
908 {
909 int ret = 0;
910 int loglevel = TRACE_DEFAULT;
911
912 if (event->metadata_dumped || !CMM_ACCESS_ONCE(session->active))
913 return 0;
914 if (chan == session->metadata)
915 return 0;
916 /*
917 * Don't print events for which probe load is pending.
918 */
919 if (!event->desc)
920 return 0;
921
922 ret = lttng_metadata_printf(session,
923 "event {\n"
924 " name = \"%s\";\n"
925 " id = %u;\n"
926 " stream_id = %u;\n",
927 event->desc->name,
928 event->id,
929 event->chan->id);
930 if (ret)
931 goto end;
932
933 if (event->desc->loglevel)
934 loglevel = *(*event->desc->loglevel);
935
936 ret = lttng_metadata_printf(session,
937 " loglevel = %d;\n",
938 loglevel);
939 if (ret)
940 goto end;
941
942 if (event->desc->u.ext.model_emf_uri) {
943 ret = lttng_metadata_printf(session,
944 " model.emf.uri = \"%s\";\n",
945 *(event->desc->u.ext.model_emf_uri));
946 if (ret)
947 goto end;
948 }
949
950 if (event->ctx) {
951 ret = lttng_metadata_printf(session,
952 " context := struct {\n");
953 if (ret)
954 goto end;
955 }
956 ret = _lttng_context_metadata_statedump(session, event->ctx);
957 if (ret)
958 goto end;
959 if (event->ctx) {
960 ret = lttng_metadata_printf(session,
961 " };\n");
962 if (ret)
963 goto end;
964 }
965
966 ret = lttng_metadata_printf(session,
967 " fields := struct {\n"
968 );
969 if (ret)
970 goto end;
971
972 ret = _lttng_fields_metadata_statedump(session, event);
973 if (ret)
974 goto end;
975
976 /*
977 * LTTng space reservation can only reserve multiples of the
978 * byte size.
979 */
980 ret = lttng_metadata_printf(session,
981 " };\n"
982 "};\n\n");
983 if (ret)
984 goto end;
985
986 event->metadata_dumped = 1;
987 end:
988 return ret;
989
990 }
991
992 static
993 int _lttng_channel_metadata_statedump(struct lttng_session *session,
994 struct lttng_channel *chan)
995 {
996 int ret = 0;
997
998 if (chan->metadata_dumped || !CMM_ACCESS_ONCE(session->active))
999 return 0;
1000 if (chan == session->metadata)
1001 return 0;
1002
1003 WARN_ON_ONCE(!chan->header_type);
1004 ret = lttng_metadata_printf(session,
1005 "stream {\n"
1006 " id = %u;\n"
1007 " event.header := %s;\n"
1008 " packet.context := struct packet_context;\n",
1009 chan->id,
1010 chan->header_type == 1 ? "struct event_header_compact" :
1011 "struct event_header_large");
1012 if (ret)
1013 goto end;
1014
1015 if (chan->ctx) {
1016 ret = lttng_metadata_printf(session,
1017 " event.context := struct {\n");
1018 if (ret)
1019 goto end;
1020 }
1021 ret = _lttng_context_metadata_statedump(session, chan->ctx);
1022 if (ret)
1023 goto end;
1024 if (chan->ctx) {
1025 ret = lttng_metadata_printf(session,
1026 " };\n");
1027 if (ret)
1028 goto end;
1029 }
1030
1031 ret = lttng_metadata_printf(session,
1032 "};\n\n");
1033
1034 chan->metadata_dumped = 1;
1035 end:
1036 return ret;
1037 }
1038
1039 static
1040 int _lttng_stream_packet_context_declare(struct lttng_session *session)
1041 {
1042 return lttng_metadata_printf(session,
1043 "struct packet_context {\n"
1044 " uint64_clock_monotonic_t timestamp_begin;\n"
1045 " uint64_clock_monotonic_t timestamp_end;\n"
1046 " uint64_t content_size;\n"
1047 " uint64_t packet_size;\n"
1048 " unsigned long events_discarded;\n"
1049 " uint32_t cpu_id;\n"
1050 "};\n\n"
1051 );
1052 }
1053
1054 /*
1055 * Compact header:
1056 * id: range: 0 - 30.
1057 * id 31 is reserved to indicate an extended header.
1058 *
1059 * Large header:
1060 * id: range: 0 - 65534.
1061 * id 65535 is reserved to indicate an extended header.
1062 */
1063 static
1064 int _lttng_event_header_declare(struct lttng_session *session)
1065 {
1066 return lttng_metadata_printf(session,
1067 "struct event_header_compact {\n"
1068 " enum : uint5_t { compact = 0 ... 30, extended = 31 } id;\n"
1069 " variant <id> {\n"
1070 " struct {\n"
1071 " uint27_clock_monotonic_t timestamp;\n"
1072 " } compact;\n"
1073 " struct {\n"
1074 " uint32_t id;\n"
1075 " uint64_clock_monotonic_t timestamp;\n"
1076 " } extended;\n"
1077 " } v;\n"
1078 "} align(%u);\n"
1079 "\n"
1080 "struct event_header_large {\n"
1081 " enum : uint16_t { compact = 0 ... 65534, extended = 65535 } id;\n"
1082 " variant <id> {\n"
1083 " struct {\n"
1084 " uint32_clock_monotonic_t timestamp;\n"
1085 " } compact;\n"
1086 " struct {\n"
1087 " uint32_t id;\n"
1088 " uint64_clock_monotonic_t timestamp;\n"
1089 " } extended;\n"
1090 " } v;\n"
1091 "} align(%u);\n\n",
1092 lttng_alignof(uint32_t) * CHAR_BIT,
1093 lttng_alignof(uint16_t) * CHAR_BIT
1094 );
1095 }
1096
1097 /*
1098 * Approximation of NTP time of day to clock monotonic correlation,
1099 * taken at start of trace.
1100 * Yes, this is only an approximation. Yes, we can (and will) do better
1101 * in future versions.
1102 */
1103 static
1104 uint64_t measure_clock_offset(void)
1105 {
1106 uint64_t offset, monotonic[2], realtime;
1107 struct timespec rts = { 0, 0 };
1108 int ret;
1109
1110 monotonic[0] = trace_clock_read64();
1111 ret = clock_gettime(CLOCK_REALTIME, &rts);
1112 if (ret < 0)
1113 return 0;
1114 monotonic[1] = trace_clock_read64();
1115 offset = (monotonic[0] + monotonic[1]) >> 1;
1116 realtime = (uint64_t) rts.tv_sec * 1000000000ULL;
1117 realtime += rts.tv_nsec;
1118 offset = realtime - offset;
1119 return offset;
1120 }
1121
1122 /*
1123 * Output metadata into this session's metadata buffers.
1124 */
1125 static
1126 int _lttng_session_metadata_statedump(struct lttng_session *session)
1127 {
1128 unsigned char *uuid_c = session->uuid;
1129 char uuid_s[LTTNG_UST_UUID_STR_LEN],
1130 clock_uuid_s[LTTNG_UST_UUID_STR_LEN];
1131 struct lttng_channel *chan;
1132 struct lttng_event *event;
1133 int ret = 0;
1134 char procname[LTTNG_UST_PROCNAME_LEN] = "";
1135 char hostname[HOST_NAME_MAX];
1136
1137 if (!CMM_ACCESS_ONCE(session->active))
1138 return 0;
1139 if (session->metadata_dumped)
1140 goto skip_session;
1141 if (!session->metadata) {
1142 DBG("LTTng: attempt to start tracing, but metadata channel is not found. Operation abort.\n");
1143 return -EPERM;
1144 }
1145
1146 snprintf(uuid_s, sizeof(uuid_s),
1147 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1148 uuid_c[0], uuid_c[1], uuid_c[2], uuid_c[3],
1149 uuid_c[4], uuid_c[5], uuid_c[6], uuid_c[7],
1150 uuid_c[8], uuid_c[9], uuid_c[10], uuid_c[11],
1151 uuid_c[12], uuid_c[13], uuid_c[14], uuid_c[15]);
1152
1153 ret = lttng_metadata_printf(session,
1154 "typealias integer { size = 8; align = %u; signed = false; } := uint8_t;\n"
1155 "typealias integer { size = 16; align = %u; signed = false; } := uint16_t;\n"
1156 "typealias integer { size = 32; align = %u; signed = false; } := uint32_t;\n"
1157 "typealias integer { size = 64; align = %u; signed = false; } := uint64_t;\n"
1158 "typealias integer { size = %u; align = %u; signed = false; } := unsigned long;\n"
1159 "typealias integer { size = 5; align = 1; signed = false; } := uint5_t;\n"
1160 "typealias integer { size = 27; align = 1; signed = false; } := uint27_t;\n"
1161 "\n"
1162 "trace {\n"
1163 " major = %u;\n"
1164 " minor = %u;\n"
1165 " uuid = \"%s\";\n"
1166 " byte_order = %s;\n"
1167 " packet.header := struct {\n"
1168 " uint32_t magic;\n"
1169 " uint8_t uuid[16];\n"
1170 " uint32_t stream_id;\n"
1171 " };\n"
1172 "};\n\n",
1173 lttng_alignof(uint8_t) * CHAR_BIT,
1174 lttng_alignof(uint16_t) * CHAR_BIT,
1175 lttng_alignof(uint32_t) * CHAR_BIT,
1176 lttng_alignof(uint64_t) * CHAR_BIT,
1177 sizeof(unsigned long) * CHAR_BIT,
1178 lttng_alignof(unsigned long) * CHAR_BIT,
1179 CTF_SPEC_MAJOR,
1180 CTF_SPEC_MINOR,
1181 uuid_s,
1182 #if (BYTE_ORDER == BIG_ENDIAN)
1183 "be"
1184 #else
1185 "le"
1186 #endif
1187 );
1188 if (ret)
1189 goto end;
1190
1191 /* ignore error, just use empty string if error. */
1192 hostname[0] = '\0';
1193 ret = gethostname(hostname, sizeof(hostname));
1194 if (ret && errno == ENAMETOOLONG)
1195 hostname[HOST_NAME_MAX - 1] = '\0';
1196 lttng_ust_getprocname(procname);
1197 procname[LTTNG_UST_PROCNAME_LEN - 1] = '\0';
1198 ret = lttng_metadata_printf(session,
1199 "env {\n"
1200 " hostname = \"%s\";\n"
1201 " vpid = %d;\n"
1202 " procname = \"%s\";\n"
1203 " domain = \"ust\";\n"
1204 " tracer_name = \"lttng-ust\";\n"
1205 " tracer_major = %u;\n"
1206 " tracer_minor = %u;\n"
1207 " tracer_patchlevel = %u;\n"
1208 "};\n\n",
1209 hostname,
1210 (int) getpid(),
1211 procname,
1212 LTTNG_UST_MAJOR_VERSION,
1213 LTTNG_UST_MINOR_VERSION,
1214 LTTNG_UST_PATCHLEVEL_VERSION
1215 );
1216 if (ret)
1217 goto end;
1218
1219 ret = lttng_metadata_printf(session,
1220 "clock {\n"
1221 " name = %s;\n",
1222 "monotonic"
1223 );
1224 if (ret)
1225 goto end;
1226
1227 if (!trace_clock_uuid(clock_uuid_s)) {
1228 ret = lttng_metadata_printf(session,
1229 " uuid = \"%s\";\n",
1230 clock_uuid_s
1231 );
1232 if (ret)
1233 goto end;
1234 }
1235
1236 ret = lttng_metadata_printf(session,
1237 " description = \"Monotonic Clock\";\n"
1238 " freq = %" PRIu64 "; /* Frequency, in Hz */\n"
1239 " /* clock value offset from Epoch is: offset * (1/freq) */\n"
1240 " offset = %" PRIu64 ";\n"
1241 "};\n\n",
1242 trace_clock_freq(),
1243 measure_clock_offset()
1244 );
1245 if (ret)
1246 goto end;
1247
1248 ret = lttng_metadata_printf(session,
1249 "typealias integer {\n"
1250 " size = 27; align = 1; signed = false;\n"
1251 " map = clock.monotonic.value;\n"
1252 "} := uint27_clock_monotonic_t;\n"
1253 "\n"
1254 "typealias integer {\n"
1255 " size = 32; align = %u; signed = false;\n"
1256 " map = clock.monotonic.value;\n"
1257 "} := uint32_clock_monotonic_t;\n"
1258 "\n"
1259 "typealias integer {\n"
1260 " size = 64; align = %u; signed = false;\n"
1261 " map = clock.monotonic.value;\n"
1262 "} := uint64_clock_monotonic_t;\n\n",
1263 lttng_alignof(uint32_t) * CHAR_BIT,
1264 lttng_alignof(uint64_t) * CHAR_BIT
1265 );
1266 if (ret)
1267 goto end;
1268
1269 ret = _lttng_stream_packet_context_declare(session);
1270 if (ret)
1271 goto end;
1272
1273 ret = _lttng_event_header_declare(session);
1274 if (ret)
1275 goto end;
1276
1277 skip_session:
1278 cds_list_for_each_entry(chan, &session->chan, list) {
1279 ret = _lttng_channel_metadata_statedump(session, chan);
1280 if (ret)
1281 goto end;
1282 }
1283
1284 cds_list_for_each_entry(event, &session->events, list) {
1285 ret = _lttng_event_metadata_statedump(session, event->chan, event);
1286 if (ret)
1287 goto end;
1288 }
1289 session->metadata_dumped = 1;
1290 end:
1291 return ret;
1292 }
1293
1294 void lttng_ust_events_exit(void)
1295 {
1296 struct lttng_session *session, *tmpsession;
1297
1298 cds_list_for_each_entry_safe(session, tmpsession, &sessions, list)
1299 lttng_session_destroy(session);
1300 }
1301
1302 /* WILDCARDS */
1303
1304 static
1305 int wildcard_same_loglevel(struct wildcard_entry *e,
1306 enum lttng_ust_loglevel_type loglevel_type,
1307 int loglevel)
1308 {
1309 if (e->loglevel_type == loglevel_type && e->loglevel == loglevel)
1310 return 1;
1311 else
1312 return 0;
1313 }
1314
1315 #if 0
1316 static
1317 int wildcard_is_within(struct wildcard_entry *e,
1318 enum lttng_ust_loglevel_type loglevel_type,
1319 int loglevel)
1320 {
1321 if (e->loglevel_type == LTTNG_UST_LOGLEVEL_ALL
1322 || e->loglevel == -1)
1323 return 1;
1324 switch (e->loglevel_type) {
1325 case LTTNG_UST_LOGLEVEL_RANGE:
1326 switch (loglevel_type) {
1327 case LTTNG_UST_LOGLEVEL_RANGE:
1328 if (e->loglevel >= loglevel)
1329 return 1;
1330 else
1331 return 0;
1332 case LTTNG_UST_LOGLEVEL_SINGLE:
1333 if (e->loglevel <= 0 && loglevel == 0)
1334 return 1;
1335 else
1336 return 0;
1337 }
1338 case LTTNG_UST_LOGLEVEL_SINGLE:
1339 switch (loglevel_type) {
1340 case LTTNG_UST_LOGLEVEL_RANGE:
1341 if (loglevel <= 0)
1342 return 1;
1343 else
1344 return 0;
1345 case LTTNG_UST_LOGLEVEL_SINGLE:
1346 if (e->loglevel == loglevel)
1347 return 1;
1348 else
1349 return 0;
1350 }
1351 }
1352 }
1353 #endif
1354
1355 /*
1356 * Add the wildcard to the wildcard list. Must be called with
1357 * ust lock held.
1358 */
1359 static
1360 struct session_wildcard *add_wildcard(struct lttng_channel *chan,
1361 struct lttng_ust_event *event_param)
1362 {
1363 struct wildcard_entry *e;
1364 struct session_wildcard *sw;
1365 size_t name_len = strlen(event_param->name) + 1;
1366 int found = 0;
1367
1368 //FIXME: ensure that wildcard re-use pending events, or
1369 //re-use actual events, applying its filter on top.
1370
1371 /*
1372 * Try to find global wildcard entry. Given that this is shared
1373 * across all sessions, we need to check for exact loglevel
1374 * match, not just whether contained within the existing ones.
1375 */
1376 cds_list_for_each_entry(e, &wildcard_list, list) {
1377 if (!strncmp(event_param->name, e->name,
1378 LTTNG_UST_SYM_NAME_LEN - 1)) {
1379 if (wildcard_same_loglevel(e,
1380 event_param->loglevel_type,
1381 event_param->loglevel)) {
1382 found = 1;
1383 break;
1384 }
1385 }
1386 }
1387
1388 if (!found) {
1389 /*
1390 * Create global wildcard entry if not found. Using
1391 * zmalloc here to allocate a variable length element.
1392 * Could cause some memory fragmentation if overused.
1393 */
1394 e = zmalloc(sizeof(struct wildcard_entry) + name_len);
1395 if (!e)
1396 return ERR_PTR(-ENOMEM);
1397 memcpy(&e->name[0], event_param->name, name_len);
1398 e->loglevel_type = event_param->loglevel_type;
1399 e->loglevel = event_param->loglevel;
1400 CDS_INIT_LIST_HEAD(&e->filter_bytecode);
1401 cds_list_add(&e->list, &wildcard_list);
1402 CDS_INIT_LIST_HEAD(&e->session_list);
1403 }
1404
1405 /* session wildcard */
1406 cds_list_for_each_entry(sw, &e->session_list, session_list) {
1407 if (chan == sw->chan) {
1408 DBG("wildcard %s busy for this channel",
1409 event_param->name);
1410 return ERR_PTR(-EEXIST); /* Already there */
1411 }
1412 }
1413 sw = zmalloc(sizeof(struct session_wildcard));
1414 if (!sw)
1415 return ERR_PTR(-ENOMEM);
1416 sw->chan = chan;
1417 sw->enabled = 1;
1418 memcpy(&sw->event_param, event_param, sizeof(sw->event_param));
1419 sw->event_param.instrumentation = LTTNG_UST_TRACEPOINT;
1420 sw->event_param.loglevel_type = event_param->loglevel_type;
1421 sw->event_param.loglevel = event_param->loglevel;
1422 CDS_INIT_LIST_HEAD(&sw->filter_bytecode);
1423 CDS_INIT_LIST_HEAD(&sw->events);
1424 cds_list_add(&sw->list, &chan->session->wildcards);
1425 cds_list_add(&sw->session_list, &e->session_list);
1426 sw->entry = e;
1427 lttng_probes_create_wildcard_events(e, sw);
1428 return sw;
1429 }
1430
1431 /*
1432 * Remove the wildcard from the wildcard list. Must be called with
1433 * ust_lock held. Only called at session teardown.
1434 */
1435 static
1436 void _remove_wildcard(struct session_wildcard *wildcard)
1437 {
1438 struct lttng_event *ev, *tmp;
1439
1440 /*
1441 * Just remove the events owned (for enable/disable) by this
1442 * wildcard from the list. The session teardown will take care
1443 * of freeing the event memory.
1444 */
1445 cds_list_for_each_entry_safe(ev, tmp, &wildcard->events,
1446 wildcard_list) {
1447 cds_list_del(&ev->wildcard_list);
1448 }
1449 cds_list_del(&wildcard->session_list);
1450 cds_list_del(&wildcard->list);
1451 if (cds_list_empty(&wildcard->entry->session_list)) {
1452 cds_list_del(&wildcard->entry->list);
1453 free(wildcard->entry);
1454 }
1455 lttng_free_wildcard_filter_bytecode(wildcard);
1456 free(wildcard);
1457 }
1458
1459 int lttng_wildcard_create(struct lttng_channel *chan,
1460 struct lttng_ust_event *event_param,
1461 struct session_wildcard **_sw)
1462 {
1463 struct session_wildcard *sw;
1464
1465 sw = add_wildcard(chan, event_param);
1466 if (!sw || IS_ERR(sw)) {
1467 return PTR_ERR(sw);
1468 }
1469 *_sw = sw;
1470 return 0;
1471 }
1472
1473 static
1474 void _lttng_wildcard_destroy(struct session_wildcard *sw)
1475 {
1476 _remove_wildcard(sw);
1477 }
1478
1479 int lttng_wildcard_enable(struct session_wildcard *wildcard)
1480 {
1481 struct lttng_event *ev;
1482 int ret;
1483
1484 if (wildcard->enabled)
1485 return -EEXIST;
1486 cds_list_for_each_entry(ev, &wildcard->events, wildcard_list) {
1487 ret = lttng_event_enable(ev);
1488 if (ret) {
1489 DBG("Error: enable error.\n");
1490 return ret;
1491 }
1492 }
1493 wildcard->enabled = 1;
1494 return 0;
1495 }
1496
1497 int lttng_wildcard_disable(struct session_wildcard *wildcard)
1498 {
1499 struct lttng_event *ev;
1500 int ret;
1501
1502 if (!wildcard->enabled)
1503 return -EEXIST;
1504 cds_list_for_each_entry(ev, &wildcard->events, wildcard_list) {
1505 ret = lttng_event_disable(ev);
1506 if (ret) {
1507 DBG("Error: disable error.\n");
1508 return ret;
1509 }
1510 }
1511 wildcard->enabled = 0;
1512 return 0;
1513 }
1514
1515 /*
1516 * Take the TLS "fault" in libuuid if dlopen'd, which can take the
1517 * dynamic linker mutex, outside of the UST lock, since the UST lock is
1518 * taken in constructors, which are called with dynamic linker mutex
1519 * held.
1520 */
1521 void lttng_fixup_event_tls(void)
1522 {
1523 unsigned char uuid[LTTNG_UST_UUID_STR_LEN];
1524
1525 (void) lttng_ust_uuid_generate(uuid);
1526 }
This page took 0.064384 seconds and 5 git commands to generate.