Fix: ust: segfault on lttng start on filter bytecode copy
[lttng-tools.git] / src / bin / lttng-sessiond / event.c
1 /*
2 * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
3 * Copyright (C) 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 */
8
9 #define _LGPL_SOURCE
10 #include <errno.h>
11 #include <urcu/list.h>
12 #include <string.h>
13
14 #include <lttng/lttng.h>
15 #include <common/error.h>
16 #include <common/sessiond-comm/sessiond-comm.h>
17 #include <common/filter.h>
18 #include <common/context.h>
19
20 #include "channel.h"
21 #include "event.h"
22 #include "kernel.h"
23 #include "lttng-sessiond.h"
24 #include "lttng-ust-ctl.h"
25 #include "lttng-ust-error.h"
26 #include "ust-app.h"
27 #include "trace-kernel.h"
28 #include "trace-ust.h"
29 #include "agent.h"
30
31 /*
32 * Add unique UST event based on the event name, filter bytecode and loglevel.
33 */
34 static void add_unique_ust_event(struct lttng_ht *ht,
35 struct ltt_ust_event *event)
36 {
37 struct cds_lfht_node *node_ptr;
38 struct ltt_ust_ht_key key;
39
40 assert(ht);
41 assert(ht->ht);
42 assert(event);
43
44 key.name = event->attr.name;
45 key.filter = (struct lttng_filter_bytecode *) event->filter;
46 key.loglevel_type = event->attr.loglevel_type;
47 key.loglevel_value = event->attr.loglevel;
48 key.exclusion = event->exclusion;
49
50 node_ptr = cds_lfht_add_unique(ht->ht,
51 ht->hash_fct(event->node.key, lttng_ht_seed),
52 trace_ust_ht_match_event, &key, &event->node.node);
53 assert(node_ptr == &event->node.node);
54 }
55
56 /*
57 * Disable kernel tracepoint events for a channel from the kernel session of
58 * a specified event_name and event type.
59 * On type LTTNG_EVENT_ALL all events with event_name are disabled.
60 * If event_name is NULL all events of the specified type are disabled.
61 */
62 int event_kernel_disable_event(struct ltt_kernel_channel *kchan,
63 const char *event_name, enum lttng_event_type type)
64 {
65 int ret, error = 0, found = 0;
66 struct ltt_kernel_event *kevent;
67
68 assert(kchan);
69
70 /* For each event in the kernel session */
71 cds_list_for_each_entry(kevent, &kchan->events_list.head, list) {
72 if (type != LTTNG_EVENT_ALL && kevent->type != type)
73 continue;
74 if (event_name != NULL && strcmp(event_name, kevent->event->name)) {
75 continue;
76 }
77 found++;
78 ret = kernel_disable_event(kevent);
79 if (ret < 0) {
80 error = 1;
81 continue;
82 }
83 }
84 DBG("Disable kernel event: found %d events with name: %s and type: %d",
85 found, event_name ? event_name : "NULL", type);
86
87 if (event_name != NULL && !found) {
88 ret = LTTNG_ERR_NO_EVENT;
89 } else {
90 ret = error ? LTTNG_ERR_KERN_DISABLE_FAIL : LTTNG_OK;
91 }
92
93 return ret;
94 }
95
96 /*
97 * Enable kernel tracepoint event for a channel from the kernel session.
98 * We own filter_expression and filter.
99 */
100 int event_kernel_enable_event(struct ltt_kernel_channel *kchan,
101 struct lttng_event *event, char *filter_expression,
102 struct lttng_filter_bytecode *filter)
103 {
104 int ret;
105 struct ltt_kernel_event *kevent;
106
107 assert(kchan);
108 assert(event);
109
110 kevent = trace_kernel_find_event(event->name, kchan,
111 event->type, filter);
112 if (kevent == NULL) {
113 ret = kernel_create_event(event, kchan, filter_expression, filter);
114 /* We have passed ownership */
115 filter_expression = NULL;
116 filter = NULL;
117 if (ret) {
118 goto end;
119 }
120 } else if (kevent->enabled == 0) {
121 ret = kernel_enable_event(kevent);
122 if (ret < 0) {
123 ret = LTTNG_ERR_KERN_ENABLE_FAIL;
124 goto end;
125 }
126 } else {
127 /* At this point, the event is considered enabled */
128 ret = LTTNG_ERR_KERN_EVENT_EXIST;
129 goto end;
130 }
131
132 ret = LTTNG_OK;
133 end:
134 free(filter_expression);
135 free(filter);
136 return ret;
137 }
138
139 /*
140 * ============================
141 * UST : The Ultimate Frontier!
142 * ============================
143 */
144
145 /*
146 * Enable UST tracepoint event for a channel from a UST session.
147 * We own filter_expression, filter, and exclusion.
148 */
149 int event_ust_enable_tracepoint(struct ltt_ust_session *usess,
150 struct ltt_ust_channel *uchan, struct lttng_event *event,
151 char *filter_expression,
152 struct lttng_filter_bytecode *filter,
153 struct lttng_event_exclusion *exclusion,
154 bool internal_event)
155 {
156 int ret = LTTNG_OK, to_create = 0;
157 struct ltt_ust_event *uevent;
158
159 assert(usess);
160 assert(uchan);
161 assert(event);
162
163 rcu_read_lock();
164
165 uevent = trace_ust_find_event(uchan->events, event->name, filter,
166 (enum lttng_ust_loglevel_type) event->loglevel_type,
167 event->loglevel, exclusion);
168 if (!uevent) {
169 ret = trace_ust_create_event(event, filter_expression,
170 filter, exclusion, internal_event, &uevent);
171 /* We have passed ownership */
172 filter_expression = NULL;
173 filter = NULL;
174 exclusion = NULL;
175 if (ret != LTTNG_OK) {
176 goto end;
177 }
178
179 /* Valid to set it after the goto error since uevent is still NULL */
180 to_create = 1;
181 }
182
183 if (uevent->enabled) {
184 /* It's already enabled so everything is OK */
185 assert(!to_create);
186 ret = LTTNG_ERR_UST_EVENT_ENABLED;
187 goto end;
188 }
189
190 uevent->enabled = 1;
191 if (to_create) {
192 /* Add ltt ust event to channel */
193 add_unique_ust_event(uchan->events, uevent);
194 }
195
196 if (!usess->active) {
197 goto end;
198 }
199
200 if (to_create) {
201 /* Create event on all UST registered apps for session */
202 ret = ust_app_create_event_glb(usess, uchan, uevent);
203 } else {
204 /* Enable event on all UST registered apps for session */
205 ret = ust_app_enable_event_glb(usess, uchan, uevent);
206 }
207
208 if (ret < 0) {
209 if (ret == -LTTNG_UST_ERR_EXIST) {
210 ret = LTTNG_ERR_UST_EVENT_EXIST;
211 } else {
212 ret = LTTNG_ERR_UST_ENABLE_FAIL;
213 }
214 goto end;
215 }
216
217 DBG("Event UST %s %s in channel %s", uevent->attr.name,
218 to_create ? "created" : "enabled", uchan->name);
219
220 ret = LTTNG_OK;
221
222 end:
223 rcu_read_unlock();
224 free(filter_expression);
225 free(filter);
226 free(exclusion);
227 return ret;
228 }
229
230 /*
231 * Disable UST tracepoint of a channel from a UST session.
232 */
233 int event_ust_disable_tracepoint(struct ltt_ust_session *usess,
234 struct ltt_ust_channel *uchan, const char *event_name)
235 {
236 int ret;
237 struct ltt_ust_event *uevent;
238 struct lttng_ht_node_str *node;
239 struct lttng_ht_iter iter;
240 struct lttng_ht *ht;
241
242 assert(usess);
243 assert(uchan);
244 assert(event_name);
245
246 ht = uchan->events;
247
248 rcu_read_lock();
249
250 /*
251 * We use a custom lookup since we need the iterator for the next_duplicate
252 * call in the do while loop below.
253 */
254 cds_lfht_lookup(ht->ht, ht->hash_fct((void *) event_name, lttng_ht_seed),
255 trace_ust_ht_match_event_by_name, event_name, &iter.iter);
256 node = lttng_ht_iter_get_node_str(&iter);
257 if (node == NULL) {
258 DBG2("Trace UST event NOT found by name %s", event_name);
259 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
260 goto error;
261 }
262
263 do {
264 uevent = caa_container_of(node, struct ltt_ust_event, node);
265 assert(uevent);
266
267 if (uevent->enabled == 0) {
268 /* It's already disabled so everything is OK */
269 goto next;
270 }
271 uevent->enabled = 0;
272 DBG2("Event UST %s disabled in channel %s", uevent->attr.name,
273 uchan->name);
274
275 if (!usess->active) {
276 goto next;
277 }
278 ret = ust_app_disable_event_glb(usess, uchan, uevent);
279 if (ret < 0 && ret != -LTTNG_UST_ERR_EXIST) {
280 ret = LTTNG_ERR_UST_DISABLE_FAIL;
281 goto error;
282 }
283 next:
284 /* Get next duplicate event by name. */
285 cds_lfht_next_duplicate(ht->ht, trace_ust_ht_match_event_by_name,
286 event_name, &iter.iter);
287 node = lttng_ht_iter_get_node_str(&iter);
288 } while (node);
289
290 ret = LTTNG_OK;
291
292 error:
293 rcu_read_unlock();
294 return ret;
295 }
296
297 /*
298 * Disable all UST tracepoints for a channel from a UST session.
299 */
300 int event_ust_disable_all_tracepoints(struct ltt_ust_session *usess,
301 struct ltt_ust_channel *uchan)
302 {
303 int ret, i, size, error = 0;
304 struct lttng_ht_iter iter;
305 struct ltt_ust_event *uevent = NULL;
306 struct lttng_event *events = NULL;
307
308 assert(usess);
309 assert(uchan);
310
311 rcu_read_lock();
312
313 /* Disabling existing events */
314 cds_lfht_for_each_entry(uchan->events->ht, &iter.iter, uevent,
315 node.node) {
316 if (uevent->enabled == 1) {
317 ret = event_ust_disable_tracepoint(usess, uchan,
318 uevent->attr.name);
319 if (ret < 0) {
320 error = LTTNG_ERR_UST_DISABLE_FAIL;
321 continue;
322 }
323 }
324 }
325
326 /* Get all UST available events */
327 size = ust_app_list_events(&events);
328 if (size < 0) {
329 ret = LTTNG_ERR_UST_LIST_FAIL;
330 goto error;
331 }
332
333 for (i = 0; i < size; i++) {
334 ret = event_ust_disable_tracepoint(usess, uchan,
335 events[i].name);
336 if (ret < 0) {
337 /* Continue to disable the rest... */
338 error = LTTNG_ERR_UST_DISABLE_FAIL;
339 continue;
340 }
341 }
342
343 ret = error ? error : LTTNG_OK;
344 error:
345 rcu_read_unlock();
346 free(events);
347 return ret;
348 }
349
350 /*
351 * Enable all agent event for a given UST session.
352 *
353 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
354 */
355 int event_agent_enable_all(struct ltt_ust_session *usess,
356 struct agent *agt, struct lttng_event *event,
357 struct lttng_filter_bytecode *filter ,char *filter_expression)
358 {
359 int ret;
360 struct agent_event *aevent;
361 struct lttng_ht_iter iter;
362
363 assert(usess);
364
365 DBG("Event agent enabling ALL events for session %" PRIu64, usess->id);
366
367 /* Enable event on agent application through TCP socket. */
368 ret = event_agent_enable(usess, agt, event, filter, filter_expression);
369 if (ret != LTTNG_OK) {
370 goto error;
371 }
372
373 /* Flag every event that they are now enabled. */
374 rcu_read_lock();
375 cds_lfht_for_each_entry(agt->events->ht, &iter.iter, aevent,
376 node.node) {
377 aevent->enabled = 1;
378 }
379 rcu_read_unlock();
380
381 ret = LTTNG_OK;
382
383 error:
384 return ret;
385 }
386
387 /*
388 * Check if this event's filter requires the activation of application contexts
389 * and enable them in the agent.
390 * TODO: bytecode iterator does not support non-legacy application
391 * contexts yet. Not an issue for now, since they are not generated by
392 * the lttng-ctl library.
393 */
394 static int add_filter_app_ctx(struct lttng_filter_bytecode *bytecode,
395 const char *filter_expression, struct agent *agt)
396 {
397 int ret = LTTNG_OK;
398 char *provider_name = NULL, *ctx_name = NULL;
399 struct bytecode_symbol_iterator *it =
400 bytecode_symbol_iterator_create(bytecode);
401
402 if (!it) {
403 ret = LTTNG_ERR_NOMEM;
404 goto end;
405 }
406
407 do {
408 struct lttng_event_context ctx;
409 const char *symbol_name =
410 bytecode_symbol_iterator_get_name(it);
411
412 if (parse_application_context(symbol_name, &provider_name,
413 &ctx_name)) {
414 /* Not an application context. */
415 continue;
416 }
417
418 ctx.ctx = LTTNG_EVENT_CONTEXT_APP_CONTEXT;
419 ctx.u.app_ctx.provider_name = provider_name;
420 ctx.u.app_ctx.ctx_name = ctx_name;
421
422 /* Recognized an application context. */
423 DBG("Enabling event with filter expression \"%s\" requires enabling the %s:%s application context.",
424 filter_expression, provider_name, ctx_name);
425
426 ret = agent_add_context(&ctx, agt);
427 if (ret != LTTNG_OK) {
428 ERR("Failed to add application context %s:%s.",
429 provider_name, ctx_name);
430 goto end;
431 }
432
433 ret = agent_enable_context(&ctx, agt->domain);
434 if (ret != LTTNG_OK) {
435 ERR("Failed to enable application context %s:%s.",
436 provider_name, ctx_name);
437 goto end;
438 }
439
440 free(provider_name);
441 free(ctx_name);
442 provider_name = ctx_name = NULL;
443 } while (bytecode_symbol_iterator_next(it) == 0);
444 end:
445 free(provider_name);
446 free(ctx_name);
447 bytecode_symbol_iterator_destroy(it);
448 return ret;
449 }
450
451 /*
452 * Enable a single agent event for a given UST session.
453 *
454 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
455 */
456 int event_agent_enable(struct ltt_ust_session *usess,
457 struct agent *agt, struct lttng_event *event,
458 struct lttng_filter_bytecode *filter,
459 char *filter_expression)
460 {
461 int ret, created = 0;
462 struct agent_event *aevent;
463
464 assert(usess);
465 assert(event);
466 assert(agt);
467
468 DBG("Event agent enabling %s for session %" PRIu64 " with loglevel type %d "
469 ", loglevel %d and filter \"%s\"", event->name,
470 usess->id, event->loglevel_type, event->loglevel,
471 filter_expression ? filter_expression : "NULL");
472
473 aevent = agent_find_event(event->name, event->loglevel_type,
474 event->loglevel, filter_expression, agt);
475 if (!aevent) {
476 aevent = agent_create_event(event->name, event->loglevel_type,
477 event->loglevel, filter,
478 filter_expression);
479 if (!aevent) {
480 ret = LTTNG_ERR_NOMEM;
481 goto error;
482 }
483 filter = NULL;
484 filter_expression = NULL;
485 created = 1;
486 assert(!aevent->enabled);
487 }
488
489 if (created && aevent->filter) {
490 ret = add_filter_app_ctx(
491 aevent->filter, aevent->filter_expression, agt);
492 if (ret != LTTNG_OK) {
493 goto error;
494 }
495 }
496
497 /* Already enabled? */
498 if (aevent->enabled) {
499 ret = LTTNG_OK;
500 goto end;
501 }
502
503 ret = agent_enable_event(aevent, agt->domain);
504 if (ret != LTTNG_OK) {
505 goto error;
506 }
507
508 /* If the event was created prior to the enable, add it to the domain. */
509 if (created) {
510 agent_add_event(aevent, agt);
511 }
512
513 ret = LTTNG_OK;
514 goto end;
515
516 error:
517 if (created) {
518 agent_destroy_event(aevent);
519 }
520 end:
521 free(filter);
522 free(filter_expression);
523 return ret;
524 }
525
526 /*
527 * Return the default event name associated with the provided UST domain. Return
528 * NULL on error.
529 */
530 const char *event_get_default_agent_ust_name(enum lttng_domain_type domain)
531 {
532 const char *default_event_name = NULL;
533
534 switch (domain) {
535 case LTTNG_DOMAIN_LOG4J:
536 default_event_name = DEFAULT_LOG4J_EVENT_NAME;
537 break;
538 case LTTNG_DOMAIN_JUL:
539 default_event_name = DEFAULT_JUL_EVENT_NAME;
540 break;
541 case LTTNG_DOMAIN_PYTHON:
542 default_event_name = DEFAULT_PYTHON_EVENT_NAME;
543 break;
544 default:
545 assert(0);
546 }
547
548 return default_event_name;
549 }
550
551 /*
552 * Disable a given agent event for a given UST session.
553 *
554 * Must be called with the RCU read lock held.
555 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
556 */
557 static int event_agent_disable_one(struct ltt_ust_session *usess,
558 struct agent *agt, struct agent_event *aevent)
559 {
560 int ret;
561 struct ltt_ust_event *uevent = NULL;
562 struct ltt_ust_channel *uchan = NULL;
563 const char *ust_event_name, *ust_channel_name;
564
565 assert(agt);
566 assert(usess);
567 assert(aevent);
568
569 DBG("Event agent disabling %s (loglevel type %d, loglevel value %d) for session %" PRIu64,
570 aevent->name, aevent->loglevel_type, aevent->loglevel_value,
571 usess->id);
572
573 /* Already disabled? */
574 if (!aevent->enabled) {
575 goto end;
576 }
577
578 if (agt->domain == LTTNG_DOMAIN_JUL) {
579 ust_channel_name = DEFAULT_JUL_CHANNEL_NAME;
580 } else if (agt->domain == LTTNG_DOMAIN_LOG4J) {
581 ust_channel_name = DEFAULT_LOG4J_CHANNEL_NAME;
582 } else if (agt->domain == LTTNG_DOMAIN_PYTHON) {
583 ust_channel_name = DEFAULT_PYTHON_CHANNEL_NAME;
584 } else {
585 ret = LTTNG_ERR_INVALID;
586 goto error;
587 }
588
589 /*
590 * Disable it on the UST side. First get the channel reference then find
591 * the event and finally disable it.
592 */
593 uchan = trace_ust_find_channel_by_name(usess->domain_global.channels,
594 (char *) ust_channel_name);
595 if (!uchan) {
596 ret = LTTNG_ERR_UST_CHAN_NOT_FOUND;
597 goto error;
598 }
599
600 ust_event_name = event_get_default_agent_ust_name(agt->domain);
601 if (!ust_event_name) {
602 ret = LTTNG_ERR_FATAL;
603 goto error;
604 }
605
606 /*
607 * Agent UST event has its loglevel type forced to
608 * LTTNG_UST_LOGLEVEL_ALL. The actual loglevel type/value filtering
609 * happens thanks to an UST filter. The following -1 is actually
610 * ignored since the type is LTTNG_UST_LOGLEVEL_ALL.
611 */
612 uevent = trace_ust_find_event(uchan->events, (char *) ust_event_name,
613 aevent->filter, LTTNG_UST_LOGLEVEL_ALL, -1, NULL);
614 /* If the agent event exists, it must be available on the UST side. */
615 assert(uevent);
616
617 if (usess->active) {
618 ret = ust_app_disable_event_glb(usess, uchan, uevent);
619 if (ret < 0 && ret != -LTTNG_UST_ERR_EXIST) {
620 ret = LTTNG_ERR_UST_DISABLE_FAIL;
621 goto error;
622 }
623 }
624
625 /*
626 * Flag event that it's disabled so the shadow copy on the ust app side
627 * will disable it if an application shows up.
628 */
629 uevent->enabled = 0;
630
631 ret = agent_disable_event(aevent, agt->domain);
632 if (ret != LTTNG_OK) {
633 goto error;
634 }
635
636 end:
637 return LTTNG_OK;
638
639 error:
640 return ret;
641 }
642
643 /*
644 * Disable all agent events matching a given name for a given UST session.
645 *
646 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
647 */
648 int event_agent_disable(struct ltt_ust_session *usess, struct agent *agt,
649 const char *event_name)
650 {
651 int ret = LTTNG_OK;
652 struct agent_event *aevent;
653 struct lttng_ht_iter iter;
654 struct lttng_ht_node_str *node;
655
656 assert(agt);
657 assert(usess);
658 assert(event_name);
659
660 DBG("Event agent disabling %s (all loglevels) for session %" PRIu64, event_name, usess->id);
661
662 rcu_read_lock();
663 agent_find_events_by_name(event_name, agt, &iter);
664 node = lttng_ht_iter_get_node_str(&iter);
665
666 if (node == NULL) {
667 DBG2("Event agent NOT found by name %s", event_name);
668 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
669 goto end;
670 }
671
672 do {
673 aevent = caa_container_of(node, struct agent_event, node);
674 ret = event_agent_disable_one(usess, agt, aevent);
675
676 if (ret != LTTNG_OK) {
677 goto end;
678 }
679
680 /* Get next duplicate agent event by name. */
681 agent_event_next_duplicate(event_name, agt, &iter);
682 node = lttng_ht_iter_get_node_str(&iter);
683 } while (node);
684 end:
685 rcu_read_unlock();
686 return ret;
687 }
688 /*
689 * Disable all agent event for a given UST session.
690 *
691 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
692 */
693 int event_agent_disable_all(struct ltt_ust_session *usess,
694 struct agent *agt)
695 {
696 int ret;
697 struct agent_event *aevent;
698 struct lttng_ht_iter iter;
699
700 assert(agt);
701 assert(usess);
702
703 /*
704 * Disable event on agent application. Continue to disable all other events
705 * if the * event is not found.
706 */
707 ret = event_agent_disable(usess, agt, "*");
708 if (ret != LTTNG_OK && ret != LTTNG_ERR_UST_EVENT_NOT_FOUND) {
709 goto error;
710 }
711
712 /* Disable every event. */
713 rcu_read_lock();
714 cds_lfht_for_each_entry(agt->events->ht, &iter.iter, aevent,
715 node.node) {
716 if (!aevent->enabled) {
717 continue;
718 }
719
720 ret = event_agent_disable(usess, agt, aevent->name);
721 if (ret != LTTNG_OK) {
722 goto error_unlock;
723 }
724 }
725 ret = LTTNG_OK;
726
727 error_unlock:
728 rcu_read_unlock();
729 error:
730 return ret;
731 }
This page took 0.046471 seconds and 5 git commands to generate.