configure: add '-Wundef' to warning flags
[lttng-tools.git] / src / bin / lttng-sessiond / event.cpp
CommitLineData
54d01ffb 1/*
21cf9b6b 2 * Copyright (C) 2011 EfficiOS Inc.
ab5be9fa 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>
670a26e4 16#include <lttng/condition/event-rule-matches.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
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"
44760c20 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
a0377dfe
FD
46 LTTNG_ASSERT(ht);
47 LTTNG_ASSERT(ht->ht);
48 LTTNG_ASSERT(event);
18eace3b
DG
49
50 key.name = event->attr.name;
2b00d462 51 key.filter = (struct lttng_bytecode *) event->filter;
7966af57 52 key.loglevel_type = (lttng_ust_abi_loglevel_type) event->attr.loglevel_type;
b953b8cd 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);
a0377dfe 59 LTTNG_ASSERT(node_ptr == &event->node.node);
18eace3b
DG
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
a0377dfe 74 LTTNG_ASSERT(kchan);
0525e9ae 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,
2b00d462 108 struct lttng_bytecode *filter)
54d01ffb
DG
109{
110 int ret;
111 struct ltt_kernel_event *kevent;
112
a0377dfe
FD
113 LTTNG_ASSERT(kchan);
114 LTTNG_ASSERT(event);
0525e9ae 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,
2b00d462 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
a0377dfe
FD
165 LTTNG_ASSERT(usess);
166 LTTNG_ASSERT(uchan);
167 LTTNG_ASSERT(event);
0525e9ae 168
18eace3b
DG
169 rcu_read_lock();
170
025faf73 171 uevent = trace_ust_find_event(uchan->events, event->name, filter,
fc4b93fa 172 (enum lttng_ust_abi_loglevel_type) event->loglevel_type,
abda88ad 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) {
3a243403 182 goto end;
edb67388 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 */
a0377dfe 191 LTTNG_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;
7972aab2
DG
217 } else {
218 ret = LTTNG_ERR_UST_ENABLE_FAIL;
edb67388 219 }
3a243403 220 goto end;
2bdd86d4 221 }
48842b30 222
7f79d3a1
DG
223 DBG("Event UST %s %s in channel %s", uevent->attr.name,
224 to_create ? "created" : "enabled", uchan->name);
225
f73fabfd 226 ret = LTTNG_OK;
fc34caaa 227
fb89d070 228end:
18eace3b 229 rcu_read_unlock();
49d21f93
MD
230 free(filter_expression);
231 free(filter);
232 free(exclusion);
fc34caaa 233 return ret;
2bdd86d4
MD
234}
235
7f79d3a1
DG
236/*
237 * Disable UST tracepoint of a channel from a UST session.
238 */
7972aab2 239int event_ust_disable_tracepoint(struct ltt_ust_session *usess,
df4f5a87 240 struct ltt_ust_channel *uchan, const char *event_name)
2bdd86d4
MD
241{
242 int ret;
7f79d3a1 243 struct ltt_ust_event *uevent;
18eace3b
DG
244 struct lttng_ht_node_str *node;
245 struct lttng_ht_iter iter;
18eace3b 246 struct lttng_ht *ht;
2bdd86d4 247
a0377dfe
FD
248 LTTNG_ASSERT(usess);
249 LTTNG_ASSERT(uchan);
250 LTTNG_ASSERT(event_name);
0525e9ae 251
18eace3b
DG
252 ht = uchan->events;
253
18eace3b 254 rcu_read_lock();
025faf73
DG
255
256 /*
257 * We use a custom lookup since we need the iterator for the next_duplicate
258 * call in the do while loop below.
259 */
260 cds_lfht_lookup(ht->ht, ht->hash_fct((void *) event_name, lttng_ht_seed),
261 trace_ust_ht_match_event_by_name, event_name, &iter.iter);
18eace3b
DG
262 node = lttng_ht_iter_get_node_str(&iter);
263 if (node == NULL) {
264 DBG2("Trace UST event NOT found by name %s", event_name);
f73fabfd 265 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
7f79d3a1 266 goto error;
2bdd86d4 267 }
7f79d3a1 268
18eace3b
DG
269 do {
270 uevent = caa_container_of(node, struct ltt_ust_event, node);
a0377dfe 271 LTTNG_ASSERT(uevent);
025faf73 272
18eace3b
DG
273 if (uevent->enabled == 0) {
274 /* It's already disabled so everything is OK */
a1dcaf0f 275 goto next;
7f79d3a1 276 }
88e3c2f5
JG
277 uevent->enabled = 0;
278 DBG2("Event UST %s disabled in channel %s", uevent->attr.name,
279 uchan->name);
18eace3b 280
88e3c2f5
JG
281 if (!usess->active) {
282 goto next;
283 }
7972aab2
DG
284 ret = ust_app_disable_event_glb(usess, uchan, uevent);
285 if (ret < 0 && ret != -LTTNG_UST_ERR_EXIST) {
286 ret = LTTNG_ERR_UST_DISABLE_FAIL;
18eace3b
DG
287 goto error;
288 }
a1dcaf0f 289next:
18eace3b
DG
290 /* Get next duplicate event by name. */
291 cds_lfht_next_duplicate(ht->ht, trace_ust_ht_match_event_by_name,
292 event_name, &iter.iter);
293 node = lttng_ht_iter_get_node_str(&iter);
294 } while (node);
7f79d3a1 295
f73fabfd 296 ret = LTTNG_OK;
7f79d3a1 297
7f79d3a1 298error:
18eace3b 299 rcu_read_unlock();
7f79d3a1
DG
300 return ret;
301}
302
b1e7fe2d
JR
303/*
304 * Disable all UST tracepoints for a channel from a UST session.
305 */
306int event_ust_disable_all_tracepoints(struct ltt_ust_session *usess,
307 struct ltt_ust_channel *uchan)
308{
3e81c0f2 309 int ret, i, size, error = 0;
b1e7fe2d
JR
310 struct lttng_ht_iter iter;
311 struct ltt_ust_event *uevent = NULL;
312 struct lttng_event *events = NULL;
313
a0377dfe
FD
314 LTTNG_ASSERT(usess);
315 LTTNG_ASSERT(uchan);
b1e7fe2d
JR
316
317 rcu_read_lock();
318
319 /* Disabling existing events */
320 cds_lfht_for_each_entry(uchan->events->ht, &iter.iter, uevent,
321 node.node) {
322 if (uevent->enabled == 1) {
323 ret = event_ust_disable_tracepoint(usess, uchan,
324 uevent->attr.name);
325 if (ret < 0) {
3e81c0f2 326 error = LTTNG_ERR_UST_DISABLE_FAIL;
b1e7fe2d
JR
327 continue;
328 }
329 }
330 }
331
332 /* Get all UST available events */
333 size = ust_app_list_events(&events);
334 if (size < 0) {
335 ret = LTTNG_ERR_UST_LIST_FAIL;
336 goto error;
337 }
338
339 for (i = 0; i < size; i++) {
340 ret = event_ust_disable_tracepoint(usess, uchan,
341 events[i].name);
3e81c0f2 342 if (ret < 0) {
b1e7fe2d 343 /* Continue to disable the rest... */
3e81c0f2 344 error = LTTNG_ERR_UST_DISABLE_FAIL;
b1e7fe2d
JR
345 continue;
346 }
347 }
348
3e81c0f2 349 ret = error ? error : LTTNG_OK;
b1e7fe2d
JR
350error:
351 rcu_read_unlock();
352 free(events);
353 return ret;
354}
355
44760c20
JR
356static void agent_enable_all(struct agent *agt)
357{
358 struct agent_event *aevent;
359 struct lttng_ht_iter iter;
360
361 /* Flag every event as enabled. */
362 rcu_read_lock();
363 cds_lfht_for_each_entry (
364 agt->events->ht, &iter.iter, aevent, node.node) {
365 aevent->enabled_count++;
366 }
367 rcu_read_unlock();
368}
369
f20baf8e 370/*
022d91ba 371 * Enable all agent event for a given UST session.
f20baf8e
DG
372 *
373 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
374 */
022d91ba 375int event_agent_enable_all(struct ltt_ust_session *usess,
fefd409b 376 struct agent *agt, struct lttng_event *event,
2b00d462 377 struct lttng_bytecode *filter ,char *filter_expression)
f20baf8e
DG
378{
379 int ret;
f20baf8e 380
a0377dfe 381 LTTNG_ASSERT(usess);
f20baf8e 382
022d91ba 383 DBG("Event agent enabling ALL events for session %" PRIu64, usess->id);
f20baf8e 384
022d91ba 385 /* Enable event on agent application through TCP socket. */
8404118c 386 ret = event_agent_enable(usess, agt, event, filter, filter_expression);
f20baf8e
DG
387 if (ret != LTTNG_OK) {
388 goto error;
389 }
390
44760c20 391 agent_enable_all(agt);
f20baf8e
DG
392
393 ret = LTTNG_OK;
394
395error:
396 return ret;
397}
398
71a559f8
JG
399/*
400 * Check if this event's filter requires the activation of application contexts
401 * and enable them in the agent.
b4bc01f7
MD
402 * TODO: bytecode iterator does not support non-legacy application
403 * contexts yet. Not an issue for now, since they are not generated by
404 * the lttng-ctl library.
71a559f8 405 */
2b00d462 406static int add_filter_app_ctx(struct lttng_bytecode *bytecode,
71a559f8
JG
407 const char *filter_expression, struct agent *agt)
408{
409 int ret = LTTNG_OK;
410 char *provider_name = NULL, *ctx_name = NULL;
411 struct bytecode_symbol_iterator *it =
412 bytecode_symbol_iterator_create(bytecode);
413
414 if (!it) {
415 ret = LTTNG_ERR_NOMEM;
416 goto end;
417 }
418
419 do {
420 struct lttng_event_context ctx;
421 const char *symbol_name =
422 bytecode_symbol_iterator_get_name(it);
423
424 if (parse_application_context(symbol_name, &provider_name,
425 &ctx_name)) {
426 /* Not an application context. */
427 continue;
428 }
429
430 ctx.ctx = LTTNG_EVENT_CONTEXT_APP_CONTEXT;
431 ctx.u.app_ctx.provider_name = provider_name;
432 ctx.u.app_ctx.ctx_name = ctx_name;
433
434 /* Recognized an application context. */
435 DBG("Enabling event with filter expression \"%s\" requires enabling the %s:%s application context.",
436 filter_expression, provider_name, ctx_name);
437
438 ret = agent_add_context(&ctx, agt);
439 if (ret != LTTNG_OK) {
440 ERR("Failed to add application context %s:%s.",
441 provider_name, ctx_name);
442 goto end;
443 }
444
445 ret = agent_enable_context(&ctx, agt->domain);
446 if (ret != LTTNG_OK) {
447 ERR("Failed to enable application context %s:%s.",
448 provider_name, ctx_name);
449 goto end;
450 }
451
452 free(provider_name);
453 free(ctx_name);
454 provider_name = ctx_name = NULL;
455 } while (bytecode_symbol_iterator_next(it) == 0);
456end:
457 free(provider_name);
458 free(ctx_name);
459 bytecode_symbol_iterator_destroy(it);
460 return ret;
461}
462
44760c20
JR
463static int agent_enable(struct agent *agt,
464 struct lttng_event *event,
2b00d462 465 struct lttng_bytecode *filter,
8404118c 466 char *filter_expression)
f20baf8e
DG
467{
468 int ret, created = 0;
fefd409b 469 struct agent_event *aevent;
f20baf8e 470
a0377dfe
FD
471 LTTNG_ASSERT(event);
472 LTTNG_ASSERT(agt);
f20baf8e 473
c9753f72 474 rcu_read_lock();
a9319624 475 aevent = agent_find_event(event->name, event->loglevel_type,
71a559f8 476 event->loglevel, filter_expression, agt);
fefd409b 477 if (!aevent) {
a9319624
PP
478 aevent = agent_create_event(event->name, event->loglevel_type,
479 event->loglevel, filter,
51755dc8 480 filter_expression);
fefd409b 481 if (!aevent) {
f20baf8e
DG
482 ret = LTTNG_ERR_NOMEM;
483 goto error;
484 }
b0a23296
JG
485 filter = NULL;
486 filter_expression = NULL;
f20baf8e 487 created = 1;
a0377dfe 488 LTTNG_ASSERT(!AGENT_EVENT_IS_ENABLED(aevent));
f20baf8e
DG
489 }
490
bf7886d8
JR
491 if (created && aevent->filter) {
492 ret = add_filter_app_ctx(
493 aevent->filter, aevent->filter_expression, agt);
71a559f8
JG
494 if (ret != LTTNG_OK) {
495 goto error;
496 }
497 }
498
88e3c2f5 499 /* Already enabled? */
44760c20 500 if (AGENT_EVENT_IS_ENABLED(aevent)) {
88e3c2f5
JG
501 ret = LTTNG_OK;
502 goto end;
503 }
504
fefd409b 505 ret = agent_enable_event(aevent, agt->domain);
f20baf8e
DG
506 if (ret != LTTNG_OK) {
507 goto error;
508 }
509
510 /* If the event was created prior to the enable, add it to the domain. */
511 if (created) {
fefd409b 512 agent_add_event(aevent, agt);
f20baf8e
DG
513 }
514
b0a23296
JG
515 ret = LTTNG_OK;
516 goto end;
f20baf8e
DG
517
518error:
519 if (created) {
fefd409b 520 agent_destroy_event(aevent);
f20baf8e 521 }
b0a23296 522end:
c9753f72 523 rcu_read_unlock();
b0a23296
JG
524 free(filter);
525 free(filter_expression);
f20baf8e
DG
526 return ret;
527}
528
44760c20
JR
529/*
530 * Enable a single agent event for a given UST session.
531 *
532 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
533 */
534int event_agent_enable(struct ltt_ust_session *usess,
535 struct agent *agt,
536 struct lttng_event *event,
2b00d462 537 struct lttng_bytecode *filter,
44760c20
JR
538 char *filter_expression)
539{
a0377dfe
FD
540 LTTNG_ASSERT(usess);
541 LTTNG_ASSERT(event);
542 LTTNG_ASSERT(agt);
44760c20
JR
543
544 DBG("Enabling agent event: event pattern = '%s', session id = %" PRIu64 ", loglevel type = %d, loglevel = %d, filter expression = '%s'",
545 event->name, usess->id, event->loglevel_type,
546 event->loglevel,
547 filter_expression ? filter_expression : "(none)");
548
549 return agent_enable(agt, event, filter, filter_expression);
550}
551
552/*
553 * Enable a single agent event for a trigger.
554 *
555 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
556 */
557int trigger_agent_enable(const struct lttng_trigger *trigger, struct agent *agt)
558{
559 int ret;
560 enum lttng_condition_status c_status;
561 enum lttng_trigger_status t_status;
562 enum lttng_domain_type d_type;
563 const struct lttng_condition *condition;
564 const struct lttng_event_rule *rule;
565 const char *filter_expression;
566 char *filter_expression_copy = NULL;
2b00d462
SM
567 const struct lttng_bytecode *filter_bytecode;
568 struct lttng_bytecode *filter_bytecode_copy = NULL;
44760c20
JR
569 struct lttng_event *event = NULL;
570 uid_t trigger_owner_uid = 0;
571 const char *trigger_name;
572
a0377dfe
FD
573 LTTNG_ASSERT(trigger);
574 LTTNG_ASSERT(agt);
44760c20
JR
575
576 t_status = lttng_trigger_get_name(trigger, &trigger_name);
577 if (t_status != LTTNG_TRIGGER_STATUS_OK) {
0efb2ad7 578 trigger_name = "(anonymous)";
44760c20
JR
579 }
580
581 t_status = lttng_trigger_get_owner_uid(trigger, &trigger_owner_uid);
a0377dfe 582 LTTNG_ASSERT(t_status == LTTNG_TRIGGER_STATUS_OK);
44760c20
JR
583
584 condition = lttng_trigger_get_const_condition(trigger);
585
a0377dfe 586 LTTNG_ASSERT(lttng_condition_get_type(condition) ==
8dbb86b8 587 LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES);
44760c20 588
8dbb86b8
JR
589 c_status = lttng_condition_event_rule_matches_get_rule(
590 condition, &rule);
a0377dfe 591 LTTNG_ASSERT(c_status == LTTNG_CONDITION_STATUS_OK);
44760c20 592
695f7044
JR
593 switch (lttng_event_rule_get_type(rule)) {
594 case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
595 case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
596 case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
597 break;
598 default:
599 abort();
600 break;
601 }
44760c20
JR
602
603 d_type = lttng_event_rule_get_domain_type(rule);
a0377dfe 604 LTTNG_ASSERT(d_type == agt->domain);
44760c20
JR
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 =
2b00d462 625 lttng_bytecode_copy(filter_bytecode);
44760c20
JR
626 if (!filter_bytecode_copy) {
627 ret = LTTNG_ERR_NOMEM;
628 goto end;
629 }
630 }
631 }
632
633 DBG("Enabling agent event from trigger: trigger name = '%s', trigger owner uid = %d, token = %" PRIu64,
634 trigger_name, trigger_owner_uid,
635 lttng_trigger_get_tracer_token(trigger));
636
637 ret = agent_enable(agt, event, filter_bytecode_copy,
638 filter_expression_copy);
639 /* Ownership was passed even in case of error. */
640 filter_expression_copy = NULL;
641 filter_bytecode_copy = NULL;
642
643end:
644 free(filter_expression_copy);
645 free(filter_bytecode_copy);
646 free(event);
647 return ret;
648}
649
da6c3a50 650/*
d1ec8e20
JG
651 * Return the default event name associated with the provided UST domain. Return
652 * NULL on error.
da6c3a50
DG
653 */
654const char *event_get_default_agent_ust_name(enum lttng_domain_type domain)
655{
656 const char *default_event_name = NULL;
657
0e115563
DG
658 switch (domain) {
659 case LTTNG_DOMAIN_LOG4J:
d1ec8e20 660 default_event_name = DEFAULT_LOG4J_EVENT_NAME;
0e115563
DG
661 break;
662 case LTTNG_DOMAIN_JUL:
d1ec8e20 663 default_event_name = DEFAULT_JUL_EVENT_NAME;
0e115563
DG
664 break;
665 case LTTNG_DOMAIN_PYTHON:
e7c82272 666 default_event_name = DEFAULT_PYTHON_EVENT_NAME;
0e115563
DG
667 break;
668 default:
a0377dfe 669 abort();
da6c3a50
DG
670 }
671
672 return default_event_name;
673}
674
44760c20
JR
675static int trigger_agent_disable_one(const struct lttng_trigger *trigger,
676 struct agent *agt,
677 struct agent_event *aevent)
678
679{
680 int ret;
681
a0377dfe
FD
682 LTTNG_ASSERT(agt);
683 LTTNG_ASSERT(trigger);
684 LTTNG_ASSERT(aevent);
44760c20
JR
685
686 /*
687 * Actual ust event un-registration happens on the trigger
688 * un-registration at that point.
689 */
690
691 DBG("Event agent disabling %s (loglevel type %d, loglevel value %d) for trigger %" PRIu64,
692 aevent->name, aevent->loglevel_type,
693 aevent->loglevel_value, lttng_trigger_get_tracer_token(trigger));
694
695 /* Already disabled? */
696 if (!AGENT_EVENT_IS_ENABLED(aevent)) {
697 goto end;
698 }
699
700 ret = agent_disable_event(aevent, agt->domain);
701 if (ret != LTTNG_OK) {
702 goto error;
703 }
704
705end:
706 return LTTNG_OK;
707
708error:
709 return ret;
710}
711
f20baf8e 712/*
e261a6cc 713 * Disable a given agent event for a given UST session.
f20baf8e 714 *
e261a6cc 715 * Must be called with the RCU read lock held.
f20baf8e
DG
716 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
717 */
e261a6cc
PP
718static int event_agent_disable_one(struct ltt_ust_session *usess,
719 struct agent *agt, struct agent_event *aevent)
f20baf8e
DG
720{
721 int ret;
be6a6276
DG
722 struct ltt_ust_event *uevent = NULL;
723 struct ltt_ust_channel *uchan = NULL;
71aecbf8 724 const char *ust_event_name, *ust_channel_name;
f20baf8e 725
a0377dfe
FD
726 LTTNG_ASSERT(agt);
727 LTTNG_ASSERT(usess);
728 LTTNG_ASSERT(aevent);
f20baf8e 729
e261a6cc
PP
730 DBG("Event agent disabling %s (loglevel type %d, loglevel value %d) for session %" PRIu64,
731 aevent->name, aevent->loglevel_type, aevent->loglevel_value,
732 usess->id);
f20baf8e
DG
733
734 /* Already disabled? */
44760c20 735 if (!AGENT_EVENT_IS_ENABLED(aevent)) {
f20baf8e
DG
736 goto end;
737 }
738
71aecbf8
DG
739 if (agt->domain == LTTNG_DOMAIN_JUL) {
740 ust_channel_name = DEFAULT_JUL_CHANNEL_NAME;
741 } else if (agt->domain == LTTNG_DOMAIN_LOG4J) {
742 ust_channel_name = DEFAULT_LOG4J_CHANNEL_NAME;
0e115563
DG
743 } else if (agt->domain == LTTNG_DOMAIN_PYTHON) {
744 ust_channel_name = DEFAULT_PYTHON_CHANNEL_NAME;
71aecbf8
DG
745 } else {
746 ret = LTTNG_ERR_INVALID;
747 goto error;
748 }
749
be6a6276
DG
750 /*
751 * Disable it on the UST side. First get the channel reference then find
752 * the event and finally disable it.
753 */
754 uchan = trace_ust_find_channel_by_name(usess->domain_global.channels,
71aecbf8 755 (char *) ust_channel_name);
be6a6276
DG
756 if (!uchan) {
757 ret = LTTNG_ERR_UST_CHAN_NOT_FOUND;
758 goto error;
759 }
760
da6c3a50
DG
761 ust_event_name = event_get_default_agent_ust_name(agt->domain);
762 if (!ust_event_name) {
763 ret = LTTNG_ERR_FATAL;
764 goto error;
be6a6276
DG
765 }
766
767 /*
b953b8cd
PP
768 * Agent UST event has its loglevel type forced to
769 * LTTNG_UST_LOGLEVEL_ALL. The actual loglevel type/value filtering
770 * happens thanks to an UST filter. The following -1 is actually
771 * ignored since the type is LTTNG_UST_LOGLEVEL_ALL.
be6a6276 772 */
da6c3a50 773 uevent = trace_ust_find_event(uchan->events, (char *) ust_event_name,
fc4b93fa 774 aevent->filter, LTTNG_UST_ABI_LOGLEVEL_ALL, -1, NULL);
022d91ba 775 /* If the agent event exists, it must be available on the UST side. */
a0377dfe 776 LTTNG_ASSERT(uevent);
be6a6276 777
88e3c2f5
JG
778 if (usess->active) {
779 ret = ust_app_disable_event_glb(usess, uchan, uevent);
780 if (ret < 0 && ret != -LTTNG_UST_ERR_EXIST) {
781 ret = LTTNG_ERR_UST_DISABLE_FAIL;
782 goto error;
783 }
be6a6276
DG
784 }
785
0dcfcf94
DG
786 /*
787 * Flag event that it's disabled so the shadow copy on the ust app side
788 * will disable it if an application shows up.
789 */
790 uevent->enabled = 0;
791
fefd409b 792 ret = agent_disable_event(aevent, agt->domain);
f20baf8e
DG
793 if (ret != LTTNG_OK) {
794 goto error;
795 }
796
797end:
798 return LTTNG_OK;
799
800error:
801 return ret;
802}
e261a6cc 803
44760c20
JR
804/*
805 * Disable agent event matching a given trigger.
806 *
807 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
808 */
809int trigger_agent_disable(
810 const struct lttng_trigger *trigger, struct agent *agt)
811{
812 int ret = LTTNG_OK;
813 struct agent_event *aevent;
814
a0377dfe
FD
815 LTTNG_ASSERT(trigger);
816 LTTNG_ASSERT(agt);
44760c20
JR
817
818 DBG("Event agent disabling for trigger %" PRIu64,
819 lttng_trigger_get_tracer_token(trigger));
820
821 rcu_read_lock();
822 aevent = agent_find_event_by_trigger(trigger, agt);
823
824 if (aevent == NULL) {
825 DBG2("Event agent NOT found by trigger %" PRIu64,
826 lttng_trigger_get_tracer_token(trigger));
827 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
828 goto end;
829 }
830
831 ret = trigger_agent_disable_one(trigger, agt, aevent);
832
833 if (ret != LTTNG_OK) {
834 goto end;
835 }
836
837end:
838 rcu_read_unlock();
839 return ret;
840}
841
e261a6cc
PP
842/*
843 * Disable all agent events matching a given name for a given UST session.
844 *
845 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
846 */
847int event_agent_disable(struct ltt_ust_session *usess, struct agent *agt,
df4f5a87 848 const char *event_name)
e261a6cc
PP
849{
850 int ret = LTTNG_OK;
851 struct agent_event *aevent;
852 struct lttng_ht_iter iter;
853 struct lttng_ht_node_str *node;
854
a0377dfe
FD
855 LTTNG_ASSERT(agt);
856 LTTNG_ASSERT(usess);
857 LTTNG_ASSERT(event_name);
e261a6cc
PP
858
859 DBG("Event agent disabling %s (all loglevels) for session %" PRIu64, event_name, usess->id);
860
861 rcu_read_lock();
862 agent_find_events_by_name(event_name, agt, &iter);
863 node = lttng_ht_iter_get_node_str(&iter);
864
865 if (node == NULL) {
866 DBG2("Event agent NOT found by name %s", event_name);
867 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
868 goto end;
869 }
870
871 do {
872 aevent = caa_container_of(node, struct agent_event, node);
873 ret = event_agent_disable_one(usess, agt, aevent);
874
875 if (ret != LTTNG_OK) {
876 goto end;
877 }
878
879 /* Get next duplicate agent event by name. */
880 agent_event_next_duplicate(event_name, agt, &iter);
881 node = lttng_ht_iter_get_node_str(&iter);
882 } while (node);
883end:
884 rcu_read_unlock();
885 return ret;
886}
f20baf8e 887/*
022d91ba 888 * Disable all agent event for a given UST session.
f20baf8e
DG
889 *
890 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
891 */
fefd409b
DG
892int event_agent_disable_all(struct ltt_ust_session *usess,
893 struct agent *agt)
f20baf8e 894{
0dcfcf94 895 int ret;
fefd409b 896 struct agent_event *aevent;
f20baf8e
DG
897 struct lttng_ht_iter iter;
898
a0377dfe
FD
899 LTTNG_ASSERT(agt);
900 LTTNG_ASSERT(usess);
f20baf8e 901
0dcfcf94
DG
902 /*
903 * Disable event on agent application. Continue to disable all other events
904 * if the * event is not found.
905 */
fefd409b 906 ret = event_agent_disable(usess, agt, "*");
0dcfcf94
DG
907 if (ret != LTTNG_OK && ret != LTTNG_ERR_UST_EVENT_NOT_FOUND) {
908 goto error;
f20baf8e
DG
909 }
910
b9866e08 911 /* Disable every event. */
f20baf8e 912 rcu_read_lock();
fefd409b 913 cds_lfht_for_each_entry(agt->events->ht, &iter.iter, aevent,
f20baf8e 914 node.node) {
44760c20 915 if (!AGENT_EVENT_IS_ENABLED(aevent)) {
0dcfcf94
DG
916 continue;
917 }
918
919 ret = event_agent_disable(usess, agt, aevent->name);
920 if (ret != LTTNG_OK) {
b9866e08 921 goto error_unlock;
f20baf8e 922 }
f20baf8e 923 }
f20baf8e
DG
924 ret = LTTNG_OK;
925
b9866e08
JG
926error_unlock:
927 rcu_read_unlock();
f20baf8e
DG
928error:
929 return ret;
930}
This page took 0.122709 seconds and 4 git commands to generate.