2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2 only,
6 * as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include <sys/types.h>
29 #include <src/common/sessiond-comm/sessiond-comm.h>
30 #include <common/compat/string.h>
31 #include <common/string-utils/string-utils.h>
34 #include <common/mi-lttng.h>
36 #include "../command.h"
38 #if (LTTNG_SYMBOL_NAME_LEN == 256)
39 #define LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "255"
42 static char *opt_event_list
;
43 static int opt_event_type
;
44 static const char *opt_loglevel
;
45 static int opt_loglevel_type
;
46 static int opt_kernel
;
47 static char *opt_session_name
;
48 static int opt_userspace
;
51 static int opt_python
;
52 static int opt_enable_all
;
53 static char *opt_probe
;
54 static char *opt_function
;
55 static char *opt_channel_name
;
56 static char *opt_filter
;
57 static char *opt_exclude
;
73 static struct lttng_handle
*handle
;
74 static struct mi_writer
*writer
;
76 static struct poptOption long_options
[] = {
77 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
78 {"help", 'h', POPT_ARG_NONE
, 0, OPT_HELP
, 0, 0},
79 {"session", 's', POPT_ARG_STRING
, &opt_session_name
, 0, 0, 0},
80 {"all", 'a', POPT_ARG_VAL
, &opt_enable_all
, 1, 0, 0},
81 {"channel", 'c', POPT_ARG_STRING
, &opt_channel_name
, 0, 0, 0},
82 {"kernel", 'k', POPT_ARG_VAL
, &opt_kernel
, 1, 0, 0},
83 {"userspace", 'u', POPT_ARG_NONE
, 0, OPT_USERSPACE
, 0, 0},
84 {"jul", 'j', POPT_ARG_VAL
, &opt_jul
, 1, 0, 0},
85 {"log4j", 'l', POPT_ARG_VAL
, &opt_log4j
, 1, 0, 0},
86 {"python", 'p', POPT_ARG_VAL
, &opt_python
, 1, 0, 0},
87 {"tracepoint", 0, POPT_ARG_NONE
, 0, OPT_TRACEPOINT
, 0, 0},
88 {"probe", 0, POPT_ARG_STRING
, &opt_probe
, OPT_PROBE
, 0, 0},
89 {"function", 0, POPT_ARG_STRING
, &opt_function
, OPT_FUNCTION
, 0, 0},
90 {"syscall", 0, POPT_ARG_NONE
, 0, OPT_SYSCALL
, 0, 0},
91 {"loglevel", 0, POPT_ARG_STRING
, 0, OPT_LOGLEVEL
, 0, 0},
92 {"loglevel-only", 0, POPT_ARG_STRING
, 0, OPT_LOGLEVEL_ONLY
, 0, 0},
93 {"list-options", 0, POPT_ARG_NONE
, NULL
, OPT_LIST_OPTIONS
, NULL
, NULL
},
94 {"filter", 'f', POPT_ARG_STRING
, &opt_filter
, OPT_FILTER
, 0, 0},
95 {"exclude", 'x', POPT_ARG_STRING
, &opt_exclude
, OPT_EXCLUDE
, 0, 0},
100 * Parse probe options.
102 static int parse_probe_opts(struct lttng_event
*ev
, char *opt
)
104 int ret
= CMD_SUCCESS
;
107 #define S_HEX_LEN_SCANF_IS_A_BROKEN_API "18" /* 18 is (19 - 1) (\0 is extra) */
108 char name
[LTTNG_SYMBOL_NAME_LEN
];
115 /* Check for symbol+offset */
116 match
= sscanf(opt
, "%" LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API
117 "[^'+']+%" S_HEX_LEN_SCANF_IS_A_BROKEN_API
"s", name
, s_hex
);
119 strncpy(ev
->attr
.probe
.symbol_name
, name
, LTTNG_SYMBOL_NAME_LEN
);
120 ev
->attr
.probe
.symbol_name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
121 DBG("probe symbol %s", ev
->attr
.probe
.symbol_name
);
122 if (*s_hex
== '\0') {
123 ERR("Invalid probe offset %s", s_hex
);
127 ev
->attr
.probe
.offset
= strtoul(s_hex
, NULL
, 0);
128 DBG("probe offset %" PRIu64
, ev
->attr
.probe
.offset
);
129 ev
->attr
.probe
.addr
= 0;
133 /* Check for symbol */
134 if (isalpha(name
[0])) {
135 match
= sscanf(opt
, "%" LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API
"s",
138 strncpy(ev
->attr
.probe
.symbol_name
, name
, LTTNG_SYMBOL_NAME_LEN
);
139 ev
->attr
.probe
.symbol_name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
140 DBG("probe symbol %s", ev
->attr
.probe
.symbol_name
);
141 ev
->attr
.probe
.offset
= 0;
142 DBG("probe offset %" PRIu64
, ev
->attr
.probe
.offset
);
143 ev
->attr
.probe
.addr
= 0;
148 /* Check for address */
149 match
= sscanf(opt
, "%" S_HEX_LEN_SCANF_IS_A_BROKEN_API
"s", s_hex
);
151 if (*s_hex
== '\0') {
152 ERR("Invalid probe address %s", s_hex
);
156 ev
->attr
.probe
.addr
= strtoul(s_hex
, NULL
, 0);
157 DBG("probe addr %" PRIu64
, ev
->attr
.probe
.addr
);
158 ev
->attr
.probe
.offset
= 0;
159 memset(ev
->attr
.probe
.symbol_name
, 0, LTTNG_SYMBOL_NAME_LEN
);
171 * Maps LOG4j loglevel from string to value
173 static int loglevel_log4j_str_to_value(const char *inputstr
)
176 char str
[LTTNG_SYMBOL_NAME_LEN
];
178 if (!inputstr
|| strlen(inputstr
) == 0) {
183 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
184 * added at the end of the loop so a the upper bound we avoid the overflow.
186 while (i
< (LTTNG_SYMBOL_NAME_LEN
- 1) && inputstr
[i
] != '\0') {
187 str
[i
] = toupper(inputstr
[i
]);
192 if (!strcmp(str
, "LOG4J_OFF") || !strcmp(str
, "OFF")) {
193 return LTTNG_LOGLEVEL_LOG4J_OFF
;
194 } else if (!strcmp(str
, "LOG4J_FATAL") || !strcmp(str
, "FATAL")) {
195 return LTTNG_LOGLEVEL_LOG4J_FATAL
;
196 } else if (!strcmp(str
, "LOG4J_ERROR") || !strcmp(str
, "ERROR")) {
197 return LTTNG_LOGLEVEL_LOG4J_ERROR
;
198 } else if (!strcmp(str
, "LOG4J_WARN") || !strcmp(str
, "WARN")) {
199 return LTTNG_LOGLEVEL_LOG4J_WARN
;
200 } else if (!strcmp(str
, "LOG4J_INFO") || !strcmp(str
, "INFO")) {
201 return LTTNG_LOGLEVEL_LOG4J_INFO
;
202 } else if (!strcmp(str
, "LOG4J_DEBUG") || !strcmp(str
, "DEBUG")) {
203 return LTTNG_LOGLEVEL_LOG4J_DEBUG
;
204 } else if (!strcmp(str
, "LOG4J_TRACE") || !strcmp(str
, "TRACE")) {
205 return LTTNG_LOGLEVEL_LOG4J_TRACE
;
206 } else if (!strcmp(str
, "LOG4J_ALL") || !strcmp(str
, "ALL")) {
207 return LTTNG_LOGLEVEL_LOG4J_ALL
;
214 * Maps JUL loglevel from string to value
216 static int loglevel_jul_str_to_value(const char *inputstr
)
219 char str
[LTTNG_SYMBOL_NAME_LEN
];
221 if (!inputstr
|| strlen(inputstr
) == 0) {
226 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
227 * added at the end of the loop so a the upper bound we avoid the overflow.
229 while (i
< (LTTNG_SYMBOL_NAME_LEN
- 1) && inputstr
[i
] != '\0') {
230 str
[i
] = toupper(inputstr
[i
]);
235 if (!strcmp(str
, "JUL_OFF") || !strcmp(str
, "OFF")) {
236 return LTTNG_LOGLEVEL_JUL_OFF
;
237 } else if (!strcmp(str
, "JUL_SEVERE") || !strcmp(str
, "SEVERE")) {
238 return LTTNG_LOGLEVEL_JUL_SEVERE
;
239 } else if (!strcmp(str
, "JUL_WARNING") || !strcmp(str
, "WARNING")) {
240 return LTTNG_LOGLEVEL_JUL_WARNING
;
241 } else if (!strcmp(str
, "JUL_INFO") || !strcmp(str
, "INFO")) {
242 return LTTNG_LOGLEVEL_JUL_INFO
;
243 } else if (!strcmp(str
, "JUL_CONFIG") || !strcmp(str
, "CONFIG")) {
244 return LTTNG_LOGLEVEL_JUL_CONFIG
;
245 } else if (!strcmp(str
, "JUL_FINE") || !strcmp(str
, "FINE")) {
246 return LTTNG_LOGLEVEL_JUL_FINE
;
247 } else if (!strcmp(str
, "JUL_FINER") || !strcmp(str
, "FINER")) {
248 return LTTNG_LOGLEVEL_JUL_FINER
;
249 } else if (!strcmp(str
, "JUL_FINEST") || !strcmp(str
, "FINEST")) {
250 return LTTNG_LOGLEVEL_JUL_FINEST
;
251 } else if (!strcmp(str
, "JUL_ALL") || !strcmp(str
, "ALL")) {
252 return LTTNG_LOGLEVEL_JUL_ALL
;
259 * Maps Python loglevel from string to value
261 static int loglevel_python_str_to_value(const char *inputstr
)
264 char str
[LTTNG_SYMBOL_NAME_LEN
];
266 if (!inputstr
|| strlen(inputstr
) == 0) {
271 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
272 * added at the end of the loop so a the upper bound we avoid the overflow.
274 while (i
< (LTTNG_SYMBOL_NAME_LEN
- 1) && inputstr
[i
] != '\0') {
275 str
[i
] = toupper(inputstr
[i
]);
280 if (!strcmp(str
, "PYTHON_CRITICAL") || !strcmp(str
, "CRITICAL")) {
281 return LTTNG_LOGLEVEL_PYTHON_CRITICAL
;
282 } else if (!strcmp(str
, "PYTHON_ERROR") || !strcmp(str
, "ERROR")) {
283 return LTTNG_LOGLEVEL_PYTHON_ERROR
;
284 } else if (!strcmp(str
, "PYTHON_WARNING") || !strcmp(str
, "WARNING")) {
285 return LTTNG_LOGLEVEL_PYTHON_WARNING
;
286 } else if (!strcmp(str
, "PYTHON_INFO") || !strcmp(str
, "INFO")) {
287 return LTTNG_LOGLEVEL_PYTHON_INFO
;
288 } else if (!strcmp(str
, "PYTNON_DEBUG") || !strcmp(str
, "DEBUG")) {
289 return LTTNG_LOGLEVEL_PYTHON_DEBUG
;
290 } else if (!strcmp(str
, "PYTHON_NOTSET") || !strcmp(str
, "NOTSET")) {
291 return LTTNG_LOGLEVEL_PYTHON_NOTSET
;
298 * Maps loglevel from string to value
301 int loglevel_str_to_value(const char *inputstr
)
304 char str
[LTTNG_SYMBOL_NAME_LEN
];
306 if (!inputstr
|| strlen(inputstr
) == 0) {
311 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
312 * added at the end of the loop so a the upper bound we avoid the overflow.
314 while (i
< (LTTNG_SYMBOL_NAME_LEN
- 1) && inputstr
[i
] != '\0') {
315 str
[i
] = toupper(inputstr
[i
]);
319 if (!strcmp(str
, "TRACE_EMERG") || !strcmp(str
, "EMERG")) {
320 return LTTNG_LOGLEVEL_EMERG
;
321 } else if (!strcmp(str
, "TRACE_ALERT") || !strcmp(str
, "ALERT")) {
322 return LTTNG_LOGLEVEL_ALERT
;
323 } else if (!strcmp(str
, "TRACE_CRIT") || !strcmp(str
, "CRIT")) {
324 return LTTNG_LOGLEVEL_CRIT
;
325 } else if (!strcmp(str
, "TRACE_ERR") || !strcmp(str
, "ERR")) {
326 return LTTNG_LOGLEVEL_ERR
;
327 } else if (!strcmp(str
, "TRACE_WARNING") || !strcmp(str
, "WARNING")) {
328 return LTTNG_LOGLEVEL_WARNING
;
329 } else if (!strcmp(str
, "TRACE_NOTICE") || !strcmp(str
, "NOTICE")) {
330 return LTTNG_LOGLEVEL_NOTICE
;
331 } else if (!strcmp(str
, "TRACE_INFO") || !strcmp(str
, "INFO")) {
332 return LTTNG_LOGLEVEL_INFO
;
333 } else if (!strcmp(str
, "TRACE_DEBUG_SYSTEM") || !strcmp(str
, "DEBUG_SYSTEM") || !strcmp(str
, "SYSTEM")) {
334 return LTTNG_LOGLEVEL_DEBUG_SYSTEM
;
335 } else if (!strcmp(str
, "TRACE_DEBUG_PROGRAM") || !strcmp(str
, "DEBUG_PROGRAM") || !strcmp(str
, "PROGRAM")) {
336 return LTTNG_LOGLEVEL_DEBUG_PROGRAM
;
337 } else if (!strcmp(str
, "TRACE_DEBUG_PROCESS") || !strcmp(str
, "DEBUG_PROCESS") || !strcmp(str
, "PROCESS")) {
338 return LTTNG_LOGLEVEL_DEBUG_PROCESS
;
339 } else if (!strcmp(str
, "TRACE_DEBUG_MODULE") || !strcmp(str
, "DEBUG_MODULE") || !strcmp(str
, "MODULE")) {
340 return LTTNG_LOGLEVEL_DEBUG_MODULE
;
341 } else if (!strcmp(str
, "TRACE_DEBUG_UNIT") || !strcmp(str
, "DEBUG_UNIT") || !strcmp(str
, "UNIT")) {
342 return LTTNG_LOGLEVEL_DEBUG_UNIT
;
343 } else if (!strcmp(str
, "TRACE_DEBUG_FUNCTION") || !strcmp(str
, "DEBUG_FUNCTION") || !strcmp(str
, "FUNCTION")) {
344 return LTTNG_LOGLEVEL_DEBUG_FUNCTION
;
345 } else if (!strcmp(str
, "TRACE_DEBUG_LINE") || !strcmp(str
, "DEBUG_LINE") || !strcmp(str
, "LINE")) {
346 return LTTNG_LOGLEVEL_DEBUG_LINE
;
347 } else if (!strcmp(str
, "TRACE_DEBUG") || !strcmp(str
, "DEBUG")) {
348 return LTTNG_LOGLEVEL_DEBUG
;
355 const char *print_channel_name(const char *name
)
357 return name
? : DEFAULT_CHANNEL_NAME
;
361 const char *print_raw_channel_name(const char *name
)
363 return name
? : "<default>";
367 * Mi print exlcusion list
370 int mi_print_exclusion(char **names
)
373 int count
= names
? strutils_array_of_strings_len(names
) : 0;
381 ret
= mi_lttng_writer_open_element(writer
, config_element_exclusions
);
386 for (i
= 0; i
< count
; i
++) {
387 ret
= mi_lttng_writer_write_element_string(writer
,
388 config_element_exclusion
, names
[i
]);
394 /* Close exclusions element */
395 ret
= mi_lttng_writer_close_element(writer
);
402 * Return allocated string for pretty-printing exclusion names.
405 char *print_exclusions(char **names
)
409 const char *preamble
= " excluding ";
411 int count
= names
? strutils_array_of_strings_len(names
) : 0;
417 /* calculate total required length */
418 for (i
= 0; i
< count
; i
++) {
419 length
+= strlen(names
[i
]) + 4;
422 /* add length of preamble + one for NUL - one for last (missing) comma */
423 length
+= strlen(preamble
);
424 ret
= zmalloc(length
+ 1);
428 strncpy(ret
, preamble
, length
);
429 for (i
= 0; i
< count
; i
++) {
431 strcat(ret
, names
[i
]);
433 if (i
!= count
- 1) {
442 int check_exclusion_subsets(const char *event_name
, const char *exclusion
)
446 const char *e
= event_name
;
447 const char *x
= exclusion
;
449 /* Scan both the excluder and the event letter by letter */
463 /* Event is a subset of the excluder */
464 ERR("Event %s: %s excludes all events from %s",
465 event_name
, exclusion
, event_name
);
471 * Reached the end of the event name before the
472 * end of the exclusion: this is valid.
494 WARN("Event %s: %s does not exclude any events from %s",
495 event_name
, exclusion
, event_name
);
502 int check_exclusions_subsets(const char *event_name
,
503 char * const *exclusions
)
508 for (item
= exclusions
; *item
; item
++) {
509 ret
= check_exclusion_subsets(event_name
, *item
);
520 int create_exclusion_list_and_validate(const char *event_name
,
521 const char *exclusions_arg
,
522 char ***exclusion_list
)
525 char **exclusions
= NULL
;
527 /* Event name must be a valid globbing pattern to allow exclusions. */
528 if (!strutils_is_star_glob_pattern(event_name
)) {
529 ERR("Event %s: Exclusions can only be used with a globbing pattern",
534 /* Split exclusions. */
535 exclusions
= strutils_split(exclusions_arg
, ',', true);
541 * If the event name is a star-at-end only globbing pattern,
542 * then we can validate the individual exclusions. Otherwise
543 * all exclusions are passed to the session daemon.
545 if (strutils_is_star_at_the_end_only_glob_pattern(event_name
)) {
546 char * const *exclusion
;
548 for (exclusion
= exclusions
; *exclusion
; exclusion
++) {
549 if (!strutils_is_star_glob_pattern(*exclusion
) ||
550 strutils_is_star_at_the_end_only_glob_pattern(*exclusion
)) {
551 ret
= check_exclusions_subsets(
552 event_name
, exclusion
);
560 *exclusion_list
= exclusions
;
566 strutils_free_null_terminated_array_of_strings(exclusions
);
572 static void warn_on_truncated_exclusion_names(char * const *exclusion_list
,
575 char * const *exclusion
;
577 for (exclusion
= exclusion_list
; *exclusion
; exclusion
++) {
578 if (strlen(*exclusion
) >= LTTNG_SYMBOL_NAME_LEN
) {
579 WARN("Event exclusion \"%s\" will be truncated",
587 * Enabling event using the lttng API.
588 * Note: in case of error only the last error code will be return.
590 static int enable_events(char *session_name
)
592 int ret
= CMD_SUCCESS
, command_ret
= CMD_SUCCESS
;
593 int error_holder
= CMD_SUCCESS
, warn
= 0, error
= 0, success
= 1;
594 char *event_name
, *channel_name
= NULL
;
595 struct lttng_event ev
;
596 struct lttng_domain dom
;
597 char **exclusion_list
= NULL
;
599 memset(&ev
, 0, sizeof(ev
));
600 memset(&dom
, 0, sizeof(dom
));
604 WARN("Kernel loglevels are not supported.");
608 /* Create lttng domain */
610 dom
.type
= LTTNG_DOMAIN_KERNEL
;
611 dom
.buf_type
= LTTNG_BUFFER_GLOBAL
;
612 } else if (opt_userspace
) {
613 dom
.type
= LTTNG_DOMAIN_UST
;
615 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
616 } else if (opt_jul
) {
617 dom
.type
= LTTNG_DOMAIN_JUL
;
619 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
620 } else if (opt_log4j
) {
621 dom
.type
= LTTNG_DOMAIN_LOG4J
;
623 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
624 } else if (opt_python
) {
625 dom
.type
= LTTNG_DOMAIN_PYTHON
;
627 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
629 /* Checked by the caller. */
635 case LTTNG_DOMAIN_KERNEL
:
636 case LTTNG_DOMAIN_JUL
:
637 case LTTNG_DOMAIN_LOG4J
:
638 case LTTNG_DOMAIN_PYTHON
:
639 ERR("Event name exclusions are not yet implemented for %s events",
640 get_domain_str(dom
.type
));
643 case LTTNG_DOMAIN_UST
:
644 /* Exclusions supported */
651 channel_name
= opt_channel_name
;
653 handle
= lttng_create_handle(session_name
, &dom
);
654 if (handle
== NULL
) {
661 /* Open a events element */
662 ret
= mi_lttng_writer_open_element(writer
, config_element_events
);
669 if (opt_enable_all
) {
670 /* Default setup for enable all */
672 ev
.type
= opt_event_type
;
673 strcpy(ev
.name
, "*");
674 /* kernel loglevels not implemented */
675 ev
.loglevel_type
= LTTNG_EVENT_LOGLEVEL_ALL
;
677 ev
.type
= LTTNG_EVENT_TRACEPOINT
;
678 strcpy(ev
.name
, "*");
679 ev
.loglevel_type
= opt_loglevel_type
;
681 assert(opt_userspace
|| opt_jul
|| opt_log4j
|| opt_python
);
683 ev
.loglevel
= loglevel_str_to_value(opt_loglevel
);
684 } else if (opt_jul
) {
685 ev
.loglevel
= loglevel_jul_str_to_value(opt_loglevel
);
686 } else if (opt_log4j
) {
687 ev
.loglevel
= loglevel_log4j_str_to_value(opt_loglevel
);
688 } else if (opt_python
) {
689 ev
.loglevel
= loglevel_python_str_to_value(opt_loglevel
);
691 if (ev
.loglevel
== -1) {
692 ERR("Unknown loglevel %s", opt_loglevel
);
693 ret
= -LTTNG_ERR_INVALID
;
697 assert(opt_userspace
|| opt_jul
|| opt_log4j
|| opt_python
);
700 } else if (opt_jul
) {
701 ev
.loglevel
= LTTNG_LOGLEVEL_JUL_ALL
;
702 } else if (opt_log4j
) {
703 ev
.loglevel
= LTTNG_LOGLEVEL_LOG4J_ALL
;
704 } else if (opt_python
) {
705 ev
.loglevel
= LTTNG_LOGLEVEL_PYTHON_DEBUG
;
711 ret
= create_exclusion_list_and_validate("*",
712 opt_exclude
, &exclusion_list
);
719 warn_on_truncated_exclusion_names(exclusion_list
,
723 ret
= lttng_enable_event_with_exclusions(handle
,
726 exclusion_list
? strutils_array_of_strings_len(exclusion_list
) : 0,
730 case LTTNG_ERR_KERN_EVENT_EXIST
:
731 WARN("Kernel events already enabled (channel %s, session %s)",
732 print_channel_name(channel_name
), session_name
);
735 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
737 const char *msg
= "The command tried to enable an event in a new domain for a session that has already been started once.";
738 ERR("Events: %s (channel %s, session %s)",
740 print_channel_name(channel_name
),
746 ERR("Events: %s (channel %s, session %s)",
748 ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
749 ? print_raw_channel_name(channel_name
)
750 : print_channel_name(channel_name
),
758 switch (opt_event_type
) {
759 case LTTNG_EVENT_TRACEPOINT
:
760 if (opt_loglevel
&& dom
.type
!= LTTNG_DOMAIN_KERNEL
) {
761 char *exclusion_string
= print_exclusions(exclusion_list
);
763 if (!exclusion_string
) {
764 PERROR("Cannot allocate exclusion_string");
768 MSG("All %s tracepoints%s are enabled in channel %s for loglevel %s",
769 get_domain_str(dom
.type
),
771 print_channel_name(channel_name
),
773 free(exclusion_string
);
775 char *exclusion_string
= print_exclusions(exclusion_list
);
777 if (!exclusion_string
) {
778 PERROR("Cannot allocate exclusion_string");
782 MSG("All %s tracepoints%s are enabled in channel %s",
783 get_domain_str(dom
.type
),
785 print_channel_name(channel_name
));
786 free(exclusion_string
);
789 case LTTNG_EVENT_SYSCALL
:
791 MSG("All %s system calls are enabled in channel %s",
792 get_domain_str(dom
.type
),
793 print_channel_name(channel_name
));
796 case LTTNG_EVENT_ALL
:
797 if (opt_loglevel
&& dom
.type
!= LTTNG_DOMAIN_KERNEL
) {
798 char *exclusion_string
= print_exclusions(exclusion_list
);
800 if (!exclusion_string
) {
801 PERROR("Cannot allocate exclusion_string");
805 MSG("All %s events%s are enabled in channel %s for loglevel %s",
806 get_domain_str(dom
.type
),
808 print_channel_name(channel_name
),
810 free(exclusion_string
);
812 char *exclusion_string
= print_exclusions(exclusion_list
);
814 if (!exclusion_string
) {
815 PERROR("Cannot allocate exclusion_string");
819 MSG("All %s events%s are enabled in channel %s",
820 get_domain_str(dom
.type
),
822 print_channel_name(channel_name
));
823 free(exclusion_string
);
828 * We should not be here since lttng_enable_event should have
829 * failed on the event type.
836 command_ret
= lttng_enable_event_with_exclusions(handle
, &ev
, channel_name
,
838 exclusion_list
? strutils_array_of_strings_len(exclusion_list
) : 0,
840 if (command_ret
< 0) {
841 switch (-command_ret
) {
842 case LTTNG_ERR_FILTER_EXIST
:
843 WARN("Filter on all events is already enabled"
844 " (channel %s, session %s)",
845 print_channel_name(channel_name
), session_name
);
848 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
850 const char *msg
= "The command tried to enable an event in a new domain for a session that has already been started once.";
851 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
853 print_channel_name(channel_name
),
854 session_name
, opt_filter
);
859 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
860 lttng_strerror(command_ret
),
861 command_ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
862 ? print_raw_channel_name(channel_name
)
863 : print_channel_name(channel_name
),
864 session_name
, opt_filter
);
868 error_holder
= command_ret
;
871 MSG("Filter '%s' successfully set", opt_filter
);
876 /* The wildcard * is used for kernel and ust domain to
877 * represent ALL. We copy * in event name to force the wildcard use
880 * Note: this is strictly for semantic and printing while in
881 * machine interface mode.
883 strcpy(ev
.name
, "*");
885 /* If we reach here the events are enabled */
886 if (!error
&& !warn
) {
892 ret
= mi_lttng_event(writer
, &ev
, 1, handle
->domain
.type
);
898 /* print exclusion */
899 ret
= mi_print_exclusion(exclusion_list
);
906 ret
= mi_lttng_writer_write_element_bool(writer
,
907 mi_lttng_element_command_success
, success
);
913 /* Close event element */
914 ret
= mi_lttng_writer_close_element(writer
);
924 /* Strip event list */
925 event_name
= strtok(opt_event_list
, ",");
926 while (event_name
!= NULL
) {
927 /* Copy name and type of the event */
928 strncpy(ev
.name
, event_name
, LTTNG_SYMBOL_NAME_LEN
);
929 ev
.name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
930 ev
.type
= opt_event_type
;
932 /* Kernel tracer action */
934 DBG("Enabling kernel event %s for channel %s",
936 print_channel_name(channel_name
));
938 switch (opt_event_type
) {
939 case LTTNG_EVENT_ALL
: /* Enable tracepoints and syscalls */
940 /* If event name differs from *, select tracepoint. */
941 if (strcmp(ev
.name
, "*")) {
942 ev
.type
= LTTNG_EVENT_TRACEPOINT
;
945 case LTTNG_EVENT_TRACEPOINT
:
947 case LTTNG_EVENT_PROBE
:
948 ret
= parse_probe_opts(&ev
, opt_probe
);
950 ERR("Unable to parse probe options");
955 case LTTNG_EVENT_FUNCTION
:
956 ret
= parse_probe_opts(&ev
, opt_function
);
958 ERR("Unable to parse function probe options");
963 case LTTNG_EVENT_SYSCALL
:
964 ev
.type
= LTTNG_EVENT_SYSCALL
;
971 /* kernel loglevels not implemented */
972 ev
.loglevel_type
= LTTNG_EVENT_LOGLEVEL_ALL
;
973 } else if (opt_userspace
) { /* User-space tracer action */
974 DBG("Enabling UST event %s for channel %s, loglevel %s", event_name
,
975 print_channel_name(channel_name
), opt_loglevel
? : "<all>");
977 switch (opt_event_type
) {
978 case LTTNG_EVENT_ALL
: /* Default behavior is tracepoint */
980 case LTTNG_EVENT_TRACEPOINT
:
981 /* Copy name and type of the event */
982 ev
.type
= LTTNG_EVENT_TRACEPOINT
;
983 strncpy(ev
.name
, event_name
, LTTNG_SYMBOL_NAME_LEN
);
984 ev
.name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
986 case LTTNG_EVENT_PROBE
:
987 case LTTNG_EVENT_FUNCTION
:
988 case LTTNG_EVENT_SYSCALL
:
990 ERR("Event type not available for user-space tracing");
991 ret
= CMD_UNSUPPORTED
;
997 if (opt_event_type
!= LTTNG_EVENT_ALL
&& opt_event_type
!= LTTNG_EVENT_TRACEPOINT
) {
998 ERR("Exclusion option can only be used with tracepoint events");
1002 /* Free previously allocated items */
1003 strutils_free_null_terminated_array_of_strings(
1005 exclusion_list
= NULL
;
1006 ret
= create_exclusion_list_and_validate(
1007 event_name
, opt_exclude
,
1014 warn_on_truncated_exclusion_names(
1015 exclusion_list
, &warn
);
1018 ev
.loglevel_type
= opt_loglevel_type
;
1020 ev
.loglevel
= loglevel_str_to_value(opt_loglevel
);
1021 if (ev
.loglevel
== -1) {
1022 ERR("Unknown loglevel %s", opt_loglevel
);
1023 ret
= -LTTNG_ERR_INVALID
;
1029 } else if (opt_jul
|| opt_log4j
|| opt_python
) {
1030 if (opt_event_type
!= LTTNG_EVENT_ALL
&&
1031 opt_event_type
!= LTTNG_EVENT_TRACEPOINT
) {
1032 ERR("Event type not supported for domain.");
1033 ret
= CMD_UNSUPPORTED
;
1037 ev
.loglevel_type
= opt_loglevel_type
;
1040 ev
.loglevel
= loglevel_jul_str_to_value(opt_loglevel
);
1041 } else if (opt_log4j
) {
1042 ev
.loglevel
= loglevel_log4j_str_to_value(opt_loglevel
);
1043 } else if (opt_python
) {
1044 ev
.loglevel
= loglevel_python_str_to_value(opt_loglevel
);
1046 if (ev
.loglevel
== -1) {
1047 ERR("Unknown loglevel %s", opt_loglevel
);
1048 ret
= -LTTNG_ERR_INVALID
;
1053 ev
.loglevel
= LTTNG_LOGLEVEL_JUL_ALL
;
1054 } else if (opt_log4j
) {
1055 ev
.loglevel
= LTTNG_LOGLEVEL_LOG4J_ALL
;
1056 } else if (opt_python
) {
1057 ev
.loglevel
= LTTNG_LOGLEVEL_PYTHON_DEBUG
;
1060 ev
.type
= LTTNG_EVENT_TRACEPOINT
;
1061 strncpy(ev
.name
, event_name
, LTTNG_SYMBOL_NAME_LEN
);
1062 ev
.name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
1068 char *exclusion_string
;
1070 command_ret
= lttng_enable_event_with_exclusions(handle
,
1073 exclusion_list
? strutils_array_of_strings_len(exclusion_list
) : 0,
1075 exclusion_string
= print_exclusions(exclusion_list
);
1076 if (!exclusion_string
) {
1077 PERROR("Cannot allocate exclusion_string");
1081 if (command_ret
< 0) {
1082 /* Turn ret to positive value to handle the positive error code */
1083 switch (-command_ret
) {
1084 case LTTNG_ERR_KERN_EVENT_EXIST
:
1085 WARN("Kernel event %s%s already enabled (channel %s, session %s)",
1088 print_channel_name(channel_name
), session_name
);
1091 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
1093 const char *msg
= "The command tried to enable an event in a new domain for a session that has already been started once.";
1094 ERR("Event %s%s: %s (channel %s, session %s)", event_name
,
1097 print_channel_name(channel_name
),
1103 ERR("Event %s%s: %s (channel %s, session %s)", event_name
,
1105 lttng_strerror(command_ret
),
1106 command_ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
1107 ? print_raw_channel_name(channel_name
)
1108 : print_channel_name(channel_name
),
1113 error_holder
= command_ret
;
1116 case LTTNG_DOMAIN_KERNEL
:
1117 case LTTNG_DOMAIN_UST
:
1118 MSG("%s event %s%s created in channel %s",
1119 get_domain_str(dom
.type
),
1122 print_channel_name(channel_name
));
1124 case LTTNG_DOMAIN_JUL
:
1125 case LTTNG_DOMAIN_LOG4J
:
1126 case LTTNG_DOMAIN_PYTHON
:
1128 * Don't print the default channel
1129 * name for agent domains.
1131 MSG("%s event %s%s enabled",
1132 get_domain_str(dom
.type
),
1140 free(exclusion_string
);
1144 char *exclusion_string
;
1146 /* Filter present */
1149 command_ret
= lttng_enable_event_with_exclusions(handle
, &ev
, channel_name
,
1151 exclusion_list
? strutils_array_of_strings_len(exclusion_list
) : 0,
1153 exclusion_string
= print_exclusions(exclusion_list
);
1154 if (!exclusion_string
) {
1155 PERROR("Cannot allocate exclusion_string");
1159 if (command_ret
< 0) {
1160 switch (-command_ret
) {
1161 case LTTNG_ERR_FILTER_EXIST
:
1162 WARN("Filter on event %s%s is already enabled"
1163 " (channel %s, session %s)",
1166 print_channel_name(channel_name
), session_name
);
1169 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
1171 const char *msg
= "The command tried to enable an event in a new domain for a session that has already been started once.";
1172 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev
.name
,
1175 print_channel_name(channel_name
),
1176 session_name
, opt_filter
);
1181 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev
.name
,
1183 lttng_strerror(command_ret
),
1184 command_ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
1185 ? print_raw_channel_name(channel_name
)
1186 : print_channel_name(channel_name
),
1187 session_name
, opt_filter
);
1191 error_holder
= command_ret
;
1194 MSG("Event %s%s: Filter '%s' successfully set",
1195 event_name
, exclusion_string
,
1198 free(exclusion_string
);
1209 ret
= mi_lttng_event(writer
, &ev
, 1, handle
->domain
.type
);
1215 /* print exclusion */
1216 ret
= mi_print_exclusion(exclusion_list
);
1223 ret
= mi_lttng_writer_write_element_bool(writer
,
1224 mi_lttng_element_command_success
, success
);
1230 /* Close event element */
1231 ret
= mi_lttng_writer_close_element(writer
);
1239 event_name
= strtok(NULL
, ",");
1240 /* Reset warn, error and success */
1247 /* Close events element */
1248 ret
= mi_lttng_writer_close_element(writer
);
1261 lttng_destroy_handle(handle
);
1262 strutils_free_null_terminated_array_of_strings(exclusion_list
);
1264 /* Overwrite ret with error_holder if there was an actual error with
1265 * enabling an event.
1267 ret
= error_holder
? error_holder
: ret
;
1273 * Add event to trace session
1275 int cmd_enable_events(int argc
, const char **argv
)
1277 int opt
, ret
= CMD_SUCCESS
, command_ret
= CMD_SUCCESS
, success
= 1;
1278 static poptContext pc
;
1279 char *session_name
= NULL
;
1280 int event_type
= -1;
1282 pc
= poptGetContext(NULL
, argc
, argv
, long_options
, 0);
1283 poptReadDefaultConfig(pc
, 0);
1285 /* Default event type */
1286 opt_event_type
= LTTNG_EVENT_ALL
;
1288 while ((opt
= poptGetNextOpt(pc
)) != -1) {
1293 case OPT_TRACEPOINT
:
1294 opt_event_type
= LTTNG_EVENT_TRACEPOINT
;
1297 opt_event_type
= LTTNG_EVENT_PROBE
;
1300 opt_event_type
= LTTNG_EVENT_FUNCTION
;
1303 opt_event_type
= LTTNG_EVENT_SYSCALL
;
1309 opt_loglevel_type
= LTTNG_EVENT_LOGLEVEL_RANGE
;
1310 opt_loglevel
= poptGetOptArg(pc
);
1312 case OPT_LOGLEVEL_ONLY
:
1313 opt_loglevel_type
= LTTNG_EVENT_LOGLEVEL_SINGLE
;
1314 opt_loglevel
= poptGetOptArg(pc
);
1316 case OPT_LIST_OPTIONS
:
1317 list_cmd_options(stdout
, long_options
);
1324 ret
= CMD_UNDEFINED
;
1328 /* Validate event type. Multiple event type are not supported. */
1329 if (event_type
== -1) {
1330 event_type
= opt_event_type
;
1332 if (event_type
!= opt_event_type
) {
1333 ERR("Multiple event type not supported.");
1340 ret
= print_missing_or_multiple_domains(
1341 opt_kernel
+ opt_userspace
+ opt_jul
+ opt_log4j
+ opt_python
);
1349 writer
= mi_lttng_writer_create(fileno(stdout
), lttng_opt_mi
);
1351 ret
= -LTTNG_ERR_NOMEM
;
1355 /* Open command element */
1356 ret
= mi_lttng_writer_command_open(writer
,
1357 mi_lttng_element_command_enable_event
);
1363 /* Open output element */
1364 ret
= mi_lttng_writer_open_element(writer
,
1365 mi_lttng_element_command_output
);
1372 opt_event_list
= (char*) poptGetArg(pc
);
1373 if (opt_event_list
== NULL
&& opt_enable_all
== 0) {
1374 ERR("Missing event name(s).\n");
1379 if (!opt_session_name
) {
1380 session_name
= get_session_name();
1381 if (session_name
== NULL
) {
1382 command_ret
= CMD_ERROR
;
1387 session_name
= opt_session_name
;
1390 command_ret
= enable_events(session_name
);
1399 /* Close output element */
1400 ret
= mi_lttng_writer_close_element(writer
);
1406 ret
= mi_lttng_writer_write_element_bool(writer
,
1407 mi_lttng_element_command_success
, success
);
1413 /* Command element close */
1414 ret
= mi_lttng_writer_command_close(writer
);
1423 if (writer
&& mi_lttng_writer_destroy(writer
)) {
1424 /* Preserve original error code */
1425 ret
= ret
? ret
: LTTNG_ERR_MI_IO_FAIL
;
1428 if (opt_session_name
== NULL
) {
1432 /* Overwrite ret if an error occurred in enable_events */
1433 ret
= command_ret
? command_ret
: ret
;
1435 poptFreeContext(pc
);