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