Fix: channel names are not validated
[lttng-tools.git] / src / bin / lttng-sessiond / event.c
CommitLineData
54d01ffb
DG
1/*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 *
d14d33bf
AM
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2 only,
6 * as published by the Free Software Foundation.
54d01ffb 7 *
d14d33bf
AM
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
54d01ffb 12 *
d14d33bf
AM
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
54d01ffb
DG
16 */
17
be040666 18#define _GNU_SOURCE
6c1c0768 19#define _LGPL_SOURCE
d87bfb32 20#include <errno.h>
54d01ffb 21#include <urcu/list.h>
2bdd86d4 22#include <string.h>
54d01ffb
DG
23
24#include <lttng/lttng.h>
db758600 25#include <common/error.h>
10a8a223 26#include <common/sessiond-comm/sessiond-comm.h>
54d01ffb
DG
27
28#include "channel.h"
29#include "event.h"
4771f025 30#include "kernel.h"
be6a6276 31#include "lttng-sessiond.h"
9df8df5e 32#include "ust-ctl.h"
edb67388
DG
33#include "ust-app.h"
34#include "trace-kernel.h"
35#include "trace-ust.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;
51 key.filter = (struct lttng_filter_bytecode *) event->filter;
52 key.loglevel = event->attr.loglevel;
4031e53e 53 key.exclusion = event->exclusion;
18eace3b
DG
54
55 node_ptr = cds_lfht_add_unique(ht->ht,
56 ht->hash_fct(event->node.key, lttng_ht_seed),
57 trace_ust_ht_match_event, &key, &event->node.node);
58 assert(node_ptr == &event->node.node);
59}
60
54d01ffb 61/*
7a3d1328 62 * Disable kernel tracepoint event for a channel from the kernel session.
54d01ffb 63 */
d3a56674
DG
64int event_kernel_disable_tracepoint(struct ltt_kernel_channel *kchan,
65 char *event_name)
54d01ffb
DG
66{
67 int ret;
68 struct ltt_kernel_event *kevent;
69
0525e9ae
DG
70 assert(kchan);
71
54d01ffb
DG
72 kevent = trace_kernel_get_event_by_name(event_name, kchan);
73 if (kevent == NULL) {
f73fabfd 74 ret = LTTNG_ERR_NO_EVENT;
54d01ffb
DG
75 goto error;
76 }
77
78 ret = kernel_disable_event(kevent);
79 if (ret < 0) {
f73fabfd 80 ret = LTTNG_ERR_KERN_DISABLE_FAIL;
54d01ffb
DG
81 goto error;
82 }
83
84 DBG("Kernel event %s disable for channel %s.",
85 kevent->event->name, kchan->channel->name);
86
f73fabfd 87 ret = LTTNG_OK;
54d01ffb
DG
88
89error:
90 return ret;
91}
92
6e911cad
MD
93/*
94 * Enable kernel system call for a channel from the kernel session.
95 */
96int event_kernel_enable_syscall(struct ltt_kernel_channel *kchan,
97 char *syscall_name)
98{
99 int ret;
100
101 assert(kchan);
102
103 ret = kernel_enable_syscall(syscall_name, kchan);
104 if (ret < 0) {
105 ret = LTTNG_ERR_KERN_ENABLE_FAIL;
106 goto error;
107 }
108
109 DBG("Kernel event %s enable for channel %s.",
110 syscall_name, kchan->channel->name);
111
112 ret = LTTNG_OK;
113
114error:
115 return ret;
116}
117
118/*
119 * Disable kernel system call for a channel from the kernel session.
120 */
121int event_kernel_disable_syscall(struct ltt_kernel_channel *kchan,
122 char *syscall_name)
123{
124 int ret;
125
126 assert(kchan);
127
128 ret = kernel_disable_syscall(syscall_name, kchan);
129 if (ret < 0) {
130 ret = LTTNG_ERR_KERN_DISABLE_FAIL;
131 goto error;
132 }
133
134 DBG("Kernel syscall %s disable for channel %s.",
135 syscall_name[0] == '\0' ? "<all>" : syscall_name,
136 kchan->channel->name);
137
138 ret = LTTNG_OK;
139
140error:
141 return ret;
142}
143
54d01ffb 144/*
7a3d1328 145 * Disable kernel tracepoint events for a channel from the kernel session.
54d01ffb 146 */
d3a56674 147int event_kernel_disable_all_tracepoints(struct ltt_kernel_channel *kchan)
54d01ffb
DG
148{
149 int ret;
150 struct ltt_kernel_event *kevent;
151
0525e9ae
DG
152 assert(kchan);
153
54d01ffb
DG
154 /* For each event in the kernel session */
155 cds_list_for_each_entry(kevent, &kchan->events_list.head, list) {
156 ret = kernel_disable_event(kevent);
157 if (ret < 0) {
158 /* We continue disabling the rest */
159 continue;
160 }
161 }
f73fabfd 162 ret = LTTNG_OK;
7a3d1328
MD
163 return ret;
164}
165
7a3d1328
MD
166/*
167 * Disable all kernel event for a channel from the kernel session.
168 */
d3a56674 169int event_kernel_disable_all(struct ltt_kernel_channel *kchan)
7a3d1328
MD
170{
171 int ret;
172
0525e9ae
DG
173 assert(kchan);
174
d3a56674 175 ret = event_kernel_disable_all_tracepoints(kchan);
f73fabfd 176 if (ret != LTTNG_OK)
7a3d1328 177 return ret;
6e911cad 178 ret = event_kernel_disable_syscall(kchan, "");
54d01ffb
DG
179 return ret;
180}
181
182/*
7a3d1328 183 * Enable kernel tracepoint event for a channel from the kernel session.
49d21f93 184 * We own filter_expression and filter.
54d01ffb 185 */
d3a56674
DG
186int event_kernel_enable_tracepoint(struct ltt_kernel_channel *kchan,
187 struct lttng_event *event)
54d01ffb
DG
188{
189 int ret;
190 struct ltt_kernel_event *kevent;
191
0525e9ae
DG
192 assert(kchan);
193 assert(event);
194
54d01ffb
DG
195 kevent = trace_kernel_get_event_by_name(event->name, kchan);
196 if (kevent == NULL) {
197 ret = kernel_create_event(event, kchan);
198 if (ret < 0) {
bd29c13d
DG
199 switch (-ret) {
200 case EEXIST:
f73fabfd 201 ret = LTTNG_ERR_KERN_EVENT_EXIST;
bd29c13d
DG
202 break;
203 case ENOSYS:
f73fabfd 204 ret = LTTNG_ERR_KERN_EVENT_ENOSYS;
bd29c13d
DG
205 break;
206 default:
f73fabfd 207 ret = LTTNG_ERR_KERN_ENABLE_FAIL;
bd29c13d 208 break;
d87bfb32 209 }
7a3d1328 210 goto end;
54d01ffb
DG
211 }
212 } else if (kevent->enabled == 0) {
213 ret = kernel_enable_event(kevent);
214 if (ret < 0) {
f73fabfd 215 ret = LTTNG_ERR_KERN_ENABLE_FAIL;
7a3d1328 216 goto end;
54d01ffb 217 }
42224349
DG
218 } else {
219 /* At this point, the event is considered enabled */
f73fabfd 220 ret = LTTNG_ERR_KERN_EVENT_EXIST;
42224349 221 goto end;
54d01ffb 222 }
42224349 223
f73fabfd 224 ret = LTTNG_OK;
7a3d1328 225end:
54d01ffb
DG
226 return ret;
227}
228
229/*
7a3d1328 230 * Enable all kernel tracepoint events of a channel of the kernel session.
54d01ffb 231 */
d3a56674
DG
232int event_kernel_enable_all_tracepoints(struct ltt_kernel_channel *kchan,
233 int kernel_tracer_fd)
54d01ffb
DG
234{
235 int size, i, ret;
236 struct ltt_kernel_event *kevent;
8f69e5eb 237 struct lttng_event *event_list = NULL;
54d01ffb 238
0525e9ae
DG
239 assert(kchan);
240
54d01ffb
DG
241 /* For each event in the kernel session */
242 cds_list_for_each_entry(kevent, &kchan->events_list.head, list) {
8f69e5eb
DG
243 if (kevent->enabled == 0) {
244 ret = kernel_enable_event(kevent);
245 if (ret < 0) {
246 /* Enable failed but still continue */
247 continue;
248 }
54d01ffb
DG
249 }
250 }
251
252 size = kernel_list_events(kernel_tracer_fd, &event_list);
253 if (size < 0) {
f73fabfd 254 ret = LTTNG_ERR_KERN_LIST_FAIL;
7a3d1328 255 goto end;
54d01ffb
DG
256 }
257
258 for (i = 0; i < size; i++) {
259 kevent = trace_kernel_get_event_by_name(event_list[i].name, kchan);
260 if (kevent == NULL) {
261 /* Default event type for enable all */
262 event_list[i].type = LTTNG_EVENT_TRACEPOINT;
263 /* Enable each single tracepoint event */
264 ret = kernel_create_event(&event_list[i], kchan);
265 if (ret < 0) {
266 /* Ignore error here and continue */
267 }
268 }
269 }
54d01ffb 270 free(event_list);
8f69e5eb 271
f73fabfd 272 ret = LTTNG_OK;
7a3d1328 273end:
54d01ffb
DG
274 return ret;
275}
8c9ae521 276
7a3d1328
MD
277/*
278 * Enable all kernel events of a channel of the kernel session.
279 */
d3a56674
DG
280int event_kernel_enable_all(struct ltt_kernel_channel *kchan,
281 int kernel_tracer_fd)
7a3d1328 282{
6bd8707a 283 int tp_ret;
7a3d1328 284
0525e9ae
DG
285 assert(kchan);
286
d3a56674 287 tp_ret = event_kernel_enable_all_tracepoints(kchan, kernel_tracer_fd);
f73fabfd 288 if (tp_ret != LTTNG_OK) {
7a3d1328
MD
289 goto end;
290 }
bd29c13d
DG
291
292 /*
293 * Reaching this code path means that all tracepoints were enabled without
294 * errors so we ignore the error value of syscalls.
295 *
296 * At the moment, failing to enable syscalls on "lttng enable-event -a -k"
297 * is not considered an error that need to be returned to the client since
298 * tracepoints did not fail. Future work will allow us to send back
299 * multiple errors to the client in one API call.
300 */
6e911cad 301 (void) event_kernel_enable_syscall(kchan, "");
bd29c13d 302
7a3d1328 303end:
bd29c13d 304 return tp_ret;
8c9ae521 305}
2bdd86d4 306
7f79d3a1
DG
307/*
308 * ============================
309 * UST : The Ultimate Frontier!
310 * ============================
311 */
312
76d45b40
DG
313/*
314 * Enable all UST tracepoints for a channel from a UST session.
315 */
7972aab2 316int event_ust_enable_all_tracepoints(struct ltt_ust_session *usess,
6b453b5e
JG
317 struct ltt_ust_channel *uchan,
318 char *filter_expression,
319 struct lttng_filter_bytecode *filter)
76d45b40 320{
6775595e 321 int ret, i, size;
bec39940 322 struct lttng_ht_iter iter;
76d45b40 323 struct ltt_ust_event *uevent = NULL;
7f79d3a1 324 struct lttng_event *events = NULL;
76d45b40 325
0525e9ae
DG
326 assert(usess);
327 assert(uchan);
328
025faf73
DG
329 rcu_read_lock();
330
7972aab2
DG
331 /* Enable existing events */
332 cds_lfht_for_each_entry(uchan->events->ht, &iter.iter, uevent,
333 node.node) {
334 if (uevent->enabled == 0) {
335 ret = ust_app_enable_event_glb(usess, uchan, uevent);
336 if (ret < 0) {
76d45b40
DG
337 continue;
338 }
7972aab2
DG
339 uevent->enabled = 1;
340 }
341 }
76d45b40 342
7972aab2
DG
343 /* Get all UST available events */
344 size = ust_app_list_events(&events);
345 if (size < 0) {
346 ret = LTTNG_ERR_UST_LIST_FAIL;
347 goto error;
348 }
76d45b40 349
7972aab2
DG
350 for (i = 0; i < size; i++) {
351 /*
352 * Check if event exist and if so, continue since it was enable
353 * previously.
354 */
355 uevent = trace_ust_find_event(uchan->events, events[i].name, filter,
10646003 356 events[i].loglevel, NULL);
7972aab2 357 if (uevent != NULL) {
76d45b40
DG
358 ret = ust_app_enable_event_pid(usess, uchan, uevent,
359 events[i].pid);
360 if (ret < 0) {
7972aab2 361 if (ret != -LTTNG_UST_ERR_EXIST) {
f73fabfd 362 ret = LTTNG_ERR_UST_ENABLE_FAIL;
7972aab2 363 goto error;
76d45b40 364 }
76d45b40 365 }
7972aab2
DG
366 continue;
367 }
76d45b40 368
7972aab2 369 /* Create ust event */
6b453b5e
JG
370 uevent = trace_ust_create_event(&events[i], filter_expression,
371 filter, NULL);
7972aab2
DG
372 if (uevent == NULL) {
373 ret = LTTNG_ERR_FATAL;
374 goto error_destroy;
76d45b40
DG
375 }
376
7972aab2
DG
377 /* Create event for the specific PID */
378 ret = ust_app_enable_event_pid(usess, uchan, uevent,
379 events[i].pid);
380 if (ret < 0) {
381 if (ret == -LTTNG_UST_ERR_EXIST) {
382 ret = LTTNG_ERR_UST_EVENT_EXIST;
383 goto error;
384 } else {
385 ret = LTTNG_ERR_UST_ENABLE_FAIL;
386 goto error_destroy;
387 }
388 }
389
390 uevent->enabled = 1;
391 /* Add ltt ust event to channel */
392 rcu_read_lock();
393 add_unique_ust_event(uchan->events, uevent);
394 rcu_read_unlock();
76d45b40 395 }
7972aab2 396 free(events);
76d45b40 397
025faf73 398 rcu_read_unlock();
f73fabfd 399 return LTTNG_OK;
76d45b40 400
7f79d3a1 401error_destroy:
76d45b40 402 trace_ust_destroy_event(uevent);
7f79d3a1
DG
403
404error:
405 free(events);
025faf73 406 rcu_read_unlock();
76d45b40
DG
407 return ret;
408}
409
2bdd86d4
MD
410/*
411 * Enable UST tracepoint event for a channel from a UST session.
49d21f93 412 * We own filter_expression, filter, and exclusion.
2bdd86d4 413 */
7972aab2 414int event_ust_enable_tracepoint(struct ltt_ust_session *usess,
025faf73 415 struct ltt_ust_channel *uchan, struct lttng_event *event,
6b453b5e 416 char *filter_expression,
f1613f52
JI
417 struct lttng_filter_bytecode *filter,
418 struct lttng_event_exclusion *exclusion)
2bdd86d4 419{
f73fabfd 420 int ret = LTTNG_OK, to_create = 0;
edb67388
DG
421 struct ltt_ust_event *uevent;
422
0525e9ae
DG
423 assert(usess);
424 assert(uchan);
425 assert(event);
426
18eace3b
DG
427 rcu_read_lock();
428
025faf73 429 uevent = trace_ust_find_event(uchan->events, event->name, filter,
10646003 430 event->loglevel, exclusion);
edb67388 431 if (uevent == NULL) {
6b453b5e
JG
432 uevent = trace_ust_create_event(event, filter_expression,
433 filter, exclusion);
49d21f93
MD
434 /* We have passed ownership */
435 filter_expression = NULL;
436 filter = NULL;
437 exclusion = NULL;
edb67388 438 if (uevent == NULL) {
95a82664 439 ret = LTTNG_ERR_UST_ENABLE_FAIL;
edb67388
DG
440 goto error;
441 }
025faf73 442
fc34caaa 443 /* Valid to set it after the goto error since uevent is still NULL */
edb67388
DG
444 to_create = 1;
445 }
2bdd86d4 446
7f79d3a1
DG
447 if (uevent->enabled) {
448 /* It's already enabled so everything is OK */
5bcdda4f 449 ret = LTTNG_ERR_UST_EVENT_ENABLED;
7f79d3a1
DG
450 goto end;
451 }
452
fc34caaa
DG
453 uevent->enabled = 1;
454
7972aab2
DG
455 if (to_create) {
456 /* Create event on all UST registered apps for session */
457 ret = ust_app_create_event_glb(usess, uchan, uevent);
458 } else {
459 /* Enable event on all UST registered apps for session */
460 ret = ust_app_enable_event_glb(usess, uchan, uevent);
461 }
48842b30 462
7972aab2
DG
463 if (ret < 0) {
464 if (ret == -LTTNG_UST_ERR_EXIST) {
465 ret = LTTNG_ERR_UST_EVENT_EXIST;
466 goto end;
467 } else {
468 ret = LTTNG_ERR_UST_ENABLE_FAIL;
469 goto error;
edb67388 470 }
2bdd86d4 471 }
48842b30 472
7f79d3a1 473 if (to_create) {
fc34caaa 474 /* Add ltt ust event to channel */
18eace3b 475 add_unique_ust_event(uchan->events, uevent);
7f79d3a1 476 }
edb67388 477
7f79d3a1
DG
478 DBG("Event UST %s %s in channel %s", uevent->attr.name,
479 to_create ? "created" : "enabled", uchan->name);
480
f73fabfd 481 ret = LTTNG_OK;
fc34caaa 482
fb89d070 483end:
18eace3b 484 rcu_read_unlock();
49d21f93
MD
485 free(filter_expression);
486 free(filter);
487 free(exclusion);
fc34caaa 488 return ret;
edb67388
DG
489
490error:
fc34caaa
DG
491 /*
492 * Only destroy event on creation time (not enabling time) because if the
493 * event is found in the channel (to_create == 0), it means that at some
494 * point the enable_event worked and it's thus valid to keep it alive.
495 * Destroying it also implies that we also destroy it's shadow copy to sync
496 * everyone up.
497 */
498 if (to_create) {
499 /* In this code path, the uevent was not added to the hash table */
500 trace_ust_destroy_event(uevent);
501 }
18eace3b 502 rcu_read_unlock();
49d21f93
MD
503 free(filter_expression);
504 free(filter);
505 free(exclusion);
2bdd86d4
MD
506 return ret;
507}
508
7f79d3a1
DG
509/*
510 * Disable UST tracepoint of a channel from a UST session.
511 */
7972aab2 512int event_ust_disable_tracepoint(struct ltt_ust_session *usess,
7f79d3a1 513 struct ltt_ust_channel *uchan, char *event_name)
2bdd86d4
MD
514{
515 int ret;
7f79d3a1 516 struct ltt_ust_event *uevent;
18eace3b
DG
517 struct lttng_ht_node_str *node;
518 struct lttng_ht_iter iter;
18eace3b 519 struct lttng_ht *ht;
2bdd86d4 520
0525e9ae
DG
521 assert(usess);
522 assert(uchan);
523 assert(event_name);
524
18eace3b
DG
525 ht = uchan->events;
526
18eace3b 527 rcu_read_lock();
025faf73
DG
528
529 /*
530 * We use a custom lookup since we need the iterator for the next_duplicate
531 * call in the do while loop below.
532 */
533 cds_lfht_lookup(ht->ht, ht->hash_fct((void *) event_name, lttng_ht_seed),
534 trace_ust_ht_match_event_by_name, event_name, &iter.iter);
18eace3b
DG
535 node = lttng_ht_iter_get_node_str(&iter);
536 if (node == NULL) {
537 DBG2("Trace UST event NOT found by name %s", event_name);
f73fabfd 538 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
7f79d3a1 539 goto error;
2bdd86d4 540 }
7f79d3a1 541
18eace3b
DG
542 do {
543 uevent = caa_container_of(node, struct ltt_ust_event, node);
025faf73
DG
544 assert(uevent);
545
18eace3b
DG
546 if (uevent->enabled == 0) {
547 /* It's already disabled so everything is OK */
a1dcaf0f 548 goto next;
7f79d3a1 549 }
18eace3b 550
7972aab2
DG
551 ret = ust_app_disable_event_glb(usess, uchan, uevent);
552 if (ret < 0 && ret != -LTTNG_UST_ERR_EXIST) {
553 ret = LTTNG_ERR_UST_DISABLE_FAIL;
18eace3b
DG
554 goto error;
555 }
18eace3b
DG
556 uevent->enabled = 0;
557
025faf73
DG
558 DBG2("Event UST %s disabled in channel %s", uevent->attr.name,
559 uchan->name);
560
a1dcaf0f 561next:
18eace3b
DG
562 /* Get next duplicate event by name. */
563 cds_lfht_next_duplicate(ht->ht, trace_ust_ht_match_event_by_name,
564 event_name, &iter.iter);
565 node = lttng_ht_iter_get_node_str(&iter);
566 } while (node);
7f79d3a1 567
f73fabfd 568 ret = LTTNG_OK;
7f79d3a1 569
7f79d3a1 570error:
18eace3b 571 rcu_read_unlock();
7f79d3a1
DG
572 return ret;
573}
574
575/*
576 * Disable all UST tracepoints for a channel from a UST session.
577 */
7972aab2 578int event_ust_disable_all_tracepoints(struct ltt_ust_session *usess,
7f79d3a1
DG
579 struct ltt_ust_channel *uchan)
580{
6775595e 581 int ret, i, size;
bec39940 582 struct lttng_ht_iter iter;
7f79d3a1
DG
583 struct ltt_ust_event *uevent = NULL;
584 struct lttng_event *events = NULL;
585
0525e9ae
DG
586 assert(usess);
587 assert(uchan);
588
025faf73
DG
589 rcu_read_lock();
590
7972aab2
DG
591 /* Disabling existing events */
592 cds_lfht_for_each_entry(uchan->events->ht, &iter.iter, uevent,
593 node.node) {
594 if (uevent->enabled == 1) {
595 ret = event_ust_disable_tracepoint(usess, uchan,
596 uevent->attr.name);
597 if (ret < 0) {
7f79d3a1
DG
598 continue;
599 }
600 }
7f79d3a1 601 }
7972aab2
DG
602
603 /* Get all UST available events */
604 size = ust_app_list_events(&events);
605 if (size < 0) {
606 ret = LTTNG_ERR_UST_LIST_FAIL;
7f79d3a1
DG
607 goto error;
608 }
609
7972aab2
DG
610 for (i = 0; i < size; i++) {
611 ret = event_ust_disable_tracepoint(usess, uchan,
612 events[i].name);
613 if (ret != LTTNG_OK) {
614 /* Continue to disable the rest... */
615 continue;
616 }
617 }
618 free(events);
619
025faf73 620 rcu_read_unlock();
f73fabfd 621 return LTTNG_OK;
7f79d3a1
DG
622
623error:
624 free(events);
025faf73 625 rcu_read_unlock();
2bdd86d4
MD
626 return ret;
627}
f20baf8e
DG
628
629/*
022d91ba 630 * Enable all agent event for a given UST session.
f20baf8e
DG
631 *
632 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
633 */
022d91ba 634int event_agent_enable_all(struct ltt_ust_session *usess,
fefd409b
DG
635 struct agent *agt, struct lttng_event *event,
636 struct lttng_filter_bytecode *filter)
f20baf8e
DG
637{
638 int ret;
fefd409b 639 struct agent_event *aevent;
f20baf8e
DG
640 struct lttng_ht_iter iter;
641
642 assert(usess);
643
022d91ba 644 DBG("Event agent enabling ALL events for session %" PRIu64, usess->id);
f20baf8e 645
022d91ba 646 /* Enable event on agent application through TCP socket. */
fefd409b 647 ret = event_agent_enable(usess, agt, event, filter);
f20baf8e
DG
648 if (ret != LTTNG_OK) {
649 goto error;
650 }
651
652 /* Flag every event that they are now enabled. */
653 rcu_read_lock();
fefd409b 654 cds_lfht_for_each_entry(agt->events->ht, &iter.iter, aevent,
f20baf8e 655 node.node) {
fefd409b 656 aevent->enabled = 1;
f20baf8e
DG
657 }
658 rcu_read_unlock();
659
660 ret = LTTNG_OK;
661
662error:
663 return ret;
664}
665
666/*
022d91ba 667 * Enable a single agent event for a given UST session.
f20baf8e
DG
668 *
669 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
670 */
fefd409b
DG
671int event_agent_enable(struct ltt_ust_session *usess,
672 struct agent *agt, struct lttng_event *event,
be6a6276 673 struct lttng_filter_bytecode *filter)
f20baf8e
DG
674{
675 int ret, created = 0;
fefd409b 676 struct agent_event *aevent;
f20baf8e
DG
677
678 assert(usess);
679 assert(event);
fefd409b 680 assert(agt);
f20baf8e 681
022d91ba 682 DBG("Event agent enabling %s for session %" PRIu64 " with loglevel type %d "
b2064f54
DG
683 "and loglevel %d", event->name, usess->id, event->loglevel_type,
684 event->loglevel);
f20baf8e 685
fefd409b
DG
686 aevent = agent_find_event(event->name, event->loglevel, agt);
687 if (!aevent) {
688 aevent = agent_create_event(event->name, filter);
689 if (!aevent) {
f20baf8e
DG
690 ret = LTTNG_ERR_NOMEM;
691 goto error;
692 }
fefd409b
DG
693 aevent->loglevel = event->loglevel;
694 aevent->loglevel_type = event->loglevel_type;
f20baf8e
DG
695 created = 1;
696 }
697
698 /* Already enabled? */
fefd409b 699 if (aevent->enabled) {
f20baf8e
DG
700 goto end;
701 }
702
fefd409b 703 ret = agent_enable_event(aevent, agt->domain);
f20baf8e
DG
704 if (ret != LTTNG_OK) {
705 goto error;
706 }
707
708 /* If the event was created prior to the enable, add it to the domain. */
709 if (created) {
fefd409b 710 agent_add_event(aevent, agt);
f20baf8e
DG
711 }
712
713end:
714 return LTTNG_OK;
715
716error:
717 if (created) {
fefd409b 718 agent_destroy_event(aevent);
f20baf8e
DG
719 }
720 return ret;
721}
722
da6c3a50
DG
723/*
724 * Return the agent default event name to use by testing if the process is root
725 * or not. Return NULL on error.
726 */
727const char *event_get_default_agent_ust_name(enum lttng_domain_type domain)
728{
729 const char *default_event_name = NULL;
730
0e115563
DG
731 switch (domain) {
732 case LTTNG_DOMAIN_LOG4J:
da6c3a50 733 if (is_root) {
0e115563 734 default_event_name = DEFAULT_SYS_LOG4J_EVENT_NAME;
da6c3a50 735 } else {
0e115563 736 default_event_name = DEFAULT_USER_LOG4J_EVENT_NAME;
da6c3a50 737 }
0e115563
DG
738 break;
739 case LTTNG_DOMAIN_JUL:
da6c3a50 740 if (is_root) {
0e115563 741 default_event_name = DEFAULT_SYS_JUL_EVENT_NAME;
da6c3a50 742 } else {
0e115563 743 default_event_name = DEFAULT_USER_JUL_EVENT_NAME;
da6c3a50 744 }
0e115563
DG
745 break;
746 case LTTNG_DOMAIN_PYTHON:
747 default_event_name = DEFAULT_USER_PYTHON_EVENT_NAME;
748 break;
749 default:
da6c3a50
DG
750 assert(0);
751 }
752
753 return default_event_name;
754}
755
f20baf8e 756/*
022d91ba 757 * Disable a single agent event for a given UST session.
f20baf8e
DG
758 *
759 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
760 */
fefd409b
DG
761int event_agent_disable(struct ltt_ust_session *usess, struct agent *agt,
762 char *event_name)
f20baf8e
DG
763{
764 int ret;
fefd409b 765 struct agent_event *aevent;
be6a6276
DG
766 struct ltt_ust_event *uevent = NULL;
767 struct ltt_ust_channel *uchan = NULL;
71aecbf8 768 const char *ust_event_name, *ust_channel_name;
f20baf8e 769
fefd409b 770 assert(agt);
f20baf8e
DG
771 assert(usess);
772 assert(event_name);
773
022d91ba 774 DBG("Event agent disabling %s for session %" PRIu64, event_name, usess->id);
f20baf8e 775
fefd409b
DG
776 aevent = agent_find_event_by_name(event_name, agt);
777 if (!aevent) {
f20baf8e
DG
778 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
779 goto error;
780 }
781
782 /* Already disabled? */
fefd409b 783 if (!aevent->enabled) {
f20baf8e
DG
784 goto end;
785 }
786
71aecbf8
DG
787 if (agt->domain == LTTNG_DOMAIN_JUL) {
788 ust_channel_name = DEFAULT_JUL_CHANNEL_NAME;
789 } else if (agt->domain == LTTNG_DOMAIN_LOG4J) {
790 ust_channel_name = DEFAULT_LOG4J_CHANNEL_NAME;
0e115563
DG
791 } else if (agt->domain == LTTNG_DOMAIN_PYTHON) {
792 ust_channel_name = DEFAULT_PYTHON_CHANNEL_NAME;
71aecbf8
DG
793 } else {
794 ret = LTTNG_ERR_INVALID;
795 goto error;
796 }
797
be6a6276
DG
798 /*
799 * Disable it on the UST side. First get the channel reference then find
800 * the event and finally disable it.
801 */
802 uchan = trace_ust_find_channel_by_name(usess->domain_global.channels,
71aecbf8 803 (char *) ust_channel_name);
be6a6276
DG
804 if (!uchan) {
805 ret = LTTNG_ERR_UST_CHAN_NOT_FOUND;
806 goto error;
807 }
808
da6c3a50
DG
809 ust_event_name = event_get_default_agent_ust_name(agt->domain);
810 if (!ust_event_name) {
811 ret = LTTNG_ERR_FATAL;
812 goto error;
be6a6276
DG
813 }
814
815 /*
022d91ba 816 * The loglevel is hardcoded with 0 here since the agent ust event is set
be6a6276 817 * with the loglevel type to ALL thus the loglevel stays 0. The event's
022d91ba 818 * filter is the one handling the loglevel for agent.
be6a6276 819 */
da6c3a50 820 uevent = trace_ust_find_event(uchan->events, (char *) ust_event_name,
fefd409b 821 aevent->filter, 0, NULL);
022d91ba 822 /* If the agent event exists, it must be available on the UST side. */
be6a6276
DG
823 assert(uevent);
824
825 ret = ust_app_disable_event_glb(usess, uchan, uevent);
826 if (ret < 0 && ret != -LTTNG_UST_ERR_EXIST) {
827 ret = LTTNG_ERR_UST_DISABLE_FAIL;
828 goto error;
829 }
830
0dcfcf94
DG
831 /*
832 * Flag event that it's disabled so the shadow copy on the ust app side
833 * will disable it if an application shows up.
834 */
835 uevent->enabled = 0;
836
fefd409b 837 ret = agent_disable_event(aevent, agt->domain);
f20baf8e
DG
838 if (ret != LTTNG_OK) {
839 goto error;
840 }
841
842end:
843 return LTTNG_OK;
844
845error:
846 return ret;
847}
848/*
022d91ba 849 * Disable all agent event for a given UST session.
f20baf8e
DG
850 *
851 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
852 */
fefd409b
DG
853int event_agent_disable_all(struct ltt_ust_session *usess,
854 struct agent *agt)
f20baf8e 855{
0dcfcf94 856 int ret;
fefd409b 857 struct agent_event *aevent;
f20baf8e
DG
858 struct lttng_ht_iter iter;
859
fefd409b 860 assert(agt);
f20baf8e
DG
861 assert(usess);
862
0dcfcf94
DG
863 /*
864 * Disable event on agent application. Continue to disable all other events
865 * if the * event is not found.
866 */
fefd409b 867 ret = event_agent_disable(usess, agt, "*");
0dcfcf94
DG
868 if (ret != LTTNG_OK && ret != LTTNG_ERR_UST_EVENT_NOT_FOUND) {
869 goto error;
f20baf8e
DG
870 }
871
872 /* Flag every event that they are now enabled. */
873 rcu_read_lock();
fefd409b 874 cds_lfht_for_each_entry(agt->events->ht, &iter.iter, aevent,
f20baf8e 875 node.node) {
0dcfcf94
DG
876 if (!aevent->enabled) {
877 continue;
878 }
879
880 ret = event_agent_disable(usess, agt, aevent->name);
881 if (ret != LTTNG_OK) {
882 rcu_read_unlock();
883 goto error;
f20baf8e 884 }
f20baf8e
DG
885 }
886 rcu_read_unlock();
887
888 ret = LTTNG_OK;
889
890error:
891 return ret;
892}
This page took 0.093294 seconds and 5 git commands to generate.