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