bytecode: generalize `struct lttng_ust_filter_bytecode_node`
[lttng-ust.git] / liblttng-ust / lttng-events.c
CommitLineData
8020ceb5 1/*
7dd08bec 2 * lttng-events.c
8020ceb5 3 *
8020ceb5
MD
4 * Holds LTTng per-session event registry.
5 *
e92f3e28
MD
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
8020ceb5
MD
21 */
22
3fbec7dc 23#define _LGPL_SOURCE
b5234c06 24#include <stdio.h>
d8d2416d 25#include <assert.h>
b5234c06 26#include <errno.h>
d8d2416d
FD
27#include <limits.h>
28#include <pthread.h>
f4681817
MD
29#include <sys/shm.h>
30#include <sys/ipc.h>
44c72f10
MD
31#include <stdint.h>
32#include <stddef.h>
28b12049
MD
33#include <inttypes.h>
34#include <time.h>
196ec2df 35#include <stdbool.h>
d8d2416d 36#include <unistd.h>
2ae57758 37#include <lttng/ust-endian.h>
44c72f10
MD
38
39#include <urcu-bp.h>
d8d2416d 40#include <urcu/arch.h>
44c72f10 41#include <urcu/compiler.h>
d8d2416d
FD
42#include <urcu/hlist.h>
43#include <urcu/list.h>
44c72f10 44#include <urcu/uatomic.h>
44c72f10
MD
45
46#include <lttng/tracepoint.h>
4318ae1b 47#include <lttng/ust-events.h>
44c72f10
MD
48
49#include <usterr-signal-safe.h>
50#include <helper.h>
7d3e35b6 51#include <lttng/ust-ctl.h>
32ce8569 52#include <ust-comm.h>
d8d2416d 53#include <ust-fd.h>
53569322
MD
54#include <lttng/ust-dynamic-type.h>
55#include <lttng/ust-context-provider.h>
1f18504e 56#include "error.h"
08114193 57#include "compat.h"
eda498b8 58#include "lttng-ust-uuid.h"
44c72f10 59
457a6b58 60#include "tracepoint-internal.h"
196ec2df 61#include "string-utils.h"
7dd08bec
MD
62#include "lttng-tracer.h"
63#include "lttng-tracer-core.h"
cf73e0fe 64#include "lttng-ust-statedump.h"
d871c65b 65#include "ust-events-internal.h"
b728d87e 66#include "wait.h"
8d8a24c8 67#include "../libringbuffer/shm.h"
596c4223 68#include "jhash.h"
d8d2416d 69#include <lttng/ust-abi.h>
8165c8da
MD
70
71/*
3327ac33
MD
72 * All operations within this file are called by the communication
73 * thread, under ust_lock protection.
8165c8da 74 */
8165c8da 75
b5234c06 76static CDS_LIST_HEAD(sessions);
d8d2416d 77static CDS_LIST_HEAD(event_notifier_groups);
8165c8da 78
37dddb65
MD
79struct cds_list_head *_lttng_get_sessions(void)
80{
81 return &sessions;
82}
83
7dd08bec 84static void _lttng_event_destroy(struct lttng_event *event);
d8d2416d
FD
85static void _lttng_event_notifier_destroy(
86 struct lttng_event_notifier *event_notifier);
c785c634 87static void _lttng_enum_destroy(struct lttng_enum *_enum);
8020ceb5 88
e58095ef 89static
d871c65b 90void lttng_session_lazy_sync_event_enablers(struct lttng_session *session);
e58095ef 91static
d871c65b 92void lttng_session_sync_event_enablers(struct lttng_session *session);
e58095ef 93static
d8d2416d
FD
94void lttng_event_notifier_group_sync_enablers(
95 struct lttng_event_notifier_group *event_notifier_group);
96static
e58095ef
MD
97void lttng_enabler_destroy(struct lttng_enabler *enabler);
98
6715d7d1
MD
99/*
100 * Called with ust lock held.
101 */
102int lttng_session_active(void)
103{
104 struct lttng_session *iter;
105
106 cds_list_for_each_entry(iter, &sessions, node) {
107 if (iter->active)
108 return 1;
109 }
110 return 0;
111}
112
e58095ef
MD
113static
114int lttng_loglevel_match(int loglevel,
115 unsigned int has_loglevel,
457a6b58
MD
116 enum lttng_ust_loglevel_type req_type,
117 int req_loglevel)
118{
e58095ef
MD
119 if (!has_loglevel)
120 loglevel = TRACE_DEFAULT;
457a6b58
MD
121 switch (req_type) {
122 case LTTNG_UST_LOGLEVEL_RANGE:
aacb3774 123 if (loglevel <= req_loglevel
67ada458 124 || (req_loglevel == -1 && loglevel <= TRACE_DEBUG))
457a6b58
MD
125 return 1;
126 else
127 return 0;
128 case LTTNG_UST_LOGLEVEL_SINGLE:
aacb3774 129 if (loglevel == req_loglevel
67ada458 130 || (req_loglevel == -1 && loglevel <= TRACE_DEBUG))
457a6b58
MD
131 return 1;
132 else
133 return 0;
134 case LTTNG_UST_LOGLEVEL_ALL:
135 default:
67ada458 136 if (loglevel <= TRACE_DEBUG)
aacb3774
MD
137 return 1;
138 else
139 return 0;
457a6b58
MD
140 }
141}
142
8020ceb5
MD
143void synchronize_trace(void)
144{
8020ceb5 145 synchronize_rcu();
8020ceb5
MD
146}
147
7dd08bec 148struct lttng_session *lttng_session_create(void)
8020ceb5 149{
7dd08bec 150 struct lttng_session *session;
74d81a6c 151 int i;
8020ceb5 152
7dd08bec 153 session = zmalloc(sizeof(struct lttng_session));
8020ceb5
MD
154 if (!session)
155 return NULL;
53569322
MD
156 if (lttng_session_context_init(&session->ctx)) {
157 free(session);
158 return NULL;
159 }
e58095ef
MD
160 CDS_INIT_LIST_HEAD(&session->chan_head);
161 CDS_INIT_LIST_HEAD(&session->events_head);
c785c634 162 CDS_INIT_LIST_HEAD(&session->enums_head);
e58095ef 163 CDS_INIT_LIST_HEAD(&session->enablers_head);
d56fa719
MD
164 for (i = 0; i < LTTNG_UST_EVENT_HT_SIZE; i++)
165 CDS_INIT_HLIST_HEAD(&session->events_ht.table[i]);
c785c634
MD
166 for (i = 0; i < LTTNG_UST_ENUM_HT_SIZE; i++)
167 CDS_INIT_HLIST_HEAD(&session->enums_ht.table[i]);
e58095ef 168 cds_list_add(&session->node, &sessions);
8020ceb5
MD
169 return session;
170}
171
d8d2416d
FD
172struct lttng_event_notifier_group *lttng_event_notifier_group_create(void)
173{
174 struct lttng_event_notifier_group *event_notifier_group;
175 int i;
176
177 event_notifier_group = zmalloc(sizeof(struct lttng_event_notifier_group));
178 if (!event_notifier_group)
179 return NULL;
180
181 CDS_INIT_LIST_HEAD(&event_notifier_group->enablers_head);
182 CDS_INIT_LIST_HEAD(&event_notifier_group->event_notifiers_head);
183 for (i = 0; i < LTTNG_UST_EVENT_NOTIFIER_HT_SIZE; i++)
184 CDS_INIT_HLIST_HEAD(&event_notifier_group->event_notifiers_ht.table[i]);
185
186 cds_list_add(&event_notifier_group->node, &event_notifier_groups);
187
188 return event_notifier_group;
189}
190
74d81a6c
MD
191/*
192 * Only used internally at session destruction.
193 */
194static
195void _lttng_channel_unmap(struct lttng_channel *lttng_chan)
196{
197 struct channel *chan;
198 struct lttng_ust_shm_handle *handle;
199
200 cds_list_del(&lttng_chan->node);
201 lttng_destroy_context(lttng_chan->ctx);
202 chan = lttng_chan->chan;
203 handle = lttng_chan->handle;
204 /*
205 * note: lttng_chan is private data contained within handle. It
206 * will be freed along with the handle.
207 */
208 channel_destroy(chan, handle, 0);
209}
210
ac6b4ac6
MD
211static
212void register_event(struct lttng_event *event)
213{
214 int ret;
215 const struct lttng_event_desc *desc;
216
217 assert(event->registered == 0);
218 desc = event->desc;
baa1e0bc 219 ret = __tracepoint_probe_register_queue_release(desc->name,
ac6b4ac6
MD
220 desc->probe_callback,
221 event, desc->signature);
222 WARN_ON_ONCE(ret);
223 if (!ret)
224 event->registered = 1;
225}
226
d8d2416d
FD
227static
228void register_event_notifier(struct lttng_event_notifier *event_notifier)
229{
230 int ret;
231 const struct lttng_event_desc *desc;
232
233 assert(event_notifier->registered == 0);
234 desc = event_notifier->desc;
235 ret = __tracepoint_probe_register_queue_release(desc->name,
236 desc->u.ext.event_notifier_callback, event_notifier, desc->signature);
237 WARN_ON_ONCE(ret);
238 if (!ret)
239 event_notifier->registered = 1;
240}
241
ac6b4ac6
MD
242static
243void unregister_event(struct lttng_event *event)
244{
245 int ret;
246 const struct lttng_event_desc *desc;
247
248 assert(event->registered == 1);
249 desc = event->desc;
baa1e0bc 250 ret = __tracepoint_probe_unregister_queue_release(desc->name,
ac6b4ac6
MD
251 desc->probe_callback,
252 event);
253 WARN_ON_ONCE(ret);
254 if (!ret)
255 event->registered = 0;
256}
257
d8d2416d
FD
258static
259void unregister_event_notifier(struct lttng_event_notifier *event_notifier)
260{
261 int ret;
262 const struct lttng_event_desc *desc;
263
264 assert(event_notifier->registered == 1);
265 desc = event_notifier->desc;
266 ret = __tracepoint_probe_unregister_queue_release(desc->name,
267 desc->u.ext.event_notifier_callback, event_notifier);
268 WARN_ON_ONCE(ret);
269 if (!ret)
270 event_notifier->registered = 0;
271}
272
ac6b4ac6
MD
273/*
274 * Only used internally at session destruction.
275 */
276static
277void _lttng_event_unregister(struct lttng_event *event)
278{
279 if (event->registered)
280 unregister_event(event);
281}
282
d8d2416d
FD
283/*
284 * Only used internally at session destruction.
285 */
286static
287void _lttng_event_notifier_unregister(struct lttng_event_notifier *event_notifier)
288{
289 if (event_notifier->registered)
290 unregister_event_notifier(event_notifier);
291}
292
7dd08bec 293void lttng_session_destroy(struct lttng_session *session)
8020ceb5 294{
7dd08bec
MD
295 struct lttng_channel *chan, *tmpchan;
296 struct lttng_event *event, *tmpevent;
c785c634 297 struct lttng_enum *_enum, *tmp_enum;
d871c65b 298 struct lttng_event_enabler *event_enabler, *event_tmpenabler;
8020ceb5 299
b5234c06 300 CMM_ACCESS_ONCE(session->active) = 0;
e58095ef 301 cds_list_for_each_entry(event, &session->events_head, node) {
ac6b4ac6 302 _lttng_event_unregister(event);
8020ceb5
MD
303 }
304 synchronize_trace(); /* Wait for in-flight events to complete */
baa1e0bc 305 __tracepoint_probe_prune_release_queue();
d871c65b 306 cds_list_for_each_entry_safe(event_enabler, event_tmpenabler,
e58095ef 307 &session->enablers_head, node)
d871c65b 308 lttng_event_enabler_destroy(event_enabler);
e58095ef
MD
309 cds_list_for_each_entry_safe(event, tmpevent,
310 &session->events_head, node)
7dd08bec 311 _lttng_event_destroy(event);
c785c634
MD
312 cds_list_for_each_entry_safe(_enum, tmp_enum,
313 &session->enums_head, node)
314 _lttng_enum_destroy(_enum);
e58095ef 315 cds_list_for_each_entry_safe(chan, tmpchan, &session->chan_head, node)
74d81a6c 316 _lttng_channel_unmap(chan);
e58095ef 317 cds_list_del(&session->node);
53569322 318 lttng_destroy_context(session->ctx);
b5234c06 319 free(session);
8020ceb5
MD
320}
321
d8d2416d
FD
322void lttng_event_notifier_group_destroy(
323 struct lttng_event_notifier_group *event_notifier_group)
324{
325 int close_ret;
326 struct lttng_event_notifier_enabler *notifier_enabler, *tmpnotifier_enabler;
327 struct lttng_event_notifier *notifier, *tmpnotifier;
328
329 if (!event_notifier_group) {
330 return;
331 }
332
333 cds_list_for_each_entry(notifier,
334 &event_notifier_group->event_notifiers_head, node)
335 _lttng_event_notifier_unregister(notifier);
336
337 synchronize_trace();
338
339 cds_list_for_each_entry_safe(notifier_enabler, tmpnotifier_enabler,
340 &event_notifier_group->enablers_head, node)
341 lttng_event_notifier_enabler_destroy(notifier_enabler);
342
343 cds_list_for_each_entry_safe(notifier, tmpnotifier,
344 &event_notifier_group->event_notifiers_head, node)
345 _lttng_event_notifier_destroy(notifier);
346
347 /* Close the notification fd to the listener of event notifiers. */
348
349 lttng_ust_lock_fd_tracker();
350 close_ret = close(event_notifier_group->notification_fd);
351 if (!close_ret) {
352 lttng_ust_delete_fd_from_tracker(
353 event_notifier_group->notification_fd);
354 } else {
355 PERROR("close");
356 abort();
357 }
358 lttng_ust_unlock_fd_tracker();
359
360 cds_list_del(&event_notifier_group->node);
361
362 free(event_notifier_group);
363}
364
d871c65b
FD
365static
366void lttng_enabler_destroy(struct lttng_enabler *enabler)
367{
ab249ecf 368 struct lttng_ust_bytecode_node *filter_node, *tmp_filter_node;
d871c65b
FD
369 struct lttng_ust_excluder_node *excluder_node, *tmp_excluder_node;
370
371 if (!enabler) {
372 return;
373 }
374
375 /* Destroy filter bytecode */
376 cds_list_for_each_entry_safe(filter_node, tmp_filter_node,
377 &enabler->filter_bytecode_head, node) {
378 free(filter_node);
379 }
380
381 /* Destroy excluders */
382 cds_list_for_each_entry_safe(excluder_node, tmp_excluder_node,
383 &enabler->excluder_head, node) {
384 free(excluder_node);
385 }
386}
387
d8d2416d
FD
388 void lttng_event_notifier_enabler_destroy(struct lttng_event_notifier_enabler *event_notifier_enabler)
389{
390 if (!event_notifier_enabler) {
391 return;
392 }
393
394 cds_list_del(&event_notifier_enabler->node);
395
396 lttng_enabler_destroy(lttng_event_notifier_enabler_as_enabler(event_notifier_enabler));
397
398 free(event_notifier_enabler);
399}
400
53569322
MD
401static
402int lttng_enum_create(const struct lttng_enum_desc *desc,
403 struct lttng_session *session)
404{
405 const char *enum_name = desc->name;
406 struct lttng_enum *_enum;
407 struct cds_hlist_head *head;
53569322
MD
408 int ret = 0;
409 size_t name_len = strlen(enum_name);
410 uint32_t hash;
411 int notify_socket;
412
b33b46f7 413 /* Check if this enum is already registered for this session. */
53569322
MD
414 hash = jhash(enum_name, name_len, 0);
415 head = &session->enums_ht.table[hash & (LTTNG_UST_ENUM_HT_SIZE - 1)];
b33b46f7
FD
416
417 _enum = lttng_ust_enum_get_from_desc(session, desc);
418 if (_enum) {
419 ret = -EEXIST;
420 goto exist;
53569322
MD
421 }
422
423 notify_socket = lttng_get_notify_socket(session->owner);
424 if (notify_socket < 0) {
425 ret = notify_socket;
426 goto socket_error;
427 }
428
429 _enum = zmalloc(sizeof(*_enum));
430 if (!_enum) {
431 ret = -ENOMEM;
432 goto cache_error;
433 }
434 _enum->session = session;
435 _enum->desc = desc;
436
437 ret = ustcomm_register_enum(notify_socket,
438 session->objd,
439 enum_name,
440 desc->nr_entries,
441 desc->entries,
442 &_enum->id);
443 if (ret < 0) {
444 DBG("Error (%d) registering enumeration to sessiond", ret);
445 goto sessiond_register_error;
446 }
447 cds_list_add(&_enum->node, &session->enums_head);
448 cds_hlist_add_head(&_enum->hlist, head);
449 return 0;
450
451sessiond_register_error:
452 free(_enum);
453cache_error:
454socket_error:
455exist:
456 return ret;
457}
458
459static
460int lttng_create_enum_check(const struct lttng_type *type,
461 struct lttng_session *session)
462{
463 switch (type->atype) {
464 case atype_enum:
465 {
466 const struct lttng_enum_desc *enum_desc;
467 int ret;
468
218deb69
MD
469 enum_desc = type->u.legacy.basic.enumeration.desc;
470 ret = lttng_enum_create(enum_desc, session);
471 if (ret && ret != -EEXIST) {
472 DBG("Unable to create enum error: (%d)", ret);
473 return ret;
474 }
475 break;
476 }
477 case atype_enum_nestable:
478 {
479 const struct lttng_enum_desc *enum_desc;
480 int ret;
481
482 enum_desc = type->u.enum_nestable.desc;
53569322
MD
483 ret = lttng_enum_create(enum_desc, session);
484 if (ret && ret != -EEXIST) {
485 DBG("Unable to create enum error: (%d)", ret);
486 return ret;
487 }
488 break;
489 }
490 case atype_dynamic:
491 {
492 const struct lttng_event_field *tag_field_generic;
493 const struct lttng_enum_desc *enum_desc;
494 int ret;
495
496 tag_field_generic = lttng_ust_dynamic_type_tag_field();
218deb69 497 enum_desc = tag_field_generic->type.u.enum_nestable.desc;
53569322
MD
498 ret = lttng_enum_create(enum_desc, session);
499 if (ret && ret != -EEXIST) {
500 DBG("Unable to create enum error: (%d)", ret);
501 return ret;
502 }
503 break;
504 }
505 default:
506 /* TODO: nested types when they become supported. */
507 break;
508 }
509 return 0;
510}
511
512static
513int lttng_create_all_event_enums(size_t nr_fields,
514 const struct lttng_event_field *event_fields,
515 struct lttng_session *session)
516{
517 size_t i;
518 int ret;
519
520 /* For each field, ensure enum is part of the session. */
521 for (i = 0; i < nr_fields; i++) {
522 const struct lttng_type *type = &event_fields[i].type;
523
524 ret = lttng_create_enum_check(type, session);
525 if (ret)
526 return ret;
527 }
528 return 0;
529}
530
531static
532int lttng_create_all_ctx_enums(size_t nr_fields,
533 const struct lttng_ctx_field *ctx_fields,
534 struct lttng_session *session)
535{
536 size_t i;
537 int ret;
538
539 /* For each field, ensure enum is part of the session. */
540 for (i = 0; i < nr_fields; i++) {
541 const struct lttng_type *type = &ctx_fields[i].event_field.type;
542
543 ret = lttng_create_enum_check(type, session);
544 if (ret)
545 return ret;
546 }
547 return 0;
548}
549
710b8ee3
MD
550/*
551 * Ensure that a state-dump will be performed for this session at the end
552 * of the current handle_message().
553 */
554int lttng_session_statedump(struct lttng_session *session)
555{
556 session->statedump_pending = 1;
557 lttng_ust_sockinfo_session_enabled(session->owner);
558 return 0;
559}
53569322 560
7dd08bec 561int lttng_session_enable(struct lttng_session *session)
8020ceb5
MD
562{
563 int ret = 0;
7dd08bec 564 struct lttng_channel *chan;
32ce8569 565 int notify_socket;
8020ceb5 566
8020ceb5
MD
567 if (session->active) {
568 ret = -EBUSY;
569 goto end;
570 }
571
32ce8569
MD
572 notify_socket = lttng_get_notify_socket(session->owner);
573 if (notify_socket < 0)
574 return notify_socket;
575
ac6b4ac6
MD
576 /* Set transient enabler state to "enabled" */
577 session->tstate = 1;
e58095ef 578
3ff7660f 579 /* We need to sync enablers with session before activation. */
d871c65b 580 lttng_session_sync_event_enablers(session);
3ff7660f 581
8020ceb5
MD
582 /*
583 * Snapshot the number of events per channel to know the type of header
584 * we need to use.
585 */
e58095ef 586 cds_list_for_each_entry(chan, &session->chan_head, node) {
32ce8569 587 const struct lttng_ctx *ctx;
83e43212 588 const struct lttng_ctx_field *fields = NULL;
32ce8569 589 size_t nr_fields = 0;
6ca18e66 590 uint32_t chan_id;
32ce8569
MD
591
592 /* don't change it if session stop/restart */
8020ceb5 593 if (chan->header_type)
32ce8569
MD
594 continue;
595 ctx = chan->ctx;
596 if (ctx) {
597 nr_fields = ctx->nr_fields;
83e43212 598 fields = ctx->fields;
53569322
MD
599 ret = lttng_create_all_ctx_enums(nr_fields, fields,
600 session);
601 if (ret < 0) {
602 DBG("Error (%d) adding enum to session", ret);
603 return ret;
604 }
32ce8569
MD
605 }
606 ret = ustcomm_register_channel(notify_socket,
53569322 607 session,
32ce8569
MD
608 session->objd,
609 chan->objd,
610 nr_fields,
611 fields,
6ca18e66 612 &chan_id,
32ce8569 613 &chan->header_type);
b869b5ae
MD
614 if (ret) {
615 DBG("Error (%d) registering channel to sessiond", ret);
32ce8569 616 return ret;
b869b5ae 617 }
6ca18e66
MD
618 if (chan_id != chan->id) {
619 DBG("Error: channel registration id (%u) does not match id assigned at creation (%u)",
620 chan_id, chan->id);
621 return -EINVAL;
622 }
8020ceb5
MD
623 }
624
ac6b4ac6 625 /* Set atomically the state to "active" */
b5234c06
MD
626 CMM_ACCESS_ONCE(session->active) = 1;
627 CMM_ACCESS_ONCE(session->been_active) = 1;
95c25348 628
710b8ee3
MD
629 ret = lttng_session_statedump(session);
630 if (ret)
631 return ret;
8020ceb5 632end:
8020ceb5
MD
633 return ret;
634}
635
7dd08bec 636int lttng_session_disable(struct lttng_session *session)
8020ceb5
MD
637{
638 int ret = 0;
639
8020ceb5
MD
640 if (!session->active) {
641 ret = -EBUSY;
642 goto end;
643 }
ac6b4ac6 644 /* Set atomically the state to "inactive" */
b5234c06 645 CMM_ACCESS_ONCE(session->active) = 0;
ac6b4ac6
MD
646
647 /* Set transient enabler state to "disabled" */
648 session->tstate = 0;
d871c65b 649 lttng_session_sync_event_enablers(session);
8020ceb5 650end:
8020ceb5
MD
651 return ret;
652}
653
7dd08bec 654int lttng_channel_enable(struct lttng_channel *channel)
976fe9ea 655{
ac6b4ac6 656 int ret = 0;
976fe9ea 657
ac6b4ac6
MD
658 if (channel->enabled) {
659 ret = -EBUSY;
660 goto end;
661 }
662 /* Set transient enabler state to "enabled" */
663 channel->tstate = 1;
d871c65b 664 lttng_session_sync_event_enablers(channel->session);
ac6b4ac6
MD
665 /* Set atomically the state to "enabled" */
666 CMM_ACCESS_ONCE(channel->enabled) = 1;
667end:
668 return ret;
976fe9ea
MD
669}
670
7dd08bec 671int lttng_channel_disable(struct lttng_channel *channel)
976fe9ea 672{
ac6b4ac6 673 int ret = 0;
976fe9ea 674
ac6b4ac6
MD
675 if (!channel->enabled) {
676 ret = -EBUSY;
677 goto end;
678 }
679 /* Set atomically the state to "disabled" */
680 CMM_ACCESS_ONCE(channel->enabled) = 0;
681 /* Set transient enabler state to "enabled" */
682 channel->tstate = 0;
d871c65b 683 lttng_session_sync_event_enablers(channel->session);
ac6b4ac6
MD
684end:
685 return ret;
976fe9ea
MD
686}
687
fb470188
FD
688static inline
689struct cds_hlist_head *borrow_hash_table_bucket(
690 struct cds_hlist_head *hash_table,
691 unsigned int hash_table_size,
692 const struct lttng_event_desc *desc)
693{
694 const char *event_name;
695 size_t name_len;
696 uint32_t hash;
697
698 event_name = desc->name;
699 name_len = strlen(event_name);
700
701 hash = jhash(event_name, name_len, 0);
702 return &hash_table[hash & (hash_table_size - 1)];
703}
704
8020ceb5
MD
705/*
706 * Supports event creation while tracing session is active.
707 */
e58095ef
MD
708static
709int lttng_event_create(const struct lttng_event_desc *desc,
710 struct lttng_channel *chan)
8020ceb5 711{
7dd08bec 712 struct lttng_event *event;
32ce8569 713 struct lttng_session *session = chan->session;
d56fa719 714 struct cds_hlist_head *head;
576599a0 715 int ret = 0;
32ce8569
MD
716 int notify_socket, loglevel;
717 const char *uri;
8020ceb5 718
fb470188
FD
719 head = borrow_hash_table_bucket(chan->session->events_ht.table,
720 LTTNG_UST_EVENT_HT_SIZE, desc);
457a6b58 721
32ce8569
MD
722 notify_socket = lttng_get_notify_socket(session->owner);
723 if (notify_socket < 0) {
724 ret = notify_socket;
725 goto socket_error;
726 }
727
53569322
MD
728 ret = lttng_create_all_event_enums(desc->nr_fields, desc->fields,
729 session);
c785c634
MD
730 if (ret < 0) {
731 DBG("Error (%d) adding enum to session", ret);
732 goto create_enum_error;
733 }
734
457a6b58
MD
735 /*
736 * Check if loglevel match. Refuse to connect event if not.
737 */
7dd08bec 738 event = zmalloc(sizeof(struct lttng_event));
576599a0
MD
739 if (!event) {
740 ret = -ENOMEM;
8020ceb5 741 goto cache_error;
576599a0 742 }
8020ceb5 743 event->chan = chan;
e58095ef 744
ac6b4ac6
MD
745 /* Event will be enabled by enabler sync. */
746 event->enabled = 0;
747 event->registered = 0;
a56fd376 748 CDS_INIT_LIST_HEAD(&event->filter_bytecode_runtime_head);
e58095ef
MD
749 CDS_INIT_LIST_HEAD(&event->enablers_ref_head);
750 event->desc = desc;
32ce8569
MD
751
752 if (desc->loglevel)
753 loglevel = *(*event->desc->loglevel);
754 else
755 loglevel = TRACE_DEFAULT;
756 if (desc->u.ext.model_emf_uri)
757 uri = *(desc->u.ext.model_emf_uri);
758 else
759 uri = NULL;
760
13b21cd6
MD
761 /* Fetch event ID from sessiond */
762 ret = ustcomm_register_event(notify_socket,
c785c634 763 session,
13b21cd6
MD
764 session->objd,
765 chan->objd,
fb470188 766 desc->name,
13b21cd6
MD
767 loglevel,
768 desc->signature,
769 desc->nr_fields,
770 desc->fields,
771 uri,
772 &event->id);
773 if (ret < 0) {
774 DBG("Error (%d) registering event to sessiond", ret);
775 goto sessiond_register_error;
32ce8569 776 }
2b213b16 777
e58095ef 778 cds_list_add(&event->node, &chan->session->events_head);
d56fa719 779 cds_hlist_add_head(&event->hlist, head);
576599a0 780 return 0;
8020ceb5 781
32ce8569 782sessiond_register_error:
b5234c06 783 free(event);
8020ceb5 784cache_error:
c785c634 785create_enum_error:
32ce8569 786socket_error:
576599a0 787 return ret;
8020ceb5
MD
788}
789
d8d2416d
FD
790static
791int lttng_event_notifier_create(const struct lttng_event_desc *desc,
792 uint64_t token,
793 struct lttng_event_notifier_group *event_notifier_group)
794{
795 struct lttng_event_notifier *event_notifier;
796 struct cds_hlist_head *head;
797 int ret = 0;
798
799 /*
800 * Get the hashtable bucket the created lttng_event_notifier object
801 * should be inserted.
802 */
803 head = borrow_hash_table_bucket(
804 event_notifier_group->event_notifiers_ht.table,
805 LTTNG_UST_EVENT_NOTIFIER_HT_SIZE, desc);
806
807 event_notifier = zmalloc(sizeof(struct lttng_event_notifier));
808 if (!event_notifier) {
809 ret = -ENOMEM;
810 goto error;
811 }
812
813 event_notifier->group = event_notifier_group;
814 event_notifier->user_token = token;
815
816 /* Event notifier will be enabled by enabler sync. */
817 event_notifier->enabled = 0;
818 event_notifier->registered = 0;
819
820 CDS_INIT_LIST_HEAD(&event_notifier->filter_bytecode_runtime_head);
821 CDS_INIT_LIST_HEAD(&event_notifier->enablers_ref_head);
822 event_notifier->desc = desc;
823
824 cds_list_add(&event_notifier->node,
825 &event_notifier_group->event_notifiers_head);
826 cds_hlist_add_head(&event_notifier->hlist, head);
827
828 return 0;
829
830error:
831 return ret;
832}
833
834static
835void _lttng_event_notifier_destroy(struct lttng_event_notifier *event_notifier)
836{
837 struct lttng_enabler_ref *enabler_ref, *tmp_enabler_ref;
838
839 /* Remove from event_notifier list. */
840 cds_list_del(&event_notifier->node);
841 /* Remove from event_notifier hash table. */
842 cds_hlist_del(&event_notifier->hlist);
843
844 lttng_free_event_notifier_filter_runtime(event_notifier);
845
846 /* Free event_notifier enabler refs */
847 cds_list_for_each_entry_safe(enabler_ref, tmp_enabler_ref,
848 &event_notifier->enablers_ref_head, node)
849 free(enabler_ref);
850 free(event_notifier);
851}
852
e58095ef 853static
196ec2df 854int lttng_desc_match_star_glob_enabler(const struct lttng_event_desc *desc,
e58095ef
MD
855 struct lttng_enabler *enabler)
856{
857 int loglevel = 0;
7e2e405c 858 unsigned int has_loglevel = 0;
e58095ef 859
e450e339 860 assert(enabler->format_type == LTTNG_ENABLER_FORMAT_STAR_GLOB);
1f6f42e6
MD
861 if (!strutils_star_glob_match(enabler->event_param.name, SIZE_MAX,
862 desc->name, SIZE_MAX))
e58095ef
MD
863 return 0;
864 if (desc->loglevel) {
865 loglevel = *(*desc->loglevel);
866 has_loglevel = 1;
867 }
868 if (!lttng_loglevel_match(loglevel,
869 has_loglevel,
870 enabler->event_param.loglevel_type,
871 enabler->event_param.loglevel))
872 return 0;
873 return 1;
874}
875
876static
877int lttng_desc_match_event_enabler(const struct lttng_event_desc *desc,
878 struct lttng_enabler *enabler)
879{
880 int loglevel = 0;
881 unsigned int has_loglevel = 0;
882
e450e339 883 assert(enabler->format_type == LTTNG_ENABLER_FORMAT_EVENT);
e58095ef
MD
884 if (strcmp(desc->name, enabler->event_param.name))
885 return 0;
886 if (desc->loglevel) {
887 loglevel = *(*desc->loglevel);
888 has_loglevel = 1;
889 }
890 if (!lttng_loglevel_match(loglevel,
891 has_loglevel,
892 enabler->event_param.loglevel_type,
893 enabler->event_param.loglevel))
894 return 0;
895 return 1;
896}
897
898static
899int lttng_desc_match_enabler(const struct lttng_event_desc *desc,
900 struct lttng_enabler *enabler)
901{
e450e339
FD
902 switch (enabler->format_type) {
903 case LTTNG_ENABLER_FORMAT_STAR_GLOB:
196ec2df
PP
904 {
905 struct lttng_ust_excluder_node *excluder;
906
907 if (!lttng_desc_match_star_glob_enabler(desc, enabler)) {
908 return 0;
909 }
910
911 /*
912 * If the matching event matches with an excluder,
913 * return 'does not match'
914 */
915 cds_list_for_each_entry(excluder, &enabler->excluder_head, node) {
916 int count;
917
918 for (count = 0; count < excluder->excluder.count; count++) {
919 int len;
920 char *excluder_name;
921
922 excluder_name = (char *) (excluder->excluder.names)
923 + count * LTTNG_UST_SYM_NAME_LEN;
924 len = strnlen(excluder_name, LTTNG_UST_SYM_NAME_LEN);
1f6f42e6 925 if (len > 0 && strutils_star_glob_match(excluder_name, len, desc->name, SIZE_MAX))
196ec2df 926 return 0;
ed5b5bbd
JI
927 }
928 }
196ec2df 929 return 1;
ed5b5bbd 930 }
e450e339 931 case LTTNG_ENABLER_FORMAT_EVENT:
e58095ef
MD
932 return lttng_desc_match_event_enabler(desc, enabler);
933 default:
934 return -EINVAL;
935 }
936}
937
938static
d871c65b
FD
939int lttng_event_enabler_match_event(struct lttng_event_enabler *event_enabler,
940 struct lttng_event *event)
e58095ef 941{
d871c65b
FD
942 if (lttng_desc_match_enabler(event->desc,
943 lttng_event_enabler_as_enabler(event_enabler))
944 && event->chan == event_enabler->chan)
d970f72e
MD
945 return 1;
946 else
947 return 0;
e58095ef
MD
948}
949
d8d2416d
FD
950static
951int lttng_event_notifier_enabler_match_event_notifier(
952 struct lttng_event_notifier_enabler *event_notifier_enabler,
953 struct lttng_event_notifier *event_notifier)
954{
955 int desc_matches = lttng_desc_match_enabler(event_notifier->desc,
956 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler));
957
958 if (desc_matches && event_notifier->group == event_notifier_enabler->group &&
959 event_notifier->user_token == event_notifier_enabler->user_token)
960 return 1;
961 else
962 return 0;
963}
964
e58095ef 965static
d871c65b
FD
966struct lttng_enabler_ref *lttng_enabler_ref(
967 struct cds_list_head *enabler_ref_list,
e58095ef
MD
968 struct lttng_enabler *enabler)
969{
970 struct lttng_enabler_ref *enabler_ref;
971
d871c65b 972 cds_list_for_each_entry(enabler_ref, enabler_ref_list, node) {
e58095ef
MD
973 if (enabler_ref->ref == enabler)
974 return enabler_ref;
975 }
976 return NULL;
977}
978
8020ceb5 979/*
e58095ef
MD
980 * Create struct lttng_event if it is missing and present in the list of
981 * tracepoint probes.
8020ceb5 982 */
e58095ef 983static
d871c65b 984void lttng_create_event_if_missing(struct lttng_event_enabler *event_enabler)
8020ceb5 985{
d871c65b 986 struct lttng_session *session = event_enabler->chan->session;
e58095ef
MD
987 struct lttng_probe_desc *probe_desc;
988 const struct lttng_event_desc *desc;
989 struct lttng_event *event;
990 int i;
991 struct cds_list_head *probe_list;
992
993 probe_list = lttng_get_probe_list_head();
994 /*
995 * For each probe event, if we find that a probe event matches
996 * our enabler, create an associated lttng_event if not
997 * already present.
998 */
999 cds_list_for_each_entry(probe_desc, probe_list, head) {
1000 for (i = 0; i < probe_desc->nr_events; i++) {
98a97f24
FD
1001 int ret;
1002 bool found = false;
d56fa719
MD
1003 struct cds_hlist_head *head;
1004 struct cds_hlist_node *node;
e58095ef
MD
1005
1006 desc = probe_desc->event_desc[i];
d871c65b
FD
1007 if (!lttng_desc_match_enabler(desc,
1008 lttng_event_enabler_as_enabler(event_enabler)))
e58095ef
MD
1009 continue;
1010
fb470188
FD
1011 head = borrow_hash_table_bucket(
1012 session->events_ht.table,
1013 LTTNG_UST_EVENT_HT_SIZE, desc);
1014
d56fa719 1015 cds_hlist_for_each_entry(event, node, head, hlist) {
d970f72e 1016 if (event->desc == desc
d871c65b 1017 && event->chan == event_enabler->chan) {
98a97f24 1018 found = true;
3140bffe
FD
1019 break;
1020 }
e58095ef
MD
1021 }
1022 if (found)
1023 continue;
1024
1025 /*
1026 * We need to create an event for this
1027 * event probe.
1028 */
1029 ret = lttng_event_create(probe_desc->event_desc[i],
d871c65b 1030 event_enabler->chan);
e58095ef 1031 if (ret) {
32ce8569
MD
1032 DBG("Unable to create event %s, error %d\n",
1033 probe_desc->event_desc[i]->name, ret);
e58095ef 1034 }
8165c8da 1035 }
8020ceb5 1036 }
8020ceb5
MD
1037}
1038
a44d07da
FD
1039static
1040void probe_provider_event_for_each(struct lttng_probe_desc *provider_desc,
d8d2416d
FD
1041 void (*event_func)(struct lttng_session *session,
1042 struct lttng_event *event),
1043 void (*event_notifier_func)(struct lttng_event_notifier *event_notifier))
35ac38cb
FD
1044{
1045 struct cds_hlist_node *node, *tmp_node;
1046 struct cds_list_head *sessionsp;
a44d07da 1047 unsigned int i;
35ac38cb
FD
1048
1049 /* Get handle on list of sessions. */
1050 sessionsp = _lttng_get_sessions();
1051
1052 /*
a44d07da
FD
1053 * Iterate over all events in the probe provider descriptions and
1054 * sessions to queue the unregistration of the events.
35ac38cb
FD
1055 */
1056 for (i = 0; i < provider_desc->nr_events; i++) {
1057 const struct lttng_event_desc *event_desc;
d8d2416d
FD
1058 struct lttng_event_notifier_group *event_notifier_group;
1059 struct lttng_event_notifier *event_notifier;
a44d07da
FD
1060 struct lttng_session *session;
1061 struct cds_hlist_head *head;
1062 struct lttng_event *event;
35ac38cb
FD
1063
1064 event_desc = provider_desc->event_desc[i];
35ac38cb 1065
a44d07da
FD
1066 /*
1067 * Iterate over all session to find the current event
1068 * description.
1069 */
35ac38cb
FD
1070 cds_list_for_each_entry(session, sessionsp, node) {
1071 /*
a44d07da
FD
1072 * Get the list of events in the hashtable bucket and
1073 * iterate to find the event matching this descriptor.
35ac38cb 1074 */
fb470188
FD
1075 head = borrow_hash_table_bucket(
1076 session->events_ht.table,
1077 LTTNG_UST_EVENT_HT_SIZE, event_desc);
1078
a44d07da 1079 cds_hlist_for_each_entry_safe(event, node, tmp_node, head, hlist) {
35ac38cb 1080 if (event_desc == event->desc) {
a44d07da 1081 event_func(session, event);
35ac38cb
FD
1082 break;
1083 }
1084 }
1085 }
d8d2416d
FD
1086
1087 /*
1088 * Iterate over all event_notifier groups to find the current event
1089 * description.
1090 */
1091 cds_list_for_each_entry(event_notifier_group, &event_notifier_groups, node) {
1092 /*
1093 * Get the list of event_notifiers in the hashtable bucket and
1094 * iterate to find the event_notifier matching this
1095 * descriptor.
1096 */
1097 head = borrow_hash_table_bucket(
1098 event_notifier_group->event_notifiers_ht.table,
1099 LTTNG_UST_EVENT_NOTIFIER_HT_SIZE, event_desc);
1100
1101 cds_hlist_for_each_entry_safe(event_notifier, node, tmp_node, head, hlist) {
1102 if (event_desc == event_notifier->desc) {
1103 event_notifier_func(event_notifier);
1104 break;
1105 }
1106 }
1107 }
35ac38cb 1108 }
a44d07da
FD
1109}
1110
1111static
1112void _unregister_event(struct lttng_session *session,
1113 struct lttng_event *event)
1114{
1115 _lttng_event_unregister(event);
1116}
1117
1118static
1119void _event_enum_destroy(struct lttng_session *session,
1120 struct lttng_event *event)
1121{
1122 unsigned int i;
1123
1124 /* Destroy enums of the current event. */
1125 for (i = 0; i < event->desc->nr_fields; i++) {
1126 const struct lttng_enum_desc *enum_desc;
1127 const struct lttng_event_field *field;
1128 struct lttng_enum *curr_enum;
1129
1130 field = &(event->desc->fields[i]);
1131 switch (field->type.atype) {
1132 case atype_enum:
1133 enum_desc = field->type.u.legacy.basic.enumeration.desc;
1134 break;
1135 case atype_enum_nestable:
1136 enum_desc = field->type.u.enum_nestable.desc;
1137 break;
1138 default:
1139 continue;
1140 }
1141
1142 curr_enum = lttng_ust_enum_get_from_desc(session, enum_desc);
1143 if (curr_enum) {
1144 _lttng_enum_destroy(curr_enum);
1145 }
1146 }
1147
1148 /* Destroy event. */
1149 _lttng_event_destroy(event);
1150}
1151
1152/*
1153 * Iterate over all the UST sessions to unregister and destroy all probes from
1154 * the probe provider descriptor received as argument. Must me called with the
1155 * ust_lock held.
1156 */
1157void lttng_probe_provider_unregister_events(
1158 struct lttng_probe_desc *provider_desc)
1159{
1160 /*
1161 * Iterate over all events in the probe provider descriptions and sessions
1162 * to queue the unregistration of the events.
1163 */
d8d2416d
FD
1164 probe_provider_event_for_each(provider_desc, _unregister_event,
1165 _lttng_event_notifier_unregister);
35ac38cb
FD
1166
1167 /* Wait for grace period. */
1168 synchronize_trace();
1169 /* Prune the unregistration queue. */
1170 __tracepoint_probe_prune_release_queue();
1171
1172 /*
1173 * It is now safe to destroy the events and remove them from the event list
1174 * and hashtables.
1175 */
d8d2416d
FD
1176 probe_provider_event_for_each(provider_desc, _event_enum_destroy,
1177 _lttng_event_notifier_destroy);
35ac38cb
FD
1178}
1179
8020ceb5 1180/*
d8d2416d 1181 * Create events associated with an event enabler (if not already present),
e58095ef 1182 * and add backward reference from the event to the enabler.
8020ceb5
MD
1183 */
1184static
d871c65b 1185int lttng_event_enabler_ref_events(struct lttng_event_enabler *event_enabler)
8020ceb5 1186{
d871c65b 1187 struct lttng_session *session = event_enabler->chan->session;
e58095ef
MD
1188 struct lttng_event *event;
1189
d871c65b 1190 if (!lttng_event_enabler_as_enabler(event_enabler)->enabled)
de713d8a
FD
1191 goto end;
1192
e58095ef 1193 /* First ensure that probe events are created for this enabler. */
d871c65b 1194 lttng_create_event_if_missing(event_enabler);
e58095ef
MD
1195
1196 /* For each event matching enabler in session event list. */
1197 cds_list_for_each_entry(event, &session->events_head, node) {
1198 struct lttng_enabler_ref *enabler_ref;
1199
d871c65b 1200 if (!lttng_event_enabler_match_event(event_enabler, event))
e58095ef
MD
1201 continue;
1202
d871c65b
FD
1203 enabler_ref = lttng_enabler_ref(&event->enablers_ref_head,
1204 lttng_event_enabler_as_enabler(event_enabler));
e58095ef
MD
1205 if (!enabler_ref) {
1206 /*
1207 * If no backward ref, create it.
1208 * Add backward ref from event to enabler.
1209 */
1210 enabler_ref = zmalloc(sizeof(*enabler_ref));
1211 if (!enabler_ref)
1212 return -ENOMEM;
d871c65b
FD
1213 enabler_ref->ref = lttng_event_enabler_as_enabler(
1214 event_enabler);
e58095ef
MD
1215 cds_list_add(&enabler_ref->node,
1216 &event->enablers_ref_head);
8165c8da 1217 }
e58095ef
MD
1218
1219 /*
1220 * Link filter bytecodes if not linked yet.
1221 */
53b9d7db
FD
1222 lttng_enabler_link_bytecode(event->desc,
1223 &session->ctx,
a56fd376 1224 &event->filter_bytecode_runtime_head,
53b9d7db 1225 lttng_event_enabler_as_enabler(event_enabler));
e58095ef
MD
1226
1227 /* TODO: merge event context. */
1228 }
de713d8a 1229end:
e58095ef
MD
1230 return 0;
1231}
1232
1233/*
1234 * Called at library load: connect the probe on all enablers matching
1235 * this event.
5f733922 1236 * Called with session mutex held.
e58095ef 1237 */
5f733922 1238int lttng_fix_pending_events(void)
e58095ef
MD
1239{
1240 struct lttng_session *session;
1241
1242 cds_list_for_each_entry(session, &sessions, node) {
d871c65b 1243 lttng_session_lazy_sync_event_enablers(session);
8020ceb5 1244 }
e58095ef
MD
1245 return 0;
1246}
1247
d8d2416d
FD
1248int lttng_fix_pending_event_notifiers(void)
1249{
1250 struct lttng_event_notifier_group *event_notifier_group;
1251
1252 cds_list_for_each_entry(event_notifier_group, &event_notifier_groups, node) {
1253 lttng_event_notifier_group_sync_enablers(event_notifier_group);
1254 }
1255 return 0;
1256}
1257
246be17e 1258/*
37dddb65
MD
1259 * For each session of the owner thread, execute pending statedump.
1260 * Only dump state for the sessions owned by the caller thread, because
1261 * we don't keep ust_lock across the entire iteration.
246be17e 1262 */
3327ac33 1263void lttng_handle_pending_statedump(void *owner)
246be17e
PW
1264{
1265 struct lttng_session *session;
1266
37dddb65 1267 /* Execute state dump */
cf73e0fe 1268 do_lttng_ust_statedump(owner);
37dddb65
MD
1269
1270 /* Clear pending state dump */
3327ac33
MD
1271 if (ust_lock()) {
1272 goto end;
1273 }
246be17e 1274 cds_list_for_each_entry(session, &sessions, node) {
37dddb65
MD
1275 if (session->owner != owner)
1276 continue;
1277 if (!session->statedump_pending)
1278 continue;
1279 session->statedump_pending = 0;
246be17e 1280 }
3327ac33 1281end:
37dddb65 1282 ust_unlock();
3327ac33 1283 return;
246be17e
PW
1284}
1285
e58095ef
MD
1286/*
1287 * Only used internally at session destruction.
1288 */
1289static
1290void _lttng_event_destroy(struct lttng_event *event)
1291{
1292 struct lttng_enabler_ref *enabler_ref, *tmp_enabler_ref;
1293
35ac38cb 1294 /* Remove from event list. */
e58095ef 1295 cds_list_del(&event->node);
35ac38cb
FD
1296 /* Remove from event hash table. */
1297 cds_hlist_del(&event->hlist);
1298
8020ceb5 1299 lttng_destroy_context(event->ctx);
f488575f 1300 lttng_free_event_filter_runtime(event);
e58095ef
MD
1301 /* Free event enabler refs */
1302 cds_list_for_each_entry_safe(enabler_ref, tmp_enabler_ref,
1303 &event->enablers_ref_head, node)
1304 free(enabler_ref);
b5234c06 1305 free(event);
8020ceb5
MD
1306}
1307
c785c634
MD
1308static
1309void _lttng_enum_destroy(struct lttng_enum *_enum)
1310{
1311 cds_list_del(&_enum->node);
35ac38cb 1312 cds_hlist_del(&_enum->hlist);
c785c634
MD
1313 free(_enum);
1314}
1315
003fedf4 1316void lttng_ust_events_exit(void)
8020ceb5 1317{
7dd08bec 1318 struct lttng_session *session, *tmpsession;
8020ceb5 1319
e58095ef 1320 cds_list_for_each_entry_safe(session, tmpsession, &sessions, node)
7dd08bec 1321 lttng_session_destroy(session);
8020ceb5 1322}
457a6b58 1323
e58095ef
MD
1324/*
1325 * Enabler management.
1326 */
d871c65b
FD
1327struct lttng_event_enabler *lttng_event_enabler_create(
1328 enum lttng_enabler_format_type format_type,
e58095ef
MD
1329 struct lttng_ust_event *event_param,
1330 struct lttng_channel *chan)
457a6b58 1331{
d871c65b 1332 struct lttng_event_enabler *event_enabler;
e58095ef 1333
d871c65b
FD
1334 event_enabler = zmalloc(sizeof(*event_enabler));
1335 if (!event_enabler)
e58095ef 1336 return NULL;
d871c65b
FD
1337 event_enabler->base.format_type = format_type;
1338 CDS_INIT_LIST_HEAD(&event_enabler->base.filter_bytecode_head);
1339 CDS_INIT_LIST_HEAD(&event_enabler->base.excluder_head);
1340 memcpy(&event_enabler->base.event_param, event_param,
1341 sizeof(event_enabler->base.event_param));
1342 event_enabler->chan = chan;
e58095ef 1343 /* ctx left NULL */
d871c65b
FD
1344 event_enabler->base.enabled = 0;
1345 cds_list_add(&event_enabler->node, &event_enabler->chan->session->enablers_head);
1346 lttng_session_lazy_sync_event_enablers(event_enabler->chan->session);
1347
1348 return event_enabler;
457a6b58
MD
1349}
1350
d8d2416d
FD
1351struct lttng_event_notifier_enabler *lttng_event_notifier_enabler_create(
1352 struct lttng_event_notifier_group *event_notifier_group,
1353 enum lttng_enabler_format_type format_type,
1354 struct lttng_ust_event_notifier *event_notifier_param)
1355{
1356 struct lttng_event_notifier_enabler *event_notifier_enabler;
1357
1358 event_notifier_enabler = zmalloc(sizeof(*event_notifier_enabler));
1359 if (!event_notifier_enabler)
1360 return NULL;
1361 event_notifier_enabler->base.format_type = format_type;
1362 CDS_INIT_LIST_HEAD(&event_notifier_enabler->base.filter_bytecode_head);
1363 CDS_INIT_LIST_HEAD(&event_notifier_enabler->base.excluder_head);
1364
1365 event_notifier_enabler->user_token = event_notifier_param->event.token;
1366
1367 memcpy(&event_notifier_enabler->base.event_param.name,
1368 event_notifier_param->event.name,
1369 sizeof(event_notifier_enabler->base.event_param.name));
1370 event_notifier_enabler->base.event_param.instrumentation =
1371 event_notifier_param->event.instrumentation;
1372 event_notifier_enabler->base.event_param.loglevel =
1373 event_notifier_param->event.loglevel;
1374 event_notifier_enabler->base.event_param.loglevel_type =
1375 event_notifier_param->event.loglevel_type;
1376
1377 event_notifier_enabler->base.enabled = 0;
1378 event_notifier_enabler->group = event_notifier_group;
1379
1380 cds_list_add(&event_notifier_enabler->node,
1381 &event_notifier_group->enablers_head);
1382
1383 lttng_event_notifier_group_sync_enablers(event_notifier_group);
1384
1385 return event_notifier_enabler;
1386}
1387
d871c65b 1388int lttng_event_enabler_enable(struct lttng_event_enabler *event_enabler)
457a6b58 1389{
d871c65b
FD
1390 lttng_event_enabler_as_enabler(event_enabler)->enabled = 1;
1391 lttng_session_lazy_sync_event_enablers(event_enabler->chan->session);
1392
e58095ef 1393 return 0;
457a6b58 1394}
457a6b58 1395
d871c65b 1396int lttng_event_enabler_disable(struct lttng_event_enabler *event_enabler)
457a6b58 1397{
d871c65b
FD
1398 lttng_event_enabler_as_enabler(event_enabler)->enabled = 0;
1399 lttng_session_lazy_sync_event_enablers(event_enabler->chan->session);
1400
e58095ef
MD
1401 return 0;
1402}
457a6b58 1403
d871c65b 1404static
a56fd376 1405void _lttng_enabler_attach_filter_bytecode(struct lttng_enabler *enabler,
ab249ecf 1406 struct lttng_ust_bytecode_node *bytecode)
e58095ef
MD
1407{
1408 bytecode->enabler = enabler;
1409 cds_list_add_tail(&bytecode->node, &enabler->filter_bytecode_head);
d871c65b
FD
1410}
1411
a56fd376 1412int lttng_event_enabler_attach_filter_bytecode(struct lttng_event_enabler *event_enabler,
ab249ecf 1413 struct lttng_ust_bytecode_node *bytecode)
d871c65b 1414{
a56fd376 1415 _lttng_enabler_attach_filter_bytecode(
d871c65b
FD
1416 lttng_event_enabler_as_enabler(event_enabler), bytecode);
1417
1418 lttng_session_lazy_sync_event_enablers(event_enabler->chan->session);
e58095ef 1419 return 0;
0bfb5cbd
JI
1420}
1421
d871c65b
FD
1422static
1423void _lttng_enabler_attach_exclusion(struct lttng_enabler *enabler,
0bfb5cbd
JI
1424 struct lttng_ust_excluder_node *excluder)
1425{
1426 excluder->enabler = enabler;
1427 cds_list_add_tail(&excluder->node, &enabler->excluder_head);
d871c65b
FD
1428}
1429
1430int lttng_event_enabler_attach_exclusion(struct lttng_event_enabler *event_enabler,
1431 struct lttng_ust_excluder_node *excluder)
1432{
1433 _lttng_enabler_attach_exclusion(
1434 lttng_event_enabler_as_enabler(event_enabler), excluder);
1435
1436 lttng_session_lazy_sync_event_enablers(event_enabler->chan->session);
0bfb5cbd 1437 return 0;
e58095ef 1438}
f488575f 1439
d8d2416d
FD
1440int lttng_event_notifier_enabler_enable(
1441 struct lttng_event_notifier_enabler *event_notifier_enabler)
1442{
1443 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler)->enabled = 1;
1444 lttng_event_notifier_group_sync_enablers(event_notifier_enabler->group);
1445
1446 return 0;
1447}
1448
1449int lttng_event_notifier_enabler_disable(
1450 struct lttng_event_notifier_enabler *event_notifier_enabler)
1451{
1452 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler)->enabled = 0;
1453 lttng_event_notifier_group_sync_enablers(event_notifier_enabler->group);
1454
1455 return 0;
1456}
1457
a56fd376 1458int lttng_event_notifier_enabler_attach_filter_bytecode(
d8d2416d 1459 struct lttng_event_notifier_enabler *event_notifier_enabler,
ab249ecf 1460 struct lttng_ust_bytecode_node *bytecode)
d8d2416d 1461{
a56fd376 1462 _lttng_enabler_attach_filter_bytecode(
d8d2416d
FD
1463 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler),
1464 bytecode);
1465
1466 lttng_event_notifier_group_sync_enablers(event_notifier_enabler->group);
1467 return 0;
1468}
1469
1470int lttng_event_notifier_enabler_attach_exclusion(
1471 struct lttng_event_notifier_enabler *event_notifier_enabler,
1472 struct lttng_ust_excluder_node *excluder)
1473{
1474 _lttng_enabler_attach_exclusion(
1475 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler),
1476 excluder);
1477
1478 lttng_event_notifier_group_sync_enablers(event_notifier_enabler->group);
1479 return 0;
1480}
1481
e58095ef 1482int lttng_attach_context(struct lttng_ust_context *context_param,
8e696cfa 1483 union ust_args *uargs,
e58095ef
MD
1484 struct lttng_ctx **ctx, struct lttng_session *session)
1485{
457a6b58 1486 /*
e58095ef
MD
1487 * We cannot attach a context after trace has been started for a
1488 * session because the metadata does not allow expressing this
1489 * information outside of the original channel scope.
457a6b58 1490 */
e58095ef
MD
1491 if (session->been_active)
1492 return -EPERM;
457a6b58 1493
e58095ef
MD
1494 switch (context_param->ctx) {
1495 case LTTNG_UST_CONTEXT_PTHREAD_ID:
1496 return lttng_add_pthread_id_to_ctx(ctx);
d58d1454
MD
1497 case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER:
1498 {
1499 struct lttng_ust_perf_counter_ctx *perf_ctx_param;
1500
1501 perf_ctx_param = &context_param->u.perf_counter;
1502 return lttng_add_perf_counter_to_ctx(
1503 perf_ctx_param->type,
1504 perf_ctx_param->config,
1505 perf_ctx_param->name,
1506 ctx);
1507 }
e58095ef
MD
1508 case LTTNG_UST_CONTEXT_VTID:
1509 return lttng_add_vtid_to_ctx(ctx);
1510 case LTTNG_UST_CONTEXT_VPID:
1511 return lttng_add_vpid_to_ctx(ctx);
1512 case LTTNG_UST_CONTEXT_PROCNAME:
1513 return lttng_add_procname_to_ctx(ctx);
96f85541
MD
1514 case LTTNG_UST_CONTEXT_IP:
1515 return lttng_add_ip_to_ctx(ctx);
c7ea8487
MD
1516 case LTTNG_UST_CONTEXT_CPU_ID:
1517 return lttng_add_cpu_id_to_ctx(ctx);
8e696cfa
MD
1518 case LTTNG_UST_CONTEXT_APP_CONTEXT:
1519 return lttng_ust_add_app_context_to_ctx_rcu(uargs->app_context.ctxname,
1520 ctx);
735bef47
MJ
1521 case LTTNG_UST_CONTEXT_CGROUP_NS:
1522 return lttng_add_cgroup_ns_to_ctx(ctx);
1523 case LTTNG_UST_CONTEXT_IPC_NS:
1524 return lttng_add_ipc_ns_to_ctx(ctx);
1525 case LTTNG_UST_CONTEXT_MNT_NS:
1526 return lttng_add_mnt_ns_to_ctx(ctx);
1527 case LTTNG_UST_CONTEXT_NET_NS:
1528 return lttng_add_net_ns_to_ctx(ctx);
1529 case LTTNG_UST_CONTEXT_PID_NS:
1530 return lttng_add_pid_ns_to_ctx(ctx);
cefef7a7
MJ
1531 case LTTNG_UST_CONTEXT_TIME_NS:
1532 return lttng_add_time_ns_to_ctx(ctx);
735bef47
MJ
1533 case LTTNG_UST_CONTEXT_USER_NS:
1534 return lttng_add_user_ns_to_ctx(ctx);
1535 case LTTNG_UST_CONTEXT_UTS_NS:
1536 return lttng_add_uts_ns_to_ctx(ctx);
fca2f191
MJ
1537 case LTTNG_UST_CONTEXT_VUID:
1538 return lttng_add_vuid_to_ctx(ctx);
1539 case LTTNG_UST_CONTEXT_VEUID:
1540 return lttng_add_veuid_to_ctx(ctx);
1541 case LTTNG_UST_CONTEXT_VSUID:
1542 return lttng_add_vsuid_to_ctx(ctx);
1543 case LTTNG_UST_CONTEXT_VGID:
1544 return lttng_add_vgid_to_ctx(ctx);
1545 case LTTNG_UST_CONTEXT_VEGID:
1546 return lttng_add_vegid_to_ctx(ctx);
1547 case LTTNG_UST_CONTEXT_VSGID:
1548 return lttng_add_vsgid_to_ctx(ctx);
e58095ef
MD
1549 default:
1550 return -EINVAL;
457a6b58 1551 }
457a6b58
MD
1552}
1553
d871c65b 1554int lttng_event_enabler_attach_context(struct lttng_event_enabler *enabler,
e58095ef 1555 struct lttng_ust_context *context_param)
457a6b58 1556{
e58095ef 1557 return -ENOSYS;
457a6b58
MD
1558}
1559
d871c65b 1560void lttng_event_enabler_destroy(struct lttng_event_enabler *event_enabler)
457a6b58 1561{
d871c65b
FD
1562 if (!event_enabler) {
1563 return;
0f63324a 1564 }
d871c65b 1565 cds_list_del(&event_enabler->node);
0f63324a 1566
d871c65b 1567 lttng_enabler_destroy(lttng_event_enabler_as_enabler(event_enabler));
e58095ef 1568
d871c65b
FD
1569 lttng_destroy_context(event_enabler->ctx);
1570 free(event_enabler);
457a6b58
MD
1571}
1572
e58095ef 1573/*
d871c65b 1574 * lttng_session_sync_event_enablers should be called just before starting a
e58095ef
MD
1575 * session.
1576 */
457a6b58 1577static
d871c65b 1578void lttng_session_sync_event_enablers(struct lttng_session *session)
457a6b58 1579{
d871c65b 1580 struct lttng_event_enabler *event_enabler;
e58095ef 1581 struct lttng_event *event;
457a6b58 1582
d871c65b
FD
1583 cds_list_for_each_entry(event_enabler, &session->enablers_head, node)
1584 lttng_event_enabler_ref_events(event_enabler);
e58095ef
MD
1585 /*
1586 * For each event, if at least one of its enablers is enabled,
ac6b4ac6
MD
1587 * and its channel and session transient states are enabled, we
1588 * enable the event, else we disable it.
e58095ef
MD
1589 */
1590 cds_list_for_each_entry(event, &session->events_head, node) {
1591 struct lttng_enabler_ref *enabler_ref;
1592 struct lttng_bytecode_runtime *runtime;
dcdeaff0 1593 int enabled = 0, has_enablers_without_bytecode = 0;
e58095ef
MD
1594
1595 /* Enable events */
1596 cds_list_for_each_entry(enabler_ref,
1597 &event->enablers_ref_head, node) {
1598 if (enabler_ref->ref->enabled) {
1599 enabled = 1;
1600 break;
1601 }
1602 }
ac6b4ac6
MD
1603 /*
1604 * Enabled state is based on union of enablers, with
1605 * intesection of session and channel transient enable
1606 * states.
1607 */
1608 enabled = enabled && session->tstate && event->chan->tstate;
1609
1610 CMM_STORE_SHARED(event->enabled, enabled);
1611 /*
1612 * Sync tracepoint registration with event enabled
1613 * state.
1614 */
1615 if (enabled) {
1616 if (!event->registered)
1617 register_event(event);
1618 } else {
1619 if (event->registered)
1620 unregister_event(event);
1621 }
457a6b58 1622
1f49fc05 1623 /* Check if has enablers without bytecode enabled */
dcdeaff0
MD
1624 cds_list_for_each_entry(enabler_ref,
1625 &event->enablers_ref_head, node) {
1f49fc05
MD
1626 if (enabler_ref->ref->enabled
1627 && cds_list_empty(&enabler_ref->ref->filter_bytecode_head)) {
dcdeaff0
MD
1628 has_enablers_without_bytecode = 1;
1629 break;
1630 }
1631 }
1632 event->has_enablers_without_bytecode =
1633 has_enablers_without_bytecode;
1634
e58095ef
MD
1635 /* Enable filters */
1636 cds_list_for_each_entry(runtime,
a56fd376 1637 &event->filter_bytecode_runtime_head, node) {
e58095ef 1638 lttng_filter_sync_state(runtime);
457a6b58
MD
1639 }
1640 }
baa1e0bc 1641 __tracepoint_probe_prune_release_queue();
457a6b58
MD
1642}
1643
d8d2416d
FD
1644static
1645void lttng_create_event_notifier_if_missing(
1646 struct lttng_event_notifier_enabler *event_notifier_enabler)
1647{
1648 struct lttng_event_notifier_group *event_notifier_group = event_notifier_enabler->group;
1649 struct lttng_probe_desc *probe_desc;
1650 struct cds_list_head *probe_list;
1651 int i;
1652
1653 probe_list = lttng_get_probe_list_head();
1654
1655 cds_list_for_each_entry(probe_desc, probe_list, head) {
1656 for (i = 0; i < probe_desc->nr_events; i++) {
1657 int ret;
1658 bool found = false;
1659 const struct lttng_event_desc *desc;
1660 struct lttng_event_notifier *event_notifier;
1661 struct cds_hlist_head *head;
1662 struct cds_hlist_node *node;
1663
1664 desc = probe_desc->event_desc[i];
1665 if (!lttng_desc_match_enabler(desc,
1666 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler)))
1667 continue;
1668
1669 /*
1670 * Given the current event_notifier group, get the bucket that
1671 * the target event_notifier would be if it was already
1672 * created.
1673 */
1674 head = borrow_hash_table_bucket(
1675 event_notifier_group->event_notifiers_ht.table,
1676 LTTNG_UST_EVENT_NOTIFIER_HT_SIZE, desc);
1677
1678 cds_hlist_for_each_entry(event_notifier, node, head, hlist) {
1679 /*
1680 * Check if event_notifier already exists by checking
1681 * if the event_notifier and enabler share the same
1682 * description and id.
1683 */
1684 if (event_notifier->desc == desc &&
1685 event_notifier->user_token == event_notifier_enabler->user_token) {
1686 found = true;
1687 break;
1688 }
1689 }
1690
1691 if (found)
1692 continue;
1693
1694 /*
1695 * We need to create a event_notifier for this event probe.
1696 */
1697 ret = lttng_event_notifier_create(desc,
1698 event_notifier_enabler->user_token,
1699 event_notifier_group);
1700 if (ret) {
1701 DBG("Unable to create event_notifier %s, error %d\n",
1702 probe_desc->event_desc[i]->name, ret);
1703 }
1704 }
1705 }
1706}
1707
1708/*
1709 * Create event_notifiers associated with a event_notifier enabler (if not already present).
1710 */
1711static
1712int lttng_event_notifier_enabler_ref_event_notifiers(
1713 struct lttng_event_notifier_enabler *event_notifier_enabler)
1714{
1715 struct lttng_event_notifier_group *event_notifier_group = event_notifier_enabler->group;
1716 struct lttng_event_notifier *event_notifier;
1717
1718 /*
1719 * Only try to create event_notifiers for enablers that are enabled, the user
1720 * might still be attaching filter or exclusion to the
1721 * event_notifier_enabler.
1722 */
1723 if (!lttng_event_notifier_enabler_as_enabler(event_notifier_enabler)->enabled)
1724 goto end;
1725
1726 /* First, ensure that probe event_notifiers are created for this enabler. */
1727 lttng_create_event_notifier_if_missing(event_notifier_enabler);
1728
1729 /* Link the created event_notifier with its associated enabler. */
1730 cds_list_for_each_entry(event_notifier, &event_notifier_group->event_notifiers_head, node) {
1731 struct lttng_enabler_ref *enabler_ref;
1732
1733 if (!lttng_event_notifier_enabler_match_event_notifier(event_notifier_enabler, event_notifier))
1734 continue;
1735
1736 enabler_ref = lttng_enabler_ref(&event_notifier->enablers_ref_head,
1737 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler));
1738 if (!enabler_ref) {
1739 /*
1740 * If no backward ref, create it.
1741 * Add backward ref from event_notifier to enabler.
1742 */
1743 enabler_ref = zmalloc(sizeof(*enabler_ref));
1744 if (!enabler_ref)
1745 return -ENOMEM;
1746
1747 enabler_ref->ref = lttng_event_notifier_enabler_as_enabler(
1748 event_notifier_enabler);
1749 cds_list_add(&enabler_ref->node,
1750 &event_notifier->enablers_ref_head);
1751 }
1752
1753 /*
1754 * Link filter bytecodes if not linked yet.
1755 */
1756 lttng_enabler_link_bytecode(event_notifier->desc,
1757 &event_notifier_group->ctx, &event_notifier->filter_bytecode_runtime_head,
1758 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler));
1759 }
1760end:
1761 return 0;
1762}
1763
1764static
1765void lttng_event_notifier_group_sync_enablers(struct lttng_event_notifier_group *event_notifier_group)
1766{
1767 struct lttng_event_notifier_enabler *event_notifier_enabler;
1768 struct lttng_event_notifier *event_notifier;
1769
1770 cds_list_for_each_entry(event_notifier_enabler, &event_notifier_group->enablers_head, node)
1771 lttng_event_notifier_enabler_ref_event_notifiers(event_notifier_enabler);
1772
1773 /*
1774 * For each event_notifier, if at least one of its enablers is enabled,
1775 * we enable the event_notifier, else we disable it.
1776 */
1777 cds_list_for_each_entry(event_notifier, &event_notifier_group->event_notifiers_head, node) {
1778 struct lttng_enabler_ref *enabler_ref;
1779 struct lttng_bytecode_runtime *runtime;
1780 int enabled = 0, has_enablers_without_bytecode = 0;
1781
1782 /* Enable event_notifiers */
1783 cds_list_for_each_entry(enabler_ref,
1784 &event_notifier->enablers_ref_head, node) {
1785 if (enabler_ref->ref->enabled) {
1786 enabled = 1;
1787 break;
1788 }
1789 }
1790
1791 CMM_STORE_SHARED(event_notifier->enabled, enabled);
1792 /*
1793 * Sync tracepoint registration with event_notifier enabled
1794 * state.
1795 */
1796 if (enabled) {
1797 if (!event_notifier->registered)
1798 register_event_notifier(event_notifier);
1799 } else {
1800 if (event_notifier->registered)
1801 unregister_event_notifier(event_notifier);
1802 }
1803
1804 /* Check if has enablers without bytecode enabled */
1805 cds_list_for_each_entry(enabler_ref,
1806 &event_notifier->enablers_ref_head, node) {
1807 if (enabler_ref->ref->enabled
1808 && cds_list_empty(&enabler_ref->ref->filter_bytecode_head)) {
1809 has_enablers_without_bytecode = 1;
1810 break;
1811 }
1812 }
1813 event_notifier->has_enablers_without_bytecode =
1814 has_enablers_without_bytecode;
1815
1816 /* Enable filters */
1817 cds_list_for_each_entry(runtime,
1818 &event_notifier->filter_bytecode_runtime_head, node) {
1819 lttng_filter_sync_state(runtime);
1820 }
1821 }
1822 __tracepoint_probe_prune_release_queue();
1823}
1824
e58095ef
MD
1825/*
1826 * Apply enablers to session events, adding events to session if need
1827 * be. It is required after each modification applied to an active
1828 * session, and right before session "start".
1829 * "lazy" sync means we only sync if required.
1830 */
1831static
d871c65b 1832void lttng_session_lazy_sync_event_enablers(struct lttng_session *session)
457a6b58 1833{
e58095ef
MD
1834 /* We can skip if session is not active */
1835 if (!session->active)
1836 return;
d871c65b 1837 lttng_session_sync_event_enablers(session);
457a6b58 1838}
53569322
MD
1839
1840/*
1841 * Update all sessions with the given app context.
1842 * Called with ust lock held.
1843 * This is invoked when an application context gets loaded/unloaded. It
1844 * ensures the context callbacks are in sync with the application
1845 * context (either app context callbacks, or dummy callbacks).
1846 */
1847void lttng_ust_context_set_session_provider(const char *name,
1848 size_t (*get_size)(struct lttng_ctx_field *field, size_t offset),
1849 void (*record)(struct lttng_ctx_field *field,
1850 struct lttng_ust_lib_ring_buffer_ctx *ctx,
1851 struct lttng_channel *chan),
1852 void (*get_value)(struct lttng_ctx_field *field,
1853 struct lttng_ctx_value *value))
1854{
1855 struct lttng_session *session;
1856
1857 cds_list_for_each_entry(session, &sessions, node) {
1858 struct lttng_channel *chan;
1859 struct lttng_event *event;
1860 int ret;
1861
1862 ret = lttng_ust_context_set_provider_rcu(&session->ctx,
1863 name, get_size, record, get_value);
1864 if (ret)
1865 abort();
1866 cds_list_for_each_entry(chan, &session->chan_head, node) {
1867 ret = lttng_ust_context_set_provider_rcu(&chan->ctx,
1868 name, get_size, record, get_value);
1869 if (ret)
1870 abort();
1871 }
1872 cds_list_for_each_entry(event, &session->events_head, node) {
1873 ret = lttng_ust_context_set_provider_rcu(&event->ctx,
1874 name, get_size, record, get_value);
1875 if (ret)
1876 abort();
1877 }
1878 }
1879}
d8d2416d
FD
1880
1881/*
1882 * Update all event_notifier groups with the given app context.
1883 * Called with ust lock held.
1884 * This is invoked when an application context gets loaded/unloaded. It
1885 * ensures the context callbacks are in sync with the application
1886 * context (either app context callbacks, or dummy callbacks).
1887 */
1888void lttng_ust_context_set_event_notifier_group_provider(const char *name,
1889 size_t (*get_size)(struct lttng_ctx_field *field, size_t offset),
1890 void (*record)(struct lttng_ctx_field *field,
1891 struct lttng_ust_lib_ring_buffer_ctx *ctx,
1892 struct lttng_channel *chan),
1893 void (*get_value)(struct lttng_ctx_field *field,
1894 struct lttng_ctx_value *value))
1895{
1896 struct lttng_event_notifier_group *event_notifier_group;
1897
1898 cds_list_for_each_entry(event_notifier_group, &event_notifier_groups, node) {
1899 int ret;
1900
1901 ret = lttng_ust_context_set_provider_rcu(
1902 &event_notifier_group->ctx,
1903 name, get_size, record, get_value);
1904 if (ret)
1905 abort();
1906 }
1907}
This page took 0.12965 seconds and 4 git commands to generate.