lttng: move log level name to numerical value conversions to a common util
[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 #include <lttng/constant.h>
26 /* Mi dependancy */
27 #include <common/mi-lttng.h>
28
29 #include <lttng/event-internal.h>
30
31 #include "../command.h"
32 #include "../loglevel.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 /*
181 * Walk the directories in the PATH environment variable to find the target
182 * binary passed as parameter.
183 *
184 * On success, the full path of the binary is copied in binary_full_path out
185 * parameter. This buffer is allocated by the caller and must be at least
186 * LTTNG_PATH_MAX bytes long.
187 * On failure, returns -1;
188 */
189 static int walk_command_search_path(const char *binary, char *binary_full_path)
190 {
191 char *tentative_binary_path = NULL;
192 char *command_search_path = NULL;
193 char *curr_search_dir_end = NULL;
194 char *curr_search_dir = NULL;
195 struct stat stat_output;
196 int ret = 0;
197
198 command_search_path = lttng_secure_getenv("PATH");
199 if (!command_search_path) {
200 ret = -1;
201 goto end;
202 }
203
204 /*
205 * Duplicate the $PATH string as the char pointer returned by getenv() should
206 * not be modified.
207 */
208 command_search_path = strdup(command_search_path);
209 if (!command_search_path) {
210 ret = -1;
211 goto end;
212 }
213
214 /*
215 * This char array is used to concatenate path to binary to look for
216 * the binary.
217 */
218 tentative_binary_path = zmalloc(LTTNG_PATH_MAX * sizeof(char));
219 if (!tentative_binary_path) {
220 ret = -1;
221 goto alloc_error;
222 }
223
224 curr_search_dir = command_search_path;
225 do {
226 /*
227 * Split on ':'. The return value of this call points to the
228 * matching character.
229 */
230 curr_search_dir_end = strchr(curr_search_dir, ':');
231 if (curr_search_dir_end != NULL) {
232 /*
233 * Add a NULL byte to the end of the first token so it
234 * can be used as a string.
235 */
236 curr_search_dir_end[0] = '\0';
237 }
238
239 /* Empty the tentative path */
240 memset(tentative_binary_path, 0, LTTNG_PATH_MAX * sizeof(char));
241
242 /*
243 * Build the tentative path to the binary using the current
244 * search directory and the name of the binary.
245 */
246 ret = snprintf(tentative_binary_path, LTTNG_PATH_MAX, "%s/%s",
247 curr_search_dir, binary);
248 if (ret < 0) {
249 goto free_binary_path;
250 }
251 if (ret < LTTNG_PATH_MAX) {
252 /*
253 * Use STAT(2) to see if the file exists.
254 */
255 ret = stat(tentative_binary_path, &stat_output);
256 if (ret == 0) {
257 /*
258 * Verify that it is a regular file or a
259 * symlink and not a special file (e.g.
260 * device).
261 */
262 if (S_ISREG(stat_output.st_mode)
263 || S_ISLNK(stat_output.st_mode)) {
264 /*
265 * Found a match, set the out parameter
266 * and return success.
267 */
268 ret = lttng_strncpy(binary_full_path,
269 tentative_binary_path,
270 LTTNG_PATH_MAX);
271 if (ret == -1) {
272 ERR("Source path does not fit "
273 "in destination buffer.");
274 }
275 goto free_binary_path;
276 }
277 }
278 }
279 /* Go to the next entry in the $PATH variable. */
280 curr_search_dir = curr_search_dir_end + 1;
281 } while (curr_search_dir_end != NULL);
282
283 free_binary_path:
284 free(tentative_binary_path);
285 alloc_error:
286 free(command_search_path);
287 end:
288 return ret;
289 }
290
291 /*
292 * Check if the symbol field passed by the user is in fact an address or an
293 * offset from a symbol. Those two instrumentation types are not supported yet.
294 * It's expected to be a common mistake because of the existing --probe option
295 * that does support these formats.
296 *
297 * Here are examples of these unsupported formats for the --userspace-probe
298 * option:
299 * elf:/path/to/binary:0x400430
300 * elf:/path/to/binary:4194364
301 * elf:/path/to/binary:my_symbol+0x323
302 * elf:/path/to/binary:my_symbol+43
303 */
304 static int warn_userspace_probe_syntax(const char *symbol)
305 {
306 int ret;
307
308 /* Check if the symbol field is an hex address. */
309 ret = sscanf(symbol, "0x%*x");
310 if (ret > 0) {
311 /* If there is a match, print a warning and return an error. */
312 ERR("Userspace probe on address not supported yet.");
313 ret = CMD_UNSUPPORTED;
314 goto error;
315 }
316
317 /* Check if the symbol field is an decimal address. */
318 ret = sscanf(symbol, "%*u");
319 if (ret > 0) {
320 /* If there is a match, print a warning and return an error. */
321 ERR("Userspace probe on address not supported yet.");
322 ret = CMD_UNSUPPORTED;
323 goto error;
324 }
325
326 /* Check if the symbol field is symbol+hex_offset. */
327 ret = sscanf(symbol, "%*[^+]+0x%*x");
328 if (ret > 0) {
329 /* If there is a match, print a warning and return an error. */
330 ERR("Userspace probe on symbol+offset not supported yet.");
331 ret = CMD_UNSUPPORTED;
332 goto error;
333 }
334
335 /* Check if the symbol field is symbol+decimal_offset. */
336 ret = sscanf(symbol, "%*[^+]+%*u");
337 if (ret > 0) {
338 /* If there is a match, print a warning and return an error. */
339 ERR("Userspace probe on symbol+offset not supported yet.");
340 ret = CMD_UNSUPPORTED;
341 goto error;
342 }
343
344 ret = 0;
345
346 error:
347 return ret;
348 }
349
350 /*
351 * Parse userspace probe options
352 * Set the userspace probe fields in the lttng_event struct and set the
353 * target_path to the path to the binary.
354 */
355 static int parse_userspace_probe_opts(struct lttng_event *ev, char *opt)
356 {
357 int ret = CMD_SUCCESS;
358 int num_token;
359 char **tokens;
360 char *target_path = NULL;
361 char *unescaped_target_path = NULL;
362 char *real_target_path = NULL;
363 char *symbol_name = NULL, *probe_name = NULL, *provider_name = NULL;
364 struct lttng_userspace_probe_location *probe_location = NULL;
365 struct lttng_userspace_probe_location_lookup_method *lookup_method =
366 NULL;
367
368 if (opt == NULL) {
369 ret = CMD_ERROR;
370 goto end;
371 }
372
373 switch (ev->type) {
374 case LTTNG_EVENT_USERSPACE_PROBE:
375 break;
376 default:
377 assert(0);
378 }
379
380 /*
381 * userspace probe fields are separated by ':'.
382 */
383 tokens = strutils_split(opt, ':', 1);
384 num_token = strutils_array_of_strings_len(tokens);
385
386 /*
387 * Early sanity check that the number of parameter is between 2 and 4
388 * inclusively.
389 * elf:PATH:SYMBOL
390 * std:PATH:PROVIDER_NAME:PROBE_NAME
391 * PATH:SYMBOL (same behavior as ELF)
392 */
393 if (num_token < 2 || num_token > 4) {
394 ret = CMD_ERROR;
395 goto end_string;
396 }
397
398 /*
399 * Looking up the first parameter will tell the technique to use to
400 * interpret the userspace probe/function description.
401 */
402 switch (num_token) {
403 case 2:
404 /* When the probe type is omitted we assume ELF for now. */
405 case 3:
406 if (num_token == 3 && strcmp(tokens[0], "elf") == 0) {
407 target_path = tokens[1];
408 symbol_name = tokens[2];
409 } else if (num_token == 2) {
410 target_path = tokens[0];
411 symbol_name = tokens[1];
412 } else {
413 ret = CMD_ERROR;
414 goto end_string;
415 }
416 lookup_method =
417 lttng_userspace_probe_location_lookup_method_function_elf_create();
418 if (!lookup_method) {
419 WARN("Failed to create ELF lookup method");
420 ret = CMD_ERROR;
421 goto end_string;
422 }
423 break;
424 case 4:
425 if (strcmp(tokens[0], "sdt") == 0) {
426 target_path = tokens[1];
427 provider_name = tokens[2];
428 probe_name = tokens[3];
429 } else {
430 ret = CMD_ERROR;
431 goto end_string;
432 }
433 lookup_method =
434 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
435 if (!lookup_method) {
436 WARN("Failed to create SDT lookup method");
437 ret = CMD_ERROR;
438 goto end_string;
439 }
440 break;
441 default:
442 ret = CMD_ERROR;
443 goto end_string;
444 }
445
446 /* strutils_unescape_string allocates a new char *. */
447 unescaped_target_path = strutils_unescape_string(target_path, 0);
448 if (!unescaped_target_path) {
449 ret = CMD_ERROR;
450 goto end_destroy_lookup_method;
451 }
452
453 /*
454 * If there is not forward slash in the path. Walk the $PATH else
455 * expand.
456 */
457 if (strchr(unescaped_target_path, '/') == NULL) {
458 /* Walk the $PATH variable to find the targeted binary. */
459 real_target_path = zmalloc(LTTNG_PATH_MAX * sizeof(char));
460 if (!real_target_path) {
461 PERROR("Error allocating path buffer");
462 ret = CMD_ERROR;
463 goto end_destroy_lookup_method;
464 }
465 ret = walk_command_search_path(unescaped_target_path, real_target_path);
466 if (ret) {
467 ERR("Binary not found.");
468 ret = CMD_ERROR;
469 goto end_destroy_lookup_method;
470 }
471 } else {
472 /*
473 * Expand references to `/./` and `/../`. This function does not check
474 * if the file exists. This call returns an allocated buffer on
475 * success.
476 */
477 real_target_path = utils_expand_path_keep_symlink(unescaped_target_path);
478 if (!real_target_path) {
479 ERR("Error expanding the path to binary.");
480 ret = CMD_ERROR;
481 goto end_destroy_lookup_method;
482 }
483
484 /*
485 * Check if the file exists using access(2), If it does not,
486 * return an error.
487 */
488 ret = access(real_target_path, F_OK);
489 if (ret) {
490 ERR("Cannot find binary at path: %s.", real_target_path);
491 ret = CMD_ERROR;
492 goto end_destroy_lookup_method;
493 }
494 }
495
496 switch (lttng_userspace_probe_location_lookup_method_get_type(lookup_method)) {
497 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF:
498 /*
499 * Check for common mistakes in userspace probe description syntax.
500 */
501 ret = warn_userspace_probe_syntax(symbol_name);
502 if (ret) {
503 goto end_destroy_lookup_method;
504 }
505
506 probe_location = lttng_userspace_probe_location_function_create(
507 real_target_path, symbol_name, lookup_method);
508 if (!probe_location) {
509 WARN("Failed to create function probe location");
510 ret = CMD_ERROR;
511 goto end_destroy_lookup_method;
512 }
513
514 /* Ownership transferred to probe_location. */
515 lookup_method = NULL;
516
517 ret = lttng_event_set_userspace_probe_location(ev, probe_location);
518 if (ret) {
519 WARN("Failed to set probe location on event");
520 ret = CMD_ERROR;
521 goto end_destroy_location;
522 }
523 break;
524 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT:
525 probe_location = lttng_userspace_probe_location_tracepoint_create(
526 real_target_path, provider_name, probe_name, lookup_method);
527 if (!probe_location) {
528 WARN("Failed to create function probe location");
529 ret = CMD_ERROR;
530 goto end_destroy_lookup_method;
531 }
532
533 /* Ownership transferred to probe_location. */
534 lookup_method = NULL;
535
536 ret = lttng_event_set_userspace_probe_location(ev, probe_location);
537 if (ret) {
538 WARN("Failed to set probe location on event");
539 ret = CMD_ERROR;
540 goto end_destroy_location;
541 }
542 break;
543 default:
544 ret = CMD_ERROR;
545 goto end_destroy_lookup_method;
546 }
547
548 /* Successful parsing, now clean up everything and return. */
549 goto end_string;
550
551 end_destroy_location:
552 lttng_userspace_probe_location_destroy(probe_location);
553 end_destroy_lookup_method:
554 lttng_userspace_probe_location_lookup_method_destroy(lookup_method);
555 end_string:
556 strutils_free_null_terminated_array_of_strings(tokens);
557 /*
558 * Freeing both char * here makes the error handling simplier. free()
559 * performs not action if the pointer is NULL.
560 */
561 free(real_target_path);
562 free(unescaped_target_path);
563 end:
564 return ret;
565 }
566
567 static
568 const char *print_channel_name(const char *name)
569 {
570 return name ? : DEFAULT_CHANNEL_NAME;
571 }
572
573 static
574 const char *print_raw_channel_name(const char *name)
575 {
576 return name ? : "<default>";
577 }
578
579 /*
580 * Mi print exlcusion list
581 */
582 static
583 int mi_print_exclusion(char **names)
584 {
585 int i, ret;
586 int count = names ? strutils_array_of_strings_len(names) : 0;
587
588 assert(writer);
589
590 if (count == 0) {
591 ret = 0;
592 goto end;
593 }
594 ret = mi_lttng_writer_open_element(writer, config_element_exclusions);
595 if (ret) {
596 goto end;
597 }
598
599 for (i = 0; i < count; i++) {
600 ret = mi_lttng_writer_write_element_string(writer,
601 config_element_exclusion, names[i]);
602 if (ret) {
603 goto end;
604 }
605 }
606
607 /* Close exclusions element */
608 ret = mi_lttng_writer_close_element(writer);
609
610 end:
611 return ret;
612 }
613
614 /*
615 * Return allocated string for pretty-printing exclusion names.
616 */
617 static
618 char *print_exclusions(char **names)
619 {
620 int length = 0;
621 int i;
622 const char preamble[] = " excluding ";
623 char *ret;
624 int count = names ? strutils_array_of_strings_len(names) : 0;
625
626 if (count == 0) {
627 return strdup("");
628 }
629
630 /* calculate total required length */
631 for (i = 0; i < count; i++) {
632 length += strlen(names[i]) + 4;
633 }
634
635 length += sizeof(preamble);
636 ret = zmalloc(length);
637 if (!ret) {
638 return NULL;
639 }
640 strncpy(ret, preamble, length);
641 for (i = 0; i < count; i++) {
642 strcat(ret, "\"");
643 strcat(ret, names[i]);
644 strcat(ret, "\"");
645 if (i != count - 1) {
646 strcat(ret, ", ");
647 }
648 }
649
650 return ret;
651 }
652
653 static
654 int check_exclusion_subsets(const char *event_name, const char *exclusion)
655 {
656 bool warn = false;
657 int ret = 0;
658 const char *e = event_name;
659 const char *x = exclusion;
660
661 /* Scan both the excluder and the event letter by letter */
662 while (true) {
663 if (*e == '\\') {
664 if (*x != *e) {
665 warn = true;
666 goto end;
667 }
668
669 e++;
670 x++;
671 goto cmp_chars;
672 }
673
674 if (*x == '*') {
675 /* Event is a subset of the excluder */
676 ERR("Event %s: %s excludes all events from %s",
677 event_name, exclusion, event_name);
678 goto error;
679 }
680
681 if (*e == '*') {
682 /*
683 * Reached the end of the event name before the
684 * end of the exclusion: this is valid.
685 */
686 goto end;
687 }
688
689 cmp_chars:
690 if (*x != *e) {
691 warn = true;
692 break;
693 }
694
695 x++;
696 e++;
697 }
698
699 goto end;
700
701 error:
702 ret = -1;
703
704 end:
705 if (warn) {
706 WARN("Event %s: %s does not exclude any events from %s",
707 event_name, exclusion, event_name);
708 }
709
710 return ret;
711 }
712
713 static
714 int create_exclusion_list_and_validate(const char *event_name,
715 const char *exclusions_arg,
716 char ***exclusion_list)
717 {
718 int ret = 0;
719 char **exclusions = NULL;
720
721 /* Event name must be a valid globbing pattern to allow exclusions. */
722 if (!strutils_is_star_glob_pattern(event_name)) {
723 ERR("Event %s: Exclusions can only be used with a globbing pattern",
724 event_name);
725 goto error;
726 }
727
728 /* Split exclusions. */
729 exclusions = strutils_split(exclusions_arg, ',', true);
730 if (!exclusions) {
731 goto error;
732 }
733
734 /*
735 * If the event name is a star-at-end only globbing pattern,
736 * then we can validate the individual exclusions. Otherwise
737 * all exclusions are passed to the session daemon.
738 */
739 if (strutils_is_star_at_the_end_only_glob_pattern(event_name)) {
740 char * const *exclusion;
741
742 for (exclusion = exclusions; *exclusion; exclusion++) {
743 if (!strutils_is_star_glob_pattern(*exclusion) ||
744 strutils_is_star_at_the_end_only_glob_pattern(*exclusion)) {
745 ret = check_exclusion_subsets(event_name, *exclusion);
746 if (ret) {
747 goto error;
748 }
749 }
750 }
751 }
752
753 *exclusion_list = exclusions;
754
755 goto end;
756
757 error:
758 ret = -1;
759 strutils_free_null_terminated_array_of_strings(exclusions);
760
761 end:
762 return ret;
763 }
764
765 static void warn_on_truncated_exclusion_names(char * const *exclusion_list,
766 int *warn)
767 {
768 char * const *exclusion;
769
770 for (exclusion = exclusion_list; *exclusion; exclusion++) {
771 if (strlen(*exclusion) >= LTTNG_SYMBOL_NAME_LEN) {
772 WARN("Event exclusion \"%s\" will be truncated",
773 *exclusion);
774 *warn = 1;
775 }
776 }
777 }
778
779 /*
780 * Enabling event using the lttng API.
781 * Note: in case of error only the last error code will be return.
782 */
783 static int enable_events(char *session_name)
784 {
785 int ret = CMD_SUCCESS, command_ret = CMD_SUCCESS;
786 int error_holder = CMD_SUCCESS, warn = 0, error = 0, success = 1;
787 char *event_name, *channel_name = NULL;
788 struct lttng_event *ev;
789 struct lttng_domain dom;
790 char **exclusion_list = NULL;
791
792 memset(&dom, 0, sizeof(dom));
793
794 ev = lttng_event_create();
795 if (!ev) {
796 ret = CMD_ERROR;
797 goto error;
798 }
799
800 if (opt_kernel) {
801 if (opt_loglevel) {
802 WARN("Kernel loglevels are not supported.");
803 }
804 }
805
806 /* Create lttng domain */
807 if (opt_kernel) {
808 dom.type = LTTNG_DOMAIN_KERNEL;
809 dom.buf_type = LTTNG_BUFFER_GLOBAL;
810 } else if (opt_userspace) {
811 dom.type = LTTNG_DOMAIN_UST;
812 /* Default. */
813 dom.buf_type = LTTNG_BUFFER_PER_UID;
814 } else if (opt_jul) {
815 dom.type = LTTNG_DOMAIN_JUL;
816 /* Default. */
817 dom.buf_type = LTTNG_BUFFER_PER_UID;
818 } else if (opt_log4j) {
819 dom.type = LTTNG_DOMAIN_LOG4J;
820 /* Default. */
821 dom.buf_type = LTTNG_BUFFER_PER_UID;
822 } else if (opt_python) {
823 dom.type = LTTNG_DOMAIN_PYTHON;
824 /* Default. */
825 dom.buf_type = LTTNG_BUFFER_PER_UID;
826 } else {
827 /* Checked by the caller. */
828 assert(0);
829 }
830
831 if (opt_exclude) {
832 switch (dom.type) {
833 case LTTNG_DOMAIN_KERNEL:
834 case LTTNG_DOMAIN_JUL:
835 case LTTNG_DOMAIN_LOG4J:
836 case LTTNG_DOMAIN_PYTHON:
837 ERR("Event name exclusions are not yet implemented for %s events",
838 get_domain_str(dom.type));
839 ret = CMD_ERROR;
840 goto error;
841 case LTTNG_DOMAIN_UST:
842 /* Exclusions supported */
843 break;
844 default:
845 assert(0);
846 }
847 }
848
849 /*
850 * Adding a filter to a probe, function or userspace-probe would be
851 * denied by the kernel tracer as it's not supported at the moment. We
852 * do an early check here to warn the user.
853 */
854 if (opt_filter && opt_kernel) {
855 switch (opt_event_type) {
856 case LTTNG_EVENT_ALL:
857 case LTTNG_EVENT_TRACEPOINT:
858 case LTTNG_EVENT_SYSCALL:
859 break;
860 case LTTNG_EVENT_PROBE:
861 case LTTNG_EVENT_USERSPACE_PROBE:
862 case LTTNG_EVENT_FUNCTION:
863 ERR("Filter expressions are not supported for %s events",
864 get_event_type_str(opt_event_type));
865 ret = CMD_ERROR;
866 goto error;
867 default:
868 ret = CMD_UNDEFINED;
869 goto error;
870 }
871 }
872
873 channel_name = opt_channel_name;
874
875 handle = lttng_create_handle(session_name, &dom);
876 if (handle == NULL) {
877 ret = -1;
878 goto error;
879 }
880
881 /* Prepare Mi */
882 if (lttng_opt_mi) {
883 /* Open a events element */
884 ret = mi_lttng_writer_open_element(writer, config_element_events);
885 if (ret) {
886 ret = CMD_ERROR;
887 goto error;
888 }
889 }
890
891 if (opt_enable_all) {
892 /* Default setup for enable all */
893 if (opt_kernel) {
894 ev->type = opt_event_type;
895 strcpy(ev->name, "*");
896 /* kernel loglevels not implemented */
897 ev->loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
898 } else {
899 ev->type = LTTNG_EVENT_TRACEPOINT;
900 strcpy(ev->name, "*");
901 ev->loglevel_type = opt_loglevel_type;
902 if (opt_loglevel) {
903 int name_search_ret;
904
905 assert(opt_userspace || opt_jul || opt_log4j || opt_python);
906
907 if (opt_userspace) {
908 enum lttng_loglevel loglevel;
909
910 name_search_ret = loglevel_name_to_value(opt_loglevel, &loglevel);
911 ev->loglevel = (int) loglevel;
912 } else if (opt_jul) {
913 enum lttng_loglevel_jul loglevel;
914
915 name_search_ret = loglevel_jul_name_to_value(opt_loglevel, &loglevel);
916 ev->loglevel = (int) loglevel;
917 } else if (opt_log4j) {
918 enum lttng_loglevel_log4j loglevel;
919
920 name_search_ret = loglevel_log4j_name_to_value(opt_loglevel, &loglevel);
921 ev->loglevel = (int) loglevel;
922 } else if (opt_python) {
923 enum lttng_loglevel_python loglevel;
924
925 name_search_ret = loglevel_python_name_to_value(opt_loglevel, &loglevel);
926 ev->loglevel = (int) loglevel;
927 }
928
929 if (name_search_ret == -1) {
930 ERR("Unknown loglevel %s", opt_loglevel);
931 ret = -LTTNG_ERR_INVALID;
932 goto error;
933 }
934 } else {
935 assert(opt_userspace || opt_jul || opt_log4j || opt_python);
936 if (opt_userspace) {
937 ev->loglevel = -1;
938 } else if (opt_jul) {
939 ev->loglevel = LTTNG_LOGLEVEL_JUL_ALL;
940 } else if (opt_log4j) {
941 ev->loglevel = LTTNG_LOGLEVEL_LOG4J_ALL;
942 } else if (opt_python) {
943 ev->loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG;
944 }
945 }
946 }
947
948 if (opt_exclude) {
949 ret = create_exclusion_list_and_validate("*",
950 opt_exclude, &exclusion_list);
951 if (ret) {
952 ret = CMD_ERROR;
953 goto error;
954 }
955
956 ev->exclusion = 1;
957 warn_on_truncated_exclusion_names(exclusion_list,
958 &warn);
959 }
960 if (!opt_filter) {
961 ret = lttng_enable_event_with_exclusions(handle,
962 ev, channel_name,
963 NULL,
964 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
965 exclusion_list);
966 if (ret < 0) {
967 switch (-ret) {
968 case LTTNG_ERR_KERN_EVENT_EXIST:
969 WARN("Kernel events already enabled (channel %s, session %s)",
970 print_channel_name(channel_name), session_name);
971 warn = 1;
972 break;
973 case LTTNG_ERR_TRACE_ALREADY_STARTED:
974 {
975 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
976 ERR("Events: %s (channel %s, session %s)",
977 msg,
978 print_channel_name(channel_name),
979 session_name);
980 error = 1;
981 break;
982 }
983 default:
984 ERR("Events: %s (channel %s, session %s)",
985 lttng_strerror(ret),
986 ret == -LTTNG_ERR_NEED_CHANNEL_NAME
987 ? print_raw_channel_name(channel_name)
988 : print_channel_name(channel_name),
989 session_name);
990 error = 1;
991 break;
992 }
993 goto end;
994 }
995
996 switch (opt_event_type) {
997 case LTTNG_EVENT_TRACEPOINT:
998 if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) {
999 char *exclusion_string = print_exclusions(exclusion_list);
1000
1001 if (!exclusion_string) {
1002 PERROR("Cannot allocate exclusion_string");
1003 error = 1;
1004 goto end;
1005 }
1006 MSG("All %s tracepoints%s are enabled in channel %s for loglevel %s",
1007 get_domain_str(dom.type),
1008 exclusion_string,
1009 print_channel_name(channel_name),
1010 opt_loglevel);
1011 free(exclusion_string);
1012 } else {
1013 char *exclusion_string = print_exclusions(exclusion_list);
1014
1015 if (!exclusion_string) {
1016 PERROR("Cannot allocate exclusion_string");
1017 error = 1;
1018 goto end;
1019 }
1020 MSG("All %s tracepoints%s are enabled in channel %s",
1021 get_domain_str(dom.type),
1022 exclusion_string,
1023 print_channel_name(channel_name));
1024 free(exclusion_string);
1025 }
1026 break;
1027 case LTTNG_EVENT_SYSCALL:
1028 if (opt_kernel) {
1029 MSG("All %s system calls are enabled in channel %s",
1030 get_domain_str(dom.type),
1031 print_channel_name(channel_name));
1032 }
1033 break;
1034 case LTTNG_EVENT_ALL:
1035 if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) {
1036 char *exclusion_string = print_exclusions(exclusion_list);
1037
1038 if (!exclusion_string) {
1039 PERROR("Cannot allocate exclusion_string");
1040 error = 1;
1041 goto end;
1042 }
1043 MSG("All %s events%s are enabled in channel %s for loglevel %s",
1044 get_domain_str(dom.type),
1045 exclusion_string,
1046 print_channel_name(channel_name),
1047 opt_loglevel);
1048 free(exclusion_string);
1049 } else {
1050 char *exclusion_string = print_exclusions(exclusion_list);
1051
1052 if (!exclusion_string) {
1053 PERROR("Cannot allocate exclusion_string");
1054 error = 1;
1055 goto end;
1056 }
1057 MSG("All %s events%s are enabled in channel %s",
1058 get_domain_str(dom.type),
1059 exclusion_string,
1060 print_channel_name(channel_name));
1061 free(exclusion_string);
1062 }
1063 break;
1064 default:
1065 /*
1066 * We should not be here since lttng_enable_event should have
1067 * failed on the event type.
1068 */
1069 goto error;
1070 }
1071 }
1072
1073 if (opt_filter) {
1074 command_ret = lttng_enable_event_with_exclusions(handle, ev, channel_name,
1075 opt_filter,
1076 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
1077 exclusion_list);
1078 if (command_ret < 0) {
1079 switch (-command_ret) {
1080 case LTTNG_ERR_FILTER_EXIST:
1081 WARN("Filter on all events is already enabled"
1082 " (channel %s, session %s)",
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("All events: %s (channel %s, session %s, filter \'%s\')",
1090 msg,
1091 print_channel_name(channel_name),
1092 session_name, opt_filter);
1093 error = 1;
1094 break;
1095 }
1096 default:
1097 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
1098 lttng_strerror(command_ret),
1099 command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
1100 ? print_raw_channel_name(channel_name)
1101 : print_channel_name(channel_name),
1102 session_name, opt_filter);
1103 error = 1;
1104 break;
1105 }
1106 error_holder = command_ret;
1107 } else {
1108 ev->filter = 1;
1109 MSG("Filter '%s' successfully set", opt_filter);
1110 }
1111 }
1112
1113 if (lttng_opt_mi) {
1114 /* The wildcard * is used for kernel and ust domain to
1115 * represent ALL. We copy * in event name to force the wildcard use
1116 * for kernel domain
1117 *
1118 * Note: this is strictly for semantic and printing while in
1119 * machine interface mode.
1120 */
1121 strcpy(ev->name, "*");
1122
1123 /* If we reach here the events are enabled */
1124 if (!error && !warn) {
1125 ev->enabled = 1;
1126 } else {
1127 ev->enabled = 0;
1128 success = 0;
1129 }
1130 ret = mi_lttng_event(writer, ev, 1, handle->domain.type);
1131 if (ret) {
1132 ret = CMD_ERROR;
1133 goto error;
1134 }
1135
1136 /* print exclusion */
1137 ret = mi_print_exclusion(exclusion_list);
1138 if (ret) {
1139 ret = CMD_ERROR;
1140 goto error;
1141 }
1142
1143 /* Success ? */
1144 ret = mi_lttng_writer_write_element_bool(writer,
1145 mi_lttng_element_command_success, success);
1146 if (ret) {
1147 ret = CMD_ERROR;
1148 goto error;
1149 }
1150
1151 /* Close event element */
1152 ret = mi_lttng_writer_close_element(writer);
1153 if (ret) {
1154 ret = CMD_ERROR;
1155 goto error;
1156 }
1157 }
1158
1159 goto end;
1160 }
1161
1162 /* Strip event list */
1163 event_name = strtok(opt_event_list, ",");
1164 while (event_name != NULL) {
1165 /* Copy name and type of the event */
1166 strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN);
1167 ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
1168 ev->type = opt_event_type;
1169
1170 /* Kernel tracer action */
1171 if (opt_kernel) {
1172 DBG("Enabling kernel event %s for channel %s",
1173 event_name,
1174 print_channel_name(channel_name));
1175
1176 switch (opt_event_type) {
1177 case LTTNG_EVENT_ALL: /* Enable tracepoints and syscalls */
1178 /* If event name differs from *, select tracepoint. */
1179 if (strcmp(ev->name, "*")) {
1180 ev->type = LTTNG_EVENT_TRACEPOINT;
1181 }
1182 break;
1183 case LTTNG_EVENT_TRACEPOINT:
1184 break;
1185 case LTTNG_EVENT_PROBE:
1186 ret = parse_probe_opts(ev, opt_probe);
1187 if (ret) {
1188 ERR("Unable to parse probe options");
1189 ret = CMD_ERROR;
1190 goto error;
1191 }
1192 break;
1193 case LTTNG_EVENT_USERSPACE_PROBE:
1194 ret = parse_userspace_probe_opts(ev, opt_userspace_probe);
1195 if (ret) {
1196 switch (ret) {
1197 case CMD_UNSUPPORTED:
1198 /*
1199 * Error message describing
1200 * what is not supported was
1201 * printed in the function.
1202 */
1203 break;
1204 case CMD_ERROR:
1205 default:
1206 ERR("Unable to parse userspace probe options");
1207 break;
1208 }
1209 goto error;
1210 }
1211 break;
1212 case LTTNG_EVENT_FUNCTION:
1213 ret = parse_probe_opts(ev, opt_function);
1214 if (ret) {
1215 ERR("Unable to parse function probe options");
1216 ret = CMD_ERROR;
1217 goto error;
1218 }
1219 break;
1220 case LTTNG_EVENT_SYSCALL:
1221 ev->type = LTTNG_EVENT_SYSCALL;
1222 break;
1223 default:
1224 ret = CMD_UNDEFINED;
1225 goto error;
1226 }
1227
1228 /* kernel loglevels not implemented */
1229 ev->loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
1230 } else if (opt_userspace) { /* User-space tracer action */
1231 DBG("Enabling UST event %s for channel %s, loglevel %s", event_name,
1232 print_channel_name(channel_name), opt_loglevel ? : "<all>");
1233
1234 switch (opt_event_type) {
1235 case LTTNG_EVENT_ALL: /* Default behavior is tracepoint */
1236 /* Fall-through */
1237 case LTTNG_EVENT_TRACEPOINT:
1238 /* Copy name and type of the event */
1239 ev->type = LTTNG_EVENT_TRACEPOINT;
1240 strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN);
1241 ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
1242 break;
1243 case LTTNG_EVENT_PROBE:
1244 case LTTNG_EVENT_FUNCTION:
1245 case LTTNG_EVENT_SYSCALL:
1246 case LTTNG_EVENT_USERSPACE_PROBE:
1247 default:
1248 ERR("Event type not available for user-space tracing");
1249 ret = CMD_UNSUPPORTED;
1250 goto error;
1251 }
1252
1253 if (opt_exclude) {
1254 ev->exclusion = 1;
1255 if (opt_event_type != LTTNG_EVENT_ALL && opt_event_type != LTTNG_EVENT_TRACEPOINT) {
1256 ERR("Exclusion option can only be used with tracepoint events");
1257 ret = CMD_ERROR;
1258 goto error;
1259 }
1260 /* Free previously allocated items */
1261 strutils_free_null_terminated_array_of_strings(
1262 exclusion_list);
1263 exclusion_list = NULL;
1264 ret = create_exclusion_list_and_validate(
1265 event_name, opt_exclude,
1266 &exclusion_list);
1267 if (ret) {
1268 ret = CMD_ERROR;
1269 goto error;
1270 }
1271
1272 warn_on_truncated_exclusion_names(
1273 exclusion_list, &warn);
1274 }
1275
1276 ev->loglevel_type = opt_loglevel_type;
1277 if (opt_loglevel) {
1278 enum lttng_loglevel loglevel;
1279 const int name_search_ret = loglevel_name_to_value(opt_loglevel, &loglevel);
1280
1281 if (name_search_ret == -1) {
1282 ERR("Unknown loglevel %s", opt_loglevel);
1283 ret = -LTTNG_ERR_INVALID;
1284 goto error;
1285 }
1286
1287 ev->loglevel = (int) loglevel;
1288 } else {
1289 ev->loglevel = -1;
1290 }
1291 } else if (opt_jul || opt_log4j || opt_python) {
1292 if (opt_event_type != LTTNG_EVENT_ALL &&
1293 opt_event_type != LTTNG_EVENT_TRACEPOINT) {
1294 ERR("Event type not supported for domain.");
1295 ret = CMD_UNSUPPORTED;
1296 goto error;
1297 }
1298
1299 ev->loglevel_type = opt_loglevel_type;
1300 if (opt_loglevel) {
1301 int name_search_ret;
1302
1303 if (opt_jul) {
1304 enum lttng_loglevel_jul loglevel;
1305
1306 name_search_ret = loglevel_jul_name_to_value(opt_loglevel, &loglevel);
1307 ev->loglevel = (int) loglevel;
1308 } else if (opt_log4j) {
1309 enum lttng_loglevel_log4j loglevel;
1310
1311 name_search_ret = loglevel_log4j_name_to_value(opt_loglevel, &loglevel);
1312 ev->loglevel = (int) loglevel;
1313 } else if (opt_python) {
1314 enum lttng_loglevel_python loglevel;
1315
1316 name_search_ret = loglevel_python_name_to_value(opt_loglevel, &loglevel);
1317 ev->loglevel = (int) loglevel;
1318 }
1319
1320 if (name_search_ret) {
1321 ERR("Unknown loglevel %s", opt_loglevel);
1322 ret = -LTTNG_ERR_INVALID;
1323 goto error;
1324 }
1325 } else {
1326 if (opt_jul) {
1327 ev->loglevel = LTTNG_LOGLEVEL_JUL_ALL;
1328 } else if (opt_log4j) {
1329 ev->loglevel = LTTNG_LOGLEVEL_LOG4J_ALL;
1330 } else if (opt_python) {
1331 ev->loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG;
1332 }
1333 }
1334 ev->type = LTTNG_EVENT_TRACEPOINT;
1335 strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN);
1336 ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
1337 } else {
1338 assert(0);
1339 }
1340
1341 if (!opt_filter) {
1342 char *exclusion_string;
1343
1344 command_ret = lttng_enable_event_with_exclusions(handle,
1345 ev, channel_name,
1346 NULL,
1347 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
1348 exclusion_list);
1349 exclusion_string = print_exclusions(exclusion_list);
1350 if (!exclusion_string) {
1351 PERROR("Cannot allocate exclusion_string");
1352 error = 1;
1353 goto end;
1354 }
1355 if (command_ret < 0) {
1356 /* Turn ret to positive value to handle the positive error code */
1357 switch (-command_ret) {
1358 case LTTNG_ERR_KERN_EVENT_EXIST:
1359 WARN("Kernel event %s%s already enabled (channel %s, session %s)",
1360 event_name,
1361 exclusion_string,
1362 print_channel_name(channel_name), session_name);
1363 warn = 1;
1364 break;
1365 case LTTNG_ERR_TRACE_ALREADY_STARTED:
1366 {
1367 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
1368 ERR("Event %s%s: %s (channel %s, session %s)", event_name,
1369 exclusion_string,
1370 msg,
1371 print_channel_name(channel_name),
1372 session_name);
1373 error = 1;
1374 break;
1375 }
1376 case LTTNG_ERR_SDT_PROBE_SEMAPHORE:
1377 ERR("SDT probes %s guarded by semaphores are not supported (channel %s, session %s)",
1378 event_name, print_channel_name(channel_name),
1379 session_name);
1380 error = 1;
1381 break;
1382 default:
1383 ERR("Event %s%s: %s (channel %s, session %s)", event_name,
1384 exclusion_string,
1385 lttng_strerror(command_ret),
1386 command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
1387 ? print_raw_channel_name(channel_name)
1388 : print_channel_name(channel_name),
1389 session_name);
1390 error = 1;
1391 break;
1392 }
1393 error_holder = command_ret;
1394 } else {
1395 switch (dom.type) {
1396 case LTTNG_DOMAIN_KERNEL:
1397 case LTTNG_DOMAIN_UST:
1398 MSG("%s event %s%s created in channel %s",
1399 get_domain_str(dom.type),
1400 event_name,
1401 exclusion_string,
1402 print_channel_name(channel_name));
1403 break;
1404 case LTTNG_DOMAIN_JUL:
1405 case LTTNG_DOMAIN_LOG4J:
1406 case LTTNG_DOMAIN_PYTHON:
1407 /*
1408 * Don't print the default channel
1409 * name for agent domains.
1410 */
1411 MSG("%s event %s%s enabled",
1412 get_domain_str(dom.type),
1413 event_name,
1414 exclusion_string);
1415 break;
1416 default:
1417 assert(0);
1418 }
1419 }
1420 free(exclusion_string);
1421 }
1422
1423 if (opt_filter) {
1424 char *exclusion_string;
1425
1426 /* Filter present */
1427 ev->filter = 1;
1428
1429 command_ret = lttng_enable_event_with_exclusions(handle, ev, channel_name,
1430 opt_filter,
1431 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
1432 exclusion_list);
1433 exclusion_string = print_exclusions(exclusion_list);
1434 if (!exclusion_string) {
1435 PERROR("Cannot allocate exclusion_string");
1436 error = 1;
1437 goto end;
1438 }
1439 if (command_ret < 0) {
1440 switch (-command_ret) {
1441 case LTTNG_ERR_FILTER_EXIST:
1442 WARN("Filter on event %s%s is already enabled"
1443 " (channel %s, session %s)",
1444 event_name,
1445 exclusion_string,
1446 print_channel_name(channel_name), session_name);
1447 warn = 1;
1448 break;
1449 case LTTNG_ERR_TRACE_ALREADY_STARTED:
1450 {
1451 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
1452 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev->name,
1453 exclusion_string,
1454 msg,
1455 print_channel_name(channel_name),
1456 session_name, opt_filter);
1457 error = 1;
1458 break;
1459 }
1460 default:
1461 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev->name,
1462 exclusion_string,
1463 lttng_strerror(command_ret),
1464 command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
1465 ? print_raw_channel_name(channel_name)
1466 : print_channel_name(channel_name),
1467 session_name, opt_filter);
1468 error = 1;
1469 break;
1470 }
1471 error_holder = command_ret;
1472
1473 } else {
1474 MSG("Event %s%s: Filter '%s' successfully set",
1475 event_name, exclusion_string,
1476 opt_filter);
1477 }
1478 free(exclusion_string);
1479 }
1480
1481 if (lttng_opt_mi) {
1482 if (command_ret) {
1483 success = 0;
1484 ev->enabled = 0;
1485 } else {
1486 ev->enabled = 1;
1487 }
1488
1489 ret = mi_lttng_event(writer, ev, 1, handle->domain.type);
1490 if (ret) {
1491 ret = CMD_ERROR;
1492 goto error;
1493 }
1494
1495 /* print exclusion */
1496 ret = mi_print_exclusion(exclusion_list);
1497 if (ret) {
1498 ret = CMD_ERROR;
1499 goto error;
1500 }
1501
1502 /* Success ? */
1503 ret = mi_lttng_writer_write_element_bool(writer,
1504 mi_lttng_element_command_success, success);
1505 if (ret) {
1506 ret = CMD_ERROR;
1507 goto end;
1508 }
1509
1510 /* Close event element */
1511 ret = mi_lttng_writer_close_element(writer);
1512 if (ret) {
1513 ret = CMD_ERROR;
1514 goto end;
1515 }
1516 }
1517
1518 /* Next event */
1519 event_name = strtok(NULL, ",");
1520 /* Reset warn, error and success */
1521 success = 1;
1522 }
1523
1524 end:
1525 /* Close Mi */
1526 if (lttng_opt_mi) {
1527 /* Close events element */
1528 ret = mi_lttng_writer_close_element(writer);
1529 if (ret) {
1530 ret = CMD_ERROR;
1531 goto error;
1532 }
1533 }
1534 error:
1535 if (warn) {
1536 ret = CMD_WARNING;
1537 }
1538 if (error) {
1539 ret = CMD_ERROR;
1540 }
1541 lttng_destroy_handle(handle);
1542 strutils_free_null_terminated_array_of_strings(exclusion_list);
1543
1544 /* Overwrite ret with error_holder if there was an actual error with
1545 * enabling an event.
1546 */
1547 ret = error_holder ? error_holder : ret;
1548
1549 lttng_event_destroy(ev);
1550 return ret;
1551 }
1552
1553 /*
1554 * Add event to trace session
1555 */
1556 int cmd_enable_events(int argc, const char **argv)
1557 {
1558 int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
1559 static poptContext pc;
1560 char *session_name = NULL;
1561 const char *leftover = NULL;
1562 int event_type = -1;
1563
1564 pc = poptGetContext(NULL, argc, argv, long_options, 0);
1565 poptReadDefaultConfig(pc, 0);
1566
1567 /* Default event type */
1568 opt_event_type = LTTNG_EVENT_ALL;
1569
1570 while ((opt = poptGetNextOpt(pc)) != -1) {
1571 switch (opt) {
1572 case OPT_HELP:
1573 SHOW_HELP();
1574 goto end;
1575 case OPT_TRACEPOINT:
1576 opt_event_type = LTTNG_EVENT_TRACEPOINT;
1577 break;
1578 case OPT_PROBE:
1579 opt_event_type = LTTNG_EVENT_PROBE;
1580 break;
1581 case OPT_USERSPACE_PROBE:
1582 opt_event_type = LTTNG_EVENT_USERSPACE_PROBE;
1583 break;
1584 case OPT_FUNCTION:
1585 opt_event_type = LTTNG_EVENT_FUNCTION;
1586 break;
1587 case OPT_SYSCALL:
1588 opt_event_type = LTTNG_EVENT_SYSCALL;
1589 break;
1590 case OPT_USERSPACE:
1591 opt_userspace = 1;
1592 break;
1593 case OPT_LOGLEVEL:
1594 opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_RANGE;
1595 opt_loglevel = poptGetOptArg(pc);
1596 break;
1597 case OPT_LOGLEVEL_ONLY:
1598 opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_SINGLE;
1599 opt_loglevel = poptGetOptArg(pc);
1600 break;
1601 case OPT_LIST_OPTIONS:
1602 list_cmd_options(stdout, long_options);
1603 goto end;
1604 case OPT_FILTER:
1605 break;
1606 case OPT_EXCLUDE:
1607 break;
1608 default:
1609 ret = CMD_UNDEFINED;
1610 goto end;
1611 }
1612
1613 /* Validate event type. Multiple event type are not supported. */
1614 if (event_type == -1) {
1615 event_type = opt_event_type;
1616 } else {
1617 if (event_type != opt_event_type) {
1618 ERR("Multiple event type not supported.");
1619 ret = CMD_ERROR;
1620 goto end;
1621 }
1622 }
1623 }
1624
1625 ret = print_missing_or_multiple_domains(
1626 opt_kernel + opt_userspace + opt_jul + opt_log4j +
1627 opt_python,
1628 true);
1629 if (ret) {
1630 ret = CMD_ERROR;
1631 goto end;
1632 }
1633
1634 /* Mi check */
1635 if (lttng_opt_mi) {
1636 writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
1637 if (!writer) {
1638 ret = -LTTNG_ERR_NOMEM;
1639 goto end;
1640 }
1641
1642 /* Open command element */
1643 ret = mi_lttng_writer_command_open(writer,
1644 mi_lttng_element_command_enable_event);
1645 if (ret) {
1646 ret = CMD_ERROR;
1647 goto end;
1648 }
1649
1650 /* Open output element */
1651 ret = mi_lttng_writer_open_element(writer,
1652 mi_lttng_element_command_output);
1653 if (ret) {
1654 ret = CMD_ERROR;
1655 goto end;
1656 }
1657 }
1658
1659 opt_event_list = (char*) poptGetArg(pc);
1660 if (opt_event_list == NULL && opt_enable_all == 0) {
1661 ERR("Missing event name(s).\n");
1662 ret = CMD_ERROR;
1663 goto end;
1664 }
1665
1666 leftover = poptGetArg(pc);
1667 if (leftover) {
1668 ERR("Unknown argument: %s", leftover);
1669 ret = CMD_ERROR;
1670 goto end;
1671 }
1672
1673 if (!opt_session_name) {
1674 session_name = get_session_name();
1675 if (session_name == NULL) {
1676 command_ret = CMD_ERROR;
1677 success = 0;
1678 goto mi_closing;
1679 }
1680 } else {
1681 session_name = opt_session_name;
1682 }
1683
1684 command_ret = enable_events(session_name);
1685 if (command_ret) {
1686 success = 0;
1687 goto mi_closing;
1688 }
1689
1690 mi_closing:
1691 /* Mi closing */
1692 if (lttng_opt_mi) {
1693 /* Close output element */
1694 ret = mi_lttng_writer_close_element(writer);
1695 if (ret) {
1696 ret = CMD_ERROR;
1697 goto end;
1698 }
1699
1700 ret = mi_lttng_writer_write_element_bool(writer,
1701 mi_lttng_element_command_success, success);
1702 if (ret) {
1703 ret = CMD_ERROR;
1704 goto end;
1705 }
1706
1707 /* Command element close */
1708 ret = mi_lttng_writer_command_close(writer);
1709 if (ret) {
1710 ret = CMD_ERROR;
1711 goto end;
1712 }
1713 }
1714
1715 end:
1716 /* Mi clean-up */
1717 if (writer && mi_lttng_writer_destroy(writer)) {
1718 /* Preserve original error code */
1719 ret = ret ? ret : LTTNG_ERR_MI_IO_FAIL;
1720 }
1721
1722 if (opt_session_name == NULL) {
1723 free(session_name);
1724 }
1725
1726 /* Overwrite ret if an error occurred in enable_events */
1727 ret = command_ret ? command_ret : ret;
1728
1729 poptFreeContext(pc);
1730 return ret;
1731 }
1732
This page took 0.105725 seconds and 4 git commands to generate.