lttng: Add list-triggers command
[lttng-tools.git] / src / bin / lttng / commands / enable_events.c
1 /*
2 * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8 #define _LGPL_SOURCE
9 #include <assert.h>
10 #include <popt.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <sys/stat.h>
14 #include <sys/types.h>
15 #include <unistd.h>
16 #include <inttypes.h>
17 #include <ctype.h>
18
19 #include <common/sessiond-comm/sessiond-comm.h>
20 #include <common/compat/string.h>
21 #include <common/compat/getenv.h>
22 #include <common/string-utils/string-utils.h>
23 #include <common/utils.h>
24
25 /* Mi dependancy */
26 #include <common/mi-lttng.h>
27
28 #include <lttng/event-internal.h>
29
30 #include "../command.h"
31 #include "../loglevel.h"
32 #include "../uprobe.h"
33
34 #if (LTTNG_SYMBOL_NAME_LEN == 256)
35 #define LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "255"
36 #endif
37
38 static char *opt_event_list;
39 static int opt_event_type;
40 static const char *opt_loglevel;
41 static int opt_loglevel_type;
42 static int opt_kernel;
43 static char *opt_session_name;
44 static int opt_userspace;
45 static int opt_jul;
46 static int opt_log4j;
47 static int opt_python;
48 static int opt_enable_all;
49 static char *opt_probe;
50 static char *opt_userspace_probe;
51 static char *opt_function;
52 static char *opt_channel_name;
53 static char *opt_filter;
54 static char *opt_exclude;
55
56 #ifdef LTTNG_EMBED_HELP
57 static const char help_msg[] =
58 #include <lttng-enable-event.1.h>
59 ;
60 #endif
61
62 enum {
63 OPT_HELP = 1,
64 OPT_TRACEPOINT,
65 OPT_PROBE,
66 OPT_USERSPACE_PROBE,
67 OPT_FUNCTION,
68 OPT_SYSCALL,
69 OPT_USERSPACE,
70 OPT_LOGLEVEL,
71 OPT_LOGLEVEL_ONLY,
72 OPT_LIST_OPTIONS,
73 OPT_FILTER,
74 OPT_EXCLUDE,
75 };
76
77 static struct lttng_handle *handle;
78 static struct mi_writer *writer;
79
80 static struct poptOption long_options[] = {
81 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
82 {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0},
83 {"session", 's', POPT_ARG_STRING, &opt_session_name, 0, 0, 0},
84 {"all", 'a', POPT_ARG_VAL, &opt_enable_all, 1, 0, 0},
85 {"channel", 'c', POPT_ARG_STRING, &opt_channel_name, 0, 0, 0},
86 {"kernel", 'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0},
87 {"userspace", 'u', POPT_ARG_NONE, 0, OPT_USERSPACE, 0, 0},
88 {"jul", 'j', POPT_ARG_VAL, &opt_jul, 1, 0, 0},
89 {"log4j", 'l', POPT_ARG_VAL, &opt_log4j, 1, 0, 0},
90 {"python", 'p', POPT_ARG_VAL, &opt_python, 1, 0, 0},
91 {"tracepoint", 0, POPT_ARG_NONE, 0, OPT_TRACEPOINT, 0, 0},
92 {"probe", 0, POPT_ARG_STRING, &opt_probe, OPT_PROBE, 0, 0},
93 {"userspace-probe",0, POPT_ARG_STRING, &opt_userspace_probe, OPT_USERSPACE_PROBE, 0, 0},
94 {"function", 0, POPT_ARG_STRING, &opt_function, OPT_FUNCTION, 0, 0},
95 {"syscall", 0, POPT_ARG_NONE, 0, OPT_SYSCALL, 0, 0},
96 {"loglevel", 0, POPT_ARG_STRING, 0, OPT_LOGLEVEL, 0, 0},
97 {"loglevel-only", 0, POPT_ARG_STRING, 0, OPT_LOGLEVEL_ONLY, 0, 0},
98 {"list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL},
99 {"filter", 'f', POPT_ARG_STRING, &opt_filter, OPT_FILTER, 0, 0},
100 {"exclude", 'x', POPT_ARG_STRING, &opt_exclude, OPT_EXCLUDE, 0, 0},
101 {0, 0, 0, 0, 0, 0, 0}
102 };
103
104 /*
105 * Parse probe options.
106 */
107 static int parse_probe_opts(struct lttng_event *ev, char *opt)
108 {
109 int ret = CMD_SUCCESS;
110 int match;
111 char s_hex[19];
112 #define S_HEX_LEN_SCANF_IS_A_BROKEN_API "18" /* 18 is (19 - 1) (\0 is extra) */
113 char name[LTTNG_SYMBOL_NAME_LEN];
114
115 if (opt == NULL) {
116 ret = CMD_ERROR;
117 goto end;
118 }
119
120 /* Check for symbol+offset */
121 match = sscanf(opt, "%" LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API
122 "[^'+']+%" S_HEX_LEN_SCANF_IS_A_BROKEN_API "s", name, s_hex);
123 if (match == 2) {
124 strncpy(ev->attr.probe.symbol_name, name, LTTNG_SYMBOL_NAME_LEN);
125 ev->attr.probe.symbol_name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
126 DBG("probe symbol %s", ev->attr.probe.symbol_name);
127 if (*s_hex == '\0') {
128 ERR("Invalid probe offset %s", s_hex);
129 ret = CMD_ERROR;
130 goto end;
131 }
132 ev->attr.probe.offset = strtoul(s_hex, NULL, 0);
133 DBG("probe offset %" PRIu64, ev->attr.probe.offset);
134 ev->attr.probe.addr = 0;
135 goto end;
136 }
137
138 /* Check for symbol */
139 if (isalpha(name[0]) || name[0] == '_') {
140 match = sscanf(opt, "%" LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "s",
141 name);
142 if (match == 1) {
143 strncpy(ev->attr.probe.symbol_name, name, LTTNG_SYMBOL_NAME_LEN);
144 ev->attr.probe.symbol_name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
145 DBG("probe symbol %s", ev->attr.probe.symbol_name);
146 ev->attr.probe.offset = 0;
147 DBG("probe offset %" PRIu64, ev->attr.probe.offset);
148 ev->attr.probe.addr = 0;
149 goto end;
150 }
151 }
152
153 /* Check for address */
154 match = sscanf(opt, "%" S_HEX_LEN_SCANF_IS_A_BROKEN_API "s", s_hex);
155 if (match > 0) {
156 /*
157 * Return an error if the first character of the tentative
158 * address is NULL or not a digit. It can be "0" if the address
159 * is in hexadecimal and can be 1 to 9 if it's in decimal.
160 */
161 if (*s_hex == '\0' || !isdigit(*s_hex)) {
162 ERR("Invalid probe description %s", s_hex);
163 ret = CMD_ERROR;
164 goto end;
165 }
166 ev->attr.probe.addr = strtoul(s_hex, NULL, 0);
167 DBG("probe addr %" PRIu64, ev->attr.probe.addr);
168 ev->attr.probe.offset = 0;
169 memset(ev->attr.probe.symbol_name, 0, LTTNG_SYMBOL_NAME_LEN);
170 goto end;
171 }
172
173 /* No match */
174 ret = CMD_ERROR;
175
176 end:
177 return ret;
178 }
179
180 static
181 const char *print_channel_name(const char *name)
182 {
183 return name ? : DEFAULT_CHANNEL_NAME;
184 }
185
186 static
187 const char *print_raw_channel_name(const char *name)
188 {
189 return name ? : "<default>";
190 }
191
192 /*
193 * Mi print exlcusion list
194 */
195 static
196 int mi_print_exclusion(char **names)
197 {
198 int i, ret;
199 int count = names ? strutils_array_of_strings_len(names) : 0;
200
201 assert(writer);
202
203 if (count == 0) {
204 ret = 0;
205 goto end;
206 }
207 ret = mi_lttng_writer_open_element(writer, config_element_exclusions);
208 if (ret) {
209 goto end;
210 }
211
212 for (i = 0; i < count; i++) {
213 ret = mi_lttng_writer_write_element_string(writer,
214 config_element_exclusion, names[i]);
215 if (ret) {
216 goto end;
217 }
218 }
219
220 /* Close exclusions element */
221 ret = mi_lttng_writer_close_element(writer);
222
223 end:
224 return ret;
225 }
226
227 /*
228 * Return allocated string for pretty-printing exclusion names.
229 */
230 static
231 char *print_exclusions(char **names)
232 {
233 int length = 0;
234 int i;
235 const char preamble[] = " excluding ";
236 char *ret;
237 int count = names ? strutils_array_of_strings_len(names) : 0;
238
239 if (count == 0) {
240 return strdup("");
241 }
242
243 /* calculate total required length */
244 for (i = 0; i < count; i++) {
245 length += strlen(names[i]) + 4;
246 }
247
248 length += sizeof(preamble);
249 ret = zmalloc(length);
250 if (!ret) {
251 return NULL;
252 }
253 strncpy(ret, preamble, length);
254 for (i = 0; i < count; i++) {
255 strcat(ret, "\"");
256 strcat(ret, names[i]);
257 strcat(ret, "\"");
258 if (i != count - 1) {
259 strcat(ret, ", ");
260 }
261 }
262
263 return ret;
264 }
265
266 static
267 int check_exclusion_subsets(const char *event_name, const char *exclusion)
268 {
269 bool warn = false;
270 int ret = 0;
271 const char *e = event_name;
272 const char *x = exclusion;
273
274 /* Scan both the excluder and the event letter by letter */
275 while (true) {
276 if (*e == '\\') {
277 if (*x != *e) {
278 warn = true;
279 goto end;
280 }
281
282 e++;
283 x++;
284 goto cmp_chars;
285 }
286
287 if (*x == '*') {
288 /* Event is a subset of the excluder */
289 ERR("Event %s: %s excludes all events from %s",
290 event_name, exclusion, event_name);
291 goto error;
292 }
293
294 if (*e == '*') {
295 /*
296 * Reached the end of the event name before the
297 * end of the exclusion: this is valid.
298 */
299 goto end;
300 }
301
302 cmp_chars:
303 if (*x != *e) {
304 warn = true;
305 break;
306 }
307
308 x++;
309 e++;
310 }
311
312 goto end;
313
314 error:
315 ret = -1;
316
317 end:
318 if (warn) {
319 WARN("Event %s: %s does not exclude any events from %s",
320 event_name, exclusion, event_name);
321 }
322
323 return ret;
324 }
325
326 /*
327 * FIXME: find a good place to declare this since add trigger also uses it
328 */
329 LTTNG_HIDDEN
330 int create_exclusion_list_and_validate(const char *event_name,
331 const char *exclusions_arg,
332 char ***exclusion_list);
333
334
335 LTTNG_HIDDEN
336 int create_exclusion_list_and_validate(const char *event_name,
337 const char *exclusions_arg,
338 char ***exclusion_list)
339 {
340 int ret = 0;
341 char **exclusions = NULL;
342
343 /* Event name must be a valid globbing pattern to allow exclusions. */
344 if (!strutils_is_star_glob_pattern(event_name)) {
345 ERR("Event %s: Exclusions can only be used with a globbing pattern",
346 event_name);
347 goto error;
348 }
349
350 /* Split exclusions. */
351 exclusions = strutils_split(exclusions_arg, ',', true);
352 if (!exclusions) {
353 goto error;
354 }
355
356 /*
357 * If the event name is a star-at-end only globbing pattern,
358 * then we can validate the individual exclusions. Otherwise
359 * all exclusions are passed to the session daemon.
360 */
361 if (strutils_is_star_at_the_end_only_glob_pattern(event_name)) {
362 char * const *exclusion;
363
364 for (exclusion = exclusions; *exclusion; exclusion++) {
365 if (!strutils_is_star_glob_pattern(*exclusion) ||
366 strutils_is_star_at_the_end_only_glob_pattern(*exclusion)) {
367 ret = check_exclusion_subsets(event_name, *exclusion);
368 if (ret) {
369 goto error;
370 }
371 }
372 }
373 }
374
375 *exclusion_list = exclusions;
376
377 goto end;
378
379 error:
380 ret = -1;
381 strutils_free_null_terminated_array_of_strings(exclusions);
382
383 end:
384 return ret;
385 }
386
387 static void warn_on_truncated_exclusion_names(char * const *exclusion_list,
388 int *warn)
389 {
390 char * const *exclusion;
391
392 for (exclusion = exclusion_list; *exclusion; exclusion++) {
393 if (strlen(*exclusion) >= LTTNG_SYMBOL_NAME_LEN) {
394 WARN("Event exclusion \"%s\" will be truncated",
395 *exclusion);
396 *warn = 1;
397 }
398 }
399 }
400
401 /*
402 * Enabling event using the lttng API.
403 * Note: in case of error only the last error code will be return.
404 */
405 static int enable_events(char *session_name)
406 {
407 int ret = CMD_SUCCESS, command_ret = CMD_SUCCESS;
408 int error_holder = CMD_SUCCESS, warn = 0, error = 0, success = 1;
409 char *event_name, *channel_name = NULL;
410 struct lttng_event *ev;
411 struct lttng_domain dom;
412 char **exclusion_list = NULL;
413 struct lttng_userspace_probe_location *uprobe_loc = NULL;
414
415 memset(&dom, 0, sizeof(dom));
416
417 ev = lttng_event_create();
418 if (!ev) {
419 ret = CMD_ERROR;
420 goto error;
421 }
422
423 if (opt_kernel) {
424 if (opt_loglevel) {
425 WARN("Kernel loglevels are not supported.");
426 }
427 }
428
429 /* Create lttng domain */
430 if (opt_kernel) {
431 dom.type = LTTNG_DOMAIN_KERNEL;
432 dom.buf_type = LTTNG_BUFFER_GLOBAL;
433 } else if (opt_userspace) {
434 dom.type = LTTNG_DOMAIN_UST;
435 /* Default. */
436 dom.buf_type = LTTNG_BUFFER_PER_UID;
437 } else if (opt_jul) {
438 dom.type = LTTNG_DOMAIN_JUL;
439 /* Default. */
440 dom.buf_type = LTTNG_BUFFER_PER_UID;
441 } else if (opt_log4j) {
442 dom.type = LTTNG_DOMAIN_LOG4J;
443 /* Default. */
444 dom.buf_type = LTTNG_BUFFER_PER_UID;
445 } else if (opt_python) {
446 dom.type = LTTNG_DOMAIN_PYTHON;
447 /* Default. */
448 dom.buf_type = LTTNG_BUFFER_PER_UID;
449 } else {
450 /* Checked by the caller. */
451 assert(0);
452 }
453
454 if (opt_exclude) {
455 switch (dom.type) {
456 case LTTNG_DOMAIN_KERNEL:
457 case LTTNG_DOMAIN_JUL:
458 case LTTNG_DOMAIN_LOG4J:
459 case LTTNG_DOMAIN_PYTHON:
460 ERR("Event name exclusions are not yet implemented for %s events",
461 get_domain_str(dom.type));
462 ret = CMD_ERROR;
463 goto error;
464 case LTTNG_DOMAIN_UST:
465 /* Exclusions supported */
466 break;
467 default:
468 assert(0);
469 }
470 }
471
472 /*
473 * Adding a filter to a probe, function or userspace-probe would be
474 * denied by the kernel tracer as it's not supported at the moment. We
475 * do an early check here to warn the user.
476 */
477 if (opt_filter && opt_kernel) {
478 switch (opt_event_type) {
479 case LTTNG_EVENT_ALL:
480 case LTTNG_EVENT_TRACEPOINT:
481 case LTTNG_EVENT_SYSCALL:
482 break;
483 case LTTNG_EVENT_PROBE:
484 case LTTNG_EVENT_USERSPACE_PROBE:
485 case LTTNG_EVENT_FUNCTION:
486 ERR("Filter expressions are not supported for %s events",
487 get_event_type_str(opt_event_type));
488 ret = CMD_ERROR;
489 goto error;
490 default:
491 ret = CMD_UNDEFINED;
492 goto error;
493 }
494 }
495
496 channel_name = opt_channel_name;
497
498 handle = lttng_create_handle(session_name, &dom);
499 if (handle == NULL) {
500 ret = -1;
501 goto error;
502 }
503
504 /* Prepare Mi */
505 if (lttng_opt_mi) {
506 /* Open a events element */
507 ret = mi_lttng_writer_open_element(writer, config_element_events);
508 if (ret) {
509 ret = CMD_ERROR;
510 goto error;
511 }
512 }
513
514 if (opt_enable_all) {
515 /* Default setup for enable all */
516 if (opt_kernel) {
517 ev->type = opt_event_type;
518 strcpy(ev->name, "*");
519 /* kernel loglevels not implemented */
520 ev->loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
521 } else {
522 ev->type = LTTNG_EVENT_TRACEPOINT;
523 strcpy(ev->name, "*");
524 ev->loglevel_type = opt_loglevel_type;
525 if (opt_loglevel) {
526 int name_search_ret;
527
528 assert(opt_userspace || opt_jul || opt_log4j || opt_python);
529
530 if (opt_userspace) {
531 enum lttng_loglevel loglevel;
532
533 name_search_ret = loglevel_name_to_value(opt_loglevel, &loglevel);
534 ev->loglevel = (int) loglevel;
535 } else if (opt_jul) {
536 enum lttng_loglevel_jul loglevel;
537
538 name_search_ret = loglevel_jul_name_to_value(opt_loglevel, &loglevel);
539 ev->loglevel = (int) loglevel;
540 } else if (opt_log4j) {
541 enum lttng_loglevel_log4j loglevel;
542
543 name_search_ret = loglevel_log4j_name_to_value(opt_loglevel, &loglevel);
544 ev->loglevel = (int) loglevel;
545 } else {
546 /* python domain. */
547 enum lttng_loglevel_python loglevel;
548
549 name_search_ret = loglevel_python_name_to_value(opt_loglevel, &loglevel);
550 ev->loglevel = (int) loglevel;
551 }
552
553 if (name_search_ret == -1) {
554 ERR("Unknown loglevel %s", opt_loglevel);
555 ret = -LTTNG_ERR_INVALID;
556 goto error;
557 }
558 } else {
559 assert(opt_userspace || opt_jul || opt_log4j || opt_python);
560 if (opt_userspace) {
561 ev->loglevel = -1;
562 } else if (opt_jul) {
563 ev->loglevel = LTTNG_LOGLEVEL_JUL_ALL;
564 } else if (opt_log4j) {
565 ev->loglevel = LTTNG_LOGLEVEL_LOG4J_ALL;
566 } else if (opt_python) {
567 ev->loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG;
568 }
569 }
570 }
571
572 if (opt_exclude) {
573 ret = create_exclusion_list_and_validate("*",
574 opt_exclude, &exclusion_list);
575 if (ret) {
576 ret = CMD_ERROR;
577 goto error;
578 }
579
580 ev->exclusion = 1;
581 warn_on_truncated_exclusion_names(exclusion_list,
582 &warn);
583 }
584 if (!opt_filter) {
585 ret = lttng_enable_event_with_exclusions(handle,
586 ev, channel_name,
587 NULL,
588 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
589 exclusion_list);
590 if (ret < 0) {
591 switch (-ret) {
592 case LTTNG_ERR_KERN_EVENT_EXIST:
593 WARN("Kernel events already enabled (channel %s, session %s)",
594 print_channel_name(channel_name), session_name);
595 warn = 1;
596 break;
597 case LTTNG_ERR_TRACE_ALREADY_STARTED:
598 {
599 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
600 ERR("Events: %s (channel %s, session %s)",
601 msg,
602 print_channel_name(channel_name),
603 session_name);
604 error = 1;
605 break;
606 }
607 default:
608 ERR("Events: %s (channel %s, session %s)",
609 lttng_strerror(ret),
610 ret == -LTTNG_ERR_NEED_CHANNEL_NAME
611 ? print_raw_channel_name(channel_name)
612 : print_channel_name(channel_name),
613 session_name);
614 error = 1;
615 break;
616 }
617 goto end;
618 }
619
620 switch (opt_event_type) {
621 case LTTNG_EVENT_TRACEPOINT:
622 if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) {
623 char *exclusion_string = print_exclusions(exclusion_list);
624
625 if (!exclusion_string) {
626 PERROR("Cannot allocate exclusion_string");
627 error = 1;
628 goto end;
629 }
630 MSG("All %s tracepoints%s are enabled in channel %s for loglevel %s",
631 get_domain_str(dom.type),
632 exclusion_string,
633 print_channel_name(channel_name),
634 opt_loglevel);
635 free(exclusion_string);
636 } else {
637 char *exclusion_string = print_exclusions(exclusion_list);
638
639 if (!exclusion_string) {
640 PERROR("Cannot allocate exclusion_string");
641 error = 1;
642 goto end;
643 }
644 MSG("All %s tracepoints%s are enabled in channel %s",
645 get_domain_str(dom.type),
646 exclusion_string,
647 print_channel_name(channel_name));
648 free(exclusion_string);
649 }
650 break;
651 case LTTNG_EVENT_SYSCALL:
652 if (opt_kernel) {
653 MSG("All %s system calls are enabled in channel %s",
654 get_domain_str(dom.type),
655 print_channel_name(channel_name));
656 }
657 break;
658 case LTTNG_EVENT_ALL:
659 if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) {
660 char *exclusion_string = print_exclusions(exclusion_list);
661
662 if (!exclusion_string) {
663 PERROR("Cannot allocate exclusion_string");
664 error = 1;
665 goto end;
666 }
667 MSG("All %s events%s are enabled in channel %s for loglevel %s",
668 get_domain_str(dom.type),
669 exclusion_string,
670 print_channel_name(channel_name),
671 opt_loglevel);
672 free(exclusion_string);
673 } else {
674 char *exclusion_string = print_exclusions(exclusion_list);
675
676 if (!exclusion_string) {
677 PERROR("Cannot allocate exclusion_string");
678 error = 1;
679 goto end;
680 }
681 MSG("All %s events%s are enabled in channel %s",
682 get_domain_str(dom.type),
683 exclusion_string,
684 print_channel_name(channel_name));
685 free(exclusion_string);
686 }
687 break;
688 default:
689 /*
690 * We should not be here since lttng_enable_event should have
691 * failed on the event type.
692 */
693 goto error;
694 }
695 }
696
697 if (opt_filter) {
698 command_ret = lttng_enable_event_with_exclusions(handle, ev, channel_name,
699 opt_filter,
700 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
701 exclusion_list);
702 if (command_ret < 0) {
703 switch (-command_ret) {
704 case LTTNG_ERR_FILTER_EXIST:
705 WARN("Filter on all events is already enabled"
706 " (channel %s, session %s)",
707 print_channel_name(channel_name), session_name);
708 warn = 1;
709 break;
710 case LTTNG_ERR_TRACE_ALREADY_STARTED:
711 {
712 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
713 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
714 msg,
715 print_channel_name(channel_name),
716 session_name, opt_filter);
717 error = 1;
718 break;
719 }
720 default:
721 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
722 lttng_strerror(command_ret),
723 command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
724 ? print_raw_channel_name(channel_name)
725 : print_channel_name(channel_name),
726 session_name, opt_filter);
727 error = 1;
728 break;
729 }
730 error_holder = command_ret;
731 } else {
732 ev->filter = 1;
733 MSG("Filter '%s' successfully set", opt_filter);
734 }
735 }
736
737 if (lttng_opt_mi) {
738 /* The wildcard * is used for kernel and ust domain to
739 * represent ALL. We copy * in event name to force the wildcard use
740 * for kernel domain
741 *
742 * Note: this is strictly for semantic and printing while in
743 * machine interface mode.
744 */
745 strcpy(ev->name, "*");
746
747 /* If we reach here the events are enabled */
748 if (!error && !warn) {
749 ev->enabled = 1;
750 } else {
751 ev->enabled = 0;
752 success = 0;
753 }
754 ret = mi_lttng_event(writer, ev, 1, handle->domain.type);
755 if (ret) {
756 ret = CMD_ERROR;
757 goto error;
758 }
759
760 /* print exclusion */
761 ret = mi_print_exclusion(exclusion_list);
762 if (ret) {
763 ret = CMD_ERROR;
764 goto error;
765 }
766
767 /* Success ? */
768 ret = mi_lttng_writer_write_element_bool(writer,
769 mi_lttng_element_command_success, success);
770 if (ret) {
771 ret = CMD_ERROR;
772 goto error;
773 }
774
775 /* Close event element */
776 ret = mi_lttng_writer_close_element(writer);
777 if (ret) {
778 ret = CMD_ERROR;
779 goto error;
780 }
781 }
782
783 goto end;
784 }
785
786 /* Strip event list */
787 event_name = strtok(opt_event_list, ",");
788 while (event_name != NULL) {
789 /* Copy name and type of the event */
790 strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN);
791 ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
792 ev->type = opt_event_type;
793
794 /* Kernel tracer action */
795 if (opt_kernel) {
796 DBG("Enabling kernel event %s for channel %s",
797 event_name,
798 print_channel_name(channel_name));
799
800 switch (opt_event_type) {
801 case LTTNG_EVENT_ALL: /* Enable tracepoints and syscalls */
802 /* If event name differs from *, select tracepoint. */
803 if (strcmp(ev->name, "*")) {
804 ev->type = LTTNG_EVENT_TRACEPOINT;
805 }
806 break;
807 case LTTNG_EVENT_TRACEPOINT:
808 break;
809 case LTTNG_EVENT_PROBE:
810 ret = parse_probe_opts(ev, opt_probe);
811 if (ret) {
812 ERR("Unable to parse probe options");
813 ret = CMD_ERROR;
814 goto error;
815 }
816 break;
817 case LTTNG_EVENT_USERSPACE_PROBE:
818 assert(ev->type == LTTNG_EVENT_USERSPACE_PROBE);
819
820 ret = parse_userspace_probe_opts(opt_userspace_probe, &uprobe_loc);
821 if (ret) {
822 switch (ret) {
823 case CMD_UNSUPPORTED:
824 /*
825 * Error message describing
826 * what is not supported was
827 * printed in the function.
828 */
829 break;
830 case CMD_ERROR:
831 default:
832 ERR("Unable to parse userspace probe options");
833 break;
834 }
835 goto error;
836 }
837
838 ret = lttng_event_set_userspace_probe_location(ev, uprobe_loc);
839 if (ret) {
840 WARN("Failed to set probe location on event");
841 ret = CMD_ERROR;
842 goto error;
843 }
844
845 /* Ownership of the uprobe location was transferred to the event. */
846 uprobe_loc = NULL;
847 break;
848 case LTTNG_EVENT_FUNCTION:
849 ret = parse_probe_opts(ev, opt_function);
850 if (ret) {
851 ERR("Unable to parse function probe options");
852 ret = CMD_ERROR;
853 goto error;
854 }
855 break;
856 case LTTNG_EVENT_SYSCALL:
857 ev->type = LTTNG_EVENT_SYSCALL;
858 break;
859 default:
860 ret = CMD_UNDEFINED;
861 goto error;
862 }
863
864 /* kernel loglevels not implemented */
865 ev->loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
866 } else if (opt_userspace) { /* User-space tracer action */
867 DBG("Enabling UST event %s for channel %s, loglevel %s", event_name,
868 print_channel_name(channel_name), opt_loglevel ? : "<all>");
869
870 switch (opt_event_type) {
871 case LTTNG_EVENT_ALL: /* Default behavior is tracepoint */
872 /* Fall-through */
873 case LTTNG_EVENT_TRACEPOINT:
874 /* Copy name and type of the event */
875 ev->type = LTTNG_EVENT_TRACEPOINT;
876 strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN);
877 ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
878 break;
879 case LTTNG_EVENT_PROBE:
880 case LTTNG_EVENT_FUNCTION:
881 case LTTNG_EVENT_SYSCALL:
882 case LTTNG_EVENT_USERSPACE_PROBE:
883 default:
884 ERR("Event type not available for user-space tracing");
885 ret = CMD_UNSUPPORTED;
886 goto error;
887 }
888
889 if (opt_exclude) {
890 ev->exclusion = 1;
891 if (opt_event_type != LTTNG_EVENT_ALL && opt_event_type != LTTNG_EVENT_TRACEPOINT) {
892 ERR("Exclusion option can only be used with tracepoint events");
893 ret = CMD_ERROR;
894 goto error;
895 }
896 /* Free previously allocated items */
897 strutils_free_null_terminated_array_of_strings(
898 exclusion_list);
899 exclusion_list = NULL;
900 ret = create_exclusion_list_and_validate(
901 event_name, opt_exclude,
902 &exclusion_list);
903 if (ret) {
904 ret = CMD_ERROR;
905 goto error;
906 }
907
908 warn_on_truncated_exclusion_names(
909 exclusion_list, &warn);
910 }
911
912 ev->loglevel_type = opt_loglevel_type;
913 if (opt_loglevel) {
914 enum lttng_loglevel loglevel;
915 const int name_search_ret = loglevel_name_to_value(opt_loglevel, &loglevel);
916
917 if (name_search_ret == -1) {
918 ERR("Unknown loglevel %s", opt_loglevel);
919 ret = -LTTNG_ERR_INVALID;
920 goto error;
921 }
922
923 ev->loglevel = (int) loglevel;
924 } else {
925 ev->loglevel = -1;
926 }
927 } else if (opt_jul || opt_log4j || opt_python) {
928 if (opt_event_type != LTTNG_EVENT_ALL &&
929 opt_event_type != LTTNG_EVENT_TRACEPOINT) {
930 ERR("Event type not supported for domain.");
931 ret = CMD_UNSUPPORTED;
932 goto error;
933 }
934
935 ev->loglevel_type = opt_loglevel_type;
936 if (opt_loglevel) {
937 int name_search_ret;
938
939 if (opt_jul) {
940 enum lttng_loglevel_jul loglevel;
941
942 name_search_ret = loglevel_jul_name_to_value(opt_loglevel, &loglevel);
943 ev->loglevel = (int) loglevel;
944 } else if (opt_log4j) {
945 enum lttng_loglevel_log4j loglevel;
946
947 name_search_ret = loglevel_log4j_name_to_value(opt_loglevel, &loglevel);
948 ev->loglevel = (int) loglevel;
949 } else {
950 /* python domain. */
951 enum lttng_loglevel_python loglevel;
952
953 name_search_ret = loglevel_python_name_to_value(opt_loglevel, &loglevel);
954 ev->loglevel = (int) loglevel;
955 }
956
957 if (name_search_ret) {
958 ERR("Unknown loglevel %s", opt_loglevel);
959 ret = -LTTNG_ERR_INVALID;
960 goto error;
961 }
962 } else {
963 if (opt_jul) {
964 ev->loglevel = LTTNG_LOGLEVEL_JUL_ALL;
965 } else if (opt_log4j) {
966 ev->loglevel = LTTNG_LOGLEVEL_LOG4J_ALL;
967 } else if (opt_python) {
968 ev->loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG;
969 }
970 }
971 ev->type = LTTNG_EVENT_TRACEPOINT;
972 strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN);
973 ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
974 } else {
975 assert(0);
976 }
977
978 if (!opt_filter) {
979 char *exclusion_string;
980
981 command_ret = lttng_enable_event_with_exclusions(handle,
982 ev, channel_name,
983 NULL,
984 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
985 exclusion_list);
986 exclusion_string = print_exclusions(exclusion_list);
987 if (!exclusion_string) {
988 PERROR("Cannot allocate exclusion_string");
989 error = 1;
990 goto end;
991 }
992 if (command_ret < 0) {
993 /* Turn ret to positive value to handle the positive error code */
994 switch (-command_ret) {
995 case LTTNG_ERR_KERN_EVENT_EXIST:
996 WARN("Kernel event %s%s already enabled (channel %s, session %s)",
997 event_name,
998 exclusion_string,
999 print_channel_name(channel_name), session_name);
1000 warn = 1;
1001 break;
1002 case LTTNG_ERR_TRACE_ALREADY_STARTED:
1003 {
1004 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
1005 ERR("Event %s%s: %s (channel %s, session %s)", event_name,
1006 exclusion_string,
1007 msg,
1008 print_channel_name(channel_name),
1009 session_name);
1010 error = 1;
1011 break;
1012 }
1013 case LTTNG_ERR_SDT_PROBE_SEMAPHORE:
1014 ERR("SDT probes %s guarded by semaphores are not supported (channel %s, session %s)",
1015 event_name, print_channel_name(channel_name),
1016 session_name);
1017 error = 1;
1018 break;
1019 default:
1020 ERR("Event %s%s: %s (channel %s, session %s)", event_name,
1021 exclusion_string,
1022 lttng_strerror(command_ret),
1023 command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
1024 ? print_raw_channel_name(channel_name)
1025 : print_channel_name(channel_name),
1026 session_name);
1027 error = 1;
1028 break;
1029 }
1030 error_holder = command_ret;
1031 } else {
1032 switch (dom.type) {
1033 case LTTNG_DOMAIN_KERNEL:
1034 case LTTNG_DOMAIN_UST:
1035 MSG("%s event %s%s created in channel %s",
1036 get_domain_str(dom.type),
1037 event_name,
1038 exclusion_string,
1039 print_channel_name(channel_name));
1040 break;
1041 case LTTNG_DOMAIN_JUL:
1042 case LTTNG_DOMAIN_LOG4J:
1043 case LTTNG_DOMAIN_PYTHON:
1044 /*
1045 * Don't print the default channel
1046 * name for agent domains.
1047 */
1048 MSG("%s event %s%s enabled",
1049 get_domain_str(dom.type),
1050 event_name,
1051 exclusion_string);
1052 break;
1053 default:
1054 assert(0);
1055 }
1056 }
1057 free(exclusion_string);
1058 }
1059
1060 if (opt_filter) {
1061 char *exclusion_string;
1062
1063 /* Filter present */
1064 ev->filter = 1;
1065
1066 command_ret = lttng_enable_event_with_exclusions(handle, ev, channel_name,
1067 opt_filter,
1068 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
1069 exclusion_list);
1070 exclusion_string = print_exclusions(exclusion_list);
1071 if (!exclusion_string) {
1072 PERROR("Cannot allocate exclusion_string");
1073 error = 1;
1074 goto end;
1075 }
1076 if (command_ret < 0) {
1077 switch (-command_ret) {
1078 case LTTNG_ERR_FILTER_EXIST:
1079 WARN("Filter on event %s%s is already enabled"
1080 " (channel %s, session %s)",
1081 event_name,
1082 exclusion_string,
1083 print_channel_name(channel_name), session_name);
1084 warn = 1;
1085 break;
1086 case LTTNG_ERR_TRACE_ALREADY_STARTED:
1087 {
1088 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
1089 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev->name,
1090 exclusion_string,
1091 msg,
1092 print_channel_name(channel_name),
1093 session_name, opt_filter);
1094 error = 1;
1095 break;
1096 }
1097 default:
1098 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev->name,
1099 exclusion_string,
1100 lttng_strerror(command_ret),
1101 command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
1102 ? print_raw_channel_name(channel_name)
1103 : print_channel_name(channel_name),
1104 session_name, opt_filter);
1105 error = 1;
1106 break;
1107 }
1108 error_holder = command_ret;
1109
1110 } else {
1111 MSG("Event %s%s: Filter '%s' successfully set",
1112 event_name, exclusion_string,
1113 opt_filter);
1114 }
1115 free(exclusion_string);
1116 }
1117
1118 if (lttng_opt_mi) {
1119 if (command_ret) {
1120 success = 0;
1121 ev->enabled = 0;
1122 } else {
1123 ev->enabled = 1;
1124 }
1125
1126 ret = mi_lttng_event(writer, ev, 1, handle->domain.type);
1127 if (ret) {
1128 ret = CMD_ERROR;
1129 goto error;
1130 }
1131
1132 /* print exclusion */
1133 ret = mi_print_exclusion(exclusion_list);
1134 if (ret) {
1135 ret = CMD_ERROR;
1136 goto error;
1137 }
1138
1139 /* Success ? */
1140 ret = mi_lttng_writer_write_element_bool(writer,
1141 mi_lttng_element_command_success, success);
1142 if (ret) {
1143 ret = CMD_ERROR;
1144 goto end;
1145 }
1146
1147 /* Close event element */
1148 ret = mi_lttng_writer_close_element(writer);
1149 if (ret) {
1150 ret = CMD_ERROR;
1151 goto end;
1152 }
1153 }
1154
1155 /* Next event */
1156 event_name = strtok(NULL, ",");
1157 /* Reset warn, error and success */
1158 success = 1;
1159 }
1160
1161 end:
1162 /* Close Mi */
1163 if (lttng_opt_mi) {
1164 /* Close events element */
1165 ret = mi_lttng_writer_close_element(writer);
1166 if (ret) {
1167 ret = CMD_ERROR;
1168 goto error;
1169 }
1170 }
1171 error:
1172 if (warn) {
1173 ret = CMD_WARNING;
1174 }
1175 if (error) {
1176 ret = CMD_ERROR;
1177 }
1178 lttng_destroy_handle(handle);
1179 strutils_free_null_terminated_array_of_strings(exclusion_list);
1180 lttng_userspace_probe_location_destroy(uprobe_loc);
1181
1182 /* Overwrite ret with error_holder if there was an actual error with
1183 * enabling an event.
1184 */
1185 ret = error_holder ? error_holder : ret;
1186
1187 lttng_event_destroy(ev);
1188 return ret;
1189 }
1190
1191 /*
1192 * Add event to trace session
1193 */
1194 int cmd_enable_events(int argc, const char **argv)
1195 {
1196 int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
1197 static poptContext pc;
1198 char *session_name = NULL;
1199 const char *leftover = NULL;
1200 int event_type = -1;
1201
1202 pc = poptGetContext(NULL, argc, argv, long_options, 0);
1203 poptReadDefaultConfig(pc, 0);
1204
1205 /* Default event type */
1206 opt_event_type = LTTNG_EVENT_ALL;
1207
1208 while ((opt = poptGetNextOpt(pc)) != -1) {
1209 switch (opt) {
1210 case OPT_HELP:
1211 SHOW_HELP();
1212 goto end;
1213 case OPT_TRACEPOINT:
1214 opt_event_type = LTTNG_EVENT_TRACEPOINT;
1215 break;
1216 case OPT_PROBE:
1217 opt_event_type = LTTNG_EVENT_PROBE;
1218 break;
1219 case OPT_USERSPACE_PROBE:
1220 opt_event_type = LTTNG_EVENT_USERSPACE_PROBE;
1221 break;
1222 case OPT_FUNCTION:
1223 opt_event_type = LTTNG_EVENT_FUNCTION;
1224 break;
1225 case OPT_SYSCALL:
1226 opt_event_type = LTTNG_EVENT_SYSCALL;
1227 break;
1228 case OPT_USERSPACE:
1229 opt_userspace = 1;
1230 break;
1231 case OPT_LOGLEVEL:
1232 opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_RANGE;
1233 opt_loglevel = poptGetOptArg(pc);
1234 break;
1235 case OPT_LOGLEVEL_ONLY:
1236 opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_SINGLE;
1237 opt_loglevel = poptGetOptArg(pc);
1238 break;
1239 case OPT_LIST_OPTIONS:
1240 list_cmd_options(stdout, long_options);
1241 goto end;
1242 case OPT_FILTER:
1243 break;
1244 case OPT_EXCLUDE:
1245 break;
1246 default:
1247 ret = CMD_UNDEFINED;
1248 goto end;
1249 }
1250
1251 /* Validate event type. Multiple event type are not supported. */
1252 if (event_type == -1) {
1253 event_type = opt_event_type;
1254 } else {
1255 if (event_type != opt_event_type) {
1256 ERR("Multiple event type not supported.");
1257 ret = CMD_ERROR;
1258 goto end;
1259 }
1260 }
1261 }
1262
1263 ret = print_missing_or_multiple_domains(
1264 opt_kernel + opt_userspace + opt_jul + opt_log4j +
1265 opt_python,
1266 true);
1267 if (ret) {
1268 ret = CMD_ERROR;
1269 goto end;
1270 }
1271
1272 /* Mi check */
1273 if (lttng_opt_mi) {
1274 writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
1275 if (!writer) {
1276 ret = -LTTNG_ERR_NOMEM;
1277 goto end;
1278 }
1279
1280 /* Open command element */
1281 ret = mi_lttng_writer_command_open(writer,
1282 mi_lttng_element_command_enable_event);
1283 if (ret) {
1284 ret = CMD_ERROR;
1285 goto end;
1286 }
1287
1288 /* Open output element */
1289 ret = mi_lttng_writer_open_element(writer,
1290 mi_lttng_element_command_output);
1291 if (ret) {
1292 ret = CMD_ERROR;
1293 goto end;
1294 }
1295 }
1296
1297 opt_event_list = (char*) poptGetArg(pc);
1298 if (opt_event_list == NULL && opt_enable_all == 0) {
1299 ERR("Missing event name(s).\n");
1300 ret = CMD_ERROR;
1301 goto end;
1302 }
1303
1304 leftover = poptGetArg(pc);
1305 if (leftover) {
1306 ERR("Unknown argument: %s", leftover);
1307 ret = CMD_ERROR;
1308 goto end;
1309 }
1310
1311 if (!opt_session_name) {
1312 session_name = get_session_name();
1313 if (session_name == NULL) {
1314 command_ret = CMD_ERROR;
1315 success = 0;
1316 goto mi_closing;
1317 }
1318 } else {
1319 session_name = opt_session_name;
1320 }
1321
1322 command_ret = enable_events(session_name);
1323 if (command_ret) {
1324 success = 0;
1325 goto mi_closing;
1326 }
1327
1328 mi_closing:
1329 /* Mi closing */
1330 if (lttng_opt_mi) {
1331 /* Close output element */
1332 ret = mi_lttng_writer_close_element(writer);
1333 if (ret) {
1334 ret = CMD_ERROR;
1335 goto end;
1336 }
1337
1338 ret = mi_lttng_writer_write_element_bool(writer,
1339 mi_lttng_element_command_success, success);
1340 if (ret) {
1341 ret = CMD_ERROR;
1342 goto end;
1343 }
1344
1345 /* Command element close */
1346 ret = mi_lttng_writer_command_close(writer);
1347 if (ret) {
1348 ret = CMD_ERROR;
1349 goto end;
1350 }
1351 }
1352
1353 end:
1354 /* Mi clean-up */
1355 if (writer && mi_lttng_writer_destroy(writer)) {
1356 /* Preserve original error code */
1357 ret = ret ? ret : LTTNG_ERR_MI_IO_FAIL;
1358 }
1359
1360 if (opt_session_name == NULL) {
1361 free(session_name);
1362 }
1363
1364 /* Overwrite ret if an error occurred in enable_events */
1365 ret = command_ret ? command_ret : ret;
1366
1367 poptFreeContext(pc);
1368 return ret;
1369 }
1370
This page took 0.101392 seconds and 4 git commands to generate.