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