41be3a5a03fbd5476732657e35b46769b347c02d
[lttng-tools.git] / src / bin / lttng / commands / enable_events.c
1 /*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2 only,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 */
17
18 #define _LGPL_SOURCE
19 #include <assert.h>
20 #include <popt.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <sys/stat.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26 #include <inttypes.h>
27 #include <ctype.h>
28
29 #include <common/sessiond-comm/sessiond-comm.h>
30 #include <common/compat/string.h>
31 #include <common/compat/getenv.h>
32 #include <common/string-utils/string-utils.h>
33 #include <common/utils.h>
34
35 #include <lttng/constant.h>
36 /* Mi dependancy */
37 #include <common/mi-lttng.h>
38
39 #include "../command.h"
40
41 #if (LTTNG_SYMBOL_NAME_LEN == 256)
42 #define LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "255"
43 #endif
44
45 static char *opt_event_list;
46 static int opt_event_type;
47 static const char *opt_loglevel;
48 static int opt_loglevel_type;
49 static int opt_kernel;
50 static char *opt_session_name;
51 static int opt_userspace;
52 static int opt_jul;
53 static int opt_log4j;
54 static int opt_python;
55 static int opt_enable_all;
56 static char *opt_probe;
57 static char *opt_userspace_probe;
58 static char *opt_function;
59 static char *opt_channel_name;
60 static char *opt_filter;
61 static char *opt_exclude;
62
63 #ifdef LTTNG_EMBED_HELP
64 static const char help_msg[] =
65 #include <lttng-enable-event.1.h>
66 ;
67 #endif
68
69 enum {
70 OPT_HELP = 1,
71 OPT_TRACEPOINT,
72 OPT_PROBE,
73 OPT_USERSPACE_PROBE,
74 OPT_FUNCTION,
75 OPT_SYSCALL,
76 OPT_USERSPACE,
77 OPT_LOGLEVEL,
78 OPT_LOGLEVEL_ONLY,
79 OPT_LIST_OPTIONS,
80 OPT_FILTER,
81 OPT_EXCLUDE,
82 };
83
84 static struct lttng_handle *handle;
85 static struct mi_writer *writer;
86
87 static struct poptOption long_options[] = {
88 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
89 {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0},
90 {"session", 's', POPT_ARG_STRING, &opt_session_name, 0, 0, 0},
91 {"all", 'a', POPT_ARG_VAL, &opt_enable_all, 1, 0, 0},
92 {"channel", 'c', POPT_ARG_STRING, &opt_channel_name, 0, 0, 0},
93 {"kernel", 'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0},
94 {"userspace", 'u', POPT_ARG_NONE, 0, OPT_USERSPACE, 0, 0},
95 {"jul", 'j', POPT_ARG_VAL, &opt_jul, 1, 0, 0},
96 {"log4j", 'l', POPT_ARG_VAL, &opt_log4j, 1, 0, 0},
97 {"python", 'p', POPT_ARG_VAL, &opt_python, 1, 0, 0},
98 {"tracepoint", 0, POPT_ARG_NONE, 0, OPT_TRACEPOINT, 0, 0},
99 {"probe", 0, POPT_ARG_STRING, &opt_probe, OPT_PROBE, 0, 0},
100 {"userspace-probe",0, POPT_ARG_STRING, &opt_userspace_probe, OPT_USERSPACE_PROBE, 0, 0},
101 {"function", 0, POPT_ARG_STRING, &opt_function, OPT_FUNCTION, 0, 0},
102 {"syscall", 0, POPT_ARG_NONE, 0, OPT_SYSCALL, 0, 0},
103 {"loglevel", 0, POPT_ARG_STRING, 0, OPT_LOGLEVEL, 0, 0},
104 {"loglevel-only", 0, POPT_ARG_STRING, 0, OPT_LOGLEVEL_ONLY, 0, 0},
105 {"list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL},
106 {"filter", 'f', POPT_ARG_STRING, &opt_filter, OPT_FILTER, 0, 0},
107 {"exclude", 'x', POPT_ARG_STRING, &opt_exclude, OPT_EXCLUDE, 0, 0},
108 {0, 0, 0, 0, 0, 0, 0}
109 };
110
111 /*
112 * Parse probe options.
113 */
114 static int parse_probe_opts(struct lttng_event *ev, char *opt)
115 {
116 int ret = CMD_SUCCESS;
117 int match;
118 char s_hex[19];
119 #define S_HEX_LEN_SCANF_IS_A_BROKEN_API "18" /* 18 is (19 - 1) (\0 is extra) */
120 char name[LTTNG_SYMBOL_NAME_LEN];
121
122 if (opt == NULL) {
123 ret = CMD_ERROR;
124 goto end;
125 }
126
127 /* Check for symbol+offset */
128 match = sscanf(opt, "%" LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API
129 "[^'+']+%" S_HEX_LEN_SCANF_IS_A_BROKEN_API "s", name, s_hex);
130 if (match == 2) {
131 strncpy(ev->attr.probe.symbol_name, name, LTTNG_SYMBOL_NAME_LEN);
132 ev->attr.probe.symbol_name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
133 DBG("probe symbol %s", ev->attr.probe.symbol_name);
134 if (*s_hex == '\0') {
135 ERR("Invalid probe offset %s", s_hex);
136 ret = CMD_ERROR;
137 goto end;
138 }
139 ev->attr.probe.offset = strtoul(s_hex, NULL, 0);
140 DBG("probe offset %" PRIu64, ev->attr.probe.offset);
141 ev->attr.probe.addr = 0;
142 goto end;
143 }
144
145 /* Check for symbol */
146 if (isalpha(name[0])) {
147 match = sscanf(opt, "%" LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "s",
148 name);
149 if (match == 1) {
150 strncpy(ev->attr.probe.symbol_name, name, LTTNG_SYMBOL_NAME_LEN);
151 ev->attr.probe.symbol_name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
152 DBG("probe symbol %s", ev->attr.probe.symbol_name);
153 ev->attr.probe.offset = 0;
154 DBG("probe offset %" PRIu64, ev->attr.probe.offset);
155 ev->attr.probe.addr = 0;
156 goto end;
157 }
158 }
159
160 /* Check for address */
161 match = sscanf(opt, "%" S_HEX_LEN_SCANF_IS_A_BROKEN_API "s", s_hex);
162 if (match > 0) {
163 if (*s_hex == '\0') {
164 ERR("Invalid probe address %s", s_hex);
165 ret = CMD_ERROR;
166 goto end;
167 }
168 ev->attr.probe.addr = strtoul(s_hex, NULL, 0);
169 DBG("probe addr %" PRIu64, ev->attr.probe.addr);
170 ev->attr.probe.offset = 0;
171 memset(ev->attr.probe.symbol_name, 0, LTTNG_SYMBOL_NAME_LEN);
172 goto end;
173 }
174
175 /* No match */
176 ret = CMD_ERROR;
177
178 end:
179 return ret;
180 }
181
182 /*
183 * Walk the directories in the PATH environment variable to find the target
184 * binary passed as parameter.
185 *
186 * On success, the full path of the binary is copied in binary_full_path out
187 * parameter. This buffer is allocated by the caller and must be at least
188 * LTTNG_PATH_MAX bytes long.
189 * On failure, returns -1;
190 */
191 static int walk_command_search_path(const char *binary, char *binary_full_path)
192 {
193 char *tentative_binary_path = NULL;
194 char *command_search_path = NULL;
195 char *curr_search_dir_end = NULL;
196 char *curr_search_dir = NULL;
197 struct stat stat_output;
198 int ret = 0;
199
200 command_search_path = lttng_secure_getenv("PATH");
201 if (!command_search_path) {
202 ret = -1;
203 goto end;
204 }
205
206 /*
207 * Duplicate the $PATH string as the char pointer returned by getenv() should
208 * not be modified.
209 */
210 command_search_path = strdup(command_search_path);
211 if (!command_search_path) {
212 ret = -1;
213 goto end;
214 }
215
216 /*
217 * This char array is used to concatenate path to binary to look for
218 * the binary.
219 */
220 tentative_binary_path = zmalloc(LTTNG_PATH_MAX * sizeof(char));
221 if (!tentative_binary_path) {
222 ret = -1;
223 goto alloc_error;
224 }
225
226 curr_search_dir = command_search_path;
227 do {
228 /*
229 * Split on ':'. The return value of this call points to the
230 * matching character.
231 */
232 curr_search_dir_end = strchr(curr_search_dir, ':');
233 if (curr_search_dir_end != NULL) {
234 /*
235 * Add a NULL byte to the end of the first token so it
236 * can be used as a string.
237 */
238 curr_search_dir_end[0] = '\0';
239 }
240
241 /* Empty the tentative path */
242 memset(tentative_binary_path, 0, LTTNG_PATH_MAX * sizeof(char));
243
244 /*
245 * Build the tentative path to the binary using the current
246 * search directory and the name of the binary.
247 */
248 ret = snprintf(tentative_binary_path, LTTNG_PATH_MAX, "%s/%s",
249 curr_search_dir, binary);
250 if (ret < 0) {
251 goto free_binary_path;
252 }
253 if (ret < LTTNG_PATH_MAX) {
254 /*
255 * Use STAT(2) to see if the file exists.
256 */
257 ret = stat(tentative_binary_path, &stat_output);
258 if (ret == 0) {
259 /*
260 * Verify that it is a regular file or a
261 * symlink and not a special file (e.g.
262 * device).
263 */
264 if (S_ISREG(stat_output.st_mode)
265 || S_ISLNK(stat_output.st_mode)) {
266 /*
267 * Found a match, set the out parameter
268 * and return success.
269 */
270 ret = lttng_strncpy(binary_full_path,
271 tentative_binary_path,
272 LTTNG_PATH_MAX);
273 if (ret == -1) {
274 ERR("Source path does not fit "
275 "in destination buffer.");
276 }
277 goto free_binary_path;
278 }
279 }
280 }
281 /* Go to the next entry in the $PATH variable. */
282 curr_search_dir = curr_search_dir_end + 1;
283 } while (curr_search_dir_end != NULL);
284
285 free_binary_path:
286 free(tentative_binary_path);
287 alloc_error:
288 free(command_search_path);
289 end:
290 return ret;
291 }
292
293 /*
294 * Check if the symbol field passed by the user is in fact an address or an
295 * offset from a symbol. Those two instrumentation types are not supported yet.
296 * It's expected to be a common mistake because of the existing --probe option
297 * that does support these formats.
298 *
299 * Here are examples of these unsupported formats for the --userspace-probe
300 * option:
301 * elf:/path/to/binary:0x400430
302 * elf:/path/to/binary:4194364
303 * elf:/path/to/binary:my_symbol+0x323
304 * elf:/path/to/binary:my_symbol+43
305 */
306 static int warn_userspace_probe_syntax(const char *symbol)
307 {
308 unsigned long addr = 0;
309 size_t offset = 0;
310 int ret;
311
312 /* Check if the symbol field is an hex address. */
313 ret = sscanf(symbol, "0x%lx", &addr);
314 if (ret > 0) {
315 /* If there is a match, print a warning and return an error. */
316 ERR("Userspace probe on address not supported yet.");
317 ret = CMD_UNSUPPORTED;
318 goto error;
319 }
320
321 /* Check if the symbol field is an decimal address. */
322 ret = sscanf(symbol, "%lu", &addr);
323 if (ret > 0) {
324 /* If there is a match, print a warning and return an error. */
325 ERR("Userspace probe on address not supported yet.");
326 ret = CMD_UNSUPPORTED;
327 goto error;
328 }
329
330 /* Check if the symbol field is symbol+hex_offset. */
331 ret = sscanf(symbol, "%*[^+]+0x%lx", &offset);
332 if (ret > 0) {
333 /* If there is a match, print a warning and return an error. */
334 ERR("Userspace probe on symbol+offset not supported yet.");
335 ret = CMD_UNSUPPORTED;
336 goto error;
337 }
338
339 /* Check if the symbol field is symbol+decimal_offset. */
340 ret = sscanf(symbol, "%*[^+]+%lu", &offset);
341 if (ret > 0) {
342 /* If there is a match, print a warning and return an error. */
343 ERR("Userspace probe on symbol+offset not supported yet.");
344 ret = CMD_UNSUPPORTED;
345 goto error;
346 }
347
348 ret = 0;
349
350 error:
351 return ret;
352 }
353
354 /*
355 * Parse userspace probe options
356 * Set the userspace probe fields in the lttng_event struct and set the
357 * target_path to the path to the binary.
358 */
359 static int parse_userspace_probe_opts(struct lttng_event *ev, char *opt)
360 {
361 int ret = CMD_SUCCESS;
362 int num_token;
363 char **tokens;
364 char *target_path = NULL;
365 char *unescaped_target_path = NULL;
366 char *real_target_path = NULL;
367 char *symbol_name = NULL, *probe_name = NULL, *provider_name = NULL;
368 struct lttng_userspace_probe_location *probe_location = NULL;
369 struct lttng_userspace_probe_location_lookup_method *lookup_method =
370 NULL;
371
372 if (opt == NULL) {
373 ret = CMD_ERROR;
374 goto end;
375 }
376
377 switch (ev->type) {
378 case LTTNG_EVENT_USERSPACE_PROBE:
379 break;
380 default:
381 assert(0);
382 }
383
384 /*
385 * userspace probe fields are separated by ':'.
386 */
387 tokens = strutils_split(opt, ':', 1);
388 num_token = strutils_array_of_strings_len(tokens);
389
390 /*
391 * Early sanity check that the number of parameter is between 2 and 4
392 * inclusively.
393 * elf:PATH:SYMBOL
394 * std:PATH:PROVIDER_NAME:PROBE_NAME
395 * PATH:SYMBOL (same behavior as ELF)
396 */
397 if (num_token < 2 || num_token > 4) {
398 ret = CMD_ERROR;
399 goto end_string;
400 }
401
402 /*
403 * Looking up the first parameter will tell the technique to use to
404 * interpret the userspace probe/function description.
405 */
406 switch (num_token) {
407 case 2:
408 /* When the probe type is omitted we assume ELF for now. */
409 case 3:
410 if (num_token == 3 && strcmp(tokens[0], "elf") == 0) {
411 target_path = tokens[1];
412 symbol_name = tokens[2];
413 } else if (num_token == 2) {
414 target_path = tokens[0];
415 symbol_name = tokens[1];
416 } else {
417 ret = CMD_ERROR;
418 goto end_string;
419 }
420 lookup_method =
421 lttng_userspace_probe_location_lookup_method_function_elf_create();
422 if (!lookup_method) {
423 WARN("Failed to create ELF lookup method");
424 ret = CMD_ERROR;
425 goto end_string;
426 }
427 break;
428 case 4:
429 if (strcmp(tokens[0], "sdt") == 0) {
430 target_path = tokens[1];
431 provider_name = tokens[2];
432 probe_name = tokens[3];
433 } else {
434 ret = CMD_ERROR;
435 goto end_string;
436 }
437 lookup_method =
438 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
439 if (!lookup_method) {
440 WARN("Failed to create ELF lookup method");
441 ret = CMD_ERROR;
442 goto end_string;
443 }
444 break;
445 default:
446 ret = CMD_ERROR;
447 goto end_string;
448 }
449
450 /* strutils_unescape_string allocates a new char *. */
451 unescaped_target_path = strutils_unescape_string(target_path, 0);
452 if (!unescaped_target_path) {
453 ret = CMD_ERROR;
454 goto end_destroy_lookup_method;
455 }
456
457 /*
458 * If there is not forward slash in the path. Walk the $PATH else
459 * expand.
460 */
461 if (strchr(unescaped_target_path, '/') == NULL) {
462 /* Walk the $PATH variable to find the targeted binary. */
463 real_target_path = zmalloc(LTTNG_PATH_MAX * sizeof(char));
464 if (!real_target_path) {
465 PERROR("Error allocating path buffer");
466 ret = CMD_ERROR;
467 goto end_destroy_lookup_method;
468 }
469 ret = walk_command_search_path(unescaped_target_path, real_target_path);
470 if (ret) {
471 ERR("Binary not found.");
472 ret = CMD_ERROR;
473 goto end_destroy_lookup_method;
474 }
475 } else {
476 /*
477 * Expand references to `/./` and `/../`. This function does not check
478 * if the file exists. This call returns an allocated buffer on
479 * success.
480 */
481 real_target_path = utils_expand_path_keep_symlink(unescaped_target_path);
482 if (!real_target_path) {
483 ERR("Error expanding the path to binary.");
484 ret = CMD_ERROR;
485 goto end_destroy_lookup_method;
486 }
487
488 /*
489 * Check if the file exists using access(2). If it does not, walk the
490 * $PATH.
491 */
492 ret = access(real_target_path, F_OK);
493 if (ret) {
494 ret = CMD_ERROR;
495 goto end_destroy_lookup_method;
496 }
497 }
498
499 switch (lttng_userspace_probe_location_lookup_method_get_type(lookup_method)) {
500 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF:
501 /*
502 * Check for common mistakes in userspace probe description syntax.
503 */
504 ret = warn_userspace_probe_syntax(symbol_name);
505 if (ret) {
506 goto end_destroy_lookup_method;
507 }
508
509 probe_location = lttng_userspace_probe_location_function_create(
510 real_target_path, symbol_name, lookup_method);
511 if (!probe_location) {
512 WARN("Failed to create function probe location");
513 ret = CMD_ERROR;
514 goto end_destroy_lookup_method;
515 }
516
517 /* Ownership transferred to probe_location. */
518 lookup_method = NULL;
519
520 ret = lttng_event_set_userspace_probe_location(ev, probe_location);
521 if (ret) {
522 WARN("Failed to set probe location on event");
523 ret = CMD_ERROR;
524 goto end_destroy_location;
525 }
526 break;
527 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT:
528 probe_location = lttng_userspace_probe_location_tracepoint_create(
529 real_target_path, provider_name, probe_name, lookup_method);
530 if (!probe_location) {
531 WARN("Failed to create function probe location");
532 ret = CMD_ERROR;
533 goto end_destroy_lookup_method;
534 }
535
536 /* Ownership transferred to probe_location. */
537 lookup_method = NULL;
538
539 ret = lttng_event_set_userspace_probe_location(ev, probe_location);
540 if (ret) {
541 WARN("Failed to set probe location on event");
542 ret = CMD_ERROR;
543 goto end_destroy_location;
544 }
545 break;
546 default:
547 ret = CMD_ERROR;
548 goto end_destroy_lookup_method;
549 }
550
551 /* Successful parsing, now clean up everything and return. */
552 goto end_string;
553
554 end_destroy_location:
555 lttng_userspace_probe_location_destroy(probe_location);
556 end_destroy_lookup_method:
557 lttng_userspace_probe_location_lookup_method_destroy(lookup_method);
558 end_string:
559 strutils_free_null_terminated_array_of_strings(tokens);
560 /*
561 * Freeing both char * here makes the error handling simplier. free()
562 * performs not action if the pointer is NULL.
563 */
564 free(real_target_path);
565 free(unescaped_target_path);
566 end:
567 return ret;
568 }
569
570 /*
571 * Maps LOG4j loglevel from string to value
572 */
573 static int loglevel_log4j_str_to_value(const char *inputstr)
574 {
575 int i = 0;
576 char str[LTTNG_SYMBOL_NAME_LEN];
577
578 if (!inputstr || strlen(inputstr) == 0) {
579 return -1;
580 }
581
582 /*
583 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
584 * added at the end of the loop so a the upper bound we avoid the overflow.
585 */
586 while (i < (LTTNG_SYMBOL_NAME_LEN - 1) && inputstr[i] != '\0') {
587 str[i] = toupper(inputstr[i]);
588 i++;
589 }
590 str[i] = '\0';
591
592 if (!strcmp(str, "LOG4J_OFF") || !strcmp(str, "OFF")) {
593 return LTTNG_LOGLEVEL_LOG4J_OFF;
594 } else if (!strcmp(str, "LOG4J_FATAL") || !strcmp(str, "FATAL")) {
595 return LTTNG_LOGLEVEL_LOG4J_FATAL;
596 } else if (!strcmp(str, "LOG4J_ERROR") || !strcmp(str, "ERROR")) {
597 return LTTNG_LOGLEVEL_LOG4J_ERROR;
598 } else if (!strcmp(str, "LOG4J_WARN") || !strcmp(str, "WARN")) {
599 return LTTNG_LOGLEVEL_LOG4J_WARN;
600 } else if (!strcmp(str, "LOG4J_INFO") || !strcmp(str, "INFO")) {
601 return LTTNG_LOGLEVEL_LOG4J_INFO;
602 } else if (!strcmp(str, "LOG4J_DEBUG") || !strcmp(str, "DEBUG")) {
603 return LTTNG_LOGLEVEL_LOG4J_DEBUG;
604 } else if (!strcmp(str, "LOG4J_TRACE") || !strcmp(str, "TRACE")) {
605 return LTTNG_LOGLEVEL_LOG4J_TRACE;
606 } else if (!strcmp(str, "LOG4J_ALL") || !strcmp(str, "ALL")) {
607 return LTTNG_LOGLEVEL_LOG4J_ALL;
608 } else {
609 return -1;
610 }
611 }
612
613 /*
614 * Maps JUL loglevel from string to value
615 */
616 static int loglevel_jul_str_to_value(const char *inputstr)
617 {
618 int i = 0;
619 char str[LTTNG_SYMBOL_NAME_LEN];
620
621 if (!inputstr || strlen(inputstr) == 0) {
622 return -1;
623 }
624
625 /*
626 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
627 * added at the end of the loop so a the upper bound we avoid the overflow.
628 */
629 while (i < (LTTNG_SYMBOL_NAME_LEN - 1) && inputstr[i] != '\0') {
630 str[i] = toupper(inputstr[i]);
631 i++;
632 }
633 str[i] = '\0';
634
635 if (!strcmp(str, "JUL_OFF") || !strcmp(str, "OFF")) {
636 return LTTNG_LOGLEVEL_JUL_OFF;
637 } else if (!strcmp(str, "JUL_SEVERE") || !strcmp(str, "SEVERE")) {
638 return LTTNG_LOGLEVEL_JUL_SEVERE;
639 } else if (!strcmp(str, "JUL_WARNING") || !strcmp(str, "WARNING")) {
640 return LTTNG_LOGLEVEL_JUL_WARNING;
641 } else if (!strcmp(str, "JUL_INFO") || !strcmp(str, "INFO")) {
642 return LTTNG_LOGLEVEL_JUL_INFO;
643 } else if (!strcmp(str, "JUL_CONFIG") || !strcmp(str, "CONFIG")) {
644 return LTTNG_LOGLEVEL_JUL_CONFIG;
645 } else if (!strcmp(str, "JUL_FINE") || !strcmp(str, "FINE")) {
646 return LTTNG_LOGLEVEL_JUL_FINE;
647 } else if (!strcmp(str, "JUL_FINER") || !strcmp(str, "FINER")) {
648 return LTTNG_LOGLEVEL_JUL_FINER;
649 } else if (!strcmp(str, "JUL_FINEST") || !strcmp(str, "FINEST")) {
650 return LTTNG_LOGLEVEL_JUL_FINEST;
651 } else if (!strcmp(str, "JUL_ALL") || !strcmp(str, "ALL")) {
652 return LTTNG_LOGLEVEL_JUL_ALL;
653 } else {
654 return -1;
655 }
656 }
657
658 /*
659 * Maps Python loglevel from string to value
660 */
661 static int loglevel_python_str_to_value(const char *inputstr)
662 {
663 int i = 0;
664 char str[LTTNG_SYMBOL_NAME_LEN];
665
666 if (!inputstr || strlen(inputstr) == 0) {
667 return -1;
668 }
669
670 /*
671 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
672 * added at the end of the loop so a the upper bound we avoid the overflow.
673 */
674 while (i < (LTTNG_SYMBOL_NAME_LEN - 1) && inputstr[i] != '\0') {
675 str[i] = toupper(inputstr[i]);
676 i++;
677 }
678 str[i] = '\0';
679
680 if (!strcmp(str, "PYTHON_CRITICAL") || !strcmp(str, "CRITICAL")) {
681 return LTTNG_LOGLEVEL_PYTHON_CRITICAL;
682 } else if (!strcmp(str, "PYTHON_ERROR") || !strcmp(str, "ERROR")) {
683 return LTTNG_LOGLEVEL_PYTHON_ERROR;
684 } else if (!strcmp(str, "PYTHON_WARNING") || !strcmp(str, "WARNING")) {
685 return LTTNG_LOGLEVEL_PYTHON_WARNING;
686 } else if (!strcmp(str, "PYTHON_INFO") || !strcmp(str, "INFO")) {
687 return LTTNG_LOGLEVEL_PYTHON_INFO;
688 } else if (!strcmp(str, "PYTNON_DEBUG") || !strcmp(str, "DEBUG")) {
689 return LTTNG_LOGLEVEL_PYTHON_DEBUG;
690 } else if (!strcmp(str, "PYTHON_NOTSET") || !strcmp(str, "NOTSET")) {
691 return LTTNG_LOGLEVEL_PYTHON_NOTSET;
692 } else {
693 return -1;
694 }
695 }
696
697 /*
698 * Maps loglevel from string to value
699 */
700 static
701 int loglevel_str_to_value(const char *inputstr)
702 {
703 int i = 0;
704 char str[LTTNG_SYMBOL_NAME_LEN];
705
706 if (!inputstr || strlen(inputstr) == 0) {
707 return -1;
708 }
709
710 /*
711 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
712 * added at the end of the loop so a the upper bound we avoid the overflow.
713 */
714 while (i < (LTTNG_SYMBOL_NAME_LEN - 1) && inputstr[i] != '\0') {
715 str[i] = toupper(inputstr[i]);
716 i++;
717 }
718 str[i] = '\0';
719 if (!strcmp(str, "TRACE_EMERG") || !strcmp(str, "EMERG")) {
720 return LTTNG_LOGLEVEL_EMERG;
721 } else if (!strcmp(str, "TRACE_ALERT") || !strcmp(str, "ALERT")) {
722 return LTTNG_LOGLEVEL_ALERT;
723 } else if (!strcmp(str, "TRACE_CRIT") || !strcmp(str, "CRIT")) {
724 return LTTNG_LOGLEVEL_CRIT;
725 } else if (!strcmp(str, "TRACE_ERR") || !strcmp(str, "ERR")) {
726 return LTTNG_LOGLEVEL_ERR;
727 } else if (!strcmp(str, "TRACE_WARNING") || !strcmp(str, "WARNING")) {
728 return LTTNG_LOGLEVEL_WARNING;
729 } else if (!strcmp(str, "TRACE_NOTICE") || !strcmp(str, "NOTICE")) {
730 return LTTNG_LOGLEVEL_NOTICE;
731 } else if (!strcmp(str, "TRACE_INFO") || !strcmp(str, "INFO")) {
732 return LTTNG_LOGLEVEL_INFO;
733 } else if (!strcmp(str, "TRACE_DEBUG_SYSTEM") || !strcmp(str, "DEBUG_SYSTEM") || !strcmp(str, "SYSTEM")) {
734 return LTTNG_LOGLEVEL_DEBUG_SYSTEM;
735 } else if (!strcmp(str, "TRACE_DEBUG_PROGRAM") || !strcmp(str, "DEBUG_PROGRAM") || !strcmp(str, "PROGRAM")) {
736 return LTTNG_LOGLEVEL_DEBUG_PROGRAM;
737 } else if (!strcmp(str, "TRACE_DEBUG_PROCESS") || !strcmp(str, "DEBUG_PROCESS") || !strcmp(str, "PROCESS")) {
738 return LTTNG_LOGLEVEL_DEBUG_PROCESS;
739 } else if (!strcmp(str, "TRACE_DEBUG_MODULE") || !strcmp(str, "DEBUG_MODULE") || !strcmp(str, "MODULE")) {
740 return LTTNG_LOGLEVEL_DEBUG_MODULE;
741 } else if (!strcmp(str, "TRACE_DEBUG_UNIT") || !strcmp(str, "DEBUG_UNIT") || !strcmp(str, "UNIT")) {
742 return LTTNG_LOGLEVEL_DEBUG_UNIT;
743 } else if (!strcmp(str, "TRACE_DEBUG_FUNCTION") || !strcmp(str, "DEBUG_FUNCTION") || !strcmp(str, "FUNCTION")) {
744 return LTTNG_LOGLEVEL_DEBUG_FUNCTION;
745 } else if (!strcmp(str, "TRACE_DEBUG_LINE") || !strcmp(str, "DEBUG_LINE") || !strcmp(str, "LINE")) {
746 return LTTNG_LOGLEVEL_DEBUG_LINE;
747 } else if (!strcmp(str, "TRACE_DEBUG") || !strcmp(str, "DEBUG")) {
748 return LTTNG_LOGLEVEL_DEBUG;
749 } else {
750 return -1;
751 }
752 }
753
754 static
755 const char *print_channel_name(const char *name)
756 {
757 return name ? : DEFAULT_CHANNEL_NAME;
758 }
759
760 static
761 const char *print_raw_channel_name(const char *name)
762 {
763 return name ? : "<default>";
764 }
765
766 /*
767 * Mi print exlcusion list
768 */
769 static
770 int mi_print_exclusion(char **names)
771 {
772 int i, ret;
773 int count = names ? strutils_array_of_strings_len(names) : 0;
774
775 assert(writer);
776
777 if (count == 0) {
778 ret = 0;
779 goto end;
780 }
781 ret = mi_lttng_writer_open_element(writer, config_element_exclusions);
782 if (ret) {
783 goto end;
784 }
785
786 for (i = 0; i < count; i++) {
787 ret = mi_lttng_writer_write_element_string(writer,
788 config_element_exclusion, names[i]);
789 if (ret) {
790 goto end;
791 }
792 }
793
794 /* Close exclusions element */
795 ret = mi_lttng_writer_close_element(writer);
796
797 end:
798 return ret;
799 }
800
801 /*
802 * Return allocated string for pretty-printing exclusion names.
803 */
804 static
805 char *print_exclusions(char **names)
806 {
807 int length = 0;
808 int i;
809 const char *preamble = " excluding ";
810 char *ret;
811 int count = names ? strutils_array_of_strings_len(names) : 0;
812
813 if (count == 0) {
814 return strdup("");
815 }
816
817 /* calculate total required length */
818 for (i = 0; i < count; i++) {
819 length += strlen(names[i]) + 4;
820 }
821
822 /* add length of preamble + one for NUL - one for last (missing) comma */
823 length += strlen(preamble);
824 ret = zmalloc(length + 1);
825 if (!ret) {
826 return NULL;
827 }
828 strncpy(ret, preamble, length);
829 for (i = 0; i < count; i++) {
830 strcat(ret, "\"");
831 strcat(ret, names[i]);
832 strcat(ret, "\"");
833 if (i != count - 1) {
834 strcat(ret, ", ");
835 }
836 }
837
838 return ret;
839 }
840
841 static
842 int check_exclusion_subsets(const char *event_name, const char *exclusion)
843 {
844 bool warn = false;
845 int ret = 0;
846 const char *e = event_name;
847 const char *x = exclusion;
848
849 /* Scan both the excluder and the event letter by letter */
850 while (true) {
851 if (*e == '\\') {
852 if (*x != *e) {
853 warn = true;
854 goto end;
855 }
856
857 e++;
858 x++;
859 goto cmp_chars;
860 }
861
862 if (*x == '*') {
863 /* Event is a subset of the excluder */
864 ERR("Event %s: %s excludes all events from %s",
865 event_name, exclusion, event_name);
866 goto error;
867 }
868
869 if (*e == '*') {
870 /*
871 * Reached the end of the event name before the
872 * end of the exclusion: this is valid.
873 */
874 goto end;
875 }
876
877 cmp_chars:
878 if (*x != *e) {
879 warn = true;
880 break;
881 }
882
883 x++;
884 e++;
885 }
886
887 goto end;
888
889 error:
890 ret = -1;
891
892 end:
893 if (warn) {
894 WARN("Event %s: %s does not exclude any events from %s",
895 event_name, exclusion, event_name);
896 }
897
898 return ret;
899 }
900
901 static
902 int create_exclusion_list_and_validate(const char *event_name,
903 const char *exclusions_arg,
904 char ***exclusion_list)
905 {
906 int ret = 0;
907 char **exclusions = NULL;
908
909 /* Event name must be a valid globbing pattern to allow exclusions. */
910 if (!strutils_is_star_glob_pattern(event_name)) {
911 ERR("Event %s: Exclusions can only be used with a globbing pattern",
912 event_name);
913 goto error;
914 }
915
916 /* Split exclusions. */
917 exclusions = strutils_split(exclusions_arg, ',', true);
918 if (!exclusions) {
919 goto error;
920 }
921
922 /*
923 * If the event name is a star-at-end only globbing pattern,
924 * then we can validate the individual exclusions. Otherwise
925 * all exclusions are passed to the session daemon.
926 */
927 if (strutils_is_star_at_the_end_only_glob_pattern(event_name)) {
928 char * const *exclusion;
929
930 for (exclusion = exclusions; *exclusion; exclusion++) {
931 if (!strutils_is_star_glob_pattern(*exclusion) ||
932 strutils_is_star_at_the_end_only_glob_pattern(*exclusion)) {
933 ret = check_exclusion_subsets(event_name, *exclusion);
934 if (ret) {
935 goto error;
936 }
937 }
938 }
939 }
940
941 *exclusion_list = exclusions;
942
943 goto end;
944
945 error:
946 ret = -1;
947 strutils_free_null_terminated_array_of_strings(exclusions);
948
949 end:
950 return ret;
951 }
952
953 static void warn_on_truncated_exclusion_names(char * const *exclusion_list,
954 int *warn)
955 {
956 char * const *exclusion;
957
958 for (exclusion = exclusion_list; *exclusion; exclusion++) {
959 if (strlen(*exclusion) >= LTTNG_SYMBOL_NAME_LEN) {
960 WARN("Event exclusion \"%s\" will be truncated",
961 *exclusion);
962 *warn = 1;
963 }
964 }
965 }
966
967 /*
968 * Enabling event using the lttng API.
969 * Note: in case of error only the last error code will be return.
970 */
971 static int enable_events(char *session_name)
972 {
973 int ret = CMD_SUCCESS, command_ret = CMD_SUCCESS;
974 int error_holder = CMD_SUCCESS, warn = 0, error = 0, success = 1;
975 char *event_name, *channel_name = NULL;
976 struct lttng_event *ev;
977 struct lttng_domain dom;
978 char **exclusion_list = NULL;
979
980 memset(&dom, 0, sizeof(dom));
981
982 ev = lttng_event_create();
983 if (!ev) {
984 ret = CMD_ERROR;
985 goto error;
986 }
987
988 if (opt_kernel) {
989 if (opt_loglevel) {
990 WARN("Kernel loglevels are not supported.");
991 }
992 }
993
994 /* Create lttng domain */
995 if (opt_kernel) {
996 dom.type = LTTNG_DOMAIN_KERNEL;
997 dom.buf_type = LTTNG_BUFFER_GLOBAL;
998 } else if (opt_userspace) {
999 dom.type = LTTNG_DOMAIN_UST;
1000 /* Default. */
1001 dom.buf_type = LTTNG_BUFFER_PER_UID;
1002 } else if (opt_jul) {
1003 dom.type = LTTNG_DOMAIN_JUL;
1004 /* Default. */
1005 dom.buf_type = LTTNG_BUFFER_PER_UID;
1006 } else if (opt_log4j) {
1007 dom.type = LTTNG_DOMAIN_LOG4J;
1008 /* Default. */
1009 dom.buf_type = LTTNG_BUFFER_PER_UID;
1010 } else if (opt_python) {
1011 dom.type = LTTNG_DOMAIN_PYTHON;
1012 /* Default. */
1013 dom.buf_type = LTTNG_BUFFER_PER_UID;
1014 } else {
1015 /* Checked by the caller. */
1016 assert(0);
1017 }
1018
1019 if (opt_exclude) {
1020 switch (dom.type) {
1021 case LTTNG_DOMAIN_KERNEL:
1022 case LTTNG_DOMAIN_JUL:
1023 case LTTNG_DOMAIN_LOG4J:
1024 case LTTNG_DOMAIN_PYTHON:
1025 ERR("Event name exclusions are not yet implemented for %s events",
1026 get_domain_str(dom.type));
1027 ret = CMD_ERROR;
1028 goto error;
1029 case LTTNG_DOMAIN_UST:
1030 /* Exclusions supported */
1031 break;
1032 default:
1033 assert(0);
1034 }
1035 }
1036
1037 /*
1038 * Adding a filter to a probe, function or userspace-probe would be
1039 * denied by the kernel tracer as it's not supported at the moment. We
1040 * do an early check here to warn the user.
1041 */
1042 if (opt_filter && opt_kernel) {
1043 switch (opt_event_type) {
1044 case LTTNG_EVENT_ALL:
1045 case LTTNG_EVENT_TRACEPOINT:
1046 case LTTNG_EVENT_SYSCALL:
1047 break;
1048 case LTTNG_EVENT_PROBE:
1049 case LTTNG_EVENT_USERSPACE_PROBE:
1050 case LTTNG_EVENT_FUNCTION:
1051 ERR("Filter expressions are not supported for %s events",
1052 get_event_type_str(opt_event_type));
1053 ret = CMD_ERROR;
1054 goto error;
1055 default:
1056 ret = CMD_UNDEFINED;
1057 goto error;
1058 }
1059 }
1060
1061 channel_name = opt_channel_name;
1062
1063 handle = lttng_create_handle(session_name, &dom);
1064 if (handle == NULL) {
1065 ret = -1;
1066 goto error;
1067 }
1068
1069 /* Prepare Mi */
1070 if (lttng_opt_mi) {
1071 /* Open a events element */
1072 ret = mi_lttng_writer_open_element(writer, config_element_events);
1073 if (ret) {
1074 ret = CMD_ERROR;
1075 goto error;
1076 }
1077 }
1078
1079 if (opt_enable_all) {
1080 /* Default setup for enable all */
1081 if (opt_kernel) {
1082 ev->type = opt_event_type;
1083 strcpy(ev->name, "*");
1084 /* kernel loglevels not implemented */
1085 ev->loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
1086 } else {
1087 ev->type = LTTNG_EVENT_TRACEPOINT;
1088 strcpy(ev->name, "*");
1089 ev->loglevel_type = opt_loglevel_type;
1090 if (opt_loglevel) {
1091 assert(opt_userspace || opt_jul || opt_log4j || opt_python);
1092 if (opt_userspace) {
1093 ev->loglevel = loglevel_str_to_value(opt_loglevel);
1094 } else if (opt_jul) {
1095 ev->loglevel = loglevel_jul_str_to_value(opt_loglevel);
1096 } else if (opt_log4j) {
1097 ev->loglevel = loglevel_log4j_str_to_value(opt_loglevel);
1098 } else if (opt_python) {
1099 ev->loglevel = loglevel_python_str_to_value(opt_loglevel);
1100 }
1101 if (ev->loglevel == -1) {
1102 ERR("Unknown loglevel %s", opt_loglevel);
1103 ret = -LTTNG_ERR_INVALID;
1104 goto error;
1105 }
1106 } else {
1107 assert(opt_userspace || opt_jul || opt_log4j || opt_python);
1108 if (opt_userspace) {
1109 ev->loglevel = -1;
1110 } else if (opt_jul) {
1111 ev->loglevel = LTTNG_LOGLEVEL_JUL_ALL;
1112 } else if (opt_log4j) {
1113 ev->loglevel = LTTNG_LOGLEVEL_LOG4J_ALL;
1114 } else if (opt_python) {
1115 ev->loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG;
1116 }
1117 }
1118 }
1119
1120 if (opt_exclude) {
1121 ret = create_exclusion_list_and_validate("*",
1122 opt_exclude, &exclusion_list);
1123 if (ret) {
1124 ret = CMD_ERROR;
1125 goto error;
1126 }
1127
1128 ev->exclusion = 1;
1129 warn_on_truncated_exclusion_names(exclusion_list,
1130 &warn);
1131 }
1132 if (!opt_filter) {
1133 ret = lttng_enable_event_with_exclusions(handle,
1134 ev, channel_name,
1135 NULL,
1136 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
1137 exclusion_list);
1138 if (ret < 0) {
1139 switch (-ret) {
1140 case LTTNG_ERR_KERN_EVENT_EXIST:
1141 WARN("Kernel events already enabled (channel %s, session %s)",
1142 print_channel_name(channel_name), session_name);
1143 warn = 1;
1144 break;
1145 case LTTNG_ERR_TRACE_ALREADY_STARTED:
1146 {
1147 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
1148 ERR("Events: %s (channel %s, session %s)",
1149 msg,
1150 print_channel_name(channel_name),
1151 session_name);
1152 error = 1;
1153 break;
1154 }
1155 default:
1156 ERR("Events: %s (channel %s, session %s)",
1157 lttng_strerror(ret),
1158 ret == -LTTNG_ERR_NEED_CHANNEL_NAME
1159 ? print_raw_channel_name(channel_name)
1160 : print_channel_name(channel_name),
1161 session_name);
1162 error = 1;
1163 break;
1164 }
1165 goto end;
1166 }
1167
1168 switch (opt_event_type) {
1169 case LTTNG_EVENT_TRACEPOINT:
1170 if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) {
1171 char *exclusion_string = print_exclusions(exclusion_list);
1172
1173 if (!exclusion_string) {
1174 PERROR("Cannot allocate exclusion_string");
1175 error = 1;
1176 goto end;
1177 }
1178 MSG("All %s tracepoints%s are enabled in channel %s for loglevel %s",
1179 get_domain_str(dom.type),
1180 exclusion_string,
1181 print_channel_name(channel_name),
1182 opt_loglevel);
1183 free(exclusion_string);
1184 } else {
1185 char *exclusion_string = print_exclusions(exclusion_list);
1186
1187 if (!exclusion_string) {
1188 PERROR("Cannot allocate exclusion_string");
1189 error = 1;
1190 goto end;
1191 }
1192 MSG("All %s tracepoints%s are enabled in channel %s",
1193 get_domain_str(dom.type),
1194 exclusion_string,
1195 print_channel_name(channel_name));
1196 free(exclusion_string);
1197 }
1198 break;
1199 case LTTNG_EVENT_SYSCALL:
1200 if (opt_kernel) {
1201 MSG("All %s system calls are enabled in channel %s",
1202 get_domain_str(dom.type),
1203 print_channel_name(channel_name));
1204 }
1205 break;
1206 case LTTNG_EVENT_ALL:
1207 if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) {
1208 char *exclusion_string = print_exclusions(exclusion_list);
1209
1210 if (!exclusion_string) {
1211 PERROR("Cannot allocate exclusion_string");
1212 error = 1;
1213 goto end;
1214 }
1215 MSG("All %s events%s are enabled in channel %s for loglevel %s",
1216 get_domain_str(dom.type),
1217 exclusion_string,
1218 print_channel_name(channel_name),
1219 opt_loglevel);
1220 free(exclusion_string);
1221 } else {
1222 char *exclusion_string = print_exclusions(exclusion_list);
1223
1224 if (!exclusion_string) {
1225 PERROR("Cannot allocate exclusion_string");
1226 error = 1;
1227 goto end;
1228 }
1229 MSG("All %s events%s are enabled in channel %s",
1230 get_domain_str(dom.type),
1231 exclusion_string,
1232 print_channel_name(channel_name));
1233 free(exclusion_string);
1234 }
1235 break;
1236 default:
1237 /*
1238 * We should not be here since lttng_enable_event should have
1239 * failed on the event type.
1240 */
1241 goto error;
1242 }
1243 }
1244
1245 if (opt_filter) {
1246 command_ret = lttng_enable_event_with_exclusions(handle, ev, channel_name,
1247 opt_filter,
1248 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
1249 exclusion_list);
1250 if (command_ret < 0) {
1251 switch (-command_ret) {
1252 case LTTNG_ERR_FILTER_EXIST:
1253 WARN("Filter on all events is already enabled"
1254 " (channel %s, session %s)",
1255 print_channel_name(channel_name), session_name);
1256 warn = 1;
1257 break;
1258 case LTTNG_ERR_TRACE_ALREADY_STARTED:
1259 {
1260 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
1261 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
1262 msg,
1263 print_channel_name(channel_name),
1264 session_name, opt_filter);
1265 error = 1;
1266 break;
1267 }
1268 default:
1269 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
1270 lttng_strerror(command_ret),
1271 command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
1272 ? print_raw_channel_name(channel_name)
1273 : print_channel_name(channel_name),
1274 session_name, opt_filter);
1275 error = 1;
1276 break;
1277 }
1278 error_holder = command_ret;
1279 } else {
1280 ev->filter = 1;
1281 MSG("Filter '%s' successfully set", opt_filter);
1282 }
1283 }
1284
1285 if (lttng_opt_mi) {
1286 /* The wildcard * is used for kernel and ust domain to
1287 * represent ALL. We copy * in event name to force the wildcard use
1288 * for kernel domain
1289 *
1290 * Note: this is strictly for semantic and printing while in
1291 * machine interface mode.
1292 */
1293 strcpy(ev->name, "*");
1294
1295 /* If we reach here the events are enabled */
1296 if (!error && !warn) {
1297 ev->enabled = 1;
1298 } else {
1299 ev->enabled = 0;
1300 success = 0;
1301 }
1302 ret = mi_lttng_event(writer, ev, 1, handle->domain.type);
1303 if (ret) {
1304 ret = CMD_ERROR;
1305 goto error;
1306 }
1307
1308 /* print exclusion */
1309 ret = mi_print_exclusion(exclusion_list);
1310 if (ret) {
1311 ret = CMD_ERROR;
1312 goto error;
1313 }
1314
1315 /* Success ? */
1316 ret = mi_lttng_writer_write_element_bool(writer,
1317 mi_lttng_element_command_success, success);
1318 if (ret) {
1319 ret = CMD_ERROR;
1320 goto error;
1321 }
1322
1323 /* Close event element */
1324 ret = mi_lttng_writer_close_element(writer);
1325 if (ret) {
1326 ret = CMD_ERROR;
1327 goto error;
1328 }
1329 }
1330
1331 goto end;
1332 }
1333
1334 /* Strip event list */
1335 event_name = strtok(opt_event_list, ",");
1336 while (event_name != NULL) {
1337 /* Copy name and type of the event */
1338 strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN);
1339 ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
1340 ev->type = opt_event_type;
1341
1342 /* Kernel tracer action */
1343 if (opt_kernel) {
1344 DBG("Enabling kernel event %s for channel %s",
1345 event_name,
1346 print_channel_name(channel_name));
1347
1348 switch (opt_event_type) {
1349 case LTTNG_EVENT_ALL: /* Enable tracepoints and syscalls */
1350 /* If event name differs from *, select tracepoint. */
1351 if (strcmp(ev->name, "*")) {
1352 ev->type = LTTNG_EVENT_TRACEPOINT;
1353 }
1354 break;
1355 case LTTNG_EVENT_TRACEPOINT:
1356 break;
1357 case LTTNG_EVENT_PROBE:
1358 ret = parse_probe_opts(ev, opt_probe);
1359 if (ret) {
1360 ERR("Unable to parse probe options");
1361 ret = CMD_ERROR;
1362 goto error;
1363 }
1364 break;
1365 case LTTNG_EVENT_USERSPACE_PROBE:
1366 ret = parse_userspace_probe_opts(ev, opt_userspace_probe);
1367 if (ret) {
1368 switch (ret) {
1369 case CMD_UNSUPPORTED:
1370 /*
1371 * Error message describing
1372 * what is not supported was
1373 * printed in the function.
1374 */
1375 break;
1376 case CMD_ERROR:
1377 default:
1378 ERR("Unable to parse userspace probe options");
1379 break;
1380 }
1381 goto error;
1382 }
1383 break;
1384 case LTTNG_EVENT_FUNCTION:
1385 ret = parse_probe_opts(ev, opt_function);
1386 if (ret) {
1387 ERR("Unable to parse function probe options");
1388 ret = CMD_ERROR;
1389 goto error;
1390 }
1391 break;
1392 case LTTNG_EVENT_SYSCALL:
1393 ev->type = LTTNG_EVENT_SYSCALL;
1394 break;
1395 default:
1396 ret = CMD_UNDEFINED;
1397 goto error;
1398 }
1399
1400 /* kernel loglevels not implemented */
1401 ev->loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
1402 } else if (opt_userspace) { /* User-space tracer action */
1403 DBG("Enabling UST event %s for channel %s, loglevel %s", event_name,
1404 print_channel_name(channel_name), opt_loglevel ? : "<all>");
1405
1406 switch (opt_event_type) {
1407 case LTTNG_EVENT_ALL: /* Default behavior is tracepoint */
1408 /* Fall-through */
1409 case LTTNG_EVENT_TRACEPOINT:
1410 /* Copy name and type of the event */
1411 ev->type = LTTNG_EVENT_TRACEPOINT;
1412 strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN);
1413 ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
1414 break;
1415 case LTTNG_EVENT_PROBE:
1416 case LTTNG_EVENT_FUNCTION:
1417 case LTTNG_EVENT_SYSCALL:
1418 case LTTNG_EVENT_USERSPACE_PROBE:
1419 default:
1420 ERR("Event type not available for user-space tracing");
1421 ret = CMD_UNSUPPORTED;
1422 goto error;
1423 }
1424
1425 if (opt_exclude) {
1426 ev->exclusion = 1;
1427 if (opt_event_type != LTTNG_EVENT_ALL && opt_event_type != LTTNG_EVENT_TRACEPOINT) {
1428 ERR("Exclusion option can only be used with tracepoint events");
1429 ret = CMD_ERROR;
1430 goto error;
1431 }
1432 /* Free previously allocated items */
1433 strutils_free_null_terminated_array_of_strings(
1434 exclusion_list);
1435 exclusion_list = NULL;
1436 ret = create_exclusion_list_and_validate(
1437 event_name, opt_exclude,
1438 &exclusion_list);
1439 if (ret) {
1440 ret = CMD_ERROR;
1441 goto error;
1442 }
1443
1444 warn_on_truncated_exclusion_names(
1445 exclusion_list, &warn);
1446 }
1447
1448 ev->loglevel_type = opt_loglevel_type;
1449 if (opt_loglevel) {
1450 ev->loglevel = loglevel_str_to_value(opt_loglevel);
1451 if (ev->loglevel == -1) {
1452 ERR("Unknown loglevel %s", opt_loglevel);
1453 ret = -LTTNG_ERR_INVALID;
1454 goto error;
1455 }
1456 } else {
1457 ev->loglevel = -1;
1458 }
1459 } else if (opt_jul || opt_log4j || opt_python) {
1460 if (opt_event_type != LTTNG_EVENT_ALL &&
1461 opt_event_type != LTTNG_EVENT_TRACEPOINT) {
1462 ERR("Event type not supported for domain.");
1463 ret = CMD_UNSUPPORTED;
1464 goto error;
1465 }
1466
1467 ev->loglevel_type = opt_loglevel_type;
1468 if (opt_loglevel) {
1469 if (opt_jul) {
1470 ev->loglevel = loglevel_jul_str_to_value(opt_loglevel);
1471 } else if (opt_log4j) {
1472 ev->loglevel = loglevel_log4j_str_to_value(opt_loglevel);
1473 } else if (opt_python) {
1474 ev->loglevel = loglevel_python_str_to_value(opt_loglevel);
1475 }
1476 if (ev->loglevel == -1) {
1477 ERR("Unknown loglevel %s", opt_loglevel);
1478 ret = -LTTNG_ERR_INVALID;
1479 goto error;
1480 }
1481 } else {
1482 if (opt_jul) {
1483 ev->loglevel = LTTNG_LOGLEVEL_JUL_ALL;
1484 } else if (opt_log4j) {
1485 ev->loglevel = LTTNG_LOGLEVEL_LOG4J_ALL;
1486 } else if (opt_python) {
1487 ev->loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG;
1488 }
1489 }
1490 ev->type = LTTNG_EVENT_TRACEPOINT;
1491 strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN);
1492 ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
1493 } else {
1494 assert(0);
1495 }
1496
1497 if (!opt_filter) {
1498 char *exclusion_string;
1499
1500 command_ret = lttng_enable_event_with_exclusions(handle,
1501 ev, channel_name,
1502 NULL,
1503 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
1504 exclusion_list);
1505 exclusion_string = print_exclusions(exclusion_list);
1506 if (!exclusion_string) {
1507 PERROR("Cannot allocate exclusion_string");
1508 error = 1;
1509 goto end;
1510 }
1511 if (command_ret < 0) {
1512 /* Turn ret to positive value to handle the positive error code */
1513 switch (-command_ret) {
1514 case LTTNG_ERR_KERN_EVENT_EXIST:
1515 WARN("Kernel event %s%s already enabled (channel %s, session %s)",
1516 event_name,
1517 exclusion_string,
1518 print_channel_name(channel_name), session_name);
1519 warn = 1;
1520 break;
1521 case LTTNG_ERR_TRACE_ALREADY_STARTED:
1522 {
1523 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
1524 ERR("Event %s%s: %s (channel %s, session %s)", event_name,
1525 exclusion_string,
1526 msg,
1527 print_channel_name(channel_name),
1528 session_name);
1529 error = 1;
1530 break;
1531 }
1532 case LTTNG_ERR_SDT_PROBE_SEMAPHORE:
1533 ERR("SDT probes %s guarded by semaphores are not supported (channel %s, session %s)",
1534 event_name, print_channel_name(channel_name),
1535 session_name);
1536 error = 1;
1537 break;
1538 default:
1539 ERR("Event %s%s: %s (channel %s, session %s)", event_name,
1540 exclusion_string,
1541 lttng_strerror(command_ret),
1542 command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
1543 ? print_raw_channel_name(channel_name)
1544 : print_channel_name(channel_name),
1545 session_name);
1546 error = 1;
1547 break;
1548 }
1549 error_holder = command_ret;
1550 } else {
1551 switch (dom.type) {
1552 case LTTNG_DOMAIN_KERNEL:
1553 case LTTNG_DOMAIN_UST:
1554 MSG("%s event %s%s created in channel %s",
1555 get_domain_str(dom.type),
1556 event_name,
1557 exclusion_string,
1558 print_channel_name(channel_name));
1559 break;
1560 case LTTNG_DOMAIN_JUL:
1561 case LTTNG_DOMAIN_LOG4J:
1562 case LTTNG_DOMAIN_PYTHON:
1563 /*
1564 * Don't print the default channel
1565 * name for agent domains.
1566 */
1567 MSG("%s event %s%s enabled",
1568 get_domain_str(dom.type),
1569 event_name,
1570 exclusion_string);
1571 break;
1572 default:
1573 assert(0);
1574 }
1575 }
1576 free(exclusion_string);
1577 }
1578
1579 if (opt_filter) {
1580 char *exclusion_string;
1581
1582 /* Filter present */
1583 ev->filter = 1;
1584
1585 command_ret = lttng_enable_event_with_exclusions(handle, ev, channel_name,
1586 opt_filter,
1587 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
1588 exclusion_list);
1589 exclusion_string = print_exclusions(exclusion_list);
1590 if (!exclusion_string) {
1591 PERROR("Cannot allocate exclusion_string");
1592 error = 1;
1593 goto end;
1594 }
1595 if (command_ret < 0) {
1596 switch (-command_ret) {
1597 case LTTNG_ERR_FILTER_EXIST:
1598 WARN("Filter on event %s%s is already enabled"
1599 " (channel %s, session %s)",
1600 event_name,
1601 exclusion_string,
1602 print_channel_name(channel_name), session_name);
1603 warn = 1;
1604 break;
1605 case LTTNG_ERR_TRACE_ALREADY_STARTED:
1606 {
1607 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
1608 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev->name,
1609 exclusion_string,
1610 msg,
1611 print_channel_name(channel_name),
1612 session_name, opt_filter);
1613 error = 1;
1614 break;
1615 }
1616 default:
1617 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev->name,
1618 exclusion_string,
1619 lttng_strerror(command_ret),
1620 command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
1621 ? print_raw_channel_name(channel_name)
1622 : print_channel_name(channel_name),
1623 session_name, opt_filter);
1624 error = 1;
1625 break;
1626 }
1627 error_holder = command_ret;
1628
1629 } else {
1630 MSG("Event %s%s: Filter '%s' successfully set",
1631 event_name, exclusion_string,
1632 opt_filter);
1633 }
1634 free(exclusion_string);
1635 }
1636
1637 if (lttng_opt_mi) {
1638 if (command_ret) {
1639 success = 0;
1640 ev->enabled = 0;
1641 } else {
1642 ev->enabled = 1;
1643 }
1644
1645 ret = mi_lttng_event(writer, ev, 1, handle->domain.type);
1646 if (ret) {
1647 ret = CMD_ERROR;
1648 goto error;
1649 }
1650
1651 /* print exclusion */
1652 ret = mi_print_exclusion(exclusion_list);
1653 if (ret) {
1654 ret = CMD_ERROR;
1655 goto error;
1656 }
1657
1658 /* Success ? */
1659 ret = mi_lttng_writer_write_element_bool(writer,
1660 mi_lttng_element_command_success, success);
1661 if (ret) {
1662 ret = CMD_ERROR;
1663 goto end;
1664 }
1665
1666 /* Close event element */
1667 ret = mi_lttng_writer_close_element(writer);
1668 if (ret) {
1669 ret = CMD_ERROR;
1670 goto end;
1671 }
1672 }
1673
1674 /* Next event */
1675 event_name = strtok(NULL, ",");
1676 /* Reset warn, error and success */
1677 success = 1;
1678 }
1679
1680 end:
1681 /* Close Mi */
1682 if (lttng_opt_mi) {
1683 /* Close events element */
1684 ret = mi_lttng_writer_close_element(writer);
1685 if (ret) {
1686 ret = CMD_ERROR;
1687 goto error;
1688 }
1689 }
1690 error:
1691 if (warn) {
1692 ret = CMD_WARNING;
1693 }
1694 if (error) {
1695 ret = CMD_ERROR;
1696 }
1697 lttng_destroy_handle(handle);
1698 strutils_free_null_terminated_array_of_strings(exclusion_list);
1699
1700 /* Overwrite ret with error_holder if there was an actual error with
1701 * enabling an event.
1702 */
1703 ret = error_holder ? error_holder : ret;
1704
1705 lttng_event_destroy(ev);
1706 return ret;
1707 }
1708
1709 /*
1710 * Add event to trace session
1711 */
1712 int cmd_enable_events(int argc, const char **argv)
1713 {
1714 int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
1715 static poptContext pc;
1716 char *session_name = NULL;
1717 const char *leftover = NULL;
1718 int event_type = -1;
1719
1720 pc = poptGetContext(NULL, argc, argv, long_options, 0);
1721 poptReadDefaultConfig(pc, 0);
1722
1723 /* Default event type */
1724 opt_event_type = LTTNG_EVENT_ALL;
1725
1726 while ((opt = poptGetNextOpt(pc)) != -1) {
1727 switch (opt) {
1728 case OPT_HELP:
1729 SHOW_HELP();
1730 goto end;
1731 case OPT_TRACEPOINT:
1732 opt_event_type = LTTNG_EVENT_TRACEPOINT;
1733 break;
1734 case OPT_PROBE:
1735 opt_event_type = LTTNG_EVENT_PROBE;
1736 break;
1737 case OPT_USERSPACE_PROBE:
1738 opt_event_type = LTTNG_EVENT_USERSPACE_PROBE;
1739 break;
1740 case OPT_FUNCTION:
1741 opt_event_type = LTTNG_EVENT_FUNCTION;
1742 break;
1743 case OPT_SYSCALL:
1744 opt_event_type = LTTNG_EVENT_SYSCALL;
1745 break;
1746 case OPT_USERSPACE:
1747 opt_userspace = 1;
1748 break;
1749 case OPT_LOGLEVEL:
1750 opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_RANGE;
1751 opt_loglevel = poptGetOptArg(pc);
1752 break;
1753 case OPT_LOGLEVEL_ONLY:
1754 opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_SINGLE;
1755 opt_loglevel = poptGetOptArg(pc);
1756 break;
1757 case OPT_LIST_OPTIONS:
1758 list_cmd_options(stdout, long_options);
1759 goto end;
1760 case OPT_FILTER:
1761 break;
1762 case OPT_EXCLUDE:
1763 break;
1764 default:
1765 ret = CMD_UNDEFINED;
1766 goto end;
1767 }
1768
1769 /* Validate event type. Multiple event type are not supported. */
1770 if (event_type == -1) {
1771 event_type = opt_event_type;
1772 } else {
1773 if (event_type != opt_event_type) {
1774 ERR("Multiple event type not supported.");
1775 ret = CMD_ERROR;
1776 goto end;
1777 }
1778 }
1779 }
1780
1781 ret = print_missing_or_multiple_domains(
1782 opt_kernel + opt_userspace + opt_jul + opt_log4j + opt_python);
1783 if (ret) {
1784 ret = CMD_ERROR;
1785 goto end;
1786 }
1787
1788 /* Mi check */
1789 if (lttng_opt_mi) {
1790 writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
1791 if (!writer) {
1792 ret = -LTTNG_ERR_NOMEM;
1793 goto end;
1794 }
1795
1796 /* Open command element */
1797 ret = mi_lttng_writer_command_open(writer,
1798 mi_lttng_element_command_enable_event);
1799 if (ret) {
1800 ret = CMD_ERROR;
1801 goto end;
1802 }
1803
1804 /* Open output element */
1805 ret = mi_lttng_writer_open_element(writer,
1806 mi_lttng_element_command_output);
1807 if (ret) {
1808 ret = CMD_ERROR;
1809 goto end;
1810 }
1811 }
1812
1813 opt_event_list = (char*) poptGetArg(pc);
1814 if (opt_event_list == NULL && opt_enable_all == 0) {
1815 ERR("Missing event name(s).\n");
1816 ret = CMD_ERROR;
1817 goto end;
1818 }
1819
1820 leftover = poptGetArg(pc);
1821 if (leftover) {
1822 ERR("Unknown argument: %s", leftover);
1823 ret = CMD_ERROR;
1824 goto end;
1825 }
1826
1827 if (!opt_session_name) {
1828 session_name = get_session_name();
1829 if (session_name == NULL) {
1830 command_ret = CMD_ERROR;
1831 success = 0;
1832 goto mi_closing;
1833 }
1834 } else {
1835 session_name = opt_session_name;
1836 }
1837
1838 command_ret = enable_events(session_name);
1839 if (command_ret) {
1840 success = 0;
1841 goto mi_closing;
1842 }
1843
1844 mi_closing:
1845 /* Mi closing */
1846 if (lttng_opt_mi) {
1847 /* Close output element */
1848 ret = mi_lttng_writer_close_element(writer);
1849 if (ret) {
1850 ret = CMD_ERROR;
1851 goto end;
1852 }
1853
1854 ret = mi_lttng_writer_write_element_bool(writer,
1855 mi_lttng_element_command_success, success);
1856 if (ret) {
1857 ret = CMD_ERROR;
1858 goto end;
1859 }
1860
1861 /* Command element close */
1862 ret = mi_lttng_writer_command_close(writer);
1863 if (ret) {
1864 ret = CMD_ERROR;
1865 goto end;
1866 }
1867 }
1868
1869 end:
1870 /* Mi clean-up */
1871 if (writer && mi_lttng_writer_destroy(writer)) {
1872 /* Preserve original error code */
1873 ret = ret ? ret : LTTNG_ERR_MI_IO_FAIL;
1874 }
1875
1876 if (opt_session_name == NULL) {
1877 free(session_name);
1878 }
1879
1880 /* Overwrite ret if an error occurred in enable_events */
1881 ret = command_ret ? command_ret : ret;
1882
1883 poptFreeContext(pc);
1884 return ret;
1885 }
1886
This page took 0.121771 seconds and 3 git commands to generate.