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