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 char *opt_loglevel
;
44 static int opt_loglevel_type
;
45 static int opt_kernel
;
46 static char *opt_session_name
;
47 static int opt_domain
;
48 static int opt_enable_all
;
49 static char *opt_probe
;
50 static char *opt_function
;
51 static char *opt_channel_name
;
52 static char *opt_filter
;
53 static char *opt_exclude
;
68 static struct lttng_handle
*handle
;
69 static struct mi_writer
*writer
;
71 static struct poptOption long_options
[] = {
72 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
73 {"all", 'a', POPT_ARG_VAL
, &opt_enable_all
, 1, 0, 0},
74 {"channel", 'c', POPT_ARG_STRING
, &opt_channel_name
, 0, 0, 0},
75 {"kernel", 'k', POPT_ARG_VAL
, &opt_domain
, LTTNG_DOMAIN_KERNEL
, 0, 0},
76 {"userspace", 'u', POPT_ARG_VAL
, &opt_domain
, LTTNG_DOMAIN_UST
, 0, 0},
77 {"jul", 'j', POPT_ARG_VAL
, &opt_domain
, LTTNG_DOMAIN_JUL
, 0, 0},
78 {"log4j", 'l', POPT_ARG_VAL
, &opt_domain
, LTTNG_DOMAIN_LOG4J
, 0, 0},
79 {"python", 'p', POPT_ARG_VAL
, &opt_domain
, LTTNG_DOMAIN_PYTHON
, 0, 0},
80 {"tracepoint", 0, POPT_ARG_NONE
, 0, OPT_TRACEPOINT
, 0, 0},
81 {"probe", 0, POPT_ARG_STRING
, &opt_probe
, OPT_PROBE
, 0, 0},
82 {"function", 0, POPT_ARG_STRING
, &opt_function
, OPT_FUNCTION
, 0, 0},
83 {"syscall", 0, POPT_ARG_NONE
, 0, OPT_SYSCALL
, 0, 0},
84 {"loglevel", 0, POPT_ARG_STRING
, 0, OPT_LOGLEVEL
, 0, 0},
85 {"loglevel-only", 0, POPT_ARG_STRING
, 0, OPT_LOGLEVEL_ONLY
, 0, 0},
86 {"filter", 'f', POPT_ARG_STRING
, &opt_filter
, OPT_FILTER
, 0, 0},
87 {"exclude", 'x', POPT_ARG_STRING
, &opt_exclude
, OPT_EXCLUDE
, 0, 0},
88 {"session", 's', POPT_ARG_NONE
, 0, 0, 0, 0},
92 static struct poptOption global_long_options
[] = {
93 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
94 {"help", 'h', POPT_ARG_NONE
, 0, OPT_HELP
, 0, 0},
95 {"session", 's', POPT_ARG_STRING
, &opt_session_name
, 0, 0, 0},
96 {"list-options", 0, POPT_ARG_NONE
, NULL
, OPT_LIST_OPTIONS
, NULL
, NULL
},
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_ust_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 * Map a userspace agent loglevel to it's value based on the domain type.
357 * Assert when loglevel is NULL and domain type is LTTNG_DOMAIN_NONE ||
358 * LTTNG_DOMAIN_KERNEL.
360 * return -1 on invalid loglevel.
362 static int loglevel_str_to_value(const char* loglevel
, enum lttng_domain_type type
)
366 case LTTNG_DOMAIN_UST
:
367 ret
= loglevel_ust_str_to_value(loglevel
);
369 case LTTNG_DOMAIN_JUL
:
370 ret
= loglevel_jul_str_to_value(loglevel
);
372 case LTTNG_DOMAIN_LOG4J
:
373 ret
= loglevel_log4j_str_to_value(loglevel
);
375 case LTTNG_DOMAIN_PYTHON
:
376 ret
= loglevel_python_str_to_value(loglevel
);
386 const char *print_channel_name(const char *name
)
388 return name
? : DEFAULT_CHANNEL_NAME
;
392 const char *print_raw_channel_name(const char *name
)
394 return name
? : "<default>";
398 * Mi print exlcusion list
401 int mi_print_exclusion(int count
, char **names
)
411 ret
= mi_lttng_writer_open_element(writer
, config_element_exclusions
);
416 for (i
= 0; i
< count
; i
++) {
417 ret
= mi_lttng_writer_write_element_string(writer
,
418 config_element_exclusion
, names
[i
]);
424 /* Close exclusions element */
425 ret
= mi_lttng_writer_close_element(writer
);
432 * Return allocated string for pretty-printing exclusion names.
435 char *print_exclusions(int count
, char **names
)
439 const char *preamble
= " excluding ";
446 /* calculate total required length */
447 for (i
= 0; i
< count
; i
++) {
448 length
+= strlen(names
[i
]) + 1;
451 /* add length of preamble + one for NUL - one for last (missing) comma */
452 length
+= strlen(preamble
);
453 ret
= zmalloc(length
);
457 strncpy(ret
, preamble
, length
);
458 for (i
= 0; i
< count
; i
++) {
459 strcat(ret
, names
[i
]);
460 if (i
!= count
- 1) {
469 * Compare list of exclusions against an event name.
470 * Return a list of legal exclusion names.
471 * Produce an error or a warning about others (depending on the situation)
474 int check_exclusion_subsets(const char *event_name
,
475 const char *exclusions
,
476 int *exclusion_count_ptr
,
477 char ***exclusion_list_ptr
)
479 const char *excluder_ptr
;
480 const char *event_ptr
;
481 const char *next_excluder
;
483 int exclusion_count
= 0;
484 char **exclusion_list
= NULL
;
485 int ret
= CMD_SUCCESS
;
487 if (event_name
[strlen(event_name
) - 1] != '*') {
488 ERR("Event %s: Excluders can only be used with wildcarded events", event_name
);
492 next_excluder
= exclusions
;
493 while (*next_excluder
!= 0) {
494 event_ptr
= event_name
;
495 excluder_ptr
= next_excluder
;
496 excluder_length
= strcspn(next_excluder
, ",");
498 /* Scan both the excluder and the event letter by letter */
506 /* Event is a subset of the excluder */
507 ERR("Event %s: %.*s excludes all events from %s",
516 char **new_exclusion_list
;
518 /* Excluder is a proper subset of event */
519 string
= lttng_strndup(next_excluder
, excluder_length
);
521 PERROR("lttng_strndup error");
524 new_exclusion_list
= realloc(exclusion_list
,
525 sizeof(char *) * (exclusion_count
+ 1));
526 if (!new_exclusion_list
) {
531 exclusion_list
= new_exclusion_list
;
533 exclusion_list
[exclusion_count
- 1] = string
;
537 /* Excluder and event sets have no common elements */
538 WARN("Event %s: %.*s does not exclude any events from %s",
549 next_excluder
+= excluder_length
;
550 if (*next_excluder
== ',') {
556 while (exclusion_count
--) {
557 free(exclusion_list
[exclusion_count
]);
559 if (exclusion_list
!= NULL
) {
560 free(exclusion_list
);
562 exclusion_list
= NULL
;
566 *exclusion_count_ptr
= exclusion_count
;
567 *exclusion_list_ptr
= exclusion_list
;
571 static void warn_on_truncated_exclusion_names(char **exclusion_list
,
572 int exclusion_count
, int *warn
)
576 for (i
= 0; i
< exclusion_count
; ++i
) {
577 const char *name
= exclusion_list
[i
];
578 size_t len
= strlen(name
);
580 if (len
>= LTTNG_SYMBOL_NAME_LEN
) {
581 WARN("Event exclusion \"%s\" will be truncated",
588 struct domain_configuration
{
594 enum lttng_domain_type domain_type
;
603 * Enabling event using the lttng API.
604 * Note: in case of error only the last error code will be return.
606 static int enable_events(char *session_name
, struct domain_configuration
*config
)
608 int ret
= CMD_SUCCESS
, command_ret
= CMD_SUCCESS
;
609 int error_holder
= CMD_SUCCESS
, warn
= 0, error
= 0, success
= 1;
610 char *event_name
, *channel_name
= NULL
;
611 struct lttng_event ev
;
612 struct lttng_domain dom
;
613 int exclusion_count
= 0;
614 char **exclusion_list
= NULL
;
616 int config_enable_all
;
617 int config_event_type
;
618 char *config_event_list
;
619 char *config_loglevel
;
620 int config_loglevel_type
;
621 enum lttng_domain_type config_domain_type
;
623 char *config_function
;
624 char *config_channel_name
;
626 char *config_exclude
;
630 memset(&ev
, 0, sizeof(ev
));
631 memset(&dom
, 0, sizeof(dom
));
633 config_enable_all
= config
->enable_all
;
634 config_event_type
= config
->event_type
;
635 config_event_list
= config
->event_list
;
636 config_loglevel
= config
->loglevel
;
637 config_loglevel_type
= config
->loglevel_type
;
638 config_domain_type
= config
->domain_type
;
639 config_probe
= config
->probe
;
640 config_function
= config
->function
;
641 config_channel_name
= config
->channel_name
;
642 config_filter
= config
->filter
;
643 config_exclude
= config
->exclude
;
645 if (config_domain_type
== LTTNG_DOMAIN_KERNEL
) {
646 if (config_loglevel
) {
647 WARN("Kernel loglevels are not supported.");
651 /* Create lttng domain */
652 dom
.type
= config_domain_type
;
653 switch (config_domain_type
) {
654 case LTTNG_DOMAIN_KERNEL
:
655 dom
.buf_type
= LTTNG_BUFFER_GLOBAL
;
657 case LTTNG_DOMAIN_UST
:
658 case LTTNG_DOMAIN_JUL
:
659 case LTTNG_DOMAIN_LOG4J
:
660 case LTTNG_DOMAIN_PYTHON
:
661 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
663 case LTTNG_DOMAIN_NONE
:
669 if (config_exclude
) {
671 case LTTNG_DOMAIN_KERNEL
:
672 case LTTNG_DOMAIN_JUL
:
673 case LTTNG_DOMAIN_LOG4J
:
674 case LTTNG_DOMAIN_PYTHON
:
675 ERR("Event name exclusions are not yet implemented for %s events",
676 get_domain_str(dom
.type
));
679 case LTTNG_DOMAIN_UST
:
680 /* Exclusions supported */
687 channel_name
= config_channel_name
;
689 handle
= lttng_create_handle(session_name
, &dom
);
690 if (handle
== NULL
) {
697 /* Open a domain element */
698 ret
= mi_lttng_writer_open_element(writer
, config_element_domain
);
704 /* Specify the domain type */
705 ret
= mi_lttng_writer_write_element_string(writer
,
707 mi_lttng_domaintype_string(config_domain_type
));
713 /* Open a events element */
714 ret
= mi_lttng_writer_open_element(writer
, config_element_events
);
721 if (config_enable_all
) {
722 /* Default setup for enable all */
723 if (config_domain_type
== LTTNG_DOMAIN_KERNEL
) {
724 ev
.type
= config_event_type
;
725 strcpy(ev
.name
, "*");
726 /* kernel loglevels not implemented */
727 ev
.loglevel_type
= LTTNG_EVENT_LOGLEVEL_ALL
;
729 ev
.type
= LTTNG_EVENT_TRACEPOINT
;
730 strcpy(ev
.name
, "*");
731 ev
.loglevel_type
= config_loglevel_type
;
732 if (config_loglevel
) {
733 ev
.loglevel
= loglevel_str_to_value(config_loglevel
, config_domain_type
);
734 if (ev
.loglevel
== -1) {
735 ERR("Unknown loglevel %s", config_loglevel
);
736 ret
= -LTTNG_ERR_INVALID
;
740 assert(config_domain_type
!= LTTNG_DOMAIN_NONE
|| config_domain_type
!= LTTNG_DOMAIN_KERNEL
);
741 switch (config_domain_type
) {
742 case LTTNG_DOMAIN_UST
:
745 case LTTNG_DOMAIN_JUL
:
746 ev
.loglevel
= LTTNG_LOGLEVEL_JUL_ALL
;
748 case LTTNG_DOMAIN_LOG4J
:
749 ev
.loglevel
= LTTNG_LOGLEVEL_LOG4J_ALL
;
751 case LTTNG_DOMAIN_PYTHON
:
752 ev
.loglevel
= LTTNG_LOGLEVEL_PYTHON_DEBUG
;
760 if (config_exclude
) {
761 ret
= check_exclusion_subsets("*", config_exclude
,
762 &exclusion_count
, &exclusion_list
);
763 if (ret
== CMD_ERROR
) {
768 warn_on_truncated_exclusion_names(exclusion_list
,
769 exclusion_count
, &warn
);
771 if (!config_filter
) {
772 ret
= lttng_enable_event_with_exclusions(handle
,
775 exclusion_count
, exclusion_list
);
778 case LTTNG_ERR_KERN_EVENT_EXIST
:
779 WARN("Kernel events already enabled (channel %s, session %s)",
780 print_channel_name(channel_name
), session_name
);
783 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
785 const char *msg
= "The command tried to enable an event in a new domain for a session that has already been started once.";
786 ERR("Events: %s (domain %s, channel %s, session %s)",
788 get_domain_str(dom
.type
),
789 print_channel_name(channel_name
),
795 ERR("Events: %s (domain %s, channel %s, session %s)",
797 get_domain_str(dom
.type
),
798 ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
799 ? print_raw_channel_name(channel_name
)
800 : print_channel_name(channel_name
),
808 switch (config_event_type
) {
809 case LTTNG_EVENT_TRACEPOINT
:
810 if (config_loglevel
&& dom
.type
!= LTTNG_DOMAIN_KERNEL
) {
811 char *exclusion_string
= print_exclusions(exclusion_count
, exclusion_list
);
813 if (!exclusion_string
) {
814 PERROR("Cannot allocate exclusion_string");
818 MSG("All %s tracepoints%s are enabled in channel %s for loglevel %s",
819 get_domain_str(dom
.type
),
821 print_channel_name(channel_name
),
823 free(exclusion_string
);
825 char *exclusion_string
= print_exclusions(exclusion_count
, exclusion_list
);
827 if (!exclusion_string
) {
828 PERROR("Cannot allocate exclusion_string");
832 MSG("All %s tracepoints%s are enabled in channel %s",
833 get_domain_str(dom
.type
),
835 print_channel_name(channel_name
));
836 free(exclusion_string
);
839 case LTTNG_EVENT_SYSCALL
:
841 MSG("All %s system calls are enabled in channel %s",
842 get_domain_str(dom
.type
),
843 print_channel_name(channel_name
));
846 case LTTNG_EVENT_ALL
:
847 if (config_loglevel
&& dom
.type
!= LTTNG_DOMAIN_KERNEL
) {
848 char *exclusion_string
= print_exclusions(exclusion_count
, exclusion_list
);
850 if (!exclusion_string
) {
851 PERROR("Cannot allocate exclusion_string");
855 MSG("All %s events%s are enabled in channel %s for loglevel %s",
856 get_domain_str(dom
.type
),
858 print_channel_name(channel_name
),
860 free(exclusion_string
);
862 char *exclusion_string
= print_exclusions(exclusion_count
, exclusion_list
);
864 if (!exclusion_string
) {
865 PERROR("Cannot allocate exclusion_string");
869 MSG("All %s events%s are enabled in channel %s",
870 get_domain_str(dom
.type
),
872 print_channel_name(channel_name
));
873 free(exclusion_string
);
878 * We should not be here since lttng_enable_event should have
879 * failed on the event type.
886 command_ret
= lttng_enable_event_with_exclusions(handle
, &ev
, channel_name
,
887 config_filter
, exclusion_count
, exclusion_list
);
888 if (command_ret
< 0) {
889 switch (-command_ret
) {
890 case LTTNG_ERR_FILTER_EXIST
:
891 WARN("Filter on all events is already enabled"
892 " (domain %s, channel %s, session %s)",
893 get_domain_str(dom
.type
),
894 print_channel_name(channel_name
), session_name
);
897 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
899 const char *msg
= "The command tried to enable an event in a new domain for a session that has already been started once.";
900 ERR("All events: %s (domain %s, channel %s, session %s, filter \'%s\')",
902 get_domain_str(dom
.type
),
903 print_channel_name(channel_name
),
904 session_name
, config_filter
);
909 ERR("All events: %s (domain %s, channel %s, session %s, filter \'%s\')",
910 lttng_strerror(command_ret
),
911 get_domain_str(dom
.type
),
912 command_ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
913 ? print_raw_channel_name(channel_name
)
914 : print_channel_name(channel_name
),
915 session_name
, config_filter
);
919 error_holder
= command_ret
;
922 MSG("Filter '%s' successfully set", config_filter
);
927 /* The wildcard * is used for kernel and ust domain to
928 * represent ALL. We copy * in event name to force the wildcard use
931 * Note: this is strictly for semantic and printing while in
932 * machine interface mode.
934 strcpy(ev
.name
, "*");
936 /* If we reach here the events are enabled */
937 if (!error
&& !warn
) {
943 ret
= mi_lttng_event(writer
, &ev
, 1, handle
->domain
.type
);
949 /* print exclusion */
950 ret
= mi_print_exclusion(exclusion_count
, exclusion_list
);
957 ret
= mi_lttng_writer_write_element_bool(writer
,
958 mi_lttng_element_command_success
, success
);
964 /* Close event element */
965 ret
= mi_lttng_writer_close_element(writer
);
975 /* Strip event list */
976 event_name
= strtok(config_event_list
, ",");
977 while (event_name
!= NULL
) {
978 /* Copy name and type of the event */
979 strncpy(ev
.name
, event_name
, LTTNG_SYMBOL_NAME_LEN
);
980 ev
.name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
981 ev
.type
= config_event_type
;
983 /* Kernel tracer action */
984 switch (config_domain_type
) {
985 case LTTNG_DOMAIN_KERNEL
:
986 DBG("Enabling kernel event %s for channel %s",
988 print_channel_name(channel_name
));
990 switch (config_event_type
) {
991 case LTTNG_EVENT_ALL
: /* Enable tracepoints and syscalls */
992 /* If event name differs from *, select tracepoint. */
993 if (strcmp(ev
.name
, "*")) {
994 ev
.type
= LTTNG_EVENT_TRACEPOINT
;
997 case LTTNG_EVENT_TRACEPOINT
:
999 case LTTNG_EVENT_PROBE
:
1000 ret
= parse_probe_opts(&ev
, config_probe
);
1002 ERR("Unable to parse probe options");
1007 case LTTNG_EVENT_FUNCTION
:
1008 ret
= parse_probe_opts(&ev
, config_function
);
1010 ERR("Unable to parse function probe options");
1015 case LTTNG_EVENT_SYSCALL
:
1016 ev
.type
= LTTNG_EVENT_SYSCALL
;
1019 ret
= CMD_UNDEFINED
;
1023 /* kernel loglevels not implemented */
1024 ev
.loglevel_type
= LTTNG_EVENT_LOGLEVEL_ALL
;
1026 case LTTNG_DOMAIN_UST
:
1027 /* User-space tracer action */
1028 DBG("Enabling UST event %s for channel %s, loglevel %s", event_name
,
1029 print_channel_name(channel_name
), config_loglevel
? : "<all>");
1031 switch (config_event_type
) {
1032 case LTTNG_EVENT_ALL
: /* Default behavior is tracepoint */
1034 case LTTNG_EVENT_TRACEPOINT
:
1035 /* Copy name and type of the event */
1036 ev
.type
= LTTNG_EVENT_TRACEPOINT
;
1037 strncpy(ev
.name
, event_name
, LTTNG_SYMBOL_NAME_LEN
);
1038 ev
.name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
1040 case LTTNG_EVENT_PROBE
:
1041 case LTTNG_EVENT_FUNCTION
:
1042 case LTTNG_EVENT_SYSCALL
:
1044 ERR("Event type not available for user-space tracing");
1045 ret
= CMD_UNSUPPORTED
;
1049 if (config_exclude
) {
1051 if (config_event_type
!= LTTNG_EVENT_ALL
&& config_event_type
!= LTTNG_EVENT_TRACEPOINT
) {
1052 ERR("Exclusion option can only be used with tracepoint events");
1056 /* Free previously allocated items */
1057 if (exclusion_list
!= NULL
) {
1058 while (exclusion_count
--) {
1059 free(exclusion_list
[exclusion_count
]);
1061 free(exclusion_list
);
1062 exclusion_list
= NULL
;
1064 /* Check for proper subsets */
1065 ret
= check_exclusion_subsets(event_name
, config_exclude
,
1066 &exclusion_count
, &exclusion_list
);
1067 if (ret
== CMD_ERROR
) {
1071 warn_on_truncated_exclusion_names(
1072 exclusion_list
, exclusion_count
, &warn
);
1075 ev
.loglevel_type
= config_loglevel_type
;
1076 if (config_loglevel
) {
1077 ev
.loglevel
= loglevel_ust_str_to_value(config_loglevel
);
1078 if (ev
.loglevel
== -1) {
1079 ERR("Unknown loglevel %s", config_loglevel
);
1080 ret
= -LTTNG_ERR_INVALID
;
1087 case LTTNG_DOMAIN_JUL
:
1088 case LTTNG_DOMAIN_LOG4J
:
1089 case LTTNG_DOMAIN_PYTHON
:
1090 if (config_event_type
!= LTTNG_EVENT_ALL
&&
1091 config_event_type
!= LTTNG_EVENT_TRACEPOINT
) {
1092 ERR("Event type not supported for domain.");
1093 ret
= CMD_UNSUPPORTED
;
1097 ev
.loglevel_type
= config_loglevel_type
;
1098 if (config_loglevel
) {
1099 ev
.loglevel
= loglevel_str_to_value(config_loglevel
, config_domain_type
);
1100 if (ev
.loglevel
== -1) {
1101 ERR("Unknown loglevel %s", config_loglevel
);
1102 ret
= -LTTNG_ERR_INVALID
;
1106 switch (config_domain_type
) {
1107 case LTTNG_DOMAIN_JUL
:
1108 ev
.loglevel
= LTTNG_LOGLEVEL_JUL_ALL
;
1110 case LTTNG_DOMAIN_LOG4J
:
1111 ev
.loglevel
= LTTNG_LOGLEVEL_LOG4J_ALL
;
1113 case LTTNG_DOMAIN_PYTHON
:
1114 ev
.loglevel
= LTTNG_LOGLEVEL_PYTHON_DEBUG
;
1121 ev
.type
= LTTNG_EVENT_TRACEPOINT
;
1122 strncpy(ev
.name
, event_name
, LTTNG_SYMBOL_NAME_LEN
);
1123 ev
.name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
1129 if (!config_filter
) {
1130 char *exclusion_string
;
1132 command_ret
= lttng_enable_event_with_exclusions(handle
,
1134 NULL
, exclusion_count
, exclusion_list
);
1135 exclusion_string
= print_exclusions(exclusion_count
, exclusion_list
);
1136 if (!exclusion_string
) {
1137 PERROR("Cannot allocate exclusion_string");
1141 if (command_ret
< 0) {
1142 /* Turn ret to positive value to handle the positive error code */
1143 switch (-command_ret
) {
1144 case LTTNG_ERR_KERN_EVENT_EXIST
:
1145 WARN("Kernel event %s%s already enabled (channel %s, session %s)",
1148 print_channel_name(channel_name
), session_name
);
1151 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
1153 const char *msg
= "The command tried to enable an event in a new domain for a session that has already been started once.";
1154 ERR("Event %s%s: %s (domain %s,channel %s, session %s)", event_name
,
1157 get_domain_str(dom
.type
),
1158 print_channel_name(channel_name
),
1164 ERR("Event %s%s: %s (domain %s, channel %s, session %s)", event_name
,
1166 lttng_strerror(command_ret
),
1167 get_domain_str(dom
.type
),
1168 command_ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
1169 ? print_raw_channel_name(channel_name
)
1170 : print_channel_name(channel_name
),
1175 error_holder
= command_ret
;
1178 case LTTNG_DOMAIN_KERNEL
:
1179 case LTTNG_DOMAIN_UST
:
1180 MSG("%s event %s%s created in channel %s",
1181 get_domain_str(dom
.type
),
1184 print_channel_name(channel_name
));
1186 case LTTNG_DOMAIN_JUL
:
1187 case LTTNG_DOMAIN_LOG4J
:
1188 case LTTNG_DOMAIN_PYTHON
:
1190 * Don't print the default channel
1191 * name for agent domains.
1193 MSG("%s event %s%s enabled",
1194 get_domain_str(dom
.type
),
1202 free(exclusion_string
);
1205 if (config_filter
) {
1206 char *exclusion_string
;
1208 /* Filter present */
1211 command_ret
= lttng_enable_event_with_exclusions(handle
, &ev
, channel_name
,
1212 config_filter
, exclusion_count
, exclusion_list
);
1213 exclusion_string
= print_exclusions(exclusion_count
, exclusion_list
);
1214 if (!exclusion_string
) {
1215 PERROR("Cannot allocate exclusion_string");
1219 if (command_ret
< 0) {
1220 switch (-command_ret
) {
1221 case LTTNG_ERR_FILTER_EXIST
:
1222 WARN("Filter on event %s%s is already enabled"
1223 " (domain %s, channel %s, session %s)",
1226 get_domain_str(dom
.type
),
1227 print_channel_name(channel_name
), session_name
);
1230 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
1232 const char *msg
= "The command tried to enable an event in a new domain for a session that has already been started once.";
1233 ERR("Event %s%s: %s (domain %s, channel %s, session %s, filter \'%s\')", ev
.name
,
1236 get_domain_str(dom
.type
),
1237 print_channel_name(channel_name
),
1238 session_name
, config_filter
);
1243 ERR("Event %s%s: %s (domain %s, channel %s, session %s, filter \'%s\')", ev
.name
,
1245 lttng_strerror(command_ret
),
1246 get_domain_str(dom
.type
),
1247 command_ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
1248 ? print_raw_channel_name(channel_name
)
1249 : print_channel_name(channel_name
),
1250 session_name
, config_filter
);
1254 error_holder
= command_ret
;
1257 MSG("Event %s%s: Filter '%s' for domain %s successfully set",
1258 event_name
, exclusion_string
,
1260 get_domain_str(dom
.type
));
1262 free(exclusion_string
);
1273 ret
= mi_lttng_event(writer
, &ev
, 1, handle
->domain
.type
);
1279 /* print exclusion */
1280 ret
= mi_print_exclusion(exclusion_count
, exclusion_list
);
1287 ret
= mi_lttng_writer_write_element_bool(writer
,
1288 mi_lttng_element_command_success
, success
);
1294 /* Close event element */
1295 ret
= mi_lttng_writer_close_element(writer
);
1303 event_name
= strtok(NULL
, ",");
1304 /* Reset warn, error and success */
1311 /* Close events and domain element */
1312 ret
= mi_lttng_close_multi_element(writer
, 2);
1325 lttng_destroy_handle(handle
);
1327 if (exclusion_list
!= NULL
) {
1328 while (exclusion_count
--) {
1329 free(exclusion_list
[exclusion_count
]);
1331 free(exclusion_list
);
1334 /* Overwrite ret with error_holder if there was an actual error with
1335 * enabling an event.
1337 ret
= error_holder
? error_holder
: ret
;
1343 * Add event to trace session
1347 int argv_index_start
;
1352 static struct domain_configuration
*initialize_domain_configuration(enum lttng_domain_type type
)
1355 struct domain_configuration
*config
= malloc(sizeof(struct domain_configuration
));
1362 case LTTNG_DOMAIN_KERNEL
:
1363 config
->domain_type
= LTTNG_DOMAIN_KERNEL
;
1365 case LTTNG_DOMAIN_UST
:
1366 config
->domain_type
= LTTNG_DOMAIN_UST
;
1368 case LTTNG_DOMAIN_JUL
:
1369 config
->domain_type
= LTTNG_DOMAIN_JUL
;
1371 case LTTNG_DOMAIN_LOG4J
:
1372 config
->domain_type
= LTTNG_DOMAIN_LOG4J
;
1374 case LTTNG_DOMAIN_PYTHON
:
1375 config
->domain_type
= LTTNG_DOMAIN_PYTHON
;
1377 case LTTNG_DOMAIN_NONE
:
1384 config
->event_type
= LTTNG_EVENT_ALL
;
1385 config
->enable_all
= 0;
1386 config
->loglevel_type
= LTTNG_EVENT_LOGLEVEL_ALL
;
1387 config
->loglevel
= NULL
;
1388 config
->probe
= NULL
;
1389 config
->function
= NULL
;
1390 config
->channel_name
= NULL
;
1391 config
->filter
= NULL
;
1392 config
->exclude
= NULL
;
1393 config
->event_list
= NULL
;
1398 int cmd_enable_events(int argc
, const char **argv
)
1400 int opt
, ret
= CMD_SUCCESS
, command_ret
= CMD_SUCCESS
, success
= 1;
1401 static poptContext pc
;
1402 char *session_name
= NULL
;
1403 int event_type
= -1;
1405 struct domain_configuration
*jul_config
= NULL
;
1406 struct domain_configuration
*kernel_config
= NULL
;
1407 struct domain_configuration
*log4j_config
= NULL
;
1408 struct domain_configuration
*python_config
= NULL
;
1409 struct domain_configuration
*ust_config
= NULL
;
1413 writer
= mi_lttng_writer_create(fileno(stdout
), lttng_opt_mi
);
1415 ret
= -LTTNG_ERR_NOMEM
;
1419 /* Open command element */
1420 ret
= mi_lttng_writer_command_open(writer
,
1421 mi_lttng_element_command_enable_event
);
1427 /* Open output element */
1428 ret
= mi_lttng_writer_open_element(writer
,
1429 mi_lttng_element_command_output
);
1435 /* Open the domains element */
1436 ret
= mi_lttng_domains_open(writer
);
1444 /* Parse global arguments */
1445 pc
= poptGetContext(NULL
, argc
, argv
, global_long_options
, 0);
1446 poptReadDefaultConfig(pc
, 0);
1449 while ((opt
= poptGetNextOpt(pc
)) != -1) {
1454 case OPT_LIST_OPTIONS
:
1455 list_cmd_options(stdout
, long_options
);
1462 /* Dispose the global arguments context */
1463 poptFreeContext(pc
);
1466 if (!opt_session_name
) {
1467 session_name
= get_session_name();
1468 if (session_name
== NULL
) {
1469 command_ret
= CMD_ERROR
;
1474 session_name
= opt_session_name
;
1477 /* Find the number of domain based on the passed arguments */
1479 int args_tuple_count
= 0;
1480 int arg_state_looking_for_end
= 0;
1481 struct args_tuple
*args_tuple_list
= NULL
;
1482 for (i
= 1; i
< argc
; i
++) {
1484 if (strcmp("-u", argv
[i
]) && strcmp("--userspace", argv
[i
]) &&
1485 strcmp("-j", argv
[i
]) && strcmp("--jul", argv
[i
]) &&
1486 strcmp("-l", argv
[i
]) && strcmp("--log4j", argv
[i
]) &&
1487 strcmp("-p", argv
[i
]) && strcmp("--python", argv
[i
]) &&
1488 strcmp("-k", argv
[i
]) && strcmp("--kernel", argv
[i
])) {
1493 struct args_tuple
*tmp_pointer
= NULL
;
1495 tmp_pointer
= realloc(args_tuple_list
, sizeof(struct args_tuple
) * args_tuple_count
);
1497 ERR("Realoc of args tuple failed");
1501 args_tuple_list
= tmp_pointer
;
1503 if (!arg_state_looking_for_end
) {
1504 if (args_tuple_count
-1 < 0) {
1505 ERR("Args parsing illegal state");
1509 args_tuple_list
[args_tuple_count
-1].argv_index_start
= i
;
1510 arg_state_looking_for_end
= 1;
1512 if (args_tuple_count
- 2 < 0 || args_tuple_count
-1 < 0) {
1513 ERR("Args parsing illegal state");
1518 /* Close the previous tuple */
1519 args_tuple_list
[args_tuple_count
-2].argv_index_end
= i
- 1;
1521 /* Start the new tuple */
1522 args_tuple_list
[args_tuple_count
-1].argv_index_start
= i
;
1526 if (args_tuple_count
<= 0) {
1527 ret
= print_missing_or_multiple_domains(0);
1535 /* Close the last tuple */
1536 args_tuple_list
[args_tuple_count
-1].argv_index_end
= i
- 1;
1538 if (args_tuple_count
== 1) {
1539 /* Preserve the old way with a domain flag that can be anywhere */
1540 args_tuple_list
[0].argv_index_start
= 1;
1543 for (i
= 0; i
< args_tuple_count
; i
++) {
1544 struct args_tuple
*tuple
= &args_tuple_list
[i
];
1545 int cur_argc
= tuple
->argv_index_end
- tuple
-> argv_index_start
+ 1;
1546 const char **cur_argv
= &argv
[tuple
->argv_index_start
];
1548 /* Default options */
1551 opt_domain
= LTTNG_DOMAIN_NONE
;
1555 opt_event_type
= LTTNG_EVENT_ALL
;
1556 opt_loglevel_type
= LTTNG_EVENT_LOGLEVEL_ALL
;
1557 opt_event_list
= NULL
;
1558 opt_loglevel
= NULL
;
1560 opt_function
= NULL
;
1561 opt_channel_name
= NULL
;
1565 pc
= poptGetContext(NULL
, cur_argc
, cur_argv
, long_options
, POPT_CONTEXT_KEEP_FIRST
);
1566 poptReadDefaultConfig(pc
, 0);
1568 /* Default event type */
1569 opt_event_type
= LTTNG_EVENT_ALL
;
1571 while ((opt
= poptGetNextOpt(pc
)) != -1) {
1576 case OPT_TRACEPOINT
:
1577 opt_event_type
= LTTNG_EVENT_TRACEPOINT
;
1580 opt_event_type
= LTTNG_EVENT_PROBE
;
1583 opt_event_type
= LTTNG_EVENT_FUNCTION
;
1586 opt_event_type
= LTTNG_EVENT_SYSCALL
;
1589 opt_loglevel_type
= LTTNG_EVENT_LOGLEVEL_RANGE
;
1590 opt_loglevel
= poptGetOptArg(pc
);
1592 case OPT_LOGLEVEL_ONLY
:
1593 opt_loglevel_type
= LTTNG_EVENT_LOGLEVEL_SINGLE
;
1594 opt_loglevel
= poptGetOptArg(pc
);
1596 case OPT_LIST_OPTIONS
:
1597 list_cmd_options(stdout
, long_options
);
1604 ret
= CMD_UNDEFINED
;
1608 /* Validate event type. Multiple event type are not supported. */
1609 if (event_type
== -1) {
1610 event_type
= opt_event_type
;
1612 if (event_type
!= opt_event_type
) {
1613 ERR("Multiple event type not supported.");
1620 struct domain_configuration
*tmp_config
= initialize_domain_configuration(opt_domain
);
1622 opt_event_list
= (char*) poptGetArg(pc
);
1623 if (opt_event_list
== NULL
&& opt_enable_all
== 0) {
1624 ERR("Missing event name(s).\n");
1630 tmp_config
->event_type
= opt_event_type
;
1631 tmp_config
->enable_all
= opt_enable_all
;
1632 tmp_config
->loglevel_type
= opt_loglevel_type
;
1633 tmp_config
->loglevel
= opt_loglevel
;
1634 tmp_config
->probe
= opt_probe
;
1635 tmp_config
->function
= opt_function
;
1636 tmp_config
->channel_name
= opt_channel_name
;
1637 tmp_config
->filter
= opt_filter
;
1638 tmp_config
->exclude
= opt_exclude
;
1639 tmp_config
->event_list
= opt_event_list
;
1641 switch(opt_domain
) {
1642 case LTTNG_DOMAIN_KERNEL
:
1643 if (kernel_config
) {
1644 ERR("Only one -k option is permitted per command");
1648 kernel_config
= tmp_config
;
1650 case LTTNG_DOMAIN_UST
:
1652 ERR("Only one -u option is permitted per command");
1656 ust_config
= tmp_config
;
1658 case LTTNG_DOMAIN_JUL
:
1660 ERR("Only one -j option is permitted per command");
1664 jul_config
= tmp_config
;
1666 case LTTNG_DOMAIN_LOG4J
:
1668 ERR("Only one -l option is permitted per command");
1672 log4j_config
= tmp_config
;
1674 case LTTNG_DOMAIN_PYTHON
:
1675 if (python_config
) {
1676 ERR("Only one -p option is permitted per command");
1680 python_config
= tmp_config
;
1682 case LTTNG_DOMAIN_NONE
:
1690 poptFreeContext(pc
);
1694 if (kernel_config
) {
1695 command_ret
= enable_events(session_name
, kernel_config
);
1702 command_ret
= enable_events(session_name
, ust_config
);
1709 command_ret
= enable_events(session_name
, jul_config
);
1716 command_ret
= enable_events(session_name
, log4j_config
);
1722 if (python_config
) {
1723 command_ret
= enable_events(session_name
, python_config
);
1732 /* Close domains and output element */
1733 ret
= mi_lttng_close_multi_element(writer
, 2);
1739 ret
= mi_lttng_writer_write_element_bool(writer
,
1740 mi_lttng_element_command_success
, success
);
1746 /* Command element close */
1747 ret
= mi_lttng_writer_command_close(writer
);
1756 if (writer
&& mi_lttng_writer_destroy(writer
)) {
1757 /* Preserve original error code */
1758 ret
= ret
? ret
: LTTNG_ERR_MI_IO_FAIL
;
1761 if (opt_session_name
== NULL
) {
1766 /* Overwrite ret if an error occurred in enable_events */
1767 ret
= command_ret
? command_ret
: ret
;
1769 free(args_tuple_list
);
1771 free(kernel_config
);
1773 free(python_config
);
1775 poptFreeContext(pc
);