SoW-2020-0002: Trace Hit Counters: trigger error reporting integration
[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
d87bfb32 10#include <errno.h>
54d01ffb 11#include <urcu/list.h>
2bdd86d4 12#include <string.h>
54d01ffb
DG
13
14#include <lttng/lttng.h>
2463b787
JR
15#include <lttng/condition/condition.h>
16#include <lttng/condition/event-rule.h>
17#include <lttng/event-rule/event-rule.h>
18#include <lttng/event-rule/event-rule-internal.h>
19#include <common/bytecode/bytecode.h>
db758600 20#include <common/error.h>
10a8a223 21#include <common/sessiond-comm/sessiond-comm.h>
71a559f8
JG
22#include <common/filter.h>
23#include <common/context.h>
54d01ffb
DG
24
25#include "channel.h"
26#include "event.h"
4771f025 27#include "kernel.h"
be6a6276 28#include "lttng-sessiond.h"
75018ab6
JG
29#include "lttng-ust-ctl.h"
30#include "lttng-ust-error.h"
edb67388
DG
31#include "ust-app.h"
32#include "trace-kernel.h"
33#include "trace-ust.h"
7c1d2758 34#include "agent.h"
2463b787 35#include "utils.h"
54d01ffb 36
025faf73
DG
37/*
38 * Add unique UST event based on the event name, filter bytecode and loglevel.
39 */
18eace3b
DG
40static void add_unique_ust_event(struct lttng_ht *ht,
41 struct ltt_ust_event *event)
42{
43 struct cds_lfht_node *node_ptr;
44 struct ltt_ust_ht_key key;
45
46 assert(ht);
47 assert(ht->ht);
48 assert(event);
49
50 key.name = event->attr.name;
2463b787 51 key.filter = (struct lttng_bytecode *) event->filter;
b953b8cd
PP
52 key.loglevel_type = event->attr.loglevel_type;
53 key.loglevel_value = event->attr.loglevel;
4031e53e 54 key.exclusion = event->exclusion;
18eace3b
DG
55
56 node_ptr = cds_lfht_add_unique(ht->ht,
57 ht->hash_fct(event->node.key, lttng_ht_seed),
58 trace_ust_ht_match_event, &key, &event->node.node);
59 assert(node_ptr == &event->node.node);
60}
61
54d01ffb 62/*
9550ee81
JR
63 * Disable kernel tracepoint events for a channel from the kernel session of
64 * a specified event_name and event type.
65 * On type LTTNG_EVENT_ALL all events with event_name are disabled.
66 * If event_name is NULL all events of the specified type are disabled.
54d01ffb 67 */
d0ae4ea8 68int event_kernel_disable_event(struct ltt_kernel_channel *kchan,
df4f5a87 69 const char *event_name, enum lttng_event_type type)
54d01ffb 70{
9550ee81 71 int ret, error = 0, found = 0;
54d01ffb
DG
72 struct ltt_kernel_event *kevent;
73
0525e9ae
DG
74 assert(kchan);
75
54d01ffb
DG
76 /* For each event in the kernel session */
77 cds_list_for_each_entry(kevent, &kchan->events_list.head, list) {
d0ae4ea8
MD
78 if (type != LTTNG_EVENT_ALL && kevent->type != type)
79 continue;
9550ee81
JR
80 if (event_name != NULL && strcmp(event_name, kevent->event->name)) {
81 continue;
82 }
83 found++;
54d01ffb
DG
84 ret = kernel_disable_event(kevent);
85 if (ret < 0) {
9550ee81 86 error = 1;
54d01ffb
DG
87 continue;
88 }
89 }
9550ee81
JR
90 DBG("Disable kernel event: found %d events with name: %s and type: %d",
91 found, event_name ? event_name : "NULL", type);
7a3d1328 92
9550ee81
JR
93 if (event_name != NULL && !found) {
94 ret = LTTNG_ERR_NO_EVENT;
95 } else {
96 ret = error ? LTTNG_ERR_KERN_DISABLE_FAIL : LTTNG_OK;
97 }
98
99 return ret;
54d01ffb
DG
100}
101
102/*
7a3d1328 103 * Enable kernel tracepoint event for a channel from the kernel session.
49d21f93 104 * We own filter_expression and filter.
54d01ffb 105 */
d0ae4ea8 106int event_kernel_enable_event(struct ltt_kernel_channel *kchan,
00a62084 107 struct lttng_event *event, char *filter_expression,
2463b787 108 struct lttng_bytecode *filter)
54d01ffb
DG
109{
110 int ret;
111 struct ltt_kernel_event *kevent;
112
0525e9ae
DG
113 assert(kchan);
114 assert(event);
115
00a62084
MD
116 kevent = trace_kernel_find_event(event->name, kchan,
117 event->type, filter);
54d01ffb 118 if (kevent == NULL) {
71a3bb01 119 ret = kernel_create_event(event, kchan, filter_expression, filter);
a969e101
MD
120 /* We have passed ownership */
121 filter_expression = NULL;
122 filter = NULL;
71a3bb01 123 if (ret) {
7a3d1328 124 goto end;
54d01ffb
DG
125 }
126 } else if (kevent->enabled == 0) {
127 ret = kernel_enable_event(kevent);
128 if (ret < 0) {
f73fabfd 129 ret = LTTNG_ERR_KERN_ENABLE_FAIL;
7a3d1328 130 goto end;
54d01ffb 131 }
42224349
DG
132 } else {
133 /* At this point, the event is considered enabled */
f73fabfd 134 ret = LTTNG_ERR_KERN_EVENT_EXIST;
42224349 135 goto end;
54d01ffb 136 }
42224349 137
f73fabfd 138 ret = LTTNG_OK;
7a3d1328 139end:
a969e101
MD
140 free(filter_expression);
141 free(filter);
54d01ffb
DG
142 return ret;
143}
144
7f79d3a1
DG
145/*
146 * ============================
147 * UST : The Ultimate Frontier!
148 * ============================
149 */
150
2bdd86d4
MD
151/*
152 * Enable UST tracepoint event for a channel from a UST session.
49d21f93 153 * We own filter_expression, filter, and exclusion.
2bdd86d4 154 */
7972aab2 155int event_ust_enable_tracepoint(struct ltt_ust_session *usess,
025faf73 156 struct ltt_ust_channel *uchan, struct lttng_event *event,
6b453b5e 157 char *filter_expression,
2463b787 158 struct lttng_bytecode *filter,
88f06f15
JG
159 struct lttng_event_exclusion *exclusion,
160 bool internal_event)
2bdd86d4 161{
88e3c2f5 162 int ret = LTTNG_OK, to_create = 0;
edb67388
DG
163 struct ltt_ust_event *uevent;
164
0525e9ae
DG
165 assert(usess);
166 assert(uchan);
167 assert(event);
168
18eace3b
DG
169 rcu_read_lock();
170
025faf73 171 uevent = trace_ust_find_event(uchan->events, event->name, filter,
abda88ad
JG
172 (enum lttng_ust_loglevel_type) event->loglevel_type,
173 event->loglevel, exclusion);
87c6e328 174 if (!uevent) {
39687410
FD
175 ret = trace_ust_create_event(event, filter_expression,
176 filter, exclusion, internal_event, &uevent);
49d21f93
MD
177 /* We have passed ownership */
178 filter_expression = NULL;
179 filter = NULL;
180 exclusion = NULL;
39687410 181 if (ret != LTTNG_OK) {
edb67388
DG
182 goto error;
183 }
025faf73 184
fc34caaa 185 /* Valid to set it after the goto error since uevent is still NULL */
edb67388
DG
186 to_create = 1;
187 }
2bdd86d4 188
7f79d3a1
DG
189 if (uevent->enabled) {
190 /* It's already enabled so everything is OK */
0359fdbc 191 assert(!to_create);
5bcdda4f 192 ret = LTTNG_ERR_UST_EVENT_ENABLED;
7f79d3a1
DG
193 goto end;
194 }
195
fc34caaa 196 uevent->enabled = 1;
88e3c2f5
JG
197 if (to_create) {
198 /* Add ltt ust event to channel */
199 add_unique_ust_event(uchan->events, uevent);
200 }
201
202 if (!usess->active) {
203 goto end;
204 }
fc34caaa 205
7972aab2
DG
206 if (to_create) {
207 /* Create event on all UST registered apps for session */
208 ret = ust_app_create_event_glb(usess, uchan, uevent);
209 } else {
210 /* Enable event on all UST registered apps for session */
211 ret = ust_app_enable_event_glb(usess, uchan, uevent);
212 }
48842b30 213
7972aab2
DG
214 if (ret < 0) {
215 if (ret == -LTTNG_UST_ERR_EXIST) {
216 ret = LTTNG_ERR_UST_EVENT_EXIST;
217 goto end;
218 } else {
219 ret = LTTNG_ERR_UST_ENABLE_FAIL;
220 goto error;
edb67388 221 }
2bdd86d4 222 }
48842b30 223
7f79d3a1
DG
224 DBG("Event UST %s %s in channel %s", uevent->attr.name,
225 to_create ? "created" : "enabled", uchan->name);
226
f73fabfd 227 ret = LTTNG_OK;
fc34caaa 228
fb89d070 229end:
18eace3b 230 rcu_read_unlock();
49d21f93
MD
231 free(filter_expression);
232 free(filter);
233 free(exclusion);
fc34caaa 234 return ret;
edb67388
DG
235
236error:
fc34caaa
DG
237 /*
238 * Only destroy event on creation time (not enabling time) because if the
239 * event is found in the channel (to_create == 0), it means that at some
240 * point the enable_event worked and it's thus valid to keep it alive.
241 * Destroying it also implies that we also destroy it's shadow copy to sync
242 * everyone up.
243 */
244 if (to_create) {
245 /* In this code path, the uevent was not added to the hash table */
246 trace_ust_destroy_event(uevent);
247 }
18eace3b 248 rcu_read_unlock();
49d21f93
MD
249 free(filter_expression);
250 free(filter);
251 free(exclusion);
2bdd86d4
MD
252 return ret;
253}
254
7f79d3a1
DG
255/*
256 * Disable UST tracepoint of a channel from a UST session.
257 */
7972aab2 258int event_ust_disable_tracepoint(struct ltt_ust_session *usess,
df4f5a87 259 struct ltt_ust_channel *uchan, const char *event_name)
2bdd86d4
MD
260{
261 int ret;
7f79d3a1 262 struct ltt_ust_event *uevent;
18eace3b
DG
263 struct lttng_ht_node_str *node;
264 struct lttng_ht_iter iter;
18eace3b 265 struct lttng_ht *ht;
2bdd86d4 266
0525e9ae
DG
267 assert(usess);
268 assert(uchan);
269 assert(event_name);
270
18eace3b
DG
271 ht = uchan->events;
272
18eace3b 273 rcu_read_lock();
025faf73
DG
274
275 /*
276 * We use a custom lookup since we need the iterator for the next_duplicate
277 * call in the do while loop below.
278 */
279 cds_lfht_lookup(ht->ht, ht->hash_fct((void *) event_name, lttng_ht_seed),
280 trace_ust_ht_match_event_by_name, event_name, &iter.iter);
18eace3b
DG
281 node = lttng_ht_iter_get_node_str(&iter);
282 if (node == NULL) {
283 DBG2("Trace UST event NOT found by name %s", event_name);
f73fabfd 284 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
7f79d3a1 285 goto error;
2bdd86d4 286 }
7f79d3a1 287
18eace3b
DG
288 do {
289 uevent = caa_container_of(node, struct ltt_ust_event, node);
025faf73
DG
290 assert(uevent);
291
18eace3b
DG
292 if (uevent->enabled == 0) {
293 /* It's already disabled so everything is OK */
a1dcaf0f 294 goto next;
7f79d3a1 295 }
88e3c2f5
JG
296 uevent->enabled = 0;
297 DBG2("Event UST %s disabled in channel %s", uevent->attr.name,
298 uchan->name);
18eace3b 299
88e3c2f5
JG
300 if (!usess->active) {
301 goto next;
302 }
7972aab2
DG
303 ret = ust_app_disable_event_glb(usess, uchan, uevent);
304 if (ret < 0 && ret != -LTTNG_UST_ERR_EXIST) {
305 ret = LTTNG_ERR_UST_DISABLE_FAIL;
18eace3b
DG
306 goto error;
307 }
a1dcaf0f 308next:
18eace3b
DG
309 /* Get next duplicate event by name. */
310 cds_lfht_next_duplicate(ht->ht, trace_ust_ht_match_event_by_name,
311 event_name, &iter.iter);
312 node = lttng_ht_iter_get_node_str(&iter);
313 } while (node);
7f79d3a1 314
f73fabfd 315 ret = LTTNG_OK;
7f79d3a1 316
7f79d3a1 317error:
18eace3b 318 rcu_read_unlock();
7f79d3a1
DG
319 return ret;
320}
321
b1e7fe2d
JR
322/*
323 * Disable all UST tracepoints for a channel from a UST session.
324 */
325int event_ust_disable_all_tracepoints(struct ltt_ust_session *usess,
326 struct ltt_ust_channel *uchan)
327{
3e81c0f2 328 int ret, i, size, error = 0;
b1e7fe2d
JR
329 struct lttng_ht_iter iter;
330 struct ltt_ust_event *uevent = NULL;
331 struct lttng_event *events = NULL;
332
333 assert(usess);
334 assert(uchan);
335
336 rcu_read_lock();
337
338 /* Disabling existing events */
339 cds_lfht_for_each_entry(uchan->events->ht, &iter.iter, uevent,
340 node.node) {
341 if (uevent->enabled == 1) {
342 ret = event_ust_disable_tracepoint(usess, uchan,
343 uevent->attr.name);
344 if (ret < 0) {
3e81c0f2 345 error = LTTNG_ERR_UST_DISABLE_FAIL;
b1e7fe2d
JR
346 continue;
347 }
348 }
349 }
350
351 /* Get all UST available events */
352 size = ust_app_list_events(&events);
353 if (size < 0) {
354 ret = LTTNG_ERR_UST_LIST_FAIL;
355 goto error;
356 }
357
358 for (i = 0; i < size; i++) {
359 ret = event_ust_disable_tracepoint(usess, uchan,
360 events[i].name);
3e81c0f2 361 if (ret < 0) {
b1e7fe2d 362 /* Continue to disable the rest... */
3e81c0f2 363 error = LTTNG_ERR_UST_DISABLE_FAIL;
b1e7fe2d
JR
364 continue;
365 }
366 }
367
3e81c0f2 368 ret = error ? error : LTTNG_OK;
b1e7fe2d
JR
369error:
370 rcu_read_unlock();
371 free(events);
372 return ret;
373}
374
2463b787
JR
375static void agent_enable_all(struct agent *agt)
376{
377 struct agent_event *aevent;
378 struct lttng_ht_iter iter;
379
380 /* Flag every event that they are now enabled. */
381 rcu_read_lock();
382 cds_lfht_for_each_entry (
383 agt->events->ht, &iter.iter, aevent, node.node) {
384 aevent->enabled = 1;
385 }
386 rcu_read_unlock();
387}
388
f20baf8e 389/*
022d91ba 390 * Enable all agent event for a given UST session.
f20baf8e
DG
391 *
392 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
393 */
022d91ba 394int event_agent_enable_all(struct ltt_ust_session *usess,
fefd409b 395 struct agent *agt, struct lttng_event *event,
2463b787 396 struct lttng_bytecode *filter ,char *filter_expression)
f20baf8e
DG
397{
398 int ret;
f20baf8e
DG
399
400 assert(usess);
401
022d91ba 402 DBG("Event agent enabling ALL events for session %" PRIu64, usess->id);
f20baf8e 403
022d91ba 404 /* Enable event on agent application through TCP socket. */
8404118c 405 ret = event_agent_enable(usess, agt, event, filter, filter_expression);
f20baf8e
DG
406 if (ret != LTTNG_OK) {
407 goto error;
408 }
409
2463b787 410 agent_enable_all(agt);
f20baf8e
DG
411
412 ret = LTTNG_OK;
413
414error:
415 return ret;
416}
417
71a559f8
JG
418/*
419 * Check if this event's filter requires the activation of application contexts
420 * and enable them in the agent.
b4bc01f7
MD
421 * TODO: bytecode iterator does not support non-legacy application
422 * contexts yet. Not an issue for now, since they are not generated by
423 * the lttng-ctl library.
71a559f8 424 */
2463b787 425static int add_filter_app_ctx(struct lttng_bytecode *bytecode,
71a559f8
JG
426 const char *filter_expression, struct agent *agt)
427{
428 int ret = LTTNG_OK;
429 char *provider_name = NULL, *ctx_name = NULL;
430 struct bytecode_symbol_iterator *it =
431 bytecode_symbol_iterator_create(bytecode);
432
433 if (!it) {
434 ret = LTTNG_ERR_NOMEM;
435 goto end;
436 }
437
438 do {
439 struct lttng_event_context ctx;
440 const char *symbol_name =
441 bytecode_symbol_iterator_get_name(it);
442
443 if (parse_application_context(symbol_name, &provider_name,
444 &ctx_name)) {
445 /* Not an application context. */
446 continue;
447 }
448
449 ctx.ctx = LTTNG_EVENT_CONTEXT_APP_CONTEXT;
450 ctx.u.app_ctx.provider_name = provider_name;
451 ctx.u.app_ctx.ctx_name = ctx_name;
452
453 /* Recognized an application context. */
454 DBG("Enabling event with filter expression \"%s\" requires enabling the %s:%s application context.",
455 filter_expression, provider_name, ctx_name);
456
457 ret = agent_add_context(&ctx, agt);
458 if (ret != LTTNG_OK) {
459 ERR("Failed to add application context %s:%s.",
460 provider_name, ctx_name);
461 goto end;
462 }
463
464 ret = agent_enable_context(&ctx, agt->domain);
465 if (ret != LTTNG_OK) {
466 ERR("Failed to enable application context %s:%s.",
467 provider_name, ctx_name);
468 goto end;
469 }
470
471 free(provider_name);
472 free(ctx_name);
473 provider_name = ctx_name = NULL;
474 } while (bytecode_symbol_iterator_next(it) == 0);
475end:
476 free(provider_name);
477 free(ctx_name);
478 bytecode_symbol_iterator_destroy(it);
479 return ret;
480}
481
2463b787
JR
482static int agent_enable(struct agent *agt,
483 struct lttng_event *event,
484 struct lttng_bytecode *filter,
8404118c 485 char *filter_expression)
f20baf8e
DG
486{
487 int ret, created = 0;
fefd409b 488 struct agent_event *aevent;
f20baf8e 489
f20baf8e 490 assert(event);
fefd409b 491 assert(agt);
f20baf8e 492
a9319624 493 aevent = agent_find_event(event->name, event->loglevel_type,
71a559f8 494 event->loglevel, filter_expression, agt);
fefd409b 495 if (!aevent) {
a9319624
PP
496 aevent = agent_create_event(event->name, event->loglevel_type,
497 event->loglevel, filter,
51755dc8 498 filter_expression);
fefd409b 499 if (!aevent) {
f20baf8e
DG
500 ret = LTTNG_ERR_NOMEM;
501 goto error;
502 }
b0a23296
JG
503 filter = NULL;
504 filter_expression = NULL;
f20baf8e 505 created = 1;
6fe2a7d0 506 assert(!aevent->enabled);
f20baf8e
DG
507 }
508
bf7886d8
JR
509 if (created && aevent->filter) {
510 ret = add_filter_app_ctx(
511 aevent->filter, aevent->filter_expression, agt);
71a559f8
JG
512 if (ret != LTTNG_OK) {
513 goto error;
514 }
515 }
516
88e3c2f5
JG
517 /* Already enabled? */
518 if (aevent->enabled) {
519 ret = LTTNG_OK;
520 goto end;
521 }
522
fefd409b 523 ret = agent_enable_event(aevent, agt->domain);
f20baf8e
DG
524 if (ret != LTTNG_OK) {
525 goto error;
526 }
527
528 /* If the event was created prior to the enable, add it to the domain. */
529 if (created) {
fefd409b 530 agent_add_event(aevent, agt);
f20baf8e
DG
531 }
532
b0a23296
JG
533 ret = LTTNG_OK;
534 goto end;
f20baf8e
DG
535
536error:
537 if (created) {
fefd409b 538 agent_destroy_event(aevent);
f20baf8e 539 }
b0a23296
JG
540end:
541 free(filter);
542 free(filter_expression);
f20baf8e
DG
543 return ret;
544}
545
2463b787
JR
546/*
547 * Enable a single agent event for a given UST session.
548 *
549 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
550 */
551int event_agent_enable(struct ltt_ust_session *usess,
552 struct agent *agt,
553 struct lttng_event *event,
554 struct lttng_bytecode *filter,
555 char *filter_expression)
556{
557 assert(usess);
558 assert(event);
559 assert(agt);
560
561 DBG("Event agent enabling %s for session %" PRIu64
562 " with loglevel type %d "
563 ", loglevel %d and filter \"%s\"",
564 event->name, usess->id, event->loglevel_type,
565 event->loglevel,
566 filter_expression ? filter_expression : "NULL");
567
568 return agent_enable(agt, event, filter, filter_expression);
569}
570
571/*
572 * Enable a single agent event for a trigger.
573 *
574 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
575 */
576int trigger_agent_enable(const struct lttng_trigger *trigger, struct agent *agt)
577{
578 int ret;
579 enum lttng_condition_status c_status;
580 enum lttng_domain_type d_type;
581 const struct lttng_condition *condition;
582 const struct lttng_event_rule *rule;
583 const char *filter_expression;
584 char *filter_expression_copy = NULL;
585 const struct lttng_bytecode *filter_bytecode;
586 struct lttng_bytecode *filter_bytecode_copy = NULL;
587 struct lttng_event *event = NULL;
588
589 assert(trigger);
590 assert(agt);
591
592 condition = lttng_trigger_get_const_condition(trigger);
593
594 assert(lttng_condition_get_type(condition) ==
595 LTTNG_CONDITION_TYPE_EVENT_RULE_HIT);
596
597 c_status = lttng_condition_event_rule_get_rule(condition, &rule);
598 assert(c_status == LTTNG_CONDITION_STATUS_OK);
599
600 assert(lttng_event_rule_get_type(rule) ==
601 LTTNG_EVENT_RULE_TYPE_TRACEPOINT);
602
603 d_type = lttng_event_rule_get_domain_type(rule);
604 assert(d_type == agt->domain);
605
606 event = lttng_event_rule_generate_lttng_event(rule);
607 if (!event) {
608 ret = LTTNG_ERR_NOMEM;
609 goto end;
610 }
611
612 /* Get the internal filter_expression and bytecode */
613 filter_expression = lttng_event_rule_get_filter(rule);
614 if (filter_expression) {
615 filter_expression_copy = strdup(filter_expression);
616 if (!filter_expression_copy) {
617 ret = LTTNG_ERR_NOMEM;
618 goto end;
619 }
620
621 /* Get the filter bytecode */
622 filter_bytecode = lttng_event_rule_get_filter_bytecode(rule);
623 if (filter_bytecode) {
624 filter_bytecode_copy = bytecode_copy (filter_bytecode);
625 if (!filter_bytecode_copy) {
626 ret = LTTNG_ERR_NOMEM;
627 goto end;
628 }
629 }
630 }
631
632 DBG("Event agent enabling %s for trigger %" PRIu64
633 " with loglevel type %d "
634 ", loglevel %d and filter \"%s\"",
635 event->name, lttng_trigger_get_tracer_token(trigger),
636 event->loglevel_type, event->loglevel,
637 filter_expression ? filter_expression : "NULL");
638
639 ret = agent_enable(agt, event, filter_bytecode_copy,
640 filter_expression_copy);
641 /* Ownership was passed even in case of error */
642 filter_expression_copy = NULL;
643 filter_bytecode_copy = NULL;
644
645end:
646 free(filter_expression_copy);
647 free(filter_bytecode_copy);
648 free(event);
649 return ret;
650}
651
da6c3a50 652/*
d1ec8e20
JG
653 * Return the default event name associated with the provided UST domain. Return
654 * NULL on error.
da6c3a50
DG
655 */
656const char *event_get_default_agent_ust_name(enum lttng_domain_type domain)
657{
658 const char *default_event_name = NULL;
659
0e115563
DG
660 switch (domain) {
661 case LTTNG_DOMAIN_LOG4J:
d1ec8e20 662 default_event_name = DEFAULT_LOG4J_EVENT_NAME;
0e115563
DG
663 break;
664 case LTTNG_DOMAIN_JUL:
d1ec8e20 665 default_event_name = DEFAULT_JUL_EVENT_NAME;
0e115563
DG
666 break;
667 case LTTNG_DOMAIN_PYTHON:
e7c82272 668 default_event_name = DEFAULT_PYTHON_EVENT_NAME;
0e115563
DG
669 break;
670 default:
da6c3a50
DG
671 assert(0);
672 }
673
674 return default_event_name;
675}
676
2463b787
JR
677static int trigger_agent_disable_one(const struct lttng_trigger *trigger,
678 struct agent *agt,
679 struct agent_event *aevent)
680
681{
682 int ret;
683
684 assert(agt);
685 assert(trigger);
686 assert(aevent);
687
688 /*
689 * Actual ust event un-registration happens on the trigger
690 * un-registration at that point.
691 */
692
693 DBG("Event agent disabling %s (loglevel type %d, loglevel value %d) for trigger %" PRIu64,
694 aevent->name, aevent->loglevel_type,
695 aevent->loglevel_value, lttng_trigger_get_tracer_token(trigger));
696
697 /* Already disabled? */
698 if (!aevent->enabled) {
699 goto end;
700 }
701
702 ret = agent_disable_event(aevent, agt->domain);
703 if (ret != LTTNG_OK) {
704 goto error;
705 }
706
707end:
708 return LTTNG_OK;
709
710error:
711 return ret;
712}
713
f20baf8e 714/*
e261a6cc 715 * Disable a given agent event for a given UST session.
f20baf8e 716 *
e261a6cc 717 * Must be called with the RCU read lock held.
f20baf8e
DG
718 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
719 */
e261a6cc
PP
720static int event_agent_disable_one(struct ltt_ust_session *usess,
721 struct agent *agt, struct agent_event *aevent)
f20baf8e
DG
722{
723 int ret;
be6a6276
DG
724 struct ltt_ust_event *uevent = NULL;
725 struct ltt_ust_channel *uchan = NULL;
71aecbf8 726 const char *ust_event_name, *ust_channel_name;
f20baf8e 727
fefd409b 728 assert(agt);
f20baf8e 729 assert(usess);
e261a6cc 730 assert(aevent);
f20baf8e 731
e261a6cc
PP
732 DBG("Event agent disabling %s (loglevel type %d, loglevel value %d) for session %" PRIu64,
733 aevent->name, aevent->loglevel_type, aevent->loglevel_value,
734 usess->id);
f20baf8e
DG
735
736 /* Already disabled? */
fefd409b 737 if (!aevent->enabled) {
f20baf8e
DG
738 goto end;
739 }
740
71aecbf8
DG
741 if (agt->domain == LTTNG_DOMAIN_JUL) {
742 ust_channel_name = DEFAULT_JUL_CHANNEL_NAME;
743 } else if (agt->domain == LTTNG_DOMAIN_LOG4J) {
744 ust_channel_name = DEFAULT_LOG4J_CHANNEL_NAME;
0e115563
DG
745 } else if (agt->domain == LTTNG_DOMAIN_PYTHON) {
746 ust_channel_name = DEFAULT_PYTHON_CHANNEL_NAME;
71aecbf8
DG
747 } else {
748 ret = LTTNG_ERR_INVALID;
749 goto error;
750 }
751
be6a6276
DG
752 /*
753 * Disable it on the UST side. First get the channel reference then find
754 * the event and finally disable it.
755 */
756 uchan = trace_ust_find_channel_by_name(usess->domain_global.channels,
71aecbf8 757 (char *) ust_channel_name);
be6a6276
DG
758 if (!uchan) {
759 ret = LTTNG_ERR_UST_CHAN_NOT_FOUND;
760 goto error;
761 }
762
da6c3a50
DG
763 ust_event_name = event_get_default_agent_ust_name(agt->domain);
764 if (!ust_event_name) {
765 ret = LTTNG_ERR_FATAL;
766 goto error;
be6a6276
DG
767 }
768
769 /*
b953b8cd
PP
770 * Agent UST event has its loglevel type forced to
771 * LTTNG_UST_LOGLEVEL_ALL. The actual loglevel type/value filtering
772 * happens thanks to an UST filter. The following -1 is actually
773 * ignored since the type is LTTNG_UST_LOGLEVEL_ALL.
be6a6276 774 */
da6c3a50 775 uevent = trace_ust_find_event(uchan->events, (char *) ust_event_name,
b953b8cd 776 aevent->filter, LTTNG_UST_LOGLEVEL_ALL, -1, NULL);
022d91ba 777 /* If the agent event exists, it must be available on the UST side. */
be6a6276
DG
778 assert(uevent);
779
88e3c2f5
JG
780 if (usess->active) {
781 ret = ust_app_disable_event_glb(usess, uchan, uevent);
782 if (ret < 0 && ret != -LTTNG_UST_ERR_EXIST) {
783 ret = LTTNG_ERR_UST_DISABLE_FAIL;
784 goto error;
785 }
be6a6276
DG
786 }
787
0dcfcf94
DG
788 /*
789 * Flag event that it's disabled so the shadow copy on the ust app side
790 * will disable it if an application shows up.
791 */
792 uevent->enabled = 0;
793
fefd409b 794 ret = agent_disable_event(aevent, agt->domain);
f20baf8e
DG
795 if (ret != LTTNG_OK) {
796 goto error;
797 }
798
799end:
800 return LTTNG_OK;
801
802error:
803 return ret;
804}
e261a6cc 805
2463b787
JR
806/*
807 * Disable agent event matching a given trigger.
808 *
809 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
810 */
811int trigger_agent_disable(
812 const struct lttng_trigger *trigger, struct agent *agt)
813{
814 int ret = LTTNG_OK;
815 struct agent_event *aevent;
816
817 assert(trigger);
818 assert(agt);
819
820 DBG("Event agent disabling for trigger %" PRIu64,
821 lttng_trigger_get_tracer_token(trigger));
822
823 rcu_read_lock();
824 aevent = agent_find_event_by_trigger(trigger, agt);
825
826 if (aevent == NULL) {
827 DBG2("Event agent NOT found by trigger %" PRIu64,
828 lttng_trigger_get_tracer_token(trigger));
829 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
830 goto end;
831 }
832
833 ret = trigger_agent_disable_one(trigger, agt, aevent);
834
835 if (ret != LTTNG_OK) {
836 goto end;
837 }
838
839end:
840 rcu_read_unlock();
841 return ret;
842}
843
e261a6cc
PP
844/*
845 * Disable all agent events matching a given name for a given UST session.
846 *
847 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
848 */
849int event_agent_disable(struct ltt_ust_session *usess, struct agent *agt,
df4f5a87 850 const char *event_name)
e261a6cc
PP
851{
852 int ret = LTTNG_OK;
853 struct agent_event *aevent;
854 struct lttng_ht_iter iter;
855 struct lttng_ht_node_str *node;
856
857 assert(agt);
858 assert(usess);
859 assert(event_name);
860
861 DBG("Event agent disabling %s (all loglevels) for session %" PRIu64, event_name, usess->id);
862
863 rcu_read_lock();
864 agent_find_events_by_name(event_name, agt, &iter);
865 node = lttng_ht_iter_get_node_str(&iter);
866
867 if (node == NULL) {
868 DBG2("Event agent NOT found by name %s", event_name);
869 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
870 goto end;
871 }
872
873 do {
874 aevent = caa_container_of(node, struct agent_event, node);
875 ret = event_agent_disable_one(usess, agt, aevent);
876
877 if (ret != LTTNG_OK) {
878 goto end;
879 }
880
881 /* Get next duplicate agent event by name. */
882 agent_event_next_duplicate(event_name, agt, &iter);
883 node = lttng_ht_iter_get_node_str(&iter);
884 } while (node);
885end:
886 rcu_read_unlock();
887 return ret;
888}
f20baf8e 889/*
022d91ba 890 * Disable all agent event for a given UST session.
f20baf8e
DG
891 *
892 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
893 */
fefd409b
DG
894int event_agent_disable_all(struct ltt_ust_session *usess,
895 struct agent *agt)
f20baf8e 896{
0dcfcf94 897 int ret;
fefd409b 898 struct agent_event *aevent;
f20baf8e
DG
899 struct lttng_ht_iter iter;
900
fefd409b 901 assert(agt);
f20baf8e
DG
902 assert(usess);
903
0dcfcf94
DG
904 /*
905 * Disable event on agent application. Continue to disable all other events
906 * if the * event is not found.
907 */
fefd409b 908 ret = event_agent_disable(usess, agt, "*");
0dcfcf94
DG
909 if (ret != LTTNG_OK && ret != LTTNG_ERR_UST_EVENT_NOT_FOUND) {
910 goto error;
f20baf8e
DG
911 }
912
b9866e08 913 /* Disable every event. */
f20baf8e 914 rcu_read_lock();
fefd409b 915 cds_lfht_for_each_entry(agt->events->ht, &iter.iter, aevent,
f20baf8e 916 node.node) {
0dcfcf94
DG
917 if (!aevent->enabled) {
918 continue;
919 }
920
921 ret = event_agent_disable(usess, agt, aevent->name);
922 if (ret != LTTNG_OK) {
b9866e08 923 goto error_unlock;
f20baf8e 924 }
f20baf8e 925 }
f20baf8e
DG
926 ret = LTTNG_OK;
927
b9866e08
JG
928error_unlock:
929 rcu_read_unlock();
f20baf8e
DG
930error:
931 return ret;
932}
This page took 0.19762 seconds and 5 git commands to generate.