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