2 * Copyright (C) 2011 EfficiOS Inc.
4 * SPDX-License-Identifier: GPL-2.0-only
9 #include <common/compat/getenv.hpp>
10 #include <common/compat/string.hpp>
11 #include <common/sessiond-comm/sessiond-comm.hpp>
12 #include <common/string-utils/string-utils.hpp>
13 #include <common/utils.hpp>
21 #include <sys/types.h>
25 #include "../command.hpp"
26 #include "../loglevel.hpp"
27 #include "../uprobe.hpp"
29 #include <common/mi-lttng.hpp>
31 #include <lttng/domain-internal.hpp>
32 #include <lttng/event-internal.hpp>
34 #if (LTTNG_SYMBOL_NAME_LEN == 256)
35 #define LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "255"
38 static int opt_event_type
;
39 static const char *opt_loglevel
;
40 static int opt_loglevel_type
;
41 static int opt_kernel
;
42 static char *opt_session_name
;
43 static int opt_userspace
;
46 static int opt_python
;
47 static int opt_enable_all
;
48 static char *opt_probe
;
49 static char *opt_userspace_probe
;
50 static char *opt_function
;
51 static char *opt_channel_name
;
52 static char *opt_filter
;
53 static char *opt_exclude
;
55 #ifdef LTTNG_EMBED_HELP
56 static const char help_msg
[] =
57 #include <lttng-enable-event.1.h>
76 static struct lttng_handle
*handle
;
77 static struct mi_writer
*writer
;
79 static struct poptOption long_options
[] = {
80 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
81 { "help", 'h', POPT_ARG_NONE
, nullptr, OPT_HELP
, nullptr, nullptr },
82 { "session", 's', POPT_ARG_STRING
, &opt_session_name
, 0, nullptr, nullptr },
83 { "all", 'a', POPT_ARG_VAL
, &opt_enable_all
, 1, nullptr, nullptr },
84 { "channel", 'c', POPT_ARG_STRING
, &opt_channel_name
, 0, nullptr, nullptr },
85 { "kernel", 'k', POPT_ARG_VAL
, &opt_kernel
, 1, nullptr, nullptr },
86 { "userspace", 'u', POPT_ARG_NONE
, nullptr, OPT_USERSPACE
, nullptr, nullptr },
87 { "jul", 'j', POPT_ARG_VAL
, &opt_jul
, 1, nullptr, nullptr },
88 { "log4j", 'l', POPT_ARG_VAL
, &opt_log4j
, 1, nullptr, nullptr },
89 { "python", 'p', POPT_ARG_VAL
, &opt_python
, 1, nullptr, nullptr },
90 { "tracepoint", 0, POPT_ARG_NONE
, nullptr, OPT_TRACEPOINT
, nullptr, nullptr },
91 { "probe", 0, POPT_ARG_STRING
, &opt_probe
, OPT_PROBE
, nullptr, nullptr },
99 { "function", 0, POPT_ARG_STRING
, &opt_function
, OPT_FUNCTION
, nullptr, nullptr },
100 { "syscall", 0, POPT_ARG_NONE
, nullptr, OPT_SYSCALL
, nullptr, nullptr },
101 { "loglevel", 0, POPT_ARG_STRING
, nullptr, OPT_LOGLEVEL
, nullptr, nullptr },
102 { "loglevel-only", 0, POPT_ARG_STRING
, nullptr, OPT_LOGLEVEL_ONLY
, nullptr, nullptr },
103 { "list-options", 0, POPT_ARG_NONE
, nullptr, OPT_LIST_OPTIONS
, nullptr, nullptr },
104 { "filter", 'f', POPT_ARG_STRING
, &opt_filter
, OPT_FILTER
, nullptr, nullptr },
105 { "exclude", 'x', POPT_ARG_STRING
, &opt_exclude
, OPT_EXCLUDE
, nullptr, nullptr },
106 { nullptr, 0, 0, nullptr, 0, nullptr, nullptr }
110 * Parse probe options.
112 static int parse_probe_opts(struct lttng_event
*ev
, char *opt
)
114 int ret
= CMD_SUCCESS
;
117 #define S_HEX_LEN_SCANF_IS_A_BROKEN_API "18" /* 18 is (19 - 1) (\0 is extra) */
118 char name
[LTTNG_SYMBOL_NAME_LEN
];
120 if (opt
== nullptr) {
125 /* Check for symbol+offset */
127 "%" LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API
128 "[^'+']+%" S_HEX_LEN_SCANF_IS_A_BROKEN_API
"s",
132 strncpy(ev
->attr
.probe
.symbol_name
, name
, LTTNG_SYMBOL_NAME_LEN
);
133 ev
->attr
.probe
.symbol_name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
134 DBG("probe symbol %s", ev
->attr
.probe
.symbol_name
);
135 if (*s_hex
== '\0') {
136 ERR("Invalid probe offset %s", s_hex
);
140 ev
->attr
.probe
.offset
= strtoull(s_hex
, nullptr, 0);
141 DBG("probe offset %" PRIu64
, ev
->attr
.probe
.offset
);
142 ev
->attr
.probe
.addr
= 0;
146 /* Check for symbol */
147 if (isalpha(name
[0]) || name
[0] == '_') {
148 match
= sscanf(opt
, "%" LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API
"s", name
);
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;
160 /* Check for address */
161 match
= sscanf(opt
, "%" S_HEX_LEN_SCANF_IS_A_BROKEN_API
"s", s_hex
);
164 * Return an error if the first character of the tentative
165 * address is NULL or not a digit. It can be "0" if the address
166 * is in hexadecimal and can be 1 to 9 if it's in decimal.
168 if (*s_hex
== '\0' || !isdigit(*s_hex
)) {
169 ERR("Invalid probe description %s", s_hex
);
173 ev
->attr
.probe
.addr
= strtoull(s_hex
, nullptr, 0);
174 DBG("probe addr %" PRIu64
, ev
->attr
.probe
.addr
);
175 ev
->attr
.probe
.offset
= 0;
176 memset(ev
->attr
.probe
.symbol_name
, 0, LTTNG_SYMBOL_NAME_LEN
);
187 static const char *print_channel_name(const char *name
)
189 return name
?: DEFAULT_CHANNEL_NAME
;
192 static const char *print_raw_channel_name(const char *name
)
194 return name
?: "<default>";
198 * Mi print exlcusion list
200 static int mi_print_exclusion(const struct lttng_dynamic_pointer_array
*exclusions
)
204 const size_t count
= lttng_dynamic_pointer_array_get_count(exclusions
);
206 LTTNG_ASSERT(writer
);
213 ret
= mi_lttng_writer_open_element(writer
, config_element_exclusions
);
218 for (i
= 0; i
< count
; i
++) {
219 const char *exclusion
=
220 (const char *) lttng_dynamic_pointer_array_get_pointer(exclusions
, i
);
222 ret
= mi_lttng_writer_write_element_string(
223 writer
, config_element_exclusion
, exclusion
);
229 /* Close exclusions element */
230 ret
= mi_lttng_writer_close_element(writer
);
237 * Return allocated string for pretty-printing exclusion names.
239 static char *print_exclusions(const struct lttng_dynamic_pointer_array
*exclusions
)
243 const char preamble
[] = " excluding ";
245 const size_t count
= lttng_dynamic_pointer_array_get_count(exclusions
);
251 /* Calculate total required length. */
252 for (i
= 0; i
< count
; i
++) {
253 const char *exclusion
=
254 (const char *) lttng_dynamic_pointer_array_get_pointer(exclusions
, i
);
256 length
+= strlen(exclusion
) + 4;
259 length
+= sizeof(preamble
);
260 ret
= calloc
<char>(length
);
265 strncpy(ret
, preamble
, length
);
266 for (i
= 0; i
< count
; i
++) {
267 const char *exclusion
=
268 (const char *) lttng_dynamic_pointer_array_get_pointer(exclusions
, i
);
271 strcat(ret
, exclusion
);
273 if (i
!= count
- 1) {
281 static int check_exclusion_subsets(const char *event_name
, const char *exclusion
)
285 const char *e
= event_name
;
286 const char *x
= exclusion
;
288 /* Scan both the excluder and the event letter by letter */
302 /* Event is a subset of the excluder */
303 ERR("Event %s: %s excludes all events from %s",
312 * Reached the end of the event name before the
313 * end of the exclusion: this is valid.
335 WARN("Event %s: %s does not exclude any events from %s",
344 int validate_exclusion_list(const char *event_name
,
345 const struct lttng_dynamic_pointer_array
*exclusions
)
349 /* Event name must be a valid globbing pattern to allow exclusions. */
350 if (!strutils_is_star_glob_pattern(event_name
)) {
351 ERR("Event %s: Exclusions can only be used with a globbing pattern", event_name
);
356 * If the event name is a star-at-end only globbing pattern,
357 * then we can validate the individual exclusions. Otherwise
358 * all exclusions are passed to the session daemon.
360 if (strutils_is_star_at_the_end_only_glob_pattern(event_name
)) {
361 size_t i
, num_exclusions
;
363 num_exclusions
= lttng_dynamic_pointer_array_get_count(exclusions
);
365 for (i
= 0; i
< num_exclusions
; i
++) {
366 const char *exclusion
=
367 (const char *) lttng_dynamic_pointer_array_get_pointer(exclusions
,
370 if (!strutils_is_star_glob_pattern(exclusion
) ||
371 strutils_is_star_at_the_end_only_glob_pattern(exclusion
)) {
372 ret
= check_exclusion_subsets(event_name
, exclusion
);
390 static int create_exclusion_list_and_validate(const char *event_name
,
391 const char *exclusions_arg
,
392 struct lttng_dynamic_pointer_array
*exclusions
)
396 /* Split exclusions. */
397 ret
= strutils_split(exclusions_arg
, ',', true, exclusions
);
402 if (validate_exclusion_list(event_name
, exclusions
) != 0) {
410 lttng_dynamic_pointer_array_reset(exclusions
);
416 static void warn_on_truncated_exclusion_names(const struct lttng_dynamic_pointer_array
*exclusions
,
420 const size_t num_exclusions
= lttng_dynamic_pointer_array_get_count(exclusions
);
422 for (i
= 0; i
< num_exclusions
; i
++) {
423 const char *const exclusion
=
424 (const char *) lttng_dynamic_pointer_array_get_pointer(exclusions
, i
);
426 if (strlen(exclusion
) >= LTTNG_SYMBOL_NAME_LEN
) {
427 WARN("Event exclusion \"%s\" will be truncated", exclusion
);
434 * Enabling event using the lttng API.
435 * Note: in case of error only the last error code will be return.
437 static int enable_events(char *session_name
, char *event_list
)
439 int ret
= CMD_SUCCESS
, command_ret
= CMD_SUCCESS
;
440 int error_holder
= CMD_SUCCESS
, warn
= 0, error
= 0, success
= 1;
441 char *event_name
, *channel_name
= nullptr;
442 struct lttng_event
*ev
;
443 struct lttng_domain dom
= {};
444 struct lttng_dynamic_pointer_array exclusions
;
445 struct lttng_userspace_probe_location
*uprobe_loc
= nullptr;
447 lttng_dynamic_pointer_array_init(&exclusions
, nullptr);
449 ev
= lttng_event_create();
457 WARN("Kernel loglevels are not supported.");
461 /* Create lttng domain */
463 dom
.type
= LTTNG_DOMAIN_KERNEL
;
464 dom
.buf_type
= LTTNG_BUFFER_GLOBAL
;
465 } else if (opt_userspace
) {
466 dom
.type
= LTTNG_DOMAIN_UST
;
468 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
469 } else if (opt_jul
) {
470 dom
.type
= LTTNG_DOMAIN_JUL
;
472 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
473 } else if (opt_log4j
) {
474 dom
.type
= LTTNG_DOMAIN_LOG4J
;
476 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
477 } else if (opt_python
) {
478 dom
.type
= LTTNG_DOMAIN_PYTHON
;
480 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
482 /* Checked by the caller. */
488 case LTTNG_DOMAIN_KERNEL
:
489 case LTTNG_DOMAIN_JUL
:
490 case LTTNG_DOMAIN_LOG4J
:
491 case LTTNG_DOMAIN_PYTHON
:
492 ERR("Event name exclusions are not yet implemented for %s events",
493 lttng_domain_type_str(dom
.type
));
496 case LTTNG_DOMAIN_UST
:
497 /* Exclusions supported */
505 * Adding a filter to a probe, function or userspace-probe would be
506 * denied by the kernel tracer as it's not supported at the moment. We
507 * do an early check here to warn the user.
509 if (opt_filter
&& opt_kernel
) {
510 switch (opt_event_type
) {
511 case LTTNG_EVENT_ALL
:
512 case LTTNG_EVENT_TRACEPOINT
:
513 case LTTNG_EVENT_SYSCALL
:
515 case LTTNG_EVENT_PROBE
:
516 case LTTNG_EVENT_USERSPACE_PROBE
:
517 case LTTNG_EVENT_FUNCTION
:
518 ERR("Filter expressions are not supported for %s events",
519 get_event_type_str((lttng_event_type
) opt_event_type
));
528 channel_name
= opt_channel_name
;
530 handle
= lttng_create_handle(session_name
, &dom
);
531 if (handle
== nullptr) {
538 /* Open a events element */
539 ret
= mi_lttng_writer_open_element(writer
, config_element_events
);
546 if (opt_enable_all
) {
547 /* Default setup for enable all */
549 ev
->type
= (lttng_event_type
) opt_event_type
;
550 strcpy(ev
->name
, "*");
551 /* kernel loglevels not implemented */
552 ev
->loglevel_type
= LTTNG_EVENT_LOGLEVEL_ALL
;
554 ev
->type
= LTTNG_EVENT_TRACEPOINT
;
555 strcpy(ev
->name
, "*");
556 ev
->loglevel_type
= (lttng_loglevel_type
) opt_loglevel_type
;
560 LTTNG_ASSERT(opt_userspace
|| opt_jul
|| opt_log4j
|| opt_python
);
563 enum lttng_loglevel loglevel
;
566 loglevel_name_to_value(opt_loglevel
, &loglevel
);
567 ev
->loglevel
= (int) loglevel
;
568 } else if (opt_jul
) {
569 enum lttng_loglevel_jul loglevel
;
572 loglevel_jul_name_to_value(opt_loglevel
, &loglevel
);
573 ev
->loglevel
= (int) loglevel
;
574 } else if (opt_log4j
) {
575 enum lttng_loglevel_log4j loglevel
;
577 name_search_ret
= loglevel_log4j_name_to_value(opt_loglevel
,
579 ev
->loglevel
= (int) loglevel
;
582 enum lttng_loglevel_python loglevel
;
584 name_search_ret
= loglevel_python_name_to_value(
585 opt_loglevel
, &loglevel
);
586 ev
->loglevel
= (int) loglevel
;
589 if (name_search_ret
== -1) {
590 ERR("Unknown loglevel %s", opt_loglevel
);
591 ret
= -LTTNG_ERR_INVALID
;
595 LTTNG_ASSERT(opt_userspace
|| opt_jul
|| opt_log4j
|| opt_python
);
598 } else if (opt_jul
) {
599 ev
->loglevel
= LTTNG_LOGLEVEL_JUL_ALL
;
600 } else if (opt_log4j
) {
601 ev
->loglevel
= LTTNG_LOGLEVEL_LOG4J_ALL
;
602 } else if (opt_python
) {
603 ev
->loglevel
= LTTNG_LOGLEVEL_PYTHON_DEBUG
;
609 ret
= create_exclusion_list_and_validate("*", opt_exclude
, &exclusions
);
616 warn_on_truncated_exclusion_names(&exclusions
, &warn
);
619 ret
= lttng_enable_event_with_exclusions(
624 lttng_dynamic_pointer_array_get_count(&exclusions
),
625 (char **) exclusions
.array
.buffer
.data
);
628 case LTTNG_ERR_KERN_EVENT_EXIST
:
629 WARN("Kernel events already enabled (channel %s, session %s)",
630 print_channel_name(channel_name
),
634 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
637 "The command tried to enable an event in a new domain for a session that has already been started once.";
638 ERR("Events: %s (channel %s, session %s)",
640 print_channel_name(channel_name
),
646 ERR("Events: %s (channel %s, session %s)",
648 ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
?
649 print_raw_channel_name(channel_name
) :
650 print_channel_name(channel_name
),
658 switch (opt_event_type
) {
659 case LTTNG_EVENT_TRACEPOINT
:
660 if (opt_loglevel
&& dom
.type
!= LTTNG_DOMAIN_KERNEL
) {
661 char *exclusion_string
= print_exclusions(&exclusions
);
663 if (!exclusion_string
) {
664 PERROR("Cannot allocate exclusion_string");
668 MSG("All %s tracepoints%s are enabled in channel %s for loglevel %s",
669 lttng_domain_type_str(dom
.type
),
671 print_channel_name(channel_name
),
673 free(exclusion_string
);
675 char *exclusion_string
= print_exclusions(&exclusions
);
677 if (!exclusion_string
) {
678 PERROR("Cannot allocate exclusion_string");
682 MSG("All %s tracepoints%s are enabled in channel %s",
683 lttng_domain_type_str(dom
.type
),
685 print_channel_name(channel_name
));
686 free(exclusion_string
);
689 case LTTNG_EVENT_SYSCALL
:
691 MSG("All %s system calls are enabled in channel %s",
692 lttng_domain_type_str(dom
.type
),
693 print_channel_name(channel_name
));
696 case LTTNG_EVENT_ALL
:
697 if (opt_loglevel
&& dom
.type
!= LTTNG_DOMAIN_KERNEL
) {
698 char *exclusion_string
= print_exclusions(&exclusions
);
700 if (!exclusion_string
) {
701 PERROR("Cannot allocate exclusion_string");
705 MSG("All %s events%s are enabled in channel %s for loglevel %s",
706 lttng_domain_type_str(dom
.type
),
708 print_channel_name(channel_name
),
710 free(exclusion_string
);
712 char *exclusion_string
= print_exclusions(&exclusions
);
714 if (!exclusion_string
) {
715 PERROR("Cannot allocate exclusion_string");
719 MSG("All %s events%s are enabled in channel %s",
720 lttng_domain_type_str(dom
.type
),
722 print_channel_name(channel_name
));
723 free(exclusion_string
);
728 * We should not be here since lttng_enable_event should have
729 * failed on the event type.
736 command_ret
= lttng_enable_event_with_exclusions(
741 lttng_dynamic_pointer_array_get_count(&exclusions
),
742 (char **) exclusions
.array
.buffer
.data
);
743 if (command_ret
< 0) {
744 switch (-command_ret
) {
745 case LTTNG_ERR_FILTER_EXIST
:
746 WARN("Filter on all events is already enabled"
747 " (channel %s, session %s)",
748 print_channel_name(channel_name
),
752 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
755 "The command tried to enable an event in a new domain for a session that has already been started once.";
756 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
758 print_channel_name(channel_name
),
765 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
766 lttng_strerror(command_ret
),
767 command_ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
?
768 print_raw_channel_name(channel_name
) :
769 print_channel_name(channel_name
),
775 error_holder
= command_ret
;
778 MSG("Filter '%s' successfully set", opt_filter
);
783 /* The wildcard * is used for kernel and ust domain to
784 * represent ALL. We copy * in event name to force the wildcard use
787 * Note: this is strictly for semantic and printing while in
788 * machine interface mode.
790 strcpy(ev
->name
, "*");
792 /* If we reach here the events are enabled */
793 if (!error
&& !warn
) {
799 ret
= mi_lttng_event(writer
, ev
, 1, handle
->domain
.type
);
805 /* print exclusion */
806 ret
= mi_print_exclusion(&exclusions
);
813 ret
= mi_lttng_writer_write_element_bool(
814 writer
, mi_lttng_element_command_success
, success
);
820 /* Close event element */
821 ret
= mi_lttng_writer_close_element(writer
);
831 /* Strip event list */
832 event_name
= strtok(event_list
, ",");
833 while (event_name
!= nullptr) {
834 /* Copy name and type of the event */
835 strncpy(ev
->name
, event_name
, LTTNG_SYMBOL_NAME_LEN
);
836 ev
->name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
837 ev
->type
= (lttng_event_type
) opt_event_type
;
839 /* Kernel tracer action */
841 DBG("Enabling kernel event %s for channel %s",
843 print_channel_name(channel_name
));
845 switch (opt_event_type
) {
846 case LTTNG_EVENT_ALL
: /* Enable tracepoints and syscalls */
847 /* If event name differs from *, select tracepoint. */
848 if (strcmp(ev
->name
, "*") != 0) {
849 ev
->type
= LTTNG_EVENT_TRACEPOINT
;
852 case LTTNG_EVENT_TRACEPOINT
:
854 case LTTNG_EVENT_PROBE
:
855 ret
= parse_probe_opts(ev
, opt_probe
);
857 ERR("Unable to parse probe options");
862 case LTTNG_EVENT_USERSPACE_PROBE
:
863 LTTNG_ASSERT(ev
->type
== LTTNG_EVENT_USERSPACE_PROBE
);
865 ret
= parse_userspace_probe_opts(opt_userspace_probe
, &uprobe_loc
);
868 case CMD_UNSUPPORTED
:
870 * Error message describing
871 * what is not supported was
872 * printed in the function.
877 ERR("Unable to parse userspace probe options");
883 ret
= lttng_event_set_userspace_probe_location(ev
, uprobe_loc
);
885 WARN("Failed to set probe location on event");
890 /* Ownership of the uprobe location was transferred to the event. */
891 uprobe_loc
= nullptr;
893 case LTTNG_EVENT_FUNCTION
:
894 ret
= parse_probe_opts(ev
, opt_function
);
896 ERR("Unable to parse function probe options");
901 case LTTNG_EVENT_SYSCALL
:
902 ev
->type
= LTTNG_EVENT_SYSCALL
;
909 /* kernel loglevels not implemented */
910 ev
->loglevel_type
= LTTNG_EVENT_LOGLEVEL_ALL
;
911 } else if (opt_userspace
) { /* User-space tracer action */
912 DBG("Enabling UST event %s for channel %s, loglevel %s",
914 print_channel_name(channel_name
),
915 opt_loglevel
?: "<all>");
917 switch (opt_event_type
) {
918 case LTTNG_EVENT_ALL
: /* Default behavior is tracepoint */
920 case LTTNG_EVENT_TRACEPOINT
:
921 /* Copy name and type of the event */
922 ev
->type
= LTTNG_EVENT_TRACEPOINT
;
923 strncpy(ev
->name
, event_name
, LTTNG_SYMBOL_NAME_LEN
);
924 ev
->name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
926 case LTTNG_EVENT_PROBE
:
927 case LTTNG_EVENT_FUNCTION
:
928 case LTTNG_EVENT_SYSCALL
:
929 case LTTNG_EVENT_USERSPACE_PROBE
:
931 ERR("Event type not available for user-space tracing");
932 ret
= CMD_UNSUPPORTED
;
938 if (opt_event_type
!= LTTNG_EVENT_ALL
&&
939 opt_event_type
!= LTTNG_EVENT_TRACEPOINT
) {
940 ERR("Exclusion option can only be used with tracepoint events");
944 /* Free previously allocated items. */
945 lttng_dynamic_pointer_array_reset(&exclusions
);
946 ret
= create_exclusion_list_and_validate(
947 event_name
, opt_exclude
, &exclusions
);
953 warn_on_truncated_exclusion_names(&exclusions
, &warn
);
956 ev
->loglevel_type
= (lttng_loglevel_type
) opt_loglevel_type
;
958 enum lttng_loglevel loglevel
;
959 const int name_search_ret
=
960 loglevel_name_to_value(opt_loglevel
, &loglevel
);
962 if (name_search_ret
== -1) {
963 ERR("Unknown loglevel %s", opt_loglevel
);
964 ret
= -LTTNG_ERR_INVALID
;
968 ev
->loglevel
= (int) loglevel
;
972 } else if (opt_jul
|| opt_log4j
|| opt_python
) {
973 if (opt_event_type
!= LTTNG_EVENT_ALL
&&
974 opt_event_type
!= LTTNG_EVENT_TRACEPOINT
) {
975 ERR("Event type not supported for domain.");
976 ret
= CMD_UNSUPPORTED
;
980 ev
->loglevel_type
= (lttng_loglevel_type
) opt_loglevel_type
;
985 enum lttng_loglevel_jul loglevel
;
988 loglevel_jul_name_to_value(opt_loglevel
, &loglevel
);
989 ev
->loglevel
= (int) loglevel
;
990 } else if (opt_log4j
) {
991 enum lttng_loglevel_log4j loglevel
;
993 name_search_ret
= loglevel_log4j_name_to_value(opt_loglevel
,
995 ev
->loglevel
= (int) loglevel
;
998 enum lttng_loglevel_python loglevel
;
1000 name_search_ret
= loglevel_python_name_to_value(
1001 opt_loglevel
, &loglevel
);
1002 ev
->loglevel
= (int) loglevel
;
1005 if (name_search_ret
) {
1006 ERR("Unknown loglevel %s", opt_loglevel
);
1007 ret
= -LTTNG_ERR_INVALID
;
1012 ev
->loglevel
= LTTNG_LOGLEVEL_JUL_ALL
;
1013 } else if (opt_log4j
) {
1014 ev
->loglevel
= LTTNG_LOGLEVEL_LOG4J_ALL
;
1015 } else if (opt_python
) {
1016 ev
->loglevel
= LTTNG_LOGLEVEL_PYTHON_DEBUG
;
1019 ev
->type
= LTTNG_EVENT_TRACEPOINT
;
1020 strncpy(ev
->name
, event_name
, LTTNG_SYMBOL_NAME_LEN
);
1021 ev
->name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
1027 char *exclusion_string
;
1029 command_ret
= lttng_enable_event_with_exclusions(
1034 lttng_dynamic_pointer_array_get_count(&exclusions
),
1035 (char **) exclusions
.array
.buffer
.data
);
1036 exclusion_string
= print_exclusions(&exclusions
);
1037 if (!exclusion_string
) {
1038 PERROR("Cannot allocate exclusion_string");
1042 if (command_ret
< 0) {
1043 /* Turn ret to positive value to handle the positive error code */
1044 switch (-command_ret
) {
1045 case LTTNG_ERR_KERN_EVENT_EXIST
:
1046 WARN("Kernel event %s%s already enabled (channel %s, session %s)",
1049 print_channel_name(channel_name
),
1053 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
1056 "The command tried to enable an event in a new domain for a session that has already been started once.";
1057 ERR("Event %s%s: %s (channel %s, session %s)",
1061 print_channel_name(channel_name
),
1066 case LTTNG_ERR_SDT_PROBE_SEMAPHORE
:
1067 ERR("SDT probes %s guarded by semaphores are not supported (channel %s, session %s)",
1069 print_channel_name(channel_name
),
1074 ERR("Event %s%s: %s (channel %s, session %s)",
1077 lttng_strerror(command_ret
),
1078 command_ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
?
1079 print_raw_channel_name(channel_name
) :
1080 print_channel_name(channel_name
),
1085 error_holder
= command_ret
;
1088 case LTTNG_DOMAIN_KERNEL
:
1089 case LTTNG_DOMAIN_UST
:
1090 MSG("%s event %s%s created in channel %s",
1091 lttng_domain_type_str(dom
.type
),
1094 print_channel_name(channel_name
));
1096 case LTTNG_DOMAIN_JUL
:
1097 case LTTNG_DOMAIN_LOG4J
:
1098 case LTTNG_DOMAIN_PYTHON
:
1100 * Don't print the default channel
1101 * name for agent domains.
1103 MSG("%s event %s%s enabled",
1104 lttng_domain_type_str(dom
.type
),
1112 free(exclusion_string
);
1116 char *exclusion_string
;
1118 /* Filter present */
1121 command_ret
= lttng_enable_event_with_exclusions(
1126 lttng_dynamic_pointer_array_get_count(&exclusions
),
1127 (char **) exclusions
.array
.buffer
.data
);
1128 exclusion_string
= print_exclusions(&exclusions
);
1129 if (!exclusion_string
) {
1130 PERROR("Cannot allocate exclusion_string");
1134 if (command_ret
< 0) {
1135 switch (-command_ret
) {
1136 case LTTNG_ERR_FILTER_EXIST
:
1137 WARN("Filter on event %s%s is already enabled"
1138 " (channel %s, session %s)",
1141 print_channel_name(channel_name
),
1145 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
1148 "The command tried to enable an event in a new domain for a session that has already been started once.";
1149 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')",
1153 print_channel_name(channel_name
),
1160 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')",
1163 lttng_strerror(command_ret
),
1164 command_ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
?
1165 print_raw_channel_name(channel_name
) :
1166 print_channel_name(channel_name
),
1172 error_holder
= command_ret
;
1175 MSG("Event %s%s: Filter '%s' successfully set",
1180 free(exclusion_string
);
1191 ret
= mi_lttng_event(writer
, ev
, 1, handle
->domain
.type
);
1197 /* print exclusion */
1198 ret
= mi_print_exclusion(&exclusions
);
1205 ret
= mi_lttng_writer_write_element_bool(
1206 writer
, mi_lttng_element_command_success
, success
);
1212 /* Close event element */
1213 ret
= mi_lttng_writer_close_element(writer
);
1221 event_name
= strtok(nullptr, ",");
1222 /* Reset warn, error and success */
1229 /* Close events element */
1230 ret
= mi_lttng_writer_close_element(writer
);
1243 lttng_destroy_handle(handle
);
1244 lttng_dynamic_pointer_array_reset(&exclusions
);
1245 lttng_userspace_probe_location_destroy(uprobe_loc
);
1247 /* Overwrite ret with error_holder if there was an actual error with
1248 * enabling an event.
1250 ret
= error_holder
? error_holder
: ret
;
1252 lttng_event_destroy(ev
);
1257 * Add event to trace session
1259 int cmd_enable_events(int argc
, const char **argv
)
1261 int opt
, ret
= CMD_SUCCESS
, command_ret
= CMD_SUCCESS
, success
= 1;
1262 static poptContext pc
;
1263 char *session_name
= nullptr;
1264 char *event_list
= nullptr;
1265 const char *arg_event_list
= nullptr;
1266 const char *leftover
= nullptr;
1267 int event_type
= -1;
1269 pc
= poptGetContext(nullptr, argc
, argv
, long_options
, 0);
1270 poptReadDefaultConfig(pc
, 0);
1272 /* Default event type */
1273 opt_event_type
= LTTNG_EVENT_ALL
;
1275 while ((opt
= poptGetNextOpt(pc
)) != -1) {
1280 case OPT_TRACEPOINT
:
1281 opt_event_type
= LTTNG_EVENT_TRACEPOINT
;
1284 opt_event_type
= LTTNG_EVENT_PROBE
;
1286 case OPT_USERSPACE_PROBE
:
1287 opt_event_type
= LTTNG_EVENT_USERSPACE_PROBE
;
1290 opt_event_type
= LTTNG_EVENT_FUNCTION
;
1293 opt_event_type
= LTTNG_EVENT_SYSCALL
;
1299 opt_loglevel_type
= LTTNG_EVENT_LOGLEVEL_RANGE
;
1300 opt_loglevel
= poptGetOptArg(pc
);
1302 case OPT_LOGLEVEL_ONLY
:
1303 opt_loglevel_type
= LTTNG_EVENT_LOGLEVEL_SINGLE
;
1304 opt_loglevel
= poptGetOptArg(pc
);
1306 case OPT_LIST_OPTIONS
:
1307 list_cmd_options(stdout
, long_options
);
1314 ret
= CMD_UNDEFINED
;
1318 /* Validate event type. Multiple event type are not supported. */
1319 if (event_type
== -1) {
1320 event_type
= opt_event_type
;
1322 if (event_type
!= opt_event_type
) {
1323 ERR("Multiple event type not supported.");
1330 ret
= print_missing_or_multiple_domains(
1331 opt_kernel
+ opt_userspace
+ opt_jul
+ opt_log4j
+ opt_python
, true);
1339 writer
= mi_lttng_writer_create(fileno(stdout
), lttng_opt_mi
);
1341 ret
= -LTTNG_ERR_NOMEM
;
1345 /* Open command element */
1346 ret
= mi_lttng_writer_command_open(writer
, mi_lttng_element_command_enable_event
);
1352 /* Open output element */
1353 ret
= mi_lttng_writer_open_element(writer
, mi_lttng_element_command_output
);
1360 arg_event_list
= poptGetArg(pc
);
1361 if (arg_event_list
== nullptr && opt_enable_all
== 0) {
1362 ERR("Missing event name(s).");
1367 if (opt_enable_all
== 0) {
1368 event_list
= strdup(arg_event_list
);
1369 if (event_list
== nullptr) {
1370 PERROR("Failed to copy event name(s)");
1376 leftover
= poptGetArg(pc
);
1378 ERR("Unknown argument: %s", leftover
);
1383 if (!opt_session_name
) {
1384 session_name
= get_session_name();
1385 if (session_name
== nullptr) {
1386 command_ret
= CMD_ERROR
;
1391 session_name
= opt_session_name
;
1394 command_ret
= enable_events(session_name
, event_list
);
1403 /* Close output element */
1404 ret
= mi_lttng_writer_close_element(writer
);
1410 ret
= mi_lttng_writer_write_element_bool(
1411 writer
, mi_lttng_element_command_success
, success
);
1417 /* Command element close */
1418 ret
= mi_lttng_writer_command_close(writer
);
1427 if (writer
&& mi_lttng_writer_destroy(writer
)) {
1428 /* Preserve original error code */
1429 ret
= ret
? ret
: LTTNG_ERR_MI_IO_FAIL
;
1432 if (opt_session_name
== nullptr) {
1438 /* Overwrite ret if an error occurred in enable_events */
1439 ret
= command_ret
? command_ret
: ret
;
1441 poptFreeContext(pc
);