SoW-2020-0003: Trace Hit Counters
[lttng-tools.git] / src / bin / lttng-sessiond / event.c
CommitLineData
54d01ffb 1/*
ab5be9fa
MJ
2 * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
3 * Copyright (C) 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
54d01ffb 4 *
ab5be9fa 5 * SPDX-License-Identifier: GPL-2.0-only
54d01ffb 6 *
54d01ffb
DG
7 */
8
6c1c0768 9#define _LGPL_SOURCE
54d01ffb 10#include <urcu/list.h>
2bdd86d4 11#include <string.h>
54d01ffb 12
edf4b93e 13#include <common/compat/errno.h>
54d01ffb 14#include <lttng/lttng.h>
44760c20 15#include <lttng/condition/condition.h>
ebdb334b 16#include <lttng/condition/on-event.h>
44760c20
JR
17#include <lttng/event-rule/event-rule.h>
18#include <lttng/event-rule/event-rule-internal.h>
763f0d4c 19#include <common/bytecode/bytecode.h>
db758600 20#include <common/error.h>
10a8a223 21#include <common/sessiond-comm/sessiond-comm.h>
71a559f8 22#include <common/filter.h>
ebdb334b 23#include <common/kernel-ctl/kernel-ctl.h>
71a559f8 24#include <common/context.h>
54d01ffb
DG
25
26#include "channel.h"
27#include "event.h"
4771f025 28#include "kernel.h"
be6a6276 29#include "lttng-sessiond.h"
75018ab6
JG
30#include "lttng-ust-ctl.h"
31#include "lttng-ust-error.h"
edb67388
DG
32#include "ust-app.h"
33#include "trace-kernel.h"
34#include "trace-ust.h"
7c1d2758 35#include "agent.h"
44760c20 36#include "utils.h"
54d01ffb 37
025faf73
DG
38/*
39 * Add unique UST event based on the event name, filter bytecode and loglevel.
40 */
18eace3b 41static void add_unique_ust_event(struct lttng_ht *ht,
ebdb334b 42 struct ltt_ust_event *event, struct lttng_map_key *map_key)
18eace3b
DG
43{
44 struct cds_lfht_node *node_ptr;
45 struct ltt_ust_ht_key key;
46
47 assert(ht);
48 assert(ht->ht);
49 assert(event);
50
51 key.name = event->attr.name;
2b00d462 52 key.filter = (struct lttng_bytecode *) event->filter;
b953b8cd
PP
53 key.loglevel_type = event->attr.loglevel_type;
54 key.loglevel_value = event->attr.loglevel;
4031e53e 55 key.exclusion = event->exclusion;
ebdb334b 56 key.key = map_key;
18eace3b
DG
57
58 node_ptr = cds_lfht_add_unique(ht->ht,
59 ht->hash_fct(event->node.key, lttng_ht_seed),
60 trace_ust_ht_match_event, &key, &event->node.node);
61 assert(node_ptr == &event->node.node);
62}
63
54d01ffb 64/*
9550ee81
JR
65 * Disable kernel tracepoint events for a channel from the kernel session of
66 * a specified event_name and event type.
67 * On type LTTNG_EVENT_ALL all events with event_name are disabled.
68 * If event_name is NULL all events of the specified type are disabled.
54d01ffb 69 */
d0ae4ea8 70int event_kernel_disable_event(struct ltt_kernel_channel *kchan,
df4f5a87 71 const char *event_name, enum lttng_event_type type)
54d01ffb 72{
9550ee81 73 int ret, error = 0, found = 0;
54d01ffb
DG
74 struct ltt_kernel_event *kevent;
75
0525e9ae
DG
76 assert(kchan);
77
54d01ffb
DG
78 /* For each event in the kernel session */
79 cds_list_for_each_entry(kevent, &kchan->events_list.head, list) {
d0ae4ea8
MD
80 if (type != LTTNG_EVENT_ALL && kevent->type != type)
81 continue;
9550ee81
JR
82 if (event_name != NULL && strcmp(event_name, kevent->event->name)) {
83 continue;
84 }
85 found++;
54d01ffb
DG
86 ret = kernel_disable_event(kevent);
87 if (ret < 0) {
9550ee81 88 error = 1;
54d01ffb
DG
89 continue;
90 }
91 }
9550ee81
JR
92 DBG("Disable kernel event: found %d events with name: %s and type: %d",
93 found, event_name ? event_name : "NULL", type);
7a3d1328 94
9550ee81
JR
95 if (event_name != NULL && !found) {
96 ret = LTTNG_ERR_NO_EVENT;
97 } else {
98 ret = error ? LTTNG_ERR_KERN_DISABLE_FAIL : LTTNG_OK;
99 }
100
101 return ret;
54d01ffb
DG
102}
103
104/*
7a3d1328 105 * Enable kernel tracepoint event for a channel from the kernel session.
49d21f93 106 * We own filter_expression and filter.
54d01ffb 107 */
d0ae4ea8 108int event_kernel_enable_event(struct ltt_kernel_channel *kchan,
00a62084 109 struct lttng_event *event, char *filter_expression,
2b00d462 110 struct lttng_bytecode *filter)
54d01ffb
DG
111{
112 int ret;
113 struct ltt_kernel_event *kevent;
114
0525e9ae
DG
115 assert(kchan);
116 assert(event);
117
ebdb334b
JR
118 kevent = trace_kernel_find_event(&kchan->events_list,
119 0, event->name, event->type, filter);
54d01ffb 120 if (kevent == NULL) {
71a3bb01 121 ret = kernel_create_event(event, kchan, filter_expression, filter);
a969e101
MD
122 /* We have passed ownership */
123 filter_expression = NULL;
124 filter = NULL;
71a3bb01 125 if (ret) {
7a3d1328 126 goto end;
54d01ffb
DG
127 }
128 } else if (kevent->enabled == 0) {
129 ret = kernel_enable_event(kevent);
130 if (ret < 0) {
f73fabfd 131 ret = LTTNG_ERR_KERN_ENABLE_FAIL;
7a3d1328 132 goto end;
54d01ffb 133 }
42224349
DG
134 } else {
135 /* At this point, the event is considered enabled */
f73fabfd 136 ret = LTTNG_ERR_KERN_EVENT_EXIST;
42224349 137 goto end;
54d01ffb 138 }
42224349 139
f73fabfd 140 ret = LTTNG_OK;
7a3d1328 141end:
a969e101
MD
142 free(filter_expression);
143 free(filter);
54d01ffb
DG
144 return ret;
145}
146
ebdb334b
JR
147/*
148 * Disable kernel tracepoint events for a map from the kernel session of
149 * a specified event_name and event type.
150 * On type LTTNG_EVENT_ALL all events with event_name are disabled.
151 * If event_name is NULL all events of the specified type are disabled.
152 */
153int map_event_kernel_disable_event(struct ltt_kernel_map *kmap,
154 uint64_t action_tracer_token)
155{
156 struct ltt_kernel_event_counter *kevent_counter;
157 struct lttng_ht_iter iter;
158 const struct lttng_ht_node_u64 *node;
159 enum lttng_error_code ret_code;
160 int ret;
161
162 assert(kmap);
163
164 lttng_ht_lookup(kmap->event_counters_ht, (void *) &action_tracer_token, &iter);
165 node = lttng_ht_iter_get_node_u64(&iter);
166 if (node){
167 kevent_counter = caa_container_of(node,
168 struct ltt_kernel_event_counter, ht_node);
169 ret = kernctl_disable(kevent_counter->fd);
170 if (ret < 0) {
171 ret_code = LTTNG_ERR_KERN_DISABLE_FAIL;
172 goto end;
173 }
174 kevent_counter->enabled = false;
175 DBG("Disable kernel event counter");
176 } else {
177 ret_code = LTTNG_ERR_NO_EVENT;
178 goto end;
179 }
180
181 ret_code = LTTNG_OK;
182end:
183 return ret_code;
184}
185
186/*
187 * Enable kernel tracepoint event for a map from the kernel session.
188 * We own filter_expression and filter.
189 */
190int map_event_kernel_enable_event(struct ltt_kernel_map *kmap,
191 const struct lttng_credentials *creds,
192 uint64_t action_tracer_token,
193 const struct lttng_event_rule *event_rule,
194 struct lttng_map_key *key)
195{
196 int err;
197 enum lttng_error_code ret_code;
198 struct ltt_kernel_event_counter *kevent_counter;
199 struct lttng_ht_iter iter;
200 const struct lttng_ht_node_u64 *node;
201
202 assert(kmap);
203 assert(event_rule);
204 assert(key);
205
206 lttng_ht_lookup(kmap->event_counters_ht, (void *) &action_tracer_token, &iter);
207 node = lttng_ht_iter_get_node_u64(&iter);
208 if (node){
209 kevent_counter = caa_container_of(node,
210 struct ltt_kernel_event_counter, ht_node);
211 if (kevent_counter->enabled) {
212 /* At this point, the event is considered enabled */
213 ret_code = LTTNG_ERR_KERN_EVENT_EXIST;
214 goto end;
215 }
216
217 err = kernctl_enable(kevent_counter->fd);
218 if (err < 0) {
219 switch (-err) {
220 case EEXIST:
221 ret_code = LTTNG_ERR_KERN_EVENT_EXIST;
222 break;
223 default:
224 PERROR("enable kernel event counter");
225 ret_code = LTTNG_ERR_KERN_ENABLE_FAIL;
226 break;
227 }
228 goto end;
229 }
230
231 } else {
232
233 ret_code = kernel_create_event_counter(kmap, creds,
234 action_tracer_token, event_rule, key);
235 if (ret_code != LTTNG_OK) {
236 goto end;
237 }
238 }
239
240 ret_code = LTTNG_OK;
241end:
242 return ret_code;
243}
244
7f79d3a1
DG
245/*
246 * ============================
247 * UST : The Ultimate Frontier!
248 * ============================
249 */
250
2bdd86d4
MD
251/*
252 * Enable UST tracepoint event for a channel from a UST session.
49d21f93 253 * We own filter_expression, filter, and exclusion.
2bdd86d4 254 */
7972aab2 255int event_ust_enable_tracepoint(struct ltt_ust_session *usess,
025faf73 256 struct ltt_ust_channel *uchan, struct lttng_event *event,
6b453b5e 257 char *filter_expression,
2b00d462 258 struct lttng_bytecode *filter,
88f06f15
JG
259 struct lttng_event_exclusion *exclusion,
260 bool internal_event)
2bdd86d4 261{
88e3c2f5 262 int ret = LTTNG_OK, to_create = 0;
edb67388
DG
263 struct ltt_ust_event *uevent;
264
ebdb334b
JR
265 /*
266 * FIXME: Frdeso. The tracer token should probably me set for regular
267 * events too.
268 */
269 uint64_t tracer_token = 0;
270
0525e9ae
DG
271 assert(usess);
272 assert(uchan);
273 assert(event);
274
18eace3b
DG
275 rcu_read_lock();
276
ebdb334b 277 uevent = trace_ust_find_event(uchan->events, 0, event->name, filter,
abda88ad 278 (enum lttng_ust_loglevel_type) event->loglevel_type,
ebdb334b 279 event->loglevel, exclusion, NULL);
87c6e328 280 if (!uevent) {
ebdb334b
JR
281 ret = trace_ust_create_event(tracer_token, event->name, NULL, event->type,
282 event->loglevel_type, event->loglevel,
283 filter_expression, filter, exclusion,
284 internal_event, &uevent);
49d21f93
MD
285 /* We have passed ownership */
286 filter_expression = NULL;
287 filter = NULL;
288 exclusion = NULL;
39687410 289 if (ret != LTTNG_OK) {
edb67388
DG
290 goto error;
291 }
025faf73 292
fc34caaa 293 /* Valid to set it after the goto error since uevent is still NULL */
edb67388
DG
294 to_create = 1;
295 }
2bdd86d4 296
7f79d3a1
DG
297 if (uevent->enabled) {
298 /* It's already enabled so everything is OK */
0359fdbc 299 assert(!to_create);
5bcdda4f 300 ret = LTTNG_ERR_UST_EVENT_ENABLED;
7f79d3a1
DG
301 goto end;
302 }
303
fc34caaa 304 uevent->enabled = 1;
88e3c2f5
JG
305 if (to_create) {
306 /* Add ltt ust event to channel */
ebdb334b 307 add_unique_ust_event(uchan->events, uevent, NULL);
88e3c2f5
JG
308 }
309
310 if (!usess->active) {
311 goto end;
312 }
fc34caaa 313
7972aab2
DG
314 if (to_create) {
315 /* Create event on all UST registered apps for session */
ebdb334b 316 ret = ust_app_create_channel_event_glb(usess, uchan, uevent);
7972aab2
DG
317 } else {
318 /* Enable event on all UST registered apps for session */
ebdb334b 319 ret = ust_app_enable_channel_event_glb(usess, uchan, uevent);
7972aab2 320 }
48842b30 321
7972aab2
DG
322 if (ret < 0) {
323 if (ret == -LTTNG_UST_ERR_EXIST) {
324 ret = LTTNG_ERR_UST_EVENT_EXIST;
325 goto end;
326 } else {
327 ret = LTTNG_ERR_UST_ENABLE_FAIL;
328 goto error;
edb67388 329 }
2bdd86d4 330 }
48842b30 331
7f79d3a1
DG
332 DBG("Event UST %s %s in channel %s", uevent->attr.name,
333 to_create ? "created" : "enabled", uchan->name);
334
f73fabfd 335 ret = LTTNG_OK;
fc34caaa 336
fb89d070 337end:
18eace3b 338 rcu_read_unlock();
49d21f93
MD
339 free(filter_expression);
340 free(filter);
341 free(exclusion);
fc34caaa 342 return ret;
edb67388
DG
343
344error:
fc34caaa
DG
345 /*
346 * Only destroy event on creation time (not enabling time) because if the
347 * event is found in the channel (to_create == 0), it means that at some
348 * point the enable_event worked and it's thus valid to keep it alive.
349 * Destroying it also implies that we also destroy it's shadow copy to sync
350 * everyone up.
351 */
352 if (to_create) {
353 /* In this code path, the uevent was not added to the hash table */
354 trace_ust_destroy_event(uevent);
355 }
18eace3b 356 rcu_read_unlock();
49d21f93
MD
357 free(filter_expression);
358 free(filter);
359 free(exclusion);
2bdd86d4
MD
360 return ret;
361}
362
ebdb334b
JR
363/*
364 * Enable UST tracepoint event for a map from a UST session.
365 */
366enum lttng_error_code map_event_ust_enable_tracepoint(
367 struct ltt_ust_session *usess,
368 struct ltt_ust_map *umap,
369 uint64_t tracer_token,
370 char *ev_name,
371 struct lttng_map_key *key,
372 enum lttng_event_type ev_type,
373 enum lttng_loglevel_type ev_loglevel_type,
374 int ev_loglevel_value,
375 char *_filter_expression,
376 struct lttng_bytecode *_filter,
377 struct lttng_event_exclusion *exclusion,
378 bool internal_event)
379{
380 enum lttng_error_code ret_code = LTTNG_OK;
381 int ret, to_create = 0;
382 struct ltt_ust_event *uevent;
383 struct lttng_bytecode *filter = NULL;
384 char *filter_expression = NULL;
385
386
387 assert(usess);
388 assert(umap);
389
390 /*
391 * FIXME: FRDESO: this function was copied from ust-app.c
392 */
393 if (_filter_expression) {
394 filter_expression = strdup(_filter_expression);
395 }
396
397 if (_filter) {
398 filter = zmalloc(sizeof(*filter) + _filter->len);
399 if (!filter) {
400 PERROR("Failed to allocate lttng_ust_filter_bytecode: bytecode len = %" PRIu32 " bytes", _filter->len);
401 goto error;
402 }
403
404 assert(sizeof(struct lttng_bytecode) ==
405 sizeof(struct lttng_ust_filter_bytecode));
406 memcpy(filter, _filter, sizeof(*filter) + _filter->len);
407 }
408
409 rcu_read_lock();
410
411 uevent = trace_ust_find_event(umap->events, tracer_token, ev_name, filter,
412 (enum lttng_ust_loglevel_type) ev_loglevel_type,
413 ev_loglevel_value, exclusion, key);
414 if (!uevent) {
415 ret_code = trace_ust_create_event(tracer_token, ev_name, key, ev_type,
416 ev_loglevel_type, ev_loglevel_value,
417 filter_expression, filter, exclusion,
418 internal_event, &uevent);
419 /* We have passed ownership */
420 filter_expression = NULL;
421 filter = NULL;
422 exclusion = NULL;
423 if (ret_code != LTTNG_OK) {
424 goto error;
425 }
426
427 /* Valid to set it after the goto error since uevent is still NULL */
428 to_create = 1;
429 }
430
431 if (uevent->enabled) {
432 /* It's already enabled so everything is OK */
433 assert(!to_create);
434 ret_code = LTTNG_ERR_UST_EVENT_ENABLED;
435 goto end;
436 }
437
438 uevent->enabled = 1;
439 if (to_create) {
440 /* Add ltt ust event to map */
441 add_unique_ust_event(umap->events, uevent, key);
442 }
443
444 if (!usess->active) {
445 goto end;
446 }
447
448 if (to_create) {
449 /* Create event on all UST registered apps for session */
450 ret = ust_app_create_map_event_glb(usess, umap, uevent);
451 } else {
452 /* Enable event on all UST registered apps for session */
453 ret = ust_app_enable_map_event_glb(usess, umap, uevent);
454 }
455
456 if (ret < 0) {
457 if (ret == -LTTNG_UST_ERR_EXIST) {
458 ret_code = LTTNG_ERR_UST_EVENT_EXIST;
459 goto end;
460 } else {
461 ret_code = LTTNG_ERR_UST_ENABLE_FAIL;
462 goto error;
463 }
464 }
465
466 DBG("Event UST %s %s in map %s", uevent->attr.name,
467 to_create ? "created" : "enabled", umap->name);
468
469 ret_code = LTTNG_OK;
470
471end:
472 rcu_read_unlock();
473 free(filter_expression);
474 free(filter);
475 free(exclusion);
476 return ret_code;
477
478error:
479 /*
480 * Only destroy event on creation time (not enabling time) because if the
481 * event is found in the map (to_create == 0), it means that at some
482 * point the enable_event worked and it's thus valid to keep it alive.
483 * Destroying it also implies that we also destroy it's shadow copy to sync
484 * everyone up.
485 */
486 if (to_create) {
487 /* In this code path, the uevent was not added to the hash table */
488 trace_ust_destroy_event(uevent);
489 }
490 rcu_read_unlock();
491 free(filter_expression);
492 free(filter);
493 free(exclusion);
494 return ret_code;
495}
496
7f79d3a1
DG
497/*
498 * Disable UST tracepoint of a channel from a UST session.
499 */
7972aab2 500int event_ust_disable_tracepoint(struct ltt_ust_session *usess,
df4f5a87 501 struct ltt_ust_channel *uchan, const char *event_name)
2bdd86d4
MD
502{
503 int ret;
7f79d3a1 504 struct ltt_ust_event *uevent;
18eace3b
DG
505 struct lttng_ht_node_str *node;
506 struct lttng_ht_iter iter;
18eace3b 507 struct lttng_ht *ht;
2bdd86d4 508
0525e9ae
DG
509 assert(usess);
510 assert(uchan);
511 assert(event_name);
512
18eace3b
DG
513 ht = uchan->events;
514
18eace3b 515 rcu_read_lock();
025faf73
DG
516
517 /*
518 * We use a custom lookup since we need the iterator for the next_duplicate
519 * call in the do while loop below.
520 */
521 cds_lfht_lookup(ht->ht, ht->hash_fct((void *) event_name, lttng_ht_seed),
522 trace_ust_ht_match_event_by_name, event_name, &iter.iter);
18eace3b
DG
523 node = lttng_ht_iter_get_node_str(&iter);
524 if (node == NULL) {
525 DBG2("Trace UST event NOT found by name %s", event_name);
f73fabfd 526 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
7f79d3a1 527 goto error;
2bdd86d4 528 }
7f79d3a1 529
18eace3b
DG
530 do {
531 uevent = caa_container_of(node, struct ltt_ust_event, node);
025faf73
DG
532 assert(uevent);
533
18eace3b
DG
534 if (uevent->enabled == 0) {
535 /* It's already disabled so everything is OK */
a1dcaf0f 536 goto next;
7f79d3a1 537 }
88e3c2f5
JG
538 uevent->enabled = 0;
539 DBG2("Event UST %s disabled in channel %s", uevent->attr.name,
540 uchan->name);
18eace3b 541
88e3c2f5
JG
542 if (!usess->active) {
543 goto next;
544 }
ebdb334b 545 ret = ust_app_disable_channel_event_glb(usess, uchan, uevent);
7972aab2
DG
546 if (ret < 0 && ret != -LTTNG_UST_ERR_EXIST) {
547 ret = LTTNG_ERR_UST_DISABLE_FAIL;
18eace3b
DG
548 goto error;
549 }
a1dcaf0f 550next:
18eace3b
DG
551 /* Get next duplicate event by name. */
552 cds_lfht_next_duplicate(ht->ht, trace_ust_ht_match_event_by_name,
553 event_name, &iter.iter);
554 node = lttng_ht_iter_get_node_str(&iter);
555 } while (node);
7f79d3a1 556
f73fabfd 557 ret = LTTNG_OK;
7f79d3a1 558
7f79d3a1 559error:
18eace3b 560 rcu_read_unlock();
7f79d3a1
DG
561 return ret;
562}
563
ebdb334b
JR
564/*
565 * Disable UST tracepoint of a map from a UST session.
566 */
567enum lttng_error_code map_event_ust_disable_tracepoint(
568 struct ltt_ust_session *usess,
569 struct ltt_ust_map *umap,
570 uint64_t tracer_token,
571 char *event_name,
572 struct lttng_map_key *key,
573 enum lttng_event_type ev_type,
574 enum lttng_loglevel_type ev_loglevel_type,
575 int ev_loglevel_value,
576 char *filter_expression,
577 struct lttng_bytecode *filter,
578 struct lttng_event_exclusion *exclusion,
579 bool internal_event)
580{
581 int ret;
582 enum lttng_error_code ret_code;
583 struct ltt_ust_event *uevent;
584
585 assert(usess);
586 assert(umap);
587 assert(event_name);
588
589 rcu_read_lock();
590
591 /*
592 * FIXME: frdeso: We need to pass all the parameters to find the right
593 * event.
594 */
595 uevent = trace_ust_find_event(umap->events, tracer_token, event_name, filter,
596 (enum lttng_ust_loglevel_type) ev_loglevel_type,
597 ev_loglevel_value, exclusion, key);
598 assert(uevent);
599
600 if (uevent->enabled == 0) {
601 ret_code = LTTNG_OK;
602 goto end;
603 }
604
605 uevent->enabled = 0;
606 DBG2("Event UST %s disabled in map %s", uevent->attr.name,
607 umap->name);
608
609 if (!usess->active) {
610 ret_code = LTTNG_OK;
611 goto end;
612 }
613
614 ret = ust_app_disable_map_event_glb(usess, umap, uevent);
615 if (ret < 0 && ret != -LTTNG_UST_ERR_EXIST) {
616 ret_code = LTTNG_ERR_UST_DISABLE_FAIL;
617 goto end;
618 }
619
620 ret_code = LTTNG_OK;
621
622end:
623 rcu_read_unlock();
624 return ret_code;
625}
626
b1e7fe2d
JR
627/*
628 * Disable all UST tracepoints for a channel from a UST session.
629 */
630int event_ust_disable_all_tracepoints(struct ltt_ust_session *usess,
631 struct ltt_ust_channel *uchan)
632{
3e81c0f2 633 int ret, i, size, error = 0;
b1e7fe2d
JR
634 struct lttng_ht_iter iter;
635 struct ltt_ust_event *uevent = NULL;
636 struct lttng_event *events = NULL;
637
638 assert(usess);
639 assert(uchan);
640
641 rcu_read_lock();
642
643 /* Disabling existing events */
644 cds_lfht_for_each_entry(uchan->events->ht, &iter.iter, uevent,
645 node.node) {
646 if (uevent->enabled == 1) {
647 ret = event_ust_disable_tracepoint(usess, uchan,
648 uevent->attr.name);
649 if (ret < 0) {
3e81c0f2 650 error = LTTNG_ERR_UST_DISABLE_FAIL;
b1e7fe2d
JR
651 continue;
652 }
653 }
654 }
655
656 /* Get all UST available events */
657 size = ust_app_list_events(&events);
658 if (size < 0) {
659 ret = LTTNG_ERR_UST_LIST_FAIL;
660 goto error;
661 }
662
663 for (i = 0; i < size; i++) {
664 ret = event_ust_disable_tracepoint(usess, uchan,
665 events[i].name);
3e81c0f2 666 if (ret < 0) {
b1e7fe2d 667 /* Continue to disable the rest... */
3e81c0f2 668 error = LTTNG_ERR_UST_DISABLE_FAIL;
b1e7fe2d
JR
669 continue;
670 }
671 }
672
3e81c0f2 673 ret = error ? error : LTTNG_OK;
b1e7fe2d
JR
674error:
675 rcu_read_unlock();
676 free(events);
677 return ret;
678}
679
ebdb334b
JR
680/*
681 * Disable all UST tracepoints for a map from a UST session.
682 */
683int map_event_ust_disable_all_tracepoints(struct ltt_ust_session *usess,
684 struct ltt_ust_map *umap)
685{
686 int ret, error = 0;
687 struct lttng_ht_iter iter;
688 struct ltt_ust_event *uevent = NULL;
689 struct lttng_event *events = NULL;
690
691 assert(usess);
692 assert(umap);
693
694 rcu_read_lock();
695
696 /* Disabling existing events */
697 cds_lfht_for_each_entry(umap->events->ht, &iter.iter, uevent,
698 node.node) {
699 if (uevent->enabled == 1) {
700 ret = map_event_ust_disable_tracepoint(usess, umap,
701 uevent->attr.token,
702 uevent->attr.name,
703 uevent->key,
704 uevent->attr.instrumentation,
705 (enum lttng_loglevel_type) uevent->attr.loglevel_type,
706 uevent->attr.loglevel,
707 uevent->filter_expression,
708 uevent->filter,
709 uevent->exclusion,
710 false);
711 if (ret < 0) {
712 error = LTTNG_ERR_UST_DISABLE_FAIL;
713 continue;
714 }
715 }
716 }
717
718 /*
719 * FIXME: FRDESO: in the equivalent function
720 * event_ust_disable_all_tracepoints() (above ^) we also iterator over
721 * all lttng_event. Do we need to do this here too?
722 */
723
724 ret = error ? error : LTTNG_OK;
725 rcu_read_unlock();
726 free(events);
727 return ret;
728}
729
44760c20
JR
730static void agent_enable_all(struct agent *agt)
731{
732 struct agent_event *aevent;
733 struct lttng_ht_iter iter;
734
735 /* Flag every event as enabled. */
736 rcu_read_lock();
737 cds_lfht_for_each_entry (
738 agt->events->ht, &iter.iter, aevent, node.node) {
739 aevent->enabled_count++;
740 }
741 rcu_read_unlock();
742}
743
f20baf8e 744/*
022d91ba 745 * Enable all agent event for a given UST session.
f20baf8e
DG
746 *
747 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
748 */
022d91ba 749int event_agent_enable_all(struct ltt_ust_session *usess,
fefd409b 750 struct agent *agt, struct lttng_event *event,
2b00d462 751 struct lttng_bytecode *filter ,char *filter_expression)
f20baf8e
DG
752{
753 int ret;
f20baf8e
DG
754
755 assert(usess);
756
022d91ba 757 DBG("Event agent enabling ALL events for session %" PRIu64, usess->id);
f20baf8e 758
022d91ba 759 /* Enable event on agent application through TCP socket. */
8404118c 760 ret = event_agent_enable(usess, agt, event, filter, filter_expression);
f20baf8e
DG
761 if (ret != LTTNG_OK) {
762 goto error;
763 }
764
44760c20 765 agent_enable_all(agt);
f20baf8e
DG
766
767 ret = LTTNG_OK;
768
769error:
770 return ret;
771}
772
71a559f8
JG
773/*
774 * Check if this event's filter requires the activation of application contexts
775 * and enable them in the agent.
b4bc01f7
MD
776 * TODO: bytecode iterator does not support non-legacy application
777 * contexts yet. Not an issue for now, since they are not generated by
778 * the lttng-ctl library.
71a559f8 779 */
2b00d462 780static int add_filter_app_ctx(struct lttng_bytecode *bytecode,
71a559f8
JG
781 const char *filter_expression, struct agent *agt)
782{
783 int ret = LTTNG_OK;
784 char *provider_name = NULL, *ctx_name = NULL;
785 struct bytecode_symbol_iterator *it =
786 bytecode_symbol_iterator_create(bytecode);
787
788 if (!it) {
789 ret = LTTNG_ERR_NOMEM;
790 goto end;
791 }
792
793 do {
794 struct lttng_event_context ctx;
795 const char *symbol_name =
796 bytecode_symbol_iterator_get_name(it);
797
798 if (parse_application_context(symbol_name, &provider_name,
799 &ctx_name)) {
800 /* Not an application context. */
801 continue;
802 }
803
804 ctx.ctx = LTTNG_EVENT_CONTEXT_APP_CONTEXT;
805 ctx.u.app_ctx.provider_name = provider_name;
806 ctx.u.app_ctx.ctx_name = ctx_name;
807
808 /* Recognized an application context. */
809 DBG("Enabling event with filter expression \"%s\" requires enabling the %s:%s application context.",
810 filter_expression, provider_name, ctx_name);
811
812 ret = agent_add_context(&ctx, agt);
813 if (ret != LTTNG_OK) {
814 ERR("Failed to add application context %s:%s.",
815 provider_name, ctx_name);
816 goto end;
817 }
818
819 ret = agent_enable_context(&ctx, agt->domain);
820 if (ret != LTTNG_OK) {
821 ERR("Failed to enable application context %s:%s.",
822 provider_name, ctx_name);
823 goto end;
824 }
825
826 free(provider_name);
827 free(ctx_name);
828 provider_name = ctx_name = NULL;
829 } while (bytecode_symbol_iterator_next(it) == 0);
830end:
831 free(provider_name);
832 free(ctx_name);
833 bytecode_symbol_iterator_destroy(it);
834 return ret;
835}
836
44760c20
JR
837static int agent_enable(struct agent *agt,
838 struct lttng_event *event,
2b00d462 839 struct lttng_bytecode *filter,
8404118c 840 char *filter_expression)
f20baf8e
DG
841{
842 int ret, created = 0;
fefd409b 843 struct agent_event *aevent;
f20baf8e 844
f20baf8e 845 assert(event);
fefd409b 846 assert(agt);
f20baf8e 847
a9319624 848 aevent = agent_find_event(event->name, event->loglevel_type,
71a559f8 849 event->loglevel, filter_expression, agt);
fefd409b 850 if (!aevent) {
a9319624
PP
851 aevent = agent_create_event(event->name, event->loglevel_type,
852 event->loglevel, filter,
51755dc8 853 filter_expression);
fefd409b 854 if (!aevent) {
f20baf8e
DG
855 ret = LTTNG_ERR_NOMEM;
856 goto error;
857 }
b0a23296
JG
858 filter = NULL;
859 filter_expression = NULL;
f20baf8e 860 created = 1;
44760c20 861 assert(!AGENT_EVENT_IS_ENABLED(aevent));
f20baf8e
DG
862 }
863
bf7886d8
JR
864 if (created && aevent->filter) {
865 ret = add_filter_app_ctx(
866 aevent->filter, aevent->filter_expression, agt);
71a559f8
JG
867 if (ret != LTTNG_OK) {
868 goto error;
869 }
870 }
871
88e3c2f5 872 /* Already enabled? */
44760c20 873 if (AGENT_EVENT_IS_ENABLED(aevent)) {
88e3c2f5
JG
874 ret = LTTNG_OK;
875 goto end;
876 }
877
fefd409b 878 ret = agent_enable_event(aevent, agt->domain);
f20baf8e
DG
879 if (ret != LTTNG_OK) {
880 goto error;
881 }
882
883 /* If the event was created prior to the enable, add it to the domain. */
884 if (created) {
fefd409b 885 agent_add_event(aevent, agt);
f20baf8e
DG
886 }
887
b0a23296
JG
888 ret = LTTNG_OK;
889 goto end;
f20baf8e
DG
890
891error:
892 if (created) {
fefd409b 893 agent_destroy_event(aevent);
f20baf8e 894 }
b0a23296
JG
895end:
896 free(filter);
897 free(filter_expression);
f20baf8e
DG
898 return ret;
899}
900
44760c20
JR
901/*
902 * Enable a single agent event for a given UST session.
903 *
904 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
905 */
906int event_agent_enable(struct ltt_ust_session *usess,
907 struct agent *agt,
908 struct lttng_event *event,
2b00d462 909 struct lttng_bytecode *filter,
44760c20
JR
910 char *filter_expression)
911{
912 assert(usess);
913 assert(event);
914 assert(agt);
915
916 DBG("Enabling agent event: event pattern = '%s', session id = %" PRIu64 ", loglevel type = %d, loglevel = %d, filter expression = '%s'",
917 event->name, usess->id, event->loglevel_type,
918 event->loglevel,
919 filter_expression ? filter_expression : "(none)");
920
921 return agent_enable(agt, event, filter, filter_expression);
922}
923
924/*
925 * Enable a single agent event for a trigger.
926 *
927 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
928 */
929int trigger_agent_enable(const struct lttng_trigger *trigger, struct agent *agt)
930{
931 int ret;
932 enum lttng_condition_status c_status;
933 enum lttng_trigger_status t_status;
934 enum lttng_domain_type d_type;
935 const struct lttng_condition *condition;
936 const struct lttng_event_rule *rule;
937 const char *filter_expression;
938 char *filter_expression_copy = NULL;
2b00d462
SM
939 const struct lttng_bytecode *filter_bytecode;
940 struct lttng_bytecode *filter_bytecode_copy = NULL;
44760c20
JR
941 struct lttng_event *event = NULL;
942 uid_t trigger_owner_uid = 0;
943 const char *trigger_name;
944
945 assert(trigger);
946 assert(agt);
947
948 t_status = lttng_trigger_get_name(trigger, &trigger_name);
949 if (t_status != LTTNG_TRIGGER_STATUS_OK) {
950 trigger_name = "(unnamed)";
951 }
952
953 t_status = lttng_trigger_get_owner_uid(trigger, &trigger_owner_uid);
954 assert(t_status == LTTNG_TRIGGER_STATUS_OK);
955
956 condition = lttng_trigger_get_const_condition(trigger);
957
958 assert(lttng_condition_get_type(condition) ==
ebdb334b 959 LTTNG_CONDITION_TYPE_ON_EVENT);
44760c20 960
ebdb334b 961 c_status = lttng_condition_on_event_get_rule(condition, &rule);
44760c20
JR
962 assert(c_status == LTTNG_CONDITION_STATUS_OK);
963
964 assert(lttng_event_rule_get_type(rule) ==
965 LTTNG_EVENT_RULE_TYPE_TRACEPOINT);
966
967 d_type = lttng_event_rule_get_domain_type(rule);
968 assert(d_type == agt->domain);
969
970 event = lttng_event_rule_generate_lttng_event(rule);
971 if (!event) {
972 ret = LTTNG_ERR_NOMEM;
973 goto end;
974 }
975
976 /* Get the internal filter expression and bytecode. */
977 filter_expression = lttng_event_rule_get_filter(rule);
978 if (filter_expression) {
979 filter_expression_copy = strdup(filter_expression);
980 if (!filter_expression_copy) {
981 ret = LTTNG_ERR_NOMEM;
982 goto end;
983 }
984
985 /* Get the filter bytecode */
986 filter_bytecode = lttng_event_rule_get_filter_bytecode(rule);
987 if (filter_bytecode) {
988 filter_bytecode_copy =
2b00d462 989 lttng_bytecode_copy(filter_bytecode);
44760c20
JR
990 if (!filter_bytecode_copy) {
991 ret = LTTNG_ERR_NOMEM;
992 goto end;
993 }
994 }
995 }
996
997 DBG("Enabling agent event from trigger: trigger name = '%s', trigger owner uid = %d, token = %" PRIu64,
998 trigger_name, trigger_owner_uid,
999 lttng_trigger_get_tracer_token(trigger));
1000
1001 ret = agent_enable(agt, event, filter_bytecode_copy,
1002 filter_expression_copy);
1003 /* Ownership was passed even in case of error. */
1004 filter_expression_copy = NULL;
1005 filter_bytecode_copy = NULL;
1006
1007end:
1008 free(filter_expression_copy);
1009 free(filter_bytecode_copy);
1010 free(event);
1011 return ret;
1012}
1013
da6c3a50 1014/*
d1ec8e20
JG
1015 * Return the default event name associated with the provided UST domain. Return
1016 * NULL on error.
da6c3a50
DG
1017 */
1018const char *event_get_default_agent_ust_name(enum lttng_domain_type domain)
1019{
1020 const char *default_event_name = NULL;
1021
0e115563
DG
1022 switch (domain) {
1023 case LTTNG_DOMAIN_LOG4J:
d1ec8e20 1024 default_event_name = DEFAULT_LOG4J_EVENT_NAME;
0e115563
DG
1025 break;
1026 case LTTNG_DOMAIN_JUL:
d1ec8e20 1027 default_event_name = DEFAULT_JUL_EVENT_NAME;
0e115563
DG
1028 break;
1029 case LTTNG_DOMAIN_PYTHON:
e7c82272 1030 default_event_name = DEFAULT_PYTHON_EVENT_NAME;
0e115563
DG
1031 break;
1032 default:
da6c3a50
DG
1033 assert(0);
1034 }
1035
1036 return default_event_name;
1037}
1038
44760c20
JR
1039static int trigger_agent_disable_one(const struct lttng_trigger *trigger,
1040 struct agent *agt,
1041 struct agent_event *aevent)
1042
1043{
1044 int ret;
1045
1046 assert(agt);
1047 assert(trigger);
1048 assert(aevent);
1049
1050 /*
1051 * Actual ust event un-registration happens on the trigger
1052 * un-registration at that point.
1053 */
1054
1055 DBG("Event agent disabling %s (loglevel type %d, loglevel value %d) for trigger %" PRIu64,
1056 aevent->name, aevent->loglevel_type,
1057 aevent->loglevel_value, lttng_trigger_get_tracer_token(trigger));
1058
1059 /* Already disabled? */
1060 if (!AGENT_EVENT_IS_ENABLED(aevent)) {
1061 goto end;
1062 }
1063
1064 ret = agent_disable_event(aevent, agt->domain);
1065 if (ret != LTTNG_OK) {
1066 goto error;
1067 }
1068
1069end:
1070 return LTTNG_OK;
1071
1072error:
1073 return ret;
1074}
1075
f20baf8e 1076/*
e261a6cc 1077 * Disable a given agent event for a given UST session.
f20baf8e 1078 *
e261a6cc 1079 * Must be called with the RCU read lock held.
f20baf8e
DG
1080 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
1081 */
e261a6cc
PP
1082static int event_agent_disable_one(struct ltt_ust_session *usess,
1083 struct agent *agt, struct agent_event *aevent)
f20baf8e
DG
1084{
1085 int ret;
be6a6276
DG
1086 struct ltt_ust_event *uevent = NULL;
1087 struct ltt_ust_channel *uchan = NULL;
71aecbf8 1088 const char *ust_event_name, *ust_channel_name;
f20baf8e 1089
fefd409b 1090 assert(agt);
f20baf8e 1091 assert(usess);
e261a6cc 1092 assert(aevent);
f20baf8e 1093
e261a6cc
PP
1094 DBG("Event agent disabling %s (loglevel type %d, loglevel value %d) for session %" PRIu64,
1095 aevent->name, aevent->loglevel_type, aevent->loglevel_value,
1096 usess->id);
f20baf8e
DG
1097
1098 /* Already disabled? */
44760c20 1099 if (!AGENT_EVENT_IS_ENABLED(aevent)) {
f20baf8e
DG
1100 goto end;
1101 }
1102
71aecbf8
DG
1103 if (agt->domain == LTTNG_DOMAIN_JUL) {
1104 ust_channel_name = DEFAULT_JUL_CHANNEL_NAME;
1105 } else if (agt->domain == LTTNG_DOMAIN_LOG4J) {
1106 ust_channel_name = DEFAULT_LOG4J_CHANNEL_NAME;
0e115563
DG
1107 } else if (agt->domain == LTTNG_DOMAIN_PYTHON) {
1108 ust_channel_name = DEFAULT_PYTHON_CHANNEL_NAME;
71aecbf8
DG
1109 } else {
1110 ret = LTTNG_ERR_INVALID;
1111 goto error;
1112 }
1113
be6a6276
DG
1114 /*
1115 * Disable it on the UST side. First get the channel reference then find
1116 * the event and finally disable it.
1117 */
1118 uchan = trace_ust_find_channel_by_name(usess->domain_global.channels,
71aecbf8 1119 (char *) ust_channel_name);
be6a6276
DG
1120 if (!uchan) {
1121 ret = LTTNG_ERR_UST_CHAN_NOT_FOUND;
1122 goto error;
1123 }
1124
da6c3a50
DG
1125 ust_event_name = event_get_default_agent_ust_name(agt->domain);
1126 if (!ust_event_name) {
1127 ret = LTTNG_ERR_FATAL;
1128 goto error;
be6a6276
DG
1129 }
1130
1131 /*
b953b8cd
PP
1132 * Agent UST event has its loglevel type forced to
1133 * LTTNG_UST_LOGLEVEL_ALL. The actual loglevel type/value filtering
1134 * happens thanks to an UST filter. The following -1 is actually
1135 * ignored since the type is LTTNG_UST_LOGLEVEL_ALL.
be6a6276 1136 */
ebdb334b
JR
1137 /* TODO: JORAJ FRDESO: hmmm what to do with tracer token here?
1138 */
1139 uevent = trace_ust_find_event(uchan->events, 0, (char *) ust_event_name,
1140 aevent->filter, LTTNG_UST_LOGLEVEL_ALL, -1, NULL, NULL);
022d91ba 1141 /* If the agent event exists, it must be available on the UST side. */
be6a6276
DG
1142 assert(uevent);
1143
88e3c2f5 1144 if (usess->active) {
ebdb334b 1145 ret = ust_app_disable_channel_event_glb(usess, uchan, uevent);
88e3c2f5
JG
1146 if (ret < 0 && ret != -LTTNG_UST_ERR_EXIST) {
1147 ret = LTTNG_ERR_UST_DISABLE_FAIL;
1148 goto error;
1149 }
be6a6276
DG
1150 }
1151
0dcfcf94
DG
1152 /*
1153 * Flag event that it's disabled so the shadow copy on the ust app side
1154 * will disable it if an application shows up.
1155 */
1156 uevent->enabled = 0;
1157
fefd409b 1158 ret = agent_disable_event(aevent, agt->domain);
f20baf8e
DG
1159 if (ret != LTTNG_OK) {
1160 goto error;
1161 }
1162
1163end:
1164 return LTTNG_OK;
1165
1166error:
1167 return ret;
1168}
e261a6cc 1169
44760c20
JR
1170/*
1171 * Disable agent event matching a given trigger.
1172 *
1173 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
1174 */
1175int trigger_agent_disable(
1176 const struct lttng_trigger *trigger, struct agent *agt)
1177{
1178 int ret = LTTNG_OK;
1179 struct agent_event *aevent;
1180
1181 assert(trigger);
1182 assert(agt);
1183
1184 DBG("Event agent disabling for trigger %" PRIu64,
1185 lttng_trigger_get_tracer_token(trigger));
1186
1187 rcu_read_lock();
1188 aevent = agent_find_event_by_trigger(trigger, agt);
1189
1190 if (aevent == NULL) {
1191 DBG2("Event agent NOT found by trigger %" PRIu64,
1192 lttng_trigger_get_tracer_token(trigger));
1193 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
1194 goto end;
1195 }
1196
1197 ret = trigger_agent_disable_one(trigger, agt, aevent);
1198
1199 if (ret != LTTNG_OK) {
1200 goto end;
1201 }
1202
1203end:
1204 rcu_read_unlock();
1205 return ret;
1206}
1207
e261a6cc
PP
1208/*
1209 * Disable all agent events matching a given name for a given UST session.
1210 *
1211 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
1212 */
1213int event_agent_disable(struct ltt_ust_session *usess, struct agent *agt,
df4f5a87 1214 const char *event_name)
e261a6cc
PP
1215{
1216 int ret = LTTNG_OK;
1217 struct agent_event *aevent;
1218 struct lttng_ht_iter iter;
1219 struct lttng_ht_node_str *node;
1220
1221 assert(agt);
1222 assert(usess);
1223 assert(event_name);
1224
1225 DBG("Event agent disabling %s (all loglevels) for session %" PRIu64, event_name, usess->id);
1226
1227 rcu_read_lock();
1228 agent_find_events_by_name(event_name, agt, &iter);
1229 node = lttng_ht_iter_get_node_str(&iter);
1230
1231 if (node == NULL) {
1232 DBG2("Event agent NOT found by name %s", event_name);
1233 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
1234 goto end;
1235 }
1236
1237 do {
1238 aevent = caa_container_of(node, struct agent_event, node);
1239 ret = event_agent_disable_one(usess, agt, aevent);
1240
1241 if (ret != LTTNG_OK) {
1242 goto end;
1243 }
1244
1245 /* Get next duplicate agent event by name. */
1246 agent_event_next_duplicate(event_name, agt, &iter);
1247 node = lttng_ht_iter_get_node_str(&iter);
1248 } while (node);
1249end:
1250 rcu_read_unlock();
1251 return ret;
1252}
f20baf8e 1253/*
022d91ba 1254 * Disable all agent event for a given UST session.
f20baf8e
DG
1255 *
1256 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
1257 */
fefd409b
DG
1258int event_agent_disable_all(struct ltt_ust_session *usess,
1259 struct agent *agt)
f20baf8e 1260{
0dcfcf94 1261 int ret;
fefd409b 1262 struct agent_event *aevent;
f20baf8e
DG
1263 struct lttng_ht_iter iter;
1264
fefd409b 1265 assert(agt);
f20baf8e
DG
1266 assert(usess);
1267
0dcfcf94
DG
1268 /*
1269 * Disable event on agent application. Continue to disable all other events
1270 * if the * event is not found.
1271 */
fefd409b 1272 ret = event_agent_disable(usess, agt, "*");
0dcfcf94
DG
1273 if (ret != LTTNG_OK && ret != LTTNG_ERR_UST_EVENT_NOT_FOUND) {
1274 goto error;
f20baf8e
DG
1275 }
1276
b9866e08 1277 /* Disable every event. */
f20baf8e 1278 rcu_read_lock();
fefd409b 1279 cds_lfht_for_each_entry(agt->events->ht, &iter.iter, aevent,
f20baf8e 1280 node.node) {
44760c20 1281 if (!AGENT_EVENT_IS_ENABLED(aevent)) {
0dcfcf94
DG
1282 continue;
1283 }
1284
1285 ret = event_agent_disable(usess, agt, aevent->name);
1286 if (ret != LTTNG_OK) {
b9866e08 1287 goto error_unlock;
f20baf8e 1288 }
f20baf8e 1289 }
f20baf8e
DG
1290 ret = LTTNG_OK;
1291
b9866e08
JG
1292error_unlock:
1293 rcu_read_unlock();
f20baf8e
DG
1294error:
1295 return ret;
1296}
This page took 0.147106 seconds and 5 git commands to generate.