Clean-up: lttng: silence bogus warning
[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 {
923 /* python domain. */
924 enum lttng_loglevel_python loglevel;
925
926 name_search_ret = loglevel_python_name_to_value(opt_loglevel, &loglevel);
927 ev->loglevel = (int) loglevel;
928 }
929
930 if (name_search_ret == -1) {
931 ERR("Unknown loglevel %s", opt_loglevel);
932 ret = -LTTNG_ERR_INVALID;
933 goto error;
934 }
935 } else {
936 assert(opt_userspace || opt_jul || opt_log4j || opt_python);
937 if (opt_userspace) {
938 ev->loglevel = -1;
939 } else if (opt_jul) {
940 ev->loglevel = LTTNG_LOGLEVEL_JUL_ALL;
941 } else if (opt_log4j) {
942 ev->loglevel = LTTNG_LOGLEVEL_LOG4J_ALL;
943 } else if (opt_python) {
944 ev->loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG;
945 }
946 }
947 }
948
949 if (opt_exclude) {
950 ret = create_exclusion_list_and_validate("*",
951 opt_exclude, &exclusion_list);
952 if (ret) {
953 ret = CMD_ERROR;
954 goto error;
955 }
956
957 ev->exclusion = 1;
958 warn_on_truncated_exclusion_names(exclusion_list,
959 &warn);
960 }
961 if (!opt_filter) {
962 ret = lttng_enable_event_with_exclusions(handle,
963 ev, channel_name,
964 NULL,
965 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
966 exclusion_list);
967 if (ret < 0) {
968 switch (-ret) {
969 case LTTNG_ERR_KERN_EVENT_EXIST:
970 WARN("Kernel events already enabled (channel %s, session %s)",
971 print_channel_name(channel_name), session_name);
972 warn = 1;
973 break;
974 case LTTNG_ERR_TRACE_ALREADY_STARTED:
975 {
976 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
977 ERR("Events: %s (channel %s, session %s)",
978 msg,
979 print_channel_name(channel_name),
980 session_name);
981 error = 1;
982 break;
983 }
984 default:
985 ERR("Events: %s (channel %s, session %s)",
986 lttng_strerror(ret),
987 ret == -LTTNG_ERR_NEED_CHANNEL_NAME
988 ? print_raw_channel_name(channel_name)
989 : print_channel_name(channel_name),
990 session_name);
991 error = 1;
992 break;
993 }
994 goto end;
995 }
996
997 switch (opt_event_type) {
998 case LTTNG_EVENT_TRACEPOINT:
999 if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) {
1000 char *exclusion_string = print_exclusions(exclusion_list);
1001
1002 if (!exclusion_string) {
1003 PERROR("Cannot allocate exclusion_string");
1004 error = 1;
1005 goto end;
1006 }
1007 MSG("All %s tracepoints%s are enabled in channel %s for loglevel %s",
1008 get_domain_str(dom.type),
1009 exclusion_string,
1010 print_channel_name(channel_name),
1011 opt_loglevel);
1012 free(exclusion_string);
1013 } else {
1014 char *exclusion_string = print_exclusions(exclusion_list);
1015
1016 if (!exclusion_string) {
1017 PERROR("Cannot allocate exclusion_string");
1018 error = 1;
1019 goto end;
1020 }
1021 MSG("All %s tracepoints%s are enabled in channel %s",
1022 get_domain_str(dom.type),
1023 exclusion_string,
1024 print_channel_name(channel_name));
1025 free(exclusion_string);
1026 }
1027 break;
1028 case LTTNG_EVENT_SYSCALL:
1029 if (opt_kernel) {
1030 MSG("All %s system calls are enabled in channel %s",
1031 get_domain_str(dom.type),
1032 print_channel_name(channel_name));
1033 }
1034 break;
1035 case LTTNG_EVENT_ALL:
1036 if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) {
1037 char *exclusion_string = print_exclusions(exclusion_list);
1038
1039 if (!exclusion_string) {
1040 PERROR("Cannot allocate exclusion_string");
1041 error = 1;
1042 goto end;
1043 }
1044 MSG("All %s events%s are enabled in channel %s for loglevel %s",
1045 get_domain_str(dom.type),
1046 exclusion_string,
1047 print_channel_name(channel_name),
1048 opt_loglevel);
1049 free(exclusion_string);
1050 } else {
1051 char *exclusion_string = print_exclusions(exclusion_list);
1052
1053 if (!exclusion_string) {
1054 PERROR("Cannot allocate exclusion_string");
1055 error = 1;
1056 goto end;
1057 }
1058 MSG("All %s events%s are enabled in channel %s",
1059 get_domain_str(dom.type),
1060 exclusion_string,
1061 print_channel_name(channel_name));
1062 free(exclusion_string);
1063 }
1064 break;
1065 default:
1066 /*
1067 * We should not be here since lttng_enable_event should have
1068 * failed on the event type.
1069 */
1070 goto error;
1071 }
1072 }
1073
1074 if (opt_filter) {
1075 command_ret = lttng_enable_event_with_exclusions(handle, ev, channel_name,
1076 opt_filter,
1077 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
1078 exclusion_list);
1079 if (command_ret < 0) {
1080 switch (-command_ret) {
1081 case LTTNG_ERR_FILTER_EXIST:
1082 WARN("Filter on all events is already enabled"
1083 " (channel %s, session %s)",
1084 print_channel_name(channel_name), session_name);
1085 warn = 1;
1086 break;
1087 case LTTNG_ERR_TRACE_ALREADY_STARTED:
1088 {
1089 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
1090 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
1091 msg,
1092 print_channel_name(channel_name),
1093 session_name, opt_filter);
1094 error = 1;
1095 break;
1096 }
1097 default:
1098 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
1099 lttng_strerror(command_ret),
1100 command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
1101 ? print_raw_channel_name(channel_name)
1102 : print_channel_name(channel_name),
1103 session_name, opt_filter);
1104 error = 1;
1105 break;
1106 }
1107 error_holder = command_ret;
1108 } else {
1109 ev->filter = 1;
1110 MSG("Filter '%s' successfully set", opt_filter);
1111 }
1112 }
1113
1114 if (lttng_opt_mi) {
1115 /* The wildcard * is used for kernel and ust domain to
1116 * represent ALL. We copy * in event name to force the wildcard use
1117 * for kernel domain
1118 *
1119 * Note: this is strictly for semantic and printing while in
1120 * machine interface mode.
1121 */
1122 strcpy(ev->name, "*");
1123
1124 /* If we reach here the events are enabled */
1125 if (!error && !warn) {
1126 ev->enabled = 1;
1127 } else {
1128 ev->enabled = 0;
1129 success = 0;
1130 }
1131 ret = mi_lttng_event(writer, ev, 1, handle->domain.type);
1132 if (ret) {
1133 ret = CMD_ERROR;
1134 goto error;
1135 }
1136
1137 /* print exclusion */
1138 ret = mi_print_exclusion(exclusion_list);
1139 if (ret) {
1140 ret = CMD_ERROR;
1141 goto error;
1142 }
1143
1144 /* Success ? */
1145 ret = mi_lttng_writer_write_element_bool(writer,
1146 mi_lttng_element_command_success, success);
1147 if (ret) {
1148 ret = CMD_ERROR;
1149 goto error;
1150 }
1151
1152 /* Close event element */
1153 ret = mi_lttng_writer_close_element(writer);
1154 if (ret) {
1155 ret = CMD_ERROR;
1156 goto error;
1157 }
1158 }
1159
1160 goto end;
1161 }
1162
1163 /* Strip event list */
1164 event_name = strtok(opt_event_list, ",");
1165 while (event_name != NULL) {
1166 /* Copy name and type of the event */
1167 strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN);
1168 ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
1169 ev->type = opt_event_type;
1170
1171 /* Kernel tracer action */
1172 if (opt_kernel) {
1173 DBG("Enabling kernel event %s for channel %s",
1174 event_name,
1175 print_channel_name(channel_name));
1176
1177 switch (opt_event_type) {
1178 case LTTNG_EVENT_ALL: /* Enable tracepoints and syscalls */
1179 /* If event name differs from *, select tracepoint. */
1180 if (strcmp(ev->name, "*")) {
1181 ev->type = LTTNG_EVENT_TRACEPOINT;
1182 }
1183 break;
1184 case LTTNG_EVENT_TRACEPOINT:
1185 break;
1186 case LTTNG_EVENT_PROBE:
1187 ret = parse_probe_opts(ev, opt_probe);
1188 if (ret) {
1189 ERR("Unable to parse probe options");
1190 ret = CMD_ERROR;
1191 goto error;
1192 }
1193 break;
1194 case LTTNG_EVENT_USERSPACE_PROBE:
1195 ret = parse_userspace_probe_opts(ev, opt_userspace_probe);
1196 if (ret) {
1197 switch (ret) {
1198 case CMD_UNSUPPORTED:
1199 /*
1200 * Error message describing
1201 * what is not supported was
1202 * printed in the function.
1203 */
1204 break;
1205 case CMD_ERROR:
1206 default:
1207 ERR("Unable to parse userspace probe options");
1208 break;
1209 }
1210 goto error;
1211 }
1212 break;
1213 case LTTNG_EVENT_FUNCTION:
1214 ret = parse_probe_opts(ev, opt_function);
1215 if (ret) {
1216 ERR("Unable to parse function probe options");
1217 ret = CMD_ERROR;
1218 goto error;
1219 }
1220 break;
1221 case LTTNG_EVENT_SYSCALL:
1222 ev->type = LTTNG_EVENT_SYSCALL;
1223 break;
1224 default:
1225 ret = CMD_UNDEFINED;
1226 goto error;
1227 }
1228
1229 /* kernel loglevels not implemented */
1230 ev->loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
1231 } else if (opt_userspace) { /* User-space tracer action */
1232 DBG("Enabling UST event %s for channel %s, loglevel %s", event_name,
1233 print_channel_name(channel_name), opt_loglevel ? : "<all>");
1234
1235 switch (opt_event_type) {
1236 case LTTNG_EVENT_ALL: /* Default behavior is tracepoint */
1237 /* Fall-through */
1238 case LTTNG_EVENT_TRACEPOINT:
1239 /* Copy name and type of the event */
1240 ev->type = LTTNG_EVENT_TRACEPOINT;
1241 strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN);
1242 ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
1243 break;
1244 case LTTNG_EVENT_PROBE:
1245 case LTTNG_EVENT_FUNCTION:
1246 case LTTNG_EVENT_SYSCALL:
1247 case LTTNG_EVENT_USERSPACE_PROBE:
1248 default:
1249 ERR("Event type not available for user-space tracing");
1250 ret = CMD_UNSUPPORTED;
1251 goto error;
1252 }
1253
1254 if (opt_exclude) {
1255 ev->exclusion = 1;
1256 if (opt_event_type != LTTNG_EVENT_ALL && opt_event_type != LTTNG_EVENT_TRACEPOINT) {
1257 ERR("Exclusion option can only be used with tracepoint events");
1258 ret = CMD_ERROR;
1259 goto error;
1260 }
1261 /* Free previously allocated items */
1262 strutils_free_null_terminated_array_of_strings(
1263 exclusion_list);
1264 exclusion_list = NULL;
1265 ret = create_exclusion_list_and_validate(
1266 event_name, opt_exclude,
1267 &exclusion_list);
1268 if (ret) {
1269 ret = CMD_ERROR;
1270 goto error;
1271 }
1272
1273 warn_on_truncated_exclusion_names(
1274 exclusion_list, &warn);
1275 }
1276
1277 ev->loglevel_type = opt_loglevel_type;
1278 if (opt_loglevel) {
1279 enum lttng_loglevel loglevel;
1280 const int name_search_ret = loglevel_name_to_value(opt_loglevel, &loglevel);
1281
1282 if (name_search_ret == -1) {
1283 ERR("Unknown loglevel %s", opt_loglevel);
1284 ret = -LTTNG_ERR_INVALID;
1285 goto error;
1286 }
1287
1288 ev->loglevel = (int) loglevel;
1289 } else {
1290 ev->loglevel = -1;
1291 }
1292 } else if (opt_jul || opt_log4j || opt_python) {
1293 if (opt_event_type != LTTNG_EVENT_ALL &&
1294 opt_event_type != LTTNG_EVENT_TRACEPOINT) {
1295 ERR("Event type not supported for domain.");
1296 ret = CMD_UNSUPPORTED;
1297 goto error;
1298 }
1299
1300 ev->loglevel_type = opt_loglevel_type;
1301 if (opt_loglevel) {
1302 int name_search_ret;
1303
1304 if (opt_jul) {
1305 enum lttng_loglevel_jul loglevel;
1306
1307 name_search_ret = loglevel_jul_name_to_value(opt_loglevel, &loglevel);
1308 ev->loglevel = (int) loglevel;
1309 } else if (opt_log4j) {
1310 enum lttng_loglevel_log4j loglevel;
1311
1312 name_search_ret = loglevel_log4j_name_to_value(opt_loglevel, &loglevel);
1313 ev->loglevel = (int) loglevel;
1314 } else {
1315 /* python domain. */
1316 enum lttng_loglevel_python loglevel;
1317
1318 name_search_ret = loglevel_python_name_to_value(opt_loglevel, &loglevel);
1319 ev->loglevel = (int) loglevel;
1320 }
1321
1322 if (name_search_ret) {
1323 ERR("Unknown loglevel %s", opt_loglevel);
1324 ret = -LTTNG_ERR_INVALID;
1325 goto error;
1326 }
1327 } else {
1328 if (opt_jul) {
1329 ev->loglevel = LTTNG_LOGLEVEL_JUL_ALL;
1330 } else if (opt_log4j) {
1331 ev->loglevel = LTTNG_LOGLEVEL_LOG4J_ALL;
1332 } else if (opt_python) {
1333 ev->loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG;
1334 }
1335 }
1336 ev->type = LTTNG_EVENT_TRACEPOINT;
1337 strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN);
1338 ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
1339 } else {
1340 assert(0);
1341 }
1342
1343 if (!opt_filter) {
1344 char *exclusion_string;
1345
1346 command_ret = lttng_enable_event_with_exclusions(handle,
1347 ev, channel_name,
1348 NULL,
1349 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
1350 exclusion_list);
1351 exclusion_string = print_exclusions(exclusion_list);
1352 if (!exclusion_string) {
1353 PERROR("Cannot allocate exclusion_string");
1354 error = 1;
1355 goto end;
1356 }
1357 if (command_ret < 0) {
1358 /* Turn ret to positive value to handle the positive error code */
1359 switch (-command_ret) {
1360 case LTTNG_ERR_KERN_EVENT_EXIST:
1361 WARN("Kernel event %s%s already enabled (channel %s, session %s)",
1362 event_name,
1363 exclusion_string,
1364 print_channel_name(channel_name), session_name);
1365 warn = 1;
1366 break;
1367 case LTTNG_ERR_TRACE_ALREADY_STARTED:
1368 {
1369 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
1370 ERR("Event %s%s: %s (channel %s, session %s)", event_name,
1371 exclusion_string,
1372 msg,
1373 print_channel_name(channel_name),
1374 session_name);
1375 error = 1;
1376 break;
1377 }
1378 case LTTNG_ERR_SDT_PROBE_SEMAPHORE:
1379 ERR("SDT probes %s guarded by semaphores are not supported (channel %s, session %s)",
1380 event_name, print_channel_name(channel_name),
1381 session_name);
1382 error = 1;
1383 break;
1384 default:
1385 ERR("Event %s%s: %s (channel %s, session %s)", event_name,
1386 exclusion_string,
1387 lttng_strerror(command_ret),
1388 command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
1389 ? print_raw_channel_name(channel_name)
1390 : print_channel_name(channel_name),
1391 session_name);
1392 error = 1;
1393 break;
1394 }
1395 error_holder = command_ret;
1396 } else {
1397 switch (dom.type) {
1398 case LTTNG_DOMAIN_KERNEL:
1399 case LTTNG_DOMAIN_UST:
1400 MSG("%s event %s%s created in channel %s",
1401 get_domain_str(dom.type),
1402 event_name,
1403 exclusion_string,
1404 print_channel_name(channel_name));
1405 break;
1406 case LTTNG_DOMAIN_JUL:
1407 case LTTNG_DOMAIN_LOG4J:
1408 case LTTNG_DOMAIN_PYTHON:
1409 /*
1410 * Don't print the default channel
1411 * name for agent domains.
1412 */
1413 MSG("%s event %s%s enabled",
1414 get_domain_str(dom.type),
1415 event_name,
1416 exclusion_string);
1417 break;
1418 default:
1419 assert(0);
1420 }
1421 }
1422 free(exclusion_string);
1423 }
1424
1425 if (opt_filter) {
1426 char *exclusion_string;
1427
1428 /* Filter present */
1429 ev->filter = 1;
1430
1431 command_ret = lttng_enable_event_with_exclusions(handle, ev, channel_name,
1432 opt_filter,
1433 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
1434 exclusion_list);
1435 exclusion_string = print_exclusions(exclusion_list);
1436 if (!exclusion_string) {
1437 PERROR("Cannot allocate exclusion_string");
1438 error = 1;
1439 goto end;
1440 }
1441 if (command_ret < 0) {
1442 switch (-command_ret) {
1443 case LTTNG_ERR_FILTER_EXIST:
1444 WARN("Filter on event %s%s is already enabled"
1445 " (channel %s, session %s)",
1446 event_name,
1447 exclusion_string,
1448 print_channel_name(channel_name), session_name);
1449 warn = 1;
1450 break;
1451 case LTTNG_ERR_TRACE_ALREADY_STARTED:
1452 {
1453 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
1454 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev->name,
1455 exclusion_string,
1456 msg,
1457 print_channel_name(channel_name),
1458 session_name, opt_filter);
1459 error = 1;
1460 break;
1461 }
1462 default:
1463 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev->name,
1464 exclusion_string,
1465 lttng_strerror(command_ret),
1466 command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
1467 ? print_raw_channel_name(channel_name)
1468 : print_channel_name(channel_name),
1469 session_name, opt_filter);
1470 error = 1;
1471 break;
1472 }
1473 error_holder = command_ret;
1474
1475 } else {
1476 MSG("Event %s%s: Filter '%s' successfully set",
1477 event_name, exclusion_string,
1478 opt_filter);
1479 }
1480 free(exclusion_string);
1481 }
1482
1483 if (lttng_opt_mi) {
1484 if (command_ret) {
1485 success = 0;
1486 ev->enabled = 0;
1487 } else {
1488 ev->enabled = 1;
1489 }
1490
1491 ret = mi_lttng_event(writer, ev, 1, handle->domain.type);
1492 if (ret) {
1493 ret = CMD_ERROR;
1494 goto error;
1495 }
1496
1497 /* print exclusion */
1498 ret = mi_print_exclusion(exclusion_list);
1499 if (ret) {
1500 ret = CMD_ERROR;
1501 goto error;
1502 }
1503
1504 /* Success ? */
1505 ret = mi_lttng_writer_write_element_bool(writer,
1506 mi_lttng_element_command_success, success);
1507 if (ret) {
1508 ret = CMD_ERROR;
1509 goto end;
1510 }
1511
1512 /* Close event element */
1513 ret = mi_lttng_writer_close_element(writer);
1514 if (ret) {
1515 ret = CMD_ERROR;
1516 goto end;
1517 }
1518 }
1519
1520 /* Next event */
1521 event_name = strtok(NULL, ",");
1522 /* Reset warn, error and success */
1523 success = 1;
1524 }
1525
1526 end:
1527 /* Close Mi */
1528 if (lttng_opt_mi) {
1529 /* Close events element */
1530 ret = mi_lttng_writer_close_element(writer);
1531 if (ret) {
1532 ret = CMD_ERROR;
1533 goto error;
1534 }
1535 }
1536 error:
1537 if (warn) {
1538 ret = CMD_WARNING;
1539 }
1540 if (error) {
1541 ret = CMD_ERROR;
1542 }
1543 lttng_destroy_handle(handle);
1544 strutils_free_null_terminated_array_of_strings(exclusion_list);
1545
1546 /* Overwrite ret with error_holder if there was an actual error with
1547 * enabling an event.
1548 */
1549 ret = error_holder ? error_holder : ret;
1550
1551 lttng_event_destroy(ev);
1552 return ret;
1553 }
1554
1555 /*
1556 * Add event to trace session
1557 */
1558 int cmd_enable_events(int argc, const char **argv)
1559 {
1560 int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
1561 static poptContext pc;
1562 char *session_name = NULL;
1563 const char *leftover = NULL;
1564 int event_type = -1;
1565
1566 pc = poptGetContext(NULL, argc, argv, long_options, 0);
1567 poptReadDefaultConfig(pc, 0);
1568
1569 /* Default event type */
1570 opt_event_type = LTTNG_EVENT_ALL;
1571
1572 while ((opt = poptGetNextOpt(pc)) != -1) {
1573 switch (opt) {
1574 case OPT_HELP:
1575 SHOW_HELP();
1576 goto end;
1577 case OPT_TRACEPOINT:
1578 opt_event_type = LTTNG_EVENT_TRACEPOINT;
1579 break;
1580 case OPT_PROBE:
1581 opt_event_type = LTTNG_EVENT_PROBE;
1582 break;
1583 case OPT_USERSPACE_PROBE:
1584 opt_event_type = LTTNG_EVENT_USERSPACE_PROBE;
1585 break;
1586 case OPT_FUNCTION:
1587 opt_event_type = LTTNG_EVENT_FUNCTION;
1588 break;
1589 case OPT_SYSCALL:
1590 opt_event_type = LTTNG_EVENT_SYSCALL;
1591 break;
1592 case OPT_USERSPACE:
1593 opt_userspace = 1;
1594 break;
1595 case OPT_LOGLEVEL:
1596 opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_RANGE;
1597 opt_loglevel = poptGetOptArg(pc);
1598 break;
1599 case OPT_LOGLEVEL_ONLY:
1600 opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_SINGLE;
1601 opt_loglevel = poptGetOptArg(pc);
1602 break;
1603 case OPT_LIST_OPTIONS:
1604 list_cmd_options(stdout, long_options);
1605 goto end;
1606 case OPT_FILTER:
1607 break;
1608 case OPT_EXCLUDE:
1609 break;
1610 default:
1611 ret = CMD_UNDEFINED;
1612 goto end;
1613 }
1614
1615 /* Validate event type. Multiple event type are not supported. */
1616 if (event_type == -1) {
1617 event_type = opt_event_type;
1618 } else {
1619 if (event_type != opt_event_type) {
1620 ERR("Multiple event type not supported.");
1621 ret = CMD_ERROR;
1622 goto end;
1623 }
1624 }
1625 }
1626
1627 ret = print_missing_or_multiple_domains(
1628 opt_kernel + opt_userspace + opt_jul + opt_log4j +
1629 opt_python,
1630 true);
1631 if (ret) {
1632 ret = CMD_ERROR;
1633 goto end;
1634 }
1635
1636 /* Mi check */
1637 if (lttng_opt_mi) {
1638 writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
1639 if (!writer) {
1640 ret = -LTTNG_ERR_NOMEM;
1641 goto end;
1642 }
1643
1644 /* Open command element */
1645 ret = mi_lttng_writer_command_open(writer,
1646 mi_lttng_element_command_enable_event);
1647 if (ret) {
1648 ret = CMD_ERROR;
1649 goto end;
1650 }
1651
1652 /* Open output element */
1653 ret = mi_lttng_writer_open_element(writer,
1654 mi_lttng_element_command_output);
1655 if (ret) {
1656 ret = CMD_ERROR;
1657 goto end;
1658 }
1659 }
1660
1661 opt_event_list = (char*) poptGetArg(pc);
1662 if (opt_event_list == NULL && opt_enable_all == 0) {
1663 ERR("Missing event name(s).\n");
1664 ret = CMD_ERROR;
1665 goto end;
1666 }
1667
1668 leftover = poptGetArg(pc);
1669 if (leftover) {
1670 ERR("Unknown argument: %s", leftover);
1671 ret = CMD_ERROR;
1672 goto end;
1673 }
1674
1675 if (!opt_session_name) {
1676 session_name = get_session_name();
1677 if (session_name == NULL) {
1678 command_ret = CMD_ERROR;
1679 success = 0;
1680 goto mi_closing;
1681 }
1682 } else {
1683 session_name = opt_session_name;
1684 }
1685
1686 command_ret = enable_events(session_name);
1687 if (command_ret) {
1688 success = 0;
1689 goto mi_closing;
1690 }
1691
1692 mi_closing:
1693 /* Mi closing */
1694 if (lttng_opt_mi) {
1695 /* Close output element */
1696 ret = mi_lttng_writer_close_element(writer);
1697 if (ret) {
1698 ret = CMD_ERROR;
1699 goto end;
1700 }
1701
1702 ret = mi_lttng_writer_write_element_bool(writer,
1703 mi_lttng_element_command_success, success);
1704 if (ret) {
1705 ret = CMD_ERROR;
1706 goto end;
1707 }
1708
1709 /* Command element close */
1710 ret = mi_lttng_writer_command_close(writer);
1711 if (ret) {
1712 ret = CMD_ERROR;
1713 goto end;
1714 }
1715 }
1716
1717 end:
1718 /* Mi clean-up */
1719 if (writer && mi_lttng_writer_destroy(writer)) {
1720 /* Preserve original error code */
1721 ret = ret ? ret : LTTNG_ERR_MI_IO_FAIL;
1722 }
1723
1724 if (opt_session_name == NULL) {
1725 free(session_name);
1726 }
1727
1728 /* Overwrite ret if an error occurred in enable_events */
1729 ret = command_ret ? command_ret : ret;
1730
1731 poptFreeContext(pc);
1732 return ret;
1733 }
1734
This page took 0.106224 seconds and 4 git commands to generate.