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"
41 const char *opt_loglevel
;
42 int opt_loglevel_type
;
44 char *opt_session_name
;
51 char *opt_userspace_probe
;
53 char *opt_channel_name
;
57 #ifdef LTTNG_EMBED_HELP
58 static const char help_msg
[] =
59 #include <lttng-enable-event.1.h>
78 struct lttng_handle
*handle
;
79 struct mi_writer
*writer
;
81 struct poptOption long_options
[] = {
82 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
83 { "help", 'h', POPT_ARG_NONE
, nullptr, OPT_HELP
, nullptr, nullptr },
84 { "session", 's', POPT_ARG_STRING
, &opt_session_name
, 0, nullptr, nullptr },
85 { "all", 'a', POPT_ARG_VAL
, &opt_enable_all
, 1, nullptr, nullptr },
86 { "channel", 'c', POPT_ARG_STRING
, &opt_channel_name
, 0, nullptr, nullptr },
87 { "kernel", 'k', POPT_ARG_VAL
, &opt_kernel
, 1, nullptr, nullptr },
88 { "userspace", 'u', POPT_ARG_NONE
, nullptr, OPT_USERSPACE
, nullptr, nullptr },
89 { "jul", 'j', POPT_ARG_VAL
, &opt_jul
, 1, nullptr, nullptr },
90 { "log4j", 'l', POPT_ARG_VAL
, &opt_log4j
, 1, nullptr, nullptr },
91 { "python", 'p', POPT_ARG_VAL
, &opt_python
, 1, nullptr, nullptr },
92 { "tracepoint", 0, POPT_ARG_NONE
, nullptr, OPT_TRACEPOINT
, nullptr, nullptr },
93 { "probe", 0, POPT_ARG_STRING
, &opt_probe
, OPT_PROBE
, nullptr, nullptr },
101 { "function", 0, POPT_ARG_STRING
, &opt_function
, OPT_FUNCTION
, nullptr, nullptr },
102 { "syscall", 0, POPT_ARG_NONE
, nullptr, OPT_SYSCALL
, nullptr, nullptr },
103 { "loglevel", 0, POPT_ARG_STRING
, nullptr, OPT_LOGLEVEL
, nullptr, nullptr },
104 { "loglevel-only", 0, POPT_ARG_STRING
, nullptr, OPT_LOGLEVEL_ONLY
, nullptr, nullptr },
105 { "list-options", 0, POPT_ARG_NONE
, nullptr, OPT_LIST_OPTIONS
, nullptr, nullptr },
106 { "filter", 'f', POPT_ARG_STRING
, &opt_filter
, OPT_FILTER
, nullptr, nullptr },
107 { "exclude", 'x', POPT_ARG_STRING
, &opt_exclude
, OPT_EXCLUDE
, nullptr, nullptr },
108 { nullptr, 0, 0, nullptr, 0, nullptr, nullptr }
112 * Parse probe options.
114 int parse_probe_opts(struct lttng_event
*ev
, char *opt
)
116 int ret
= CMD_SUCCESS
;
119 #define S_HEX_LEN_SCANF_IS_A_BROKEN_API "18" /* 18 is (19 - 1) (\0 is extra) */
120 char name
[LTTNG_SYMBOL_NAME_LEN
];
122 if (opt
== nullptr) {
127 /* Check for symbol+offset */
129 "%" LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API
130 "[^'+']+%" S_HEX_LEN_SCANF_IS_A_BROKEN_API
"s",
134 strncpy(ev
->attr
.probe
.symbol_name
, name
, LTTNG_SYMBOL_NAME_LEN
);
135 ev
->attr
.probe
.symbol_name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
136 DBG("probe symbol %s", ev
->attr
.probe
.symbol_name
);
137 if (*s_hex
== '\0') {
138 ERR("Invalid probe offset %s", s_hex
);
142 ev
->attr
.probe
.offset
= strtoull(s_hex
, nullptr, 0);
143 DBG("probe offset %" PRIu64
, ev
->attr
.probe
.offset
);
144 ev
->attr
.probe
.addr
= 0;
148 /* Check for symbol */
149 if (isalpha(name
[0]) || name
[0] == '_') {
150 match
= sscanf(opt
, "%" LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API
"s", name
);
152 strncpy(ev
->attr
.probe
.symbol_name
, name
, LTTNG_SYMBOL_NAME_LEN
);
153 ev
->attr
.probe
.symbol_name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
154 DBG("probe symbol %s", ev
->attr
.probe
.symbol_name
);
155 ev
->attr
.probe
.offset
= 0;
156 DBG("probe offset %" PRIu64
, ev
->attr
.probe
.offset
);
157 ev
->attr
.probe
.addr
= 0;
162 /* Check for address */
163 match
= sscanf(opt
, "%" S_HEX_LEN_SCANF_IS_A_BROKEN_API
"s", s_hex
);
166 * Return an error if the first character of the tentative
167 * address is NULL or not a digit. It can be "0" if the address
168 * is in hexadecimal and can be 1 to 9 if it's in decimal.
170 if (*s_hex
== '\0' || !isdigit(*s_hex
)) {
171 ERR("Invalid probe description %s", s_hex
);
175 ev
->attr
.probe
.addr
= strtoull(s_hex
, nullptr, 0);
176 DBG("probe addr %" PRIu64
, ev
->attr
.probe
.addr
);
177 ev
->attr
.probe
.offset
= 0;
178 memset(ev
->attr
.probe
.symbol_name
, 0, LTTNG_SYMBOL_NAME_LEN
);
189 const char *print_channel_name(const char *name
)
191 return name
?: DEFAULT_CHANNEL_NAME
;
194 const char *print_raw_channel_name(const char *name
)
196 return name
?: "<default>";
200 * Mi print exlcusion list
202 int mi_print_exclusion(const struct lttng_dynamic_pointer_array
*exclusions
)
206 const size_t count
= lttng_dynamic_pointer_array_get_count(exclusions
);
208 LTTNG_ASSERT(writer
);
215 ret
= mi_lttng_writer_open_element(writer
, config_element_exclusions
);
220 for (i
= 0; i
< count
; i
++) {
221 const char *exclusion
=
222 (const char *) lttng_dynamic_pointer_array_get_pointer(exclusions
, i
);
224 ret
= mi_lttng_writer_write_element_string(
225 writer
, config_element_exclusion
, exclusion
);
231 /* Close exclusions element */
232 ret
= mi_lttng_writer_close_element(writer
);
239 * Return allocated string for pretty-printing exclusion names.
241 char *print_exclusions(const struct lttng_dynamic_pointer_array
*exclusions
)
245 const char preamble
[] = " excluding ";
247 const size_t count
= lttng_dynamic_pointer_array_get_count(exclusions
);
253 /* Calculate total required length. */
254 for (i
= 0; i
< count
; i
++) {
255 const char *exclusion
=
256 (const char *) lttng_dynamic_pointer_array_get_pointer(exclusions
, i
);
258 length
+= strlen(exclusion
) + 4;
261 length
+= sizeof(preamble
);
262 ret
= calloc
<char>(length
);
267 strncpy(ret
, preamble
, length
);
268 for (i
= 0; i
< count
; i
++) {
269 const char *exclusion
=
270 (const char *) lttng_dynamic_pointer_array_get_pointer(exclusions
, i
);
273 strcat(ret
, exclusion
);
275 if (i
!= count
- 1) {
283 int check_exclusion_subsets(const char *event_name
, const char *exclusion
)
287 const char *e
= event_name
;
288 const char *x
= exclusion
;
290 /* Scan both the excluder and the event letter by letter */
304 /* Event is a subset of the excluder */
305 ERR("Event %s: %s excludes all events from %s",
314 * Reached the end of the event name before the
315 * end of the exclusion: this is valid.
337 WARN("Event %s: %s does not exclude any events from %s",
346 int create_exclusion_list_and_validate(const char *event_name
,
347 const char *exclusions_arg
,
348 struct lttng_dynamic_pointer_array
*exclusions
)
352 /* Split exclusions. */
353 ret
= strutils_split(exclusions_arg
, ',', true, exclusions
);
358 if (validate_exclusion_list(event_name
, exclusions
) != 0) {
366 lttng_dynamic_pointer_array_reset(exclusions
);
372 void warn_on_truncated_exclusion_names(const struct lttng_dynamic_pointer_array
*exclusions
,
376 const size_t num_exclusions
= lttng_dynamic_pointer_array_get_count(exclusions
);
378 for (i
= 0; i
< num_exclusions
; i
++) {
379 const char *const exclusion
=
380 (const char *) lttng_dynamic_pointer_array_get_pointer(exclusions
, i
);
382 if (strlen(exclusion
) >= LTTNG_SYMBOL_NAME_LEN
) {
383 WARN("Event exclusion \"%s\" will be truncated", exclusion
);
390 * Enabling event using the lttng API.
391 * Note: in case of error only the last error code will be return.
393 int enable_events(char *session_name
, char *event_list
)
395 int ret
= CMD_SUCCESS
, command_ret
= CMD_SUCCESS
;
396 int error_holder
= CMD_SUCCESS
, warn
= 0, error
= 0, success
= 1;
397 char *event_name
, *channel_name
= nullptr;
398 struct lttng_event
*ev
;
399 struct lttng_domain dom
= {};
400 struct lttng_dynamic_pointer_array exclusions
;
401 struct lttng_userspace_probe_location
*uprobe_loc
= nullptr;
403 lttng_dynamic_pointer_array_init(&exclusions
, nullptr);
405 ev
= lttng_event_create();
413 WARN("Kernel loglevels are not supported.");
417 /* Create lttng domain */
419 dom
.type
= LTTNG_DOMAIN_KERNEL
;
420 dom
.buf_type
= LTTNG_BUFFER_GLOBAL
;
421 } else if (opt_userspace
) {
422 dom
.type
= LTTNG_DOMAIN_UST
;
424 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
425 } else if (opt_jul
) {
426 dom
.type
= LTTNG_DOMAIN_JUL
;
428 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
429 } else if (opt_log4j
) {
430 dom
.type
= LTTNG_DOMAIN_LOG4J
;
432 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
433 } else if (opt_python
) {
434 dom
.type
= LTTNG_DOMAIN_PYTHON
;
436 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
438 /* Checked by the caller. */
444 case LTTNG_DOMAIN_KERNEL
:
445 case LTTNG_DOMAIN_JUL
:
446 case LTTNG_DOMAIN_LOG4J
:
447 case LTTNG_DOMAIN_PYTHON
:
448 ERR("Event name exclusions are not yet implemented for %s events",
449 lttng_domain_type_str(dom
.type
));
452 case LTTNG_DOMAIN_UST
:
453 /* Exclusions supported */
461 * Adding a filter to a probe, function or userspace-probe would be
462 * denied by the kernel tracer as it's not supported at the moment. We
463 * do an early check here to warn the user.
465 if (opt_filter
&& opt_kernel
) {
466 switch (opt_event_type
) {
467 case LTTNG_EVENT_ALL
:
468 case LTTNG_EVENT_TRACEPOINT
:
469 case LTTNG_EVENT_SYSCALL
:
471 case LTTNG_EVENT_PROBE
:
472 case LTTNG_EVENT_USERSPACE_PROBE
:
473 case LTTNG_EVENT_FUNCTION
:
474 ERR("Filter expressions are not supported for %s events",
475 get_event_type_str((lttng_event_type
) opt_event_type
));
484 channel_name
= opt_channel_name
;
486 handle
= lttng_create_handle(session_name
, &dom
);
487 if (handle
== nullptr) {
494 /* Open a events element */
495 ret
= mi_lttng_writer_open_element(writer
, config_element_events
);
502 if (opt_enable_all
) {
503 /* Default setup for enable all */
505 ev
->type
= (lttng_event_type
) opt_event_type
;
506 strcpy(ev
->name
, "*");
507 /* kernel loglevels not implemented */
508 ev
->loglevel_type
= LTTNG_EVENT_LOGLEVEL_ALL
;
510 ev
->type
= LTTNG_EVENT_TRACEPOINT
;
511 strcpy(ev
->name
, "*");
512 ev
->loglevel_type
= (lttng_loglevel_type
) opt_loglevel_type
;
516 LTTNG_ASSERT(opt_userspace
|| opt_jul
|| opt_log4j
|| opt_python
);
519 enum lttng_loglevel loglevel
;
522 loglevel_name_to_value(opt_loglevel
, &loglevel
);
523 ev
->loglevel
= (int) loglevel
;
524 } else if (opt_jul
) {
525 enum lttng_loglevel_jul loglevel
;
528 loglevel_jul_name_to_value(opt_loglevel
, &loglevel
);
529 ev
->loglevel
= (int) loglevel
;
530 } else if (opt_log4j
) {
531 enum lttng_loglevel_log4j loglevel
;
533 name_search_ret
= loglevel_log4j_name_to_value(opt_loglevel
,
535 ev
->loglevel
= (int) loglevel
;
538 enum lttng_loglevel_python loglevel
;
540 name_search_ret
= loglevel_python_name_to_value(
541 opt_loglevel
, &loglevel
);
542 ev
->loglevel
= (int) loglevel
;
545 if (name_search_ret
== -1) {
546 ERR("Unknown loglevel %s", opt_loglevel
);
547 ret
= -LTTNG_ERR_INVALID
;
551 LTTNG_ASSERT(opt_userspace
|| opt_jul
|| opt_log4j
|| opt_python
);
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
;
565 ret
= create_exclusion_list_and_validate("*", opt_exclude
, &exclusions
);
572 warn_on_truncated_exclusion_names(&exclusions
, &warn
);
575 ret
= lttng_enable_event_with_exclusions(
580 lttng_dynamic_pointer_array_get_count(&exclusions
),
581 (char **) exclusions
.array
.buffer
.data
);
584 case LTTNG_ERR_KERN_EVENT_EXIST
:
585 WARN("Kernel events already enabled (channel %s, session %s)",
586 print_channel_name(channel_name
),
590 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
593 "The command tried to enable an event in a new domain for a session that has already been started once.";
594 ERR("Events: %s (channel %s, session %s)",
596 print_channel_name(channel_name
),
602 ERR("Events: %s (channel %s, session %s)",
604 ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
?
605 print_raw_channel_name(channel_name
) :
606 print_channel_name(channel_name
),
614 switch (opt_event_type
) {
615 case LTTNG_EVENT_TRACEPOINT
:
616 if (opt_loglevel
&& dom
.type
!= LTTNG_DOMAIN_KERNEL
) {
617 char *exclusion_string
= print_exclusions(&exclusions
);
619 if (!exclusion_string
) {
620 PERROR("Cannot allocate exclusion_string");
624 MSG("All %s tracepoints%s are enabled in channel %s for loglevel %s",
625 lttng_domain_type_str(dom
.type
),
627 print_channel_name(channel_name
),
629 free(exclusion_string
);
631 char *exclusion_string
= print_exclusions(&exclusions
);
633 if (!exclusion_string
) {
634 PERROR("Cannot allocate exclusion_string");
638 MSG("All %s tracepoints%s are enabled in channel %s",
639 lttng_domain_type_str(dom
.type
),
641 print_channel_name(channel_name
));
642 free(exclusion_string
);
645 case LTTNG_EVENT_SYSCALL
:
647 MSG("All %s system calls are enabled in channel %s",
648 lttng_domain_type_str(dom
.type
),
649 print_channel_name(channel_name
));
652 case LTTNG_EVENT_ALL
:
653 if (opt_loglevel
&& dom
.type
!= LTTNG_DOMAIN_KERNEL
) {
654 char *exclusion_string
= print_exclusions(&exclusions
);
656 if (!exclusion_string
) {
657 PERROR("Cannot allocate exclusion_string");
661 MSG("All %s events%s are enabled in channel %s for loglevel %s",
662 lttng_domain_type_str(dom
.type
),
664 print_channel_name(channel_name
),
666 free(exclusion_string
);
668 char *exclusion_string
= print_exclusions(&exclusions
);
670 if (!exclusion_string
) {
671 PERROR("Cannot allocate exclusion_string");
675 MSG("All %s events%s are enabled in channel %s",
676 lttng_domain_type_str(dom
.type
),
678 print_channel_name(channel_name
));
679 free(exclusion_string
);
684 * We should not be here since lttng_enable_event should have
685 * failed on the event type.
692 command_ret
= lttng_enable_event_with_exclusions(
697 lttng_dynamic_pointer_array_get_count(&exclusions
),
698 (char **) exclusions
.array
.buffer
.data
);
699 if (command_ret
< 0) {
700 switch (-command_ret
) {
701 case LTTNG_ERR_FILTER_EXIST
:
702 WARN("Filter on all events is already enabled"
703 " (channel %s, session %s)",
704 print_channel_name(channel_name
),
708 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
711 "The command tried to enable an event in a new domain for a session that has already been started once.";
712 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
714 print_channel_name(channel_name
),
721 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
722 lttng_strerror(command_ret
),
723 command_ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
?
724 print_raw_channel_name(channel_name
) :
725 print_channel_name(channel_name
),
731 error_holder
= command_ret
;
734 MSG("Filter '%s' successfully set", opt_filter
);
739 /* The wildcard * is used for kernel and ust domain to
740 * represent ALL. We copy * in event name to force the wildcard use
743 * Note: this is strictly for semantic and printing while in
744 * machine interface mode.
746 strcpy(ev
->name
, "*");
748 /* If we reach here the events are enabled */
749 if (!error
&& !warn
) {
755 ret
= mi_lttng_event(writer
, ev
, 1, handle
->domain
.type
);
761 /* print exclusion */
762 ret
= mi_print_exclusion(&exclusions
);
769 ret
= mi_lttng_writer_write_element_bool(
770 writer
, mi_lttng_element_command_success
, success
);
776 /* Close event element */
777 ret
= mi_lttng_writer_close_element(writer
);
787 /* Strip event list */
788 event_name
= strtok(event_list
, ",");
789 while (event_name
!= nullptr) {
790 /* Copy name and type of the event */
791 strncpy(ev
->name
, event_name
, LTTNG_SYMBOL_NAME_LEN
);
792 ev
->name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
793 ev
->type
= (lttng_event_type
) opt_event_type
;
795 /* Kernel tracer action */
797 DBG("Enabling kernel event %s for channel %s",
799 print_channel_name(channel_name
));
801 switch (opt_event_type
) {
802 case LTTNG_EVENT_ALL
: /* Enable tracepoints and syscalls */
803 /* If event name differs from *, select tracepoint. */
804 if (strcmp(ev
->name
, "*") != 0) {
805 ev
->type
= LTTNG_EVENT_TRACEPOINT
;
808 case LTTNG_EVENT_TRACEPOINT
:
810 case LTTNG_EVENT_PROBE
:
811 ret
= parse_probe_opts(ev
, opt_probe
);
813 ERR("Unable to parse probe options");
818 case LTTNG_EVENT_USERSPACE_PROBE
:
819 LTTNG_ASSERT(ev
->type
== LTTNG_EVENT_USERSPACE_PROBE
);
821 ret
= parse_userspace_probe_opts(opt_userspace_probe
, &uprobe_loc
);
824 case CMD_UNSUPPORTED
:
826 * Error message describing
827 * what is not supported was
828 * printed in the function.
833 ERR("Unable to parse userspace probe options");
839 ret
= lttng_event_set_userspace_probe_location(ev
, uprobe_loc
);
841 WARN("Failed to set probe location on event");
846 /* Ownership of the uprobe location was transferred to the event. */
847 uprobe_loc
= nullptr;
849 case LTTNG_EVENT_FUNCTION
:
850 ret
= parse_probe_opts(ev
, opt_function
);
852 ERR("Unable to parse function probe options");
857 case LTTNG_EVENT_SYSCALL
:
858 ev
->type
= LTTNG_EVENT_SYSCALL
;
865 /* kernel loglevels not implemented */
866 ev
->loglevel_type
= LTTNG_EVENT_LOGLEVEL_ALL
;
867 } else if (opt_userspace
) { /* User-space tracer action */
868 DBG("Enabling UST event %s for channel %s, loglevel %s",
870 print_channel_name(channel_name
),
871 opt_loglevel
?: "<all>");
873 switch (opt_event_type
) {
874 case LTTNG_EVENT_ALL
: /* Default behavior is tracepoint */
876 case LTTNG_EVENT_TRACEPOINT
:
877 /* Copy name and type of the event */
878 ev
->type
= LTTNG_EVENT_TRACEPOINT
;
879 strncpy(ev
->name
, event_name
, LTTNG_SYMBOL_NAME_LEN
);
880 ev
->name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
882 case LTTNG_EVENT_PROBE
:
883 case LTTNG_EVENT_FUNCTION
:
884 case LTTNG_EVENT_SYSCALL
:
885 case LTTNG_EVENT_USERSPACE_PROBE
:
887 ERR("Event type not available for user-space tracing");
888 ret
= CMD_UNSUPPORTED
;
894 if (opt_event_type
!= LTTNG_EVENT_ALL
&&
895 opt_event_type
!= LTTNG_EVENT_TRACEPOINT
) {
896 ERR("Exclusion option can only be used with tracepoint events");
900 /* Free previously allocated items. */
901 lttng_dynamic_pointer_array_reset(&exclusions
);
902 ret
= create_exclusion_list_and_validate(
903 event_name
, opt_exclude
, &exclusions
);
909 warn_on_truncated_exclusion_names(&exclusions
, &warn
);
912 ev
->loglevel_type
= (lttng_loglevel_type
) opt_loglevel_type
;
914 enum lttng_loglevel loglevel
;
915 const int name_search_ret
=
916 loglevel_name_to_value(opt_loglevel
, &loglevel
);
918 if (name_search_ret
== -1) {
919 ERR("Unknown loglevel %s", opt_loglevel
);
920 ret
= -LTTNG_ERR_INVALID
;
924 ev
->loglevel
= (int) loglevel
;
928 } else if (opt_jul
|| opt_log4j
|| opt_python
) {
929 if (opt_event_type
!= LTTNG_EVENT_ALL
&&
930 opt_event_type
!= LTTNG_EVENT_TRACEPOINT
) {
931 ERR("Event type not supported for domain.");
932 ret
= CMD_UNSUPPORTED
;
936 ev
->loglevel_type
= (lttng_loglevel_type
) opt_loglevel_type
;
941 enum lttng_loglevel_jul loglevel
;
944 loglevel_jul_name_to_value(opt_loglevel
, &loglevel
);
945 ev
->loglevel
= (int) loglevel
;
946 } else if (opt_log4j
) {
947 enum lttng_loglevel_log4j loglevel
;
949 name_search_ret
= loglevel_log4j_name_to_value(opt_loglevel
,
951 ev
->loglevel
= (int) loglevel
;
954 enum lttng_loglevel_python loglevel
;
956 name_search_ret
= loglevel_python_name_to_value(
957 opt_loglevel
, &loglevel
);
958 ev
->loglevel
= (int) loglevel
;
961 if (name_search_ret
) {
962 ERR("Unknown loglevel %s", opt_loglevel
);
963 ret
= -LTTNG_ERR_INVALID
;
968 ev
->loglevel
= LTTNG_LOGLEVEL_JUL_ALL
;
969 } else if (opt_log4j
) {
970 ev
->loglevel
= LTTNG_LOGLEVEL_LOG4J_ALL
;
971 } else if (opt_python
) {
972 ev
->loglevel
= LTTNG_LOGLEVEL_PYTHON_DEBUG
;
975 ev
->type
= LTTNG_EVENT_TRACEPOINT
;
976 strncpy(ev
->name
, event_name
, LTTNG_SYMBOL_NAME_LEN
);
977 ev
->name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
983 char *exclusion_string
;
985 command_ret
= lttng_enable_event_with_exclusions(
990 lttng_dynamic_pointer_array_get_count(&exclusions
),
991 (char **) exclusions
.array
.buffer
.data
);
992 exclusion_string
= print_exclusions(&exclusions
);
993 if (!exclusion_string
) {
994 PERROR("Cannot allocate exclusion_string");
998 if (command_ret
< 0) {
999 /* Turn ret to positive value to handle the positive error code */
1000 switch (-command_ret
) {
1001 case LTTNG_ERR_KERN_EVENT_EXIST
:
1002 WARN("Kernel event %s%s already enabled (channel %s, session %s)",
1005 print_channel_name(channel_name
),
1009 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
1012 "The command tried to enable an event in a new domain for a session that has already been started once.";
1013 ERR("Event %s%s: %s (channel %s, session %s)",
1017 print_channel_name(channel_name
),
1022 case LTTNG_ERR_SDT_PROBE_SEMAPHORE
:
1023 ERR("SDT probes %s guarded by semaphores are not supported (channel %s, session %s)",
1025 print_channel_name(channel_name
),
1030 ERR("Event %s%s: %s (channel %s, session %s)",
1033 lttng_strerror(command_ret
),
1034 command_ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
?
1035 print_raw_channel_name(channel_name
) :
1036 print_channel_name(channel_name
),
1041 error_holder
= command_ret
;
1044 case LTTNG_DOMAIN_KERNEL
:
1045 case LTTNG_DOMAIN_UST
:
1046 MSG("%s event %s%s created in channel %s",
1047 lttng_domain_type_str(dom
.type
),
1050 print_channel_name(channel_name
));
1052 case LTTNG_DOMAIN_JUL
:
1053 case LTTNG_DOMAIN_LOG4J
:
1054 case LTTNG_DOMAIN_PYTHON
:
1056 * Don't print the default channel
1057 * name for agent domains.
1059 MSG("%s event %s%s enabled",
1060 lttng_domain_type_str(dom
.type
),
1068 free(exclusion_string
);
1072 char *exclusion_string
;
1074 /* Filter present */
1077 command_ret
= lttng_enable_event_with_exclusions(
1082 lttng_dynamic_pointer_array_get_count(&exclusions
),
1083 (char **) exclusions
.array
.buffer
.data
);
1084 exclusion_string
= print_exclusions(&exclusions
);
1085 if (!exclusion_string
) {
1086 PERROR("Cannot allocate exclusion_string");
1090 if (command_ret
< 0) {
1091 switch (-command_ret
) {
1092 case LTTNG_ERR_FILTER_EXIST
:
1093 WARN("Filter on event %s%s is already enabled"
1094 " (channel %s, session %s)",
1097 print_channel_name(channel_name
),
1101 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
1104 "The command tried to enable an event in a new domain for a session that has already been started once.";
1105 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')",
1109 print_channel_name(channel_name
),
1116 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')",
1119 lttng_strerror(command_ret
),
1120 command_ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
?
1121 print_raw_channel_name(channel_name
) :
1122 print_channel_name(channel_name
),
1128 error_holder
= command_ret
;
1131 MSG("Event %s%s: Filter '%s' successfully set",
1136 free(exclusion_string
);
1147 ret
= mi_lttng_event(writer
, ev
, 1, handle
->domain
.type
);
1153 /* print exclusion */
1154 ret
= mi_print_exclusion(&exclusions
);
1161 ret
= mi_lttng_writer_write_element_bool(
1162 writer
, mi_lttng_element_command_success
, success
);
1168 /* Close event element */
1169 ret
= mi_lttng_writer_close_element(writer
);
1177 event_name
= strtok(nullptr, ",");
1178 /* Reset warn, error and success */
1185 /* Close events element */
1186 ret
= mi_lttng_writer_close_element(writer
);
1199 lttng_destroy_handle(handle
);
1200 lttng_dynamic_pointer_array_reset(&exclusions
);
1201 lttng_userspace_probe_location_destroy(uprobe_loc
);
1203 /* Overwrite ret with error_holder if there was an actual error with
1204 * enabling an event.
1206 ret
= error_holder
? error_holder
: ret
;
1208 lttng_event_destroy(ev
);
1214 int validate_exclusion_list(const char *event_name
,
1215 const struct lttng_dynamic_pointer_array
*exclusions
)
1219 /* Event name must be a valid globbing pattern to allow exclusions. */
1220 if (!strutils_is_star_glob_pattern(event_name
)) {
1221 ERR("Event %s: Exclusions can only be used with a globbing pattern", event_name
);
1226 * If the event name is a star-at-end only globbing pattern,
1227 * then we can validate the individual exclusions. Otherwise
1228 * all exclusions are passed to the session daemon.
1230 if (strutils_is_star_at_the_end_only_glob_pattern(event_name
)) {
1231 size_t i
, num_exclusions
;
1233 num_exclusions
= lttng_dynamic_pointer_array_get_count(exclusions
);
1235 for (i
= 0; i
< num_exclusions
; i
++) {
1236 const char *exclusion
=
1237 (const char *) lttng_dynamic_pointer_array_get_pointer(exclusions
,
1240 if (!strutils_is_star_glob_pattern(exclusion
) ||
1241 strutils_is_star_at_the_end_only_glob_pattern(exclusion
)) {
1242 ret
= check_exclusion_subsets(event_name
, exclusion
);
1261 * Add event to trace session
1263 int cmd_enable_events(int argc
, const char **argv
)
1265 int opt
, ret
= CMD_SUCCESS
, command_ret
= CMD_SUCCESS
, success
= 1;
1266 static poptContext pc
;
1267 char *session_name
= nullptr;
1268 char *event_list
= nullptr;
1269 const char *arg_event_list
= nullptr;
1270 const char *leftover
= nullptr;
1271 int event_type
= -1;
1273 pc
= poptGetContext(nullptr, argc
, argv
, long_options
, 0);
1274 poptReadDefaultConfig(pc
, 0);
1276 /* Default event type */
1277 opt_event_type
= LTTNG_EVENT_ALL
;
1279 while ((opt
= poptGetNextOpt(pc
)) != -1) {
1284 case OPT_TRACEPOINT
:
1285 opt_event_type
= LTTNG_EVENT_TRACEPOINT
;
1288 opt_event_type
= LTTNG_EVENT_PROBE
;
1290 case OPT_USERSPACE_PROBE
:
1291 opt_event_type
= LTTNG_EVENT_USERSPACE_PROBE
;
1294 opt_event_type
= LTTNG_EVENT_FUNCTION
;
1297 opt_event_type
= LTTNG_EVENT_SYSCALL
;
1303 opt_loglevel_type
= LTTNG_EVENT_LOGLEVEL_RANGE
;
1304 opt_loglevel
= poptGetOptArg(pc
);
1306 case OPT_LOGLEVEL_ONLY
:
1307 opt_loglevel_type
= LTTNG_EVENT_LOGLEVEL_SINGLE
;
1308 opt_loglevel
= poptGetOptArg(pc
);
1310 case OPT_LIST_OPTIONS
:
1311 list_cmd_options(stdout
, long_options
);
1318 ret
= CMD_UNDEFINED
;
1322 /* Validate event type. Multiple event type are not supported. */
1323 if (event_type
== -1) {
1324 event_type
= opt_event_type
;
1326 if (event_type
!= opt_event_type
) {
1327 ERR("Multiple event type not supported.");
1334 ret
= print_missing_or_multiple_domains(
1335 opt_kernel
+ opt_userspace
+ opt_jul
+ opt_log4j
+ opt_python
, true);
1343 writer
= mi_lttng_writer_create(fileno(stdout
), lttng_opt_mi
);
1345 ret
= -LTTNG_ERR_NOMEM
;
1349 /* Open command element */
1350 ret
= mi_lttng_writer_command_open(writer
, mi_lttng_element_command_enable_event
);
1356 /* Open output element */
1357 ret
= mi_lttng_writer_open_element(writer
, mi_lttng_element_command_output
);
1364 arg_event_list
= poptGetArg(pc
);
1365 if (arg_event_list
== nullptr && opt_enable_all
== 0) {
1366 ERR("Missing event name(s).");
1371 if (opt_enable_all
== 0) {
1372 event_list
= strdup(arg_event_list
);
1373 if (event_list
== nullptr) {
1374 PERROR("Failed to copy event name(s)");
1380 leftover
= poptGetArg(pc
);
1382 ERR("Unknown argument: %s", leftover
);
1387 if (!opt_session_name
) {
1388 session_name
= get_session_name();
1389 if (session_name
== nullptr) {
1390 command_ret
= CMD_ERROR
;
1395 session_name
= opt_session_name
;
1398 command_ret
= enable_events(session_name
, event_list
);
1407 /* Close output element */
1408 ret
= mi_lttng_writer_close_element(writer
);
1414 ret
= mi_lttng_writer_write_element_bool(
1415 writer
, mi_lttng_element_command_success
, success
);
1421 /* Command element close */
1422 ret
= mi_lttng_writer_command_close(writer
);
1431 if (writer
&& mi_lttng_writer_destroy(writer
)) {
1432 /* Preserve original error code */
1433 ret
= ret
? ret
: LTTNG_ERR_MI_IO_FAIL
;
1436 if (opt_session_name
== nullptr) {
1442 /* Overwrite ret if an error occurred in enable_events */
1443 ret
= command_ret
? command_ret
: ret
;
1445 poptFreeContext(pc
);