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>
33 #include <common/mi-lttng.h>
35 #include "../command.h"
37 #if (LTTNG_SYMBOL_NAME_LEN == 256)
38 #define LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "255"
41 static char *opt_event_list
;
42 static int opt_event_type
;
43 static const char *opt_loglevel
;
44 static int opt_loglevel_type
;
45 static int opt_kernel
;
46 static char *opt_session_name
;
47 static int opt_userspace
;
50 static int opt_python
;
51 static int opt_enable_all
;
52 static char *opt_probe
;
53 static char *opt_function
;
54 static char *opt_channel_name
;
55 static char *opt_filter
;
56 static char *opt_exclude
;
72 static struct lttng_handle
*handle
;
73 static struct mi_writer
*writer
;
75 static struct poptOption long_options
[] = {
76 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
77 {"help", 'h', POPT_ARG_NONE
, 0, OPT_HELP
, 0, 0},
78 {"session", 's', POPT_ARG_STRING
, &opt_session_name
, 0, 0, 0},
79 {"all", 'a', POPT_ARG_VAL
, &opt_enable_all
, 1, 0, 0},
80 {"channel", 'c', POPT_ARG_STRING
, &opt_channel_name
, 0, 0, 0},
81 {"kernel", 'k', POPT_ARG_VAL
, &opt_kernel
, 1, 0, 0},
82 {"userspace", 'u', POPT_ARG_NONE
, 0, OPT_USERSPACE
, 0, 0},
83 {"jul", 'j', POPT_ARG_VAL
, &opt_jul
, 1, 0, 0},
84 {"log4j", 'l', POPT_ARG_VAL
, &opt_log4j
, 1, 0, 0},
85 {"python", 'p', POPT_ARG_VAL
, &opt_python
, 1, 0, 0},
86 {"tracepoint", 0, POPT_ARG_NONE
, 0, OPT_TRACEPOINT
, 0, 0},
87 {"probe", 0, POPT_ARG_STRING
, &opt_probe
, OPT_PROBE
, 0, 0},
88 {"function", 0, POPT_ARG_STRING
, &opt_function
, OPT_FUNCTION
, 0, 0},
89 {"syscall", 0, POPT_ARG_NONE
, 0, OPT_SYSCALL
, 0, 0},
90 {"loglevel", 0, POPT_ARG_STRING
, 0, OPT_LOGLEVEL
, 0, 0},
91 {"loglevel-only", 0, POPT_ARG_STRING
, 0, OPT_LOGLEVEL_ONLY
, 0, 0},
92 {"list-options", 0, POPT_ARG_NONE
, NULL
, OPT_LIST_OPTIONS
, NULL
, NULL
},
93 {"filter", 'f', POPT_ARG_STRING
, &opt_filter
, OPT_FILTER
, 0, 0},
94 {"exclude", 'x', POPT_ARG_STRING
, &opt_exclude
, OPT_EXCLUDE
, 0, 0},
99 * Parse probe options.
101 static int parse_probe_opts(struct lttng_event
*ev
, char *opt
)
103 int ret
= CMD_SUCCESS
;
106 #define S_HEX_LEN_SCANF_IS_A_BROKEN_API "18" /* 18 is (19 - 1) (\0 is extra) */
107 char name
[LTTNG_SYMBOL_NAME_LEN
];
114 /* Check for symbol+offset */
115 match
= sscanf(opt
, "%" LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API
116 "[^'+']+%" S_HEX_LEN_SCANF_IS_A_BROKEN_API
"s", name
, s_hex
);
118 strncpy(ev
->attr
.probe
.symbol_name
, name
, LTTNG_SYMBOL_NAME_LEN
);
119 ev
->attr
.probe
.symbol_name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
120 DBG("probe symbol %s", ev
->attr
.probe
.symbol_name
);
121 if (*s_hex
== '\0') {
122 ERR("Invalid probe offset %s", s_hex
);
126 ev
->attr
.probe
.offset
= strtoul(s_hex
, NULL
, 0);
127 DBG("probe offset %" PRIu64
, ev
->attr
.probe
.offset
);
128 ev
->attr
.probe
.addr
= 0;
132 /* Check for symbol */
133 if (isalpha(name
[0])) {
134 match
= sscanf(opt
, "%" LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API
"s",
137 strncpy(ev
->attr
.probe
.symbol_name
, name
, LTTNG_SYMBOL_NAME_LEN
);
138 ev
->attr
.probe
.symbol_name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
139 DBG("probe symbol %s", ev
->attr
.probe
.symbol_name
);
140 ev
->attr
.probe
.offset
= 0;
141 DBG("probe offset %" PRIu64
, ev
->attr
.probe
.offset
);
142 ev
->attr
.probe
.addr
= 0;
147 /* Check for address */
148 match
= sscanf(opt
, "%" S_HEX_LEN_SCANF_IS_A_BROKEN_API
"s", s_hex
);
150 if (*s_hex
== '\0') {
151 ERR("Invalid probe address %s", s_hex
);
155 ev
->attr
.probe
.addr
= strtoul(s_hex
, NULL
, 0);
156 DBG("probe addr %" PRIu64
, ev
->attr
.probe
.addr
);
157 ev
->attr
.probe
.offset
= 0;
158 memset(ev
->attr
.probe
.symbol_name
, 0, LTTNG_SYMBOL_NAME_LEN
);
170 * Maps LOG4j loglevel from string to value
172 static int loglevel_log4j_str_to_value(const char *inputstr
)
175 char str
[LTTNG_SYMBOL_NAME_LEN
];
177 if (!inputstr
|| strlen(inputstr
) == 0) {
182 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
183 * added at the end of the loop so a the upper bound we avoid the overflow.
185 while (i
< (LTTNG_SYMBOL_NAME_LEN
- 1) && inputstr
[i
] != '\0') {
186 str
[i
] = toupper(inputstr
[i
]);
191 if (!strcmp(str
, "LOG4J_OFF") || !strcmp(str
, "OFF")) {
192 return LTTNG_LOGLEVEL_LOG4J_OFF
;
193 } else if (!strcmp(str
, "LOG4J_FATAL") || !strcmp(str
, "FATAL")) {
194 return LTTNG_LOGLEVEL_LOG4J_FATAL
;
195 } else if (!strcmp(str
, "LOG4J_ERROR") || !strcmp(str
, "ERROR")) {
196 return LTTNG_LOGLEVEL_LOG4J_ERROR
;
197 } else if (!strcmp(str
, "LOG4J_WARN") || !strcmp(str
, "WARN")) {
198 return LTTNG_LOGLEVEL_LOG4J_WARN
;
199 } else if (!strcmp(str
, "LOG4J_INFO") || !strcmp(str
, "INFO")) {
200 return LTTNG_LOGLEVEL_LOG4J_INFO
;
201 } else if (!strcmp(str
, "LOG4J_DEBUG") || !strcmp(str
, "DEBUG")) {
202 return LTTNG_LOGLEVEL_LOG4J_DEBUG
;
203 } else if (!strcmp(str
, "LOG4J_TRACE") || !strcmp(str
, "TRACE")) {
204 return LTTNG_LOGLEVEL_LOG4J_TRACE
;
205 } else if (!strcmp(str
, "LOG4J_ALL") || !strcmp(str
, "ALL")) {
206 return LTTNG_LOGLEVEL_LOG4J_ALL
;
213 * Maps JUL loglevel from string to value
215 static int loglevel_jul_str_to_value(const char *inputstr
)
218 char str
[LTTNG_SYMBOL_NAME_LEN
];
220 if (!inputstr
|| strlen(inputstr
) == 0) {
225 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
226 * added at the end of the loop so a the upper bound we avoid the overflow.
228 while (i
< (LTTNG_SYMBOL_NAME_LEN
- 1) && inputstr
[i
] != '\0') {
229 str
[i
] = toupper(inputstr
[i
]);
234 if (!strcmp(str
, "JUL_OFF") || !strcmp(str
, "OFF")) {
235 return LTTNG_LOGLEVEL_JUL_OFF
;
236 } else if (!strcmp(str
, "JUL_SEVERE") || !strcmp(str
, "SEVERE")) {
237 return LTTNG_LOGLEVEL_JUL_SEVERE
;
238 } else if (!strcmp(str
, "JUL_WARNING") || !strcmp(str
, "WARNING")) {
239 return LTTNG_LOGLEVEL_JUL_WARNING
;
240 } else if (!strcmp(str
, "JUL_INFO") || !strcmp(str
, "INFO")) {
241 return LTTNG_LOGLEVEL_JUL_INFO
;
242 } else if (!strcmp(str
, "JUL_CONFIG") || !strcmp(str
, "CONFIG")) {
243 return LTTNG_LOGLEVEL_JUL_CONFIG
;
244 } else if (!strcmp(str
, "JUL_FINE") || !strcmp(str
, "FINE")) {
245 return LTTNG_LOGLEVEL_JUL_FINE
;
246 } else if (!strcmp(str
, "JUL_FINER") || !strcmp(str
, "FINER")) {
247 return LTTNG_LOGLEVEL_JUL_FINER
;
248 } else if (!strcmp(str
, "JUL_FINEST") || !strcmp(str
, "FINEST")) {
249 return LTTNG_LOGLEVEL_JUL_FINEST
;
250 } else if (!strcmp(str
, "JUL_ALL") || !strcmp(str
, "ALL")) {
251 return LTTNG_LOGLEVEL_JUL_ALL
;
258 * Maps Python loglevel from string to value
260 static int loglevel_python_str_to_value(const char *inputstr
)
263 char str
[LTTNG_SYMBOL_NAME_LEN
];
265 if (!inputstr
|| strlen(inputstr
) == 0) {
270 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
271 * added at the end of the loop so a the upper bound we avoid the overflow.
273 while (i
< (LTTNG_SYMBOL_NAME_LEN
- 1) && inputstr
[i
] != '\0') {
274 str
[i
] = toupper(inputstr
[i
]);
279 if (!strcmp(str
, "PYTHON_CRITICAL") || !strcmp(str
, "CRITICAL")) {
280 return LTTNG_LOGLEVEL_PYTHON_CRITICAL
;
281 } else if (!strcmp(str
, "PYTHON_ERROR") || !strcmp(str
, "ERROR")) {
282 return LTTNG_LOGLEVEL_PYTHON_ERROR
;
283 } else if (!strcmp(str
, "PYTHON_WARNING") || !strcmp(str
, "WARNING")) {
284 return LTTNG_LOGLEVEL_PYTHON_WARNING
;
285 } else if (!strcmp(str
, "PYTHON_INFO") || !strcmp(str
, "INFO")) {
286 return LTTNG_LOGLEVEL_PYTHON_INFO
;
287 } else if (!strcmp(str
, "PYTNON_DEBUG") || !strcmp(str
, "DEBUG")) {
288 return LTTNG_LOGLEVEL_PYTHON_DEBUG
;
289 } else if (!strcmp(str
, "PYTHON_NOTSET") || !strcmp(str
, "NOTSET")) {
290 return LTTNG_LOGLEVEL_PYTHON_NOTSET
;
297 * Maps loglevel from string to value
300 int loglevel_str_to_value(const char *inputstr
)
303 char str
[LTTNG_SYMBOL_NAME_LEN
];
305 if (!inputstr
|| strlen(inputstr
) == 0) {
310 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
311 * added at the end of the loop so a the upper bound we avoid the overflow.
313 while (i
< (LTTNG_SYMBOL_NAME_LEN
- 1) && inputstr
[i
] != '\0') {
314 str
[i
] = toupper(inputstr
[i
]);
318 if (!strcmp(str
, "TRACE_EMERG") || !strcmp(str
, "EMERG")) {
319 return LTTNG_LOGLEVEL_EMERG
;
320 } else if (!strcmp(str
, "TRACE_ALERT") || !strcmp(str
, "ALERT")) {
321 return LTTNG_LOGLEVEL_ALERT
;
322 } else if (!strcmp(str
, "TRACE_CRIT") || !strcmp(str
, "CRIT")) {
323 return LTTNG_LOGLEVEL_CRIT
;
324 } else if (!strcmp(str
, "TRACE_ERR") || !strcmp(str
, "ERR")) {
325 return LTTNG_LOGLEVEL_ERR
;
326 } else if (!strcmp(str
, "TRACE_WARNING") || !strcmp(str
, "WARNING")) {
327 return LTTNG_LOGLEVEL_WARNING
;
328 } else if (!strcmp(str
, "TRACE_NOTICE") || !strcmp(str
, "NOTICE")) {
329 return LTTNG_LOGLEVEL_NOTICE
;
330 } else if (!strcmp(str
, "TRACE_INFO") || !strcmp(str
, "INFO")) {
331 return LTTNG_LOGLEVEL_INFO
;
332 } else if (!strcmp(str
, "TRACE_DEBUG_SYSTEM") || !strcmp(str
, "DEBUG_SYSTEM") || !strcmp(str
, "SYSTEM")) {
333 return LTTNG_LOGLEVEL_DEBUG_SYSTEM
;
334 } else if (!strcmp(str
, "TRACE_DEBUG_PROGRAM") || !strcmp(str
, "DEBUG_PROGRAM") || !strcmp(str
, "PROGRAM")) {
335 return LTTNG_LOGLEVEL_DEBUG_PROGRAM
;
336 } else if (!strcmp(str
, "TRACE_DEBUG_PROCESS") || !strcmp(str
, "DEBUG_PROCESS") || !strcmp(str
, "PROCESS")) {
337 return LTTNG_LOGLEVEL_DEBUG_PROCESS
;
338 } else if (!strcmp(str
, "TRACE_DEBUG_MODULE") || !strcmp(str
, "DEBUG_MODULE") || !strcmp(str
, "MODULE")) {
339 return LTTNG_LOGLEVEL_DEBUG_MODULE
;
340 } else if (!strcmp(str
, "TRACE_DEBUG_UNIT") || !strcmp(str
, "DEBUG_UNIT") || !strcmp(str
, "UNIT")) {
341 return LTTNG_LOGLEVEL_DEBUG_UNIT
;
342 } else if (!strcmp(str
, "TRACE_DEBUG_FUNCTION") || !strcmp(str
, "DEBUG_FUNCTION") || !strcmp(str
, "FUNCTION")) {
343 return LTTNG_LOGLEVEL_DEBUG_FUNCTION
;
344 } else if (!strcmp(str
, "TRACE_DEBUG_LINE") || !strcmp(str
, "DEBUG_LINE") || !strcmp(str
, "LINE")) {
345 return LTTNG_LOGLEVEL_DEBUG_LINE
;
346 } else if (!strcmp(str
, "TRACE_DEBUG") || !strcmp(str
, "DEBUG")) {
347 return LTTNG_LOGLEVEL_DEBUG
;
354 const char *print_channel_name(const char *name
)
356 return name
? : DEFAULT_CHANNEL_NAME
;
360 const char *print_raw_channel_name(const char *name
)
362 return name
? : "<default>";
366 * Mi print exlcusion list
369 int mi_print_exclusion(int count
, char **names
)
379 ret
= mi_lttng_writer_open_element(writer
, config_element_exclusions
);
384 for (i
= 0; i
< count
; i
++) {
385 ret
= mi_lttng_writer_write_element_string(writer
,
386 config_element_exclusion
, names
[i
]);
392 /* Close exclusions element */
393 ret
= mi_lttng_writer_close_element(writer
);
400 * Return allocated string for pretty-printing exclusion names.
403 char *print_exclusions(int count
, char **names
)
407 const char *preamble
= " excluding ";
414 /* calculate total required length */
415 for (i
= 0; i
< count
; i
++) {
416 length
+= strlen(names
[i
]) + 1;
419 /* add length of preamble + one for NUL - one for last (missing) comma */
420 length
+= strlen(preamble
);
421 ret
= zmalloc(length
);
425 strncpy(ret
, preamble
, length
);
426 for (i
= 0; i
< count
; i
++) {
427 strcat(ret
, names
[i
]);
428 if (i
!= count
- 1) {
437 * Compare list of exclusions against an event name.
438 * Return a list of legal exclusion names.
439 * Produce an error or a warning about others (depending on the situation)
442 int check_exclusion_subsets(const char *event_name
,
443 const char *exclusions
,
444 int *exclusion_count_ptr
,
445 char ***exclusion_list_ptr
)
447 const char *excluder_ptr
;
448 const char *event_ptr
;
449 const char *next_excluder
;
451 int exclusion_count
= 0;
452 char **exclusion_list
= NULL
;
453 int ret
= CMD_SUCCESS
;
455 if (event_name
[strlen(event_name
) - 1] != '*') {
456 ERR("Event %s: Excluders can only be used with wildcarded events", event_name
);
460 next_excluder
= exclusions
;
461 while (*next_excluder
!= 0) {
462 event_ptr
= event_name
;
463 excluder_ptr
= next_excluder
;
464 excluder_length
= strcspn(next_excluder
, ",");
466 /* Scan both the excluder and the event letter by letter */
474 /* Event is a subset of the excluder */
475 ERR("Event %s: %.*s excludes all events from %s",
484 char **new_exclusion_list
;
486 /* Excluder is a proper subset of event */
487 string
= lttng_strndup(next_excluder
, excluder_length
);
489 PERROR("lttng_strndup error");
492 new_exclusion_list
= realloc(exclusion_list
,
493 sizeof(char *) * (exclusion_count
+ 1));
494 if (!new_exclusion_list
) {
499 exclusion_list
= new_exclusion_list
;
501 exclusion_list
[exclusion_count
- 1] = string
;
505 /* Excluder and event sets have no common elements */
506 WARN("Event %s: %.*s does not exclude any events from %s",
517 next_excluder
+= excluder_length
;
518 if (*next_excluder
== ',') {
524 while (exclusion_count
--) {
525 free(exclusion_list
[exclusion_count
]);
527 if (exclusion_list
!= NULL
) {
528 free(exclusion_list
);
530 exclusion_list
= NULL
;
534 *exclusion_count_ptr
= exclusion_count
;
535 *exclusion_list_ptr
= exclusion_list
;
539 static void warn_on_truncated_exclusion_names(char **exclusion_list
,
540 int exclusion_count
, int *warn
)
544 for (i
= 0; i
< exclusion_count
; ++i
) {
545 const char *name
= exclusion_list
[i
];
546 size_t len
= strlen(name
);
548 if (len
>= LTTNG_SYMBOL_NAME_LEN
) {
549 WARN("Event exclusion \"%s\" will be truncated",
557 * Enabling event using the lttng API.
558 * Note: in case of error only the last error code will be return.
560 static int enable_events(char *session_name
)
562 int ret
= CMD_SUCCESS
, command_ret
= CMD_SUCCESS
;
563 int error_holder
= CMD_SUCCESS
, warn
= 0, error
= 0, success
= 1;
564 char *event_name
, *channel_name
= NULL
;
565 struct lttng_event ev
;
566 struct lttng_domain dom
;
567 int exclusion_count
= 0;
568 char **exclusion_list
= NULL
;
570 memset(&ev
, 0, sizeof(ev
));
571 memset(&dom
, 0, sizeof(dom
));
575 WARN("Kernel loglevels are not supported.");
579 /* Create lttng domain */
581 dom
.type
= LTTNG_DOMAIN_KERNEL
;
582 dom
.buf_type
= LTTNG_BUFFER_GLOBAL
;
583 } else if (opt_userspace
) {
584 dom
.type
= LTTNG_DOMAIN_UST
;
586 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
587 } else if (opt_jul
) {
588 dom
.type
= LTTNG_DOMAIN_JUL
;
590 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
591 } else if (opt_log4j
) {
592 dom
.type
= LTTNG_DOMAIN_LOG4J
;
594 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
595 } else if (opt_python
) {
596 dom
.type
= LTTNG_DOMAIN_PYTHON
;
598 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
600 /* Checked by the caller. */
606 case LTTNG_DOMAIN_KERNEL
:
607 case LTTNG_DOMAIN_JUL
:
608 case LTTNG_DOMAIN_LOG4J
:
609 case LTTNG_DOMAIN_PYTHON
:
610 ERR("Event name exclusions are not yet implemented for %s events",
611 get_domain_str(dom
.type
));
614 case LTTNG_DOMAIN_UST
:
615 /* Exclusions supported */
622 channel_name
= opt_channel_name
;
624 handle
= lttng_create_handle(session_name
, &dom
);
625 if (handle
== NULL
) {
632 /* Open a events element */
633 ret
= mi_lttng_writer_open_element(writer
, config_element_events
);
640 if (opt_enable_all
) {
641 /* Default setup for enable all */
643 ev
.type
= opt_event_type
;
644 strcpy(ev
.name
, "*");
645 /* kernel loglevels not implemented */
646 ev
.loglevel_type
= LTTNG_EVENT_LOGLEVEL_ALL
;
648 ev
.type
= LTTNG_EVENT_TRACEPOINT
;
649 strcpy(ev
.name
, "*");
650 ev
.loglevel_type
= opt_loglevel_type
;
652 assert(opt_userspace
|| opt_jul
|| opt_log4j
|| opt_python
);
654 ev
.loglevel
= loglevel_str_to_value(opt_loglevel
);
655 } else if (opt_jul
) {
656 ev
.loglevel
= loglevel_jul_str_to_value(opt_loglevel
);
657 } else if (opt_log4j
) {
658 ev
.loglevel
= loglevel_log4j_str_to_value(opt_loglevel
);
659 } else if (opt_python
) {
660 ev
.loglevel
= loglevel_python_str_to_value(opt_loglevel
);
662 if (ev
.loglevel
== -1) {
663 ERR("Unknown loglevel %s", opt_loglevel
);
664 ret
= -LTTNG_ERR_INVALID
;
668 assert(opt_userspace
|| opt_jul
|| opt_log4j
|| opt_python
);
671 } else if (opt_jul
) {
672 ev
.loglevel
= LTTNG_LOGLEVEL_JUL_ALL
;
673 } else if (opt_log4j
) {
674 ev
.loglevel
= LTTNG_LOGLEVEL_LOG4J_ALL
;
675 } else if (opt_python
) {
676 ev
.loglevel
= LTTNG_LOGLEVEL_PYTHON_DEBUG
;
682 ret
= check_exclusion_subsets("*", opt_exclude
,
683 &exclusion_count
, &exclusion_list
);
684 if (ret
== CMD_ERROR
) {
689 warn_on_truncated_exclusion_names(exclusion_list
,
690 exclusion_count
, &warn
);
693 ret
= lttng_enable_event_with_exclusions(handle
,
696 exclusion_count
, exclusion_list
);
699 case LTTNG_ERR_KERN_EVENT_EXIST
:
700 WARN("Kernel events already enabled (channel %s, session %s)",
701 print_channel_name(channel_name
), session_name
);
704 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
706 const char *msg
= "The command tried to enable an event in a new domain for a session that has already been started once.";
707 ERR("Events: %s (channel %s, session %s)",
709 print_channel_name(channel_name
),
715 ERR("Events: %s (channel %s, session %s)",
717 ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
718 ? print_raw_channel_name(channel_name
)
719 : print_channel_name(channel_name
),
727 switch (opt_event_type
) {
728 case LTTNG_EVENT_TRACEPOINT
:
729 if (opt_loglevel
&& dom
.type
!= LTTNG_DOMAIN_KERNEL
) {
730 char *exclusion_string
= print_exclusions(exclusion_count
, exclusion_list
);
732 if (!exclusion_string
) {
733 PERROR("Cannot allocate exclusion_string");
737 MSG("All %s tracepoints%s are enabled in channel %s for loglevel %s",
738 get_domain_str(dom
.type
),
740 print_channel_name(channel_name
),
742 free(exclusion_string
);
744 char *exclusion_string
= print_exclusions(exclusion_count
, exclusion_list
);
746 if (!exclusion_string
) {
747 PERROR("Cannot allocate exclusion_string");
751 MSG("All %s tracepoints%s are enabled in channel %s",
752 get_domain_str(dom
.type
),
754 print_channel_name(channel_name
));
755 free(exclusion_string
);
758 case LTTNG_EVENT_SYSCALL
:
760 MSG("All %s system calls are enabled in channel %s",
761 get_domain_str(dom
.type
),
762 print_channel_name(channel_name
));
765 case LTTNG_EVENT_ALL
:
766 if (opt_loglevel
&& dom
.type
!= LTTNG_DOMAIN_KERNEL
) {
767 char *exclusion_string
= print_exclusions(exclusion_count
, exclusion_list
);
769 if (!exclusion_string
) {
770 PERROR("Cannot allocate exclusion_string");
774 MSG("All %s events%s are enabled in channel %s for loglevel %s",
775 get_domain_str(dom
.type
),
777 print_channel_name(channel_name
),
779 free(exclusion_string
);
781 char *exclusion_string
= print_exclusions(exclusion_count
, exclusion_list
);
783 if (!exclusion_string
) {
784 PERROR("Cannot allocate exclusion_string");
788 MSG("All %s events%s are enabled in channel %s",
789 get_domain_str(dom
.type
),
791 print_channel_name(channel_name
));
792 free(exclusion_string
);
797 * We should not be here since lttng_enable_event should have
798 * failed on the event type.
805 command_ret
= lttng_enable_event_with_exclusions(handle
, &ev
, channel_name
,
806 opt_filter
, exclusion_count
, exclusion_list
);
807 if (command_ret
< 0) {
808 switch (-command_ret
) {
809 case LTTNG_ERR_FILTER_EXIST
:
810 WARN("Filter on all events is already enabled"
811 " (channel %s, session %s)",
812 print_channel_name(channel_name
), session_name
);
815 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
817 const char *msg
= "The command tried to enable an event in a new domain for a session that has already been started once.";
818 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
820 print_channel_name(channel_name
),
821 session_name
, opt_filter
);
826 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
827 lttng_strerror(command_ret
),
828 command_ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
829 ? print_raw_channel_name(channel_name
)
830 : print_channel_name(channel_name
),
831 session_name
, opt_filter
);
835 error_holder
= command_ret
;
838 MSG("Filter '%s' successfully set", opt_filter
);
843 /* The wildcard * is used for kernel and ust domain to
844 * represent ALL. We copy * in event name to force the wildcard use
847 * Note: this is strictly for semantic and printing while in
848 * machine interface mode.
850 strcpy(ev
.name
, "*");
852 /* If we reach here the events are enabled */
853 if (!error
&& !warn
) {
859 ret
= mi_lttng_event(writer
, &ev
, 1, handle
->domain
.type
);
865 /* print exclusion */
866 ret
= mi_print_exclusion(exclusion_count
, exclusion_list
);
873 ret
= mi_lttng_writer_write_element_bool(writer
,
874 mi_lttng_element_command_success
, success
);
880 /* Close event element */
881 ret
= mi_lttng_writer_close_element(writer
);
891 /* Strip event list */
892 event_name
= strtok(opt_event_list
, ",");
893 while (event_name
!= NULL
) {
894 /* Copy name and type of the event */
895 strncpy(ev
.name
, event_name
, LTTNG_SYMBOL_NAME_LEN
);
896 ev
.name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
897 ev
.type
= opt_event_type
;
899 /* Kernel tracer action */
901 DBG("Enabling kernel event %s for channel %s",
903 print_channel_name(channel_name
));
905 switch (opt_event_type
) {
906 case LTTNG_EVENT_ALL
: /* Enable tracepoints and syscalls */
907 /* If event name differs from *, select tracepoint. */
908 if (strcmp(ev
.name
, "*")) {
909 ev
.type
= LTTNG_EVENT_TRACEPOINT
;
912 case LTTNG_EVENT_TRACEPOINT
:
914 case LTTNG_EVENT_PROBE
:
915 ret
= parse_probe_opts(&ev
, opt_probe
);
917 ERR("Unable to parse probe options");
922 case LTTNG_EVENT_FUNCTION
:
923 ret
= parse_probe_opts(&ev
, opt_function
);
925 ERR("Unable to parse function probe options");
930 case LTTNG_EVENT_SYSCALL
:
931 ev
.type
= LTTNG_EVENT_SYSCALL
;
938 /* kernel loglevels not implemented */
939 ev
.loglevel_type
= LTTNG_EVENT_LOGLEVEL_ALL
;
940 } else if (opt_userspace
) { /* User-space tracer action */
941 DBG("Enabling UST event %s for channel %s, loglevel %s", event_name
,
942 print_channel_name(channel_name
), opt_loglevel
? : "<all>");
944 switch (opt_event_type
) {
945 case LTTNG_EVENT_ALL
: /* Default behavior is tracepoint */
947 case LTTNG_EVENT_TRACEPOINT
:
948 /* Copy name and type of the event */
949 ev
.type
= LTTNG_EVENT_TRACEPOINT
;
950 strncpy(ev
.name
, event_name
, LTTNG_SYMBOL_NAME_LEN
);
951 ev
.name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
953 case LTTNG_EVENT_PROBE
:
954 case LTTNG_EVENT_FUNCTION
:
955 case LTTNG_EVENT_SYSCALL
:
957 ERR("Event type not available for user-space tracing");
958 ret
= CMD_UNSUPPORTED
;
964 if (opt_event_type
!= LTTNG_EVENT_ALL
&& opt_event_type
!= LTTNG_EVENT_TRACEPOINT
) {
965 ERR("Exclusion option can only be used with tracepoint events");
969 /* Free previously allocated items */
970 if (exclusion_list
!= NULL
) {
971 while (exclusion_count
--) {
972 free(exclusion_list
[exclusion_count
]);
974 free(exclusion_list
);
975 exclusion_list
= NULL
;
977 /* Check for proper subsets */
978 ret
= check_exclusion_subsets(event_name
, opt_exclude
,
979 &exclusion_count
, &exclusion_list
);
980 if (ret
== CMD_ERROR
) {
984 warn_on_truncated_exclusion_names(
985 exclusion_list
, exclusion_count
, &warn
);
988 ev
.loglevel_type
= opt_loglevel_type
;
990 ev
.loglevel
= loglevel_str_to_value(opt_loglevel
);
991 if (ev
.loglevel
== -1) {
992 ERR("Unknown loglevel %s", opt_loglevel
);
993 ret
= -LTTNG_ERR_INVALID
;
999 } else if (opt_jul
|| opt_log4j
|| opt_python
) {
1000 if (opt_event_type
!= LTTNG_EVENT_ALL
&&
1001 opt_event_type
!= LTTNG_EVENT_TRACEPOINT
) {
1002 ERR("Event type not supported for domain.");
1003 ret
= CMD_UNSUPPORTED
;
1007 ev
.loglevel_type
= opt_loglevel_type
;
1010 ev
.loglevel
= loglevel_jul_str_to_value(opt_loglevel
);
1011 } else if (opt_log4j
) {
1012 ev
.loglevel
= loglevel_log4j_str_to_value(opt_loglevel
);
1013 } else if (opt_python
) {
1014 ev
.loglevel
= loglevel_python_str_to_value(opt_loglevel
);
1016 if (ev
.loglevel
== -1) {
1017 ERR("Unknown loglevel %s", opt_loglevel
);
1018 ret
= -LTTNG_ERR_INVALID
;
1023 ev
.loglevel
= LTTNG_LOGLEVEL_JUL_ALL
;
1024 } else if (opt_log4j
) {
1025 ev
.loglevel
= LTTNG_LOGLEVEL_LOG4J_ALL
;
1026 } else if (opt_python
) {
1027 ev
.loglevel
= LTTNG_LOGLEVEL_PYTHON_DEBUG
;
1030 ev
.type
= LTTNG_EVENT_TRACEPOINT
;
1031 strncpy(ev
.name
, event_name
, LTTNG_SYMBOL_NAME_LEN
);
1032 ev
.name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
1038 char *exclusion_string
;
1040 command_ret
= lttng_enable_event_with_exclusions(handle
,
1042 NULL
, exclusion_count
, exclusion_list
);
1043 exclusion_string
= print_exclusions(exclusion_count
, exclusion_list
);
1044 if (!exclusion_string
) {
1045 PERROR("Cannot allocate exclusion_string");
1049 if (command_ret
< 0) {
1050 /* Turn ret to positive value to handle the positive error code */
1051 switch (-command_ret
) {
1052 case LTTNG_ERR_KERN_EVENT_EXIST
:
1053 WARN("Kernel event %s%s already enabled (channel %s, session %s)",
1056 print_channel_name(channel_name
), session_name
);
1059 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
1061 const char *msg
= "The command tried to enable an event in a new domain for a session that has already been started once.";
1062 ERR("Event %s%s: %s (channel %s, session %s)", event_name
,
1065 print_channel_name(channel_name
),
1071 ERR("Event %s%s: %s (channel %s, session %s)", event_name
,
1073 lttng_strerror(command_ret
),
1074 command_ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
1075 ? print_raw_channel_name(channel_name
)
1076 : print_channel_name(channel_name
),
1081 error_holder
= command_ret
;
1084 case LTTNG_DOMAIN_KERNEL
:
1085 case LTTNG_DOMAIN_UST
:
1086 MSG("%s event %s%s created in channel %s",
1087 get_domain_str(dom
.type
),
1090 print_channel_name(channel_name
));
1092 case LTTNG_DOMAIN_JUL
:
1093 case LTTNG_DOMAIN_LOG4J
:
1094 case LTTNG_DOMAIN_PYTHON
:
1096 * Don't print the default channel
1097 * name for agent domains.
1099 MSG("%s event %s%s enabled",
1100 get_domain_str(dom
.type
),
1108 free(exclusion_string
);
1112 char *exclusion_string
;
1114 /* Filter present */
1117 command_ret
= lttng_enable_event_with_exclusions(handle
, &ev
, channel_name
,
1118 opt_filter
, exclusion_count
, exclusion_list
);
1119 exclusion_string
= print_exclusions(exclusion_count
, exclusion_list
);
1120 if (!exclusion_string
) {
1121 PERROR("Cannot allocate exclusion_string");
1125 if (command_ret
< 0) {
1126 switch (-command_ret
) {
1127 case LTTNG_ERR_FILTER_EXIST
:
1128 WARN("Filter on event %s%s is already enabled"
1129 " (channel %s, session %s)",
1132 print_channel_name(channel_name
), session_name
);
1135 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
1137 const char *msg
= "The command tried to enable an event in a new domain for a session that has already been started once.";
1138 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev
.name
,
1141 print_channel_name(channel_name
),
1142 session_name
, opt_filter
);
1147 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev
.name
,
1149 lttng_strerror(command_ret
),
1150 command_ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
1151 ? print_raw_channel_name(channel_name
)
1152 : print_channel_name(channel_name
),
1153 session_name
, opt_filter
);
1157 error_holder
= command_ret
;
1160 MSG("Event %s%s: Filter '%s' successfully set",
1161 event_name
, exclusion_string
,
1164 free(exclusion_string
);
1175 ret
= mi_lttng_event(writer
, &ev
, 1, handle
->domain
.type
);
1181 /* print exclusion */
1182 ret
= mi_print_exclusion(exclusion_count
, exclusion_list
);
1189 ret
= mi_lttng_writer_write_element_bool(writer
,
1190 mi_lttng_element_command_success
, success
);
1196 /* Close event element */
1197 ret
= mi_lttng_writer_close_element(writer
);
1205 event_name
= strtok(NULL
, ",");
1206 /* Reset warn, error and success */
1213 /* Close events element */
1214 ret
= mi_lttng_writer_close_element(writer
);
1227 lttng_destroy_handle(handle
);
1229 if (exclusion_list
!= NULL
) {
1230 while (exclusion_count
--) {
1231 free(exclusion_list
[exclusion_count
]);
1233 free(exclusion_list
);
1236 /* Overwrite ret with error_holder if there was an actual error with
1237 * enabling an event.
1239 ret
= error_holder
? error_holder
: ret
;
1245 * Add event to trace session
1247 int cmd_enable_events(int argc
, const char **argv
)
1249 int opt
, ret
= CMD_SUCCESS
, command_ret
= CMD_SUCCESS
, success
= 1;
1250 static poptContext pc
;
1251 char *session_name
= NULL
;
1252 int event_type
= -1;
1254 pc
= poptGetContext(NULL
, argc
, argv
, long_options
, 0);
1255 poptReadDefaultConfig(pc
, 0);
1257 /* Default event type */
1258 opt_event_type
= LTTNG_EVENT_ALL
;
1260 while ((opt
= poptGetNextOpt(pc
)) != -1) {
1265 case OPT_TRACEPOINT
:
1266 opt_event_type
= LTTNG_EVENT_TRACEPOINT
;
1269 opt_event_type
= LTTNG_EVENT_PROBE
;
1272 opt_event_type
= LTTNG_EVENT_FUNCTION
;
1275 opt_event_type
= LTTNG_EVENT_SYSCALL
;
1281 opt_loglevel_type
= LTTNG_EVENT_LOGLEVEL_RANGE
;
1282 opt_loglevel
= poptGetOptArg(pc
);
1284 case OPT_LOGLEVEL_ONLY
:
1285 opt_loglevel_type
= LTTNG_EVENT_LOGLEVEL_SINGLE
;
1286 opt_loglevel
= poptGetOptArg(pc
);
1288 case OPT_LIST_OPTIONS
:
1289 list_cmd_options(stdout
, long_options
);
1296 ret
= CMD_UNDEFINED
;
1300 /* Validate event type. Multiple event type are not supported. */
1301 if (event_type
== -1) {
1302 event_type
= opt_event_type
;
1304 if (event_type
!= opt_event_type
) {
1305 ERR("Multiple event type not supported.");
1312 ret
= print_missing_or_multiple_domains(
1313 opt_kernel
+ opt_userspace
+ opt_jul
+ opt_log4j
+ opt_python
);
1321 writer
= mi_lttng_writer_create(fileno(stdout
), lttng_opt_mi
);
1323 ret
= -LTTNG_ERR_NOMEM
;
1327 /* Open command element */
1328 ret
= mi_lttng_writer_command_open(writer
,
1329 mi_lttng_element_command_enable_event
);
1335 /* Open output element */
1336 ret
= mi_lttng_writer_open_element(writer
,
1337 mi_lttng_element_command_output
);
1344 opt_event_list
= (char*) poptGetArg(pc
);
1345 if (opt_event_list
== NULL
&& opt_enable_all
== 0) {
1346 ERR("Missing event name(s).\n");
1351 if (!opt_session_name
) {
1352 session_name
= get_session_name();
1353 if (session_name
== NULL
) {
1354 command_ret
= CMD_ERROR
;
1359 session_name
= opt_session_name
;
1362 command_ret
= enable_events(session_name
);
1371 /* Close output element */
1372 ret
= mi_lttng_writer_close_element(writer
);
1378 ret
= mi_lttng_writer_write_element_bool(writer
,
1379 mi_lttng_element_command_success
, success
);
1385 /* Command element close */
1386 ret
= mi_lttng_writer_command_close(writer
);
1395 if (writer
&& mi_lttng_writer_destroy(writer
)) {
1396 /* Preserve original error code */
1397 ret
= ret
? ret
: LTTNG_ERR_MI_IO_FAIL
;
1400 if (opt_session_name
== NULL
) {
1404 /* Overwrite ret if an error occurred in enable_events */
1405 ret
= command_ret
? command_ret
: ret
;
1407 poptFreeContext(pc
);