SoW-2019-0002: Dynamic Snapshot
[lttng-tools.git] / src / bin / lttng / commands / enable_events.c
1 /*
2 * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8 #define _LGPL_SOURCE
9 #include <assert.h>
10 #include <popt.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <sys/stat.h>
14 #include <sys/types.h>
15 #include <unistd.h>
16 #include <inttypes.h>
17 #include <ctype.h>
18
19 #include <common/sessiond-comm/sessiond-comm.h>
20 #include <common/compat/string.h>
21 #include <common/compat/getenv.h>
22 #include <common/string-utils/string-utils.h>
23 #include <common/utils.h>
24
25 #include <lttng/constant.h>
26 /* Mi dependancy */
27 #include <common/mi-lttng.h>
28
29 #include "../command.h"
30 #include "../uprobe.h"
31
32 #if (LTTNG_SYMBOL_NAME_LEN == 256)
33 #define LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "255"
34 #endif
35
36 static char *opt_event_list;
37 static int opt_event_type;
38 static const char *opt_loglevel;
39 static int opt_loglevel_type;
40 static int opt_kernel;
41 static char *opt_session_name;
42 static int opt_userspace;
43 static int opt_jul;
44 static int opt_log4j;
45 static int opt_python;
46 static int opt_enable_all;
47 static char *opt_probe;
48 static char *opt_userspace_probe;
49 static char *opt_function;
50 static char *opt_channel_name;
51 static char *opt_filter;
52 static char *opt_exclude;
53
54 #ifdef LTTNG_EMBED_HELP
55 static const char help_msg[] =
56 #include <lttng-enable-event.1.h>
57 ;
58 #endif
59
60 enum {
61 OPT_HELP = 1,
62 OPT_TRACEPOINT,
63 OPT_PROBE,
64 OPT_USERSPACE_PROBE,
65 OPT_FUNCTION,
66 OPT_SYSCALL,
67 OPT_USERSPACE,
68 OPT_LOGLEVEL,
69 OPT_LOGLEVEL_ONLY,
70 OPT_LIST_OPTIONS,
71 OPT_FILTER,
72 OPT_EXCLUDE,
73 };
74
75 static struct lttng_handle *handle;
76 static struct mi_writer *writer;
77
78 static struct poptOption long_options[] = {
79 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
80 {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0},
81 {"session", 's', POPT_ARG_STRING, &opt_session_name, 0, 0, 0},
82 {"all", 'a', POPT_ARG_VAL, &opt_enable_all, 1, 0, 0},
83 {"channel", 'c', POPT_ARG_STRING, &opt_channel_name, 0, 0, 0},
84 {"kernel", 'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0},
85 {"userspace", 'u', POPT_ARG_NONE, 0, OPT_USERSPACE, 0, 0},
86 {"jul", 'j', POPT_ARG_VAL, &opt_jul, 1, 0, 0},
87 {"log4j", 'l', POPT_ARG_VAL, &opt_log4j, 1, 0, 0},
88 {"python", 'p', POPT_ARG_VAL, &opt_python, 1, 0, 0},
89 {"tracepoint", 0, POPT_ARG_NONE, 0, OPT_TRACEPOINT, 0, 0},
90 {"probe", 0, POPT_ARG_STRING, &opt_probe, OPT_PROBE, 0, 0},
91 {"userspace-probe",0, POPT_ARG_STRING, &opt_userspace_probe, OPT_USERSPACE_PROBE, 0, 0},
92 {"function", 0, POPT_ARG_STRING, &opt_function, OPT_FUNCTION, 0, 0},
93 {"syscall", 0, POPT_ARG_NONE, 0, OPT_SYSCALL, 0, 0},
94 {"loglevel", 0, POPT_ARG_STRING, 0, OPT_LOGLEVEL, 0, 0},
95 {"loglevel-only", 0, POPT_ARG_STRING, 0, OPT_LOGLEVEL_ONLY, 0, 0},
96 {"list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL},
97 {"filter", 'f', POPT_ARG_STRING, &opt_filter, OPT_FILTER, 0, 0},
98 {"exclude", 'x', POPT_ARG_STRING, &opt_exclude, OPT_EXCLUDE, 0, 0},
99 {0, 0, 0, 0, 0, 0, 0}
100 };
101
102 /*
103 * Parse probe options.
104 */
105 static int parse_probe_opts(struct lttng_event *ev, char *opt)
106 {
107 int ret = CMD_SUCCESS;
108 int match;
109 char s_hex[19];
110 #define S_HEX_LEN_SCANF_IS_A_BROKEN_API "18" /* 18 is (19 - 1) (\0 is extra) */
111 char name[LTTNG_SYMBOL_NAME_LEN];
112
113 if (opt == NULL) {
114 ret = CMD_ERROR;
115 goto end;
116 }
117
118 /* Check for symbol+offset */
119 match = sscanf(opt, "%" LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API
120 "[^'+']+%" S_HEX_LEN_SCANF_IS_A_BROKEN_API "s", name, s_hex);
121 if (match == 2) {
122 strncpy(ev->attr.probe.symbol_name, name, LTTNG_SYMBOL_NAME_LEN);
123 ev->attr.probe.symbol_name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
124 DBG("probe symbol %s", ev->attr.probe.symbol_name);
125 if (*s_hex == '\0') {
126 ERR("Invalid probe offset %s", s_hex);
127 ret = CMD_ERROR;
128 goto end;
129 }
130 ev->attr.probe.offset = strtoul(s_hex, NULL, 0);
131 DBG("probe offset %" PRIu64, ev->attr.probe.offset);
132 ev->attr.probe.addr = 0;
133 goto end;
134 }
135
136 /* Check for symbol */
137 if (isalpha(name[0]) || name[0] == '_') {
138 match = sscanf(opt, "%" LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "s",
139 name);
140 if (match == 1) {
141 strncpy(ev->attr.probe.symbol_name, name, LTTNG_SYMBOL_NAME_LEN);
142 ev->attr.probe.symbol_name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
143 DBG("probe symbol %s", ev->attr.probe.symbol_name);
144 ev->attr.probe.offset = 0;
145 DBG("probe offset %" PRIu64, ev->attr.probe.offset);
146 ev->attr.probe.addr = 0;
147 goto end;
148 }
149 }
150
151 /* Check for address */
152 match = sscanf(opt, "%" S_HEX_LEN_SCANF_IS_A_BROKEN_API "s", s_hex);
153 if (match > 0) {
154 /*
155 * Return an error if the first character of the tentative
156 * address is NULL or not a digit. It can be "0" if the address
157 * is in hexadecimal and can be 1 to 9 if it's in decimal.
158 */
159 if (*s_hex == '\0' || !isdigit(*s_hex)) {
160 ERR("Invalid probe description %s", s_hex);
161 ret = CMD_ERROR;
162 goto end;
163 }
164 ev->attr.probe.addr = strtoul(s_hex, NULL, 0);
165 DBG("probe addr %" PRIu64, ev->attr.probe.addr);
166 ev->attr.probe.offset = 0;
167 memset(ev->attr.probe.symbol_name, 0, LTTNG_SYMBOL_NAME_LEN);
168 goto end;
169 }
170
171 /* No match */
172 ret = CMD_ERROR;
173
174 end:
175 return ret;
176 }
177
178 /*
179 * Maps LOG4j loglevel from string to value
180 */
181 LTTNG_HIDDEN
182 int loglevel_log4j_str_to_value(const char *inputstr)
183 {
184 int i = 0;
185 char str[LTTNG_SYMBOL_NAME_LEN];
186
187 if (!inputstr || strlen(inputstr) == 0) {
188 return -1;
189 }
190
191 /*
192 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
193 * added at the end of the loop so a the upper bound we avoid the overflow.
194 */
195 while (i < (LTTNG_SYMBOL_NAME_LEN - 1) && inputstr[i] != '\0') {
196 str[i] = toupper(inputstr[i]);
197 i++;
198 }
199 str[i] = '\0';
200
201 if (!strcmp(str, "LOG4J_OFF") || !strcmp(str, "OFF")) {
202 return LTTNG_LOGLEVEL_LOG4J_OFF;
203 } else if (!strcmp(str, "LOG4J_FATAL") || !strcmp(str, "FATAL")) {
204 return LTTNG_LOGLEVEL_LOG4J_FATAL;
205 } else if (!strcmp(str, "LOG4J_ERROR") || !strcmp(str, "ERROR")) {
206 return LTTNG_LOGLEVEL_LOG4J_ERROR;
207 } else if (!strcmp(str, "LOG4J_WARN") || !strcmp(str, "WARN")) {
208 return LTTNG_LOGLEVEL_LOG4J_WARN;
209 } else if (!strcmp(str, "LOG4J_INFO") || !strcmp(str, "INFO")) {
210 return LTTNG_LOGLEVEL_LOG4J_INFO;
211 } else if (!strcmp(str, "LOG4J_DEBUG") || !strcmp(str, "DEBUG")) {
212 return LTTNG_LOGLEVEL_LOG4J_DEBUG;
213 } else if (!strcmp(str, "LOG4J_TRACE") || !strcmp(str, "TRACE")) {
214 return LTTNG_LOGLEVEL_LOG4J_TRACE;
215 } else if (!strcmp(str, "LOG4J_ALL") || !strcmp(str, "ALL")) {
216 return LTTNG_LOGLEVEL_LOG4J_ALL;
217 } else {
218 return -1;
219 }
220 }
221
222 /*
223 * Maps JUL loglevel from string to value
224 */
225 LTTNG_HIDDEN
226 int loglevel_jul_str_to_value(const char *inputstr)
227 {
228 int i = 0;
229 char str[LTTNG_SYMBOL_NAME_LEN];
230
231 if (!inputstr || strlen(inputstr) == 0) {
232 return -1;
233 }
234
235 /*
236 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
237 * added at the end of the loop so a the upper bound we avoid the overflow.
238 */
239 while (i < (LTTNG_SYMBOL_NAME_LEN - 1) && inputstr[i] != '\0') {
240 str[i] = toupper(inputstr[i]);
241 i++;
242 }
243 str[i] = '\0';
244
245 if (!strcmp(str, "JUL_OFF") || !strcmp(str, "OFF")) {
246 return LTTNG_LOGLEVEL_JUL_OFF;
247 } else if (!strcmp(str, "JUL_SEVERE") || !strcmp(str, "SEVERE")) {
248 return LTTNG_LOGLEVEL_JUL_SEVERE;
249 } else if (!strcmp(str, "JUL_WARNING") || !strcmp(str, "WARNING")) {
250 return LTTNG_LOGLEVEL_JUL_WARNING;
251 } else if (!strcmp(str, "JUL_INFO") || !strcmp(str, "INFO")) {
252 return LTTNG_LOGLEVEL_JUL_INFO;
253 } else if (!strcmp(str, "JUL_CONFIG") || !strcmp(str, "CONFIG")) {
254 return LTTNG_LOGLEVEL_JUL_CONFIG;
255 } else if (!strcmp(str, "JUL_FINE") || !strcmp(str, "FINE")) {
256 return LTTNG_LOGLEVEL_JUL_FINE;
257 } else if (!strcmp(str, "JUL_FINER") || !strcmp(str, "FINER")) {
258 return LTTNG_LOGLEVEL_JUL_FINER;
259 } else if (!strcmp(str, "JUL_FINEST") || !strcmp(str, "FINEST")) {
260 return LTTNG_LOGLEVEL_JUL_FINEST;
261 } else if (!strcmp(str, "JUL_ALL") || !strcmp(str, "ALL")) {
262 return LTTNG_LOGLEVEL_JUL_ALL;
263 } else {
264 return -1;
265 }
266 }
267
268 /*
269 * Maps Python loglevel from string to value
270 */
271 LTTNG_HIDDEN
272 int loglevel_python_str_to_value(const char *inputstr)
273 {
274 int i = 0;
275 char str[LTTNG_SYMBOL_NAME_LEN];
276
277 if (!inputstr || strlen(inputstr) == 0) {
278 return -1;
279 }
280
281 /*
282 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
283 * added at the end of the loop so a the upper bound we avoid the overflow.
284 */
285 while (i < (LTTNG_SYMBOL_NAME_LEN - 1) && inputstr[i] != '\0') {
286 str[i] = toupper(inputstr[i]);
287 i++;
288 }
289 str[i] = '\0';
290
291 if (!strcmp(str, "PYTHON_CRITICAL") || !strcmp(str, "CRITICAL")) {
292 return LTTNG_LOGLEVEL_PYTHON_CRITICAL;
293 } else if (!strcmp(str, "PYTHON_ERROR") || !strcmp(str, "ERROR")) {
294 return LTTNG_LOGLEVEL_PYTHON_ERROR;
295 } else if (!strcmp(str, "PYTHON_WARNING") || !strcmp(str, "WARNING")) {
296 return LTTNG_LOGLEVEL_PYTHON_WARNING;
297 } else if (!strcmp(str, "PYTHON_INFO") || !strcmp(str, "INFO")) {
298 return LTTNG_LOGLEVEL_PYTHON_INFO;
299 } else if (!strcmp(str, "PYTNON_DEBUG") || !strcmp(str, "DEBUG")) {
300 return LTTNG_LOGLEVEL_PYTHON_DEBUG;
301 } else if (!strcmp(str, "PYTHON_NOTSET") || !strcmp(str, "NOTSET")) {
302 return LTTNG_LOGLEVEL_PYTHON_NOTSET;
303 } else {
304 return -1;
305 }
306 }
307
308 /*
309 * Maps loglevel from string to value
310 */
311 LTTNG_HIDDEN
312 int loglevel_str_to_value(const char *inputstr)
313 {
314 int i = 0;
315 char str[LTTNG_SYMBOL_NAME_LEN];
316
317 if (!inputstr || strlen(inputstr) == 0) {
318 return -1;
319 }
320
321 /*
322 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
323 * added at the end of the loop so a the upper bound we avoid the overflow.
324 */
325 while (i < (LTTNG_SYMBOL_NAME_LEN - 1) && inputstr[i] != '\0') {
326 str[i] = toupper(inputstr[i]);
327 i++;
328 }
329 str[i] = '\0';
330 if (!strcmp(str, "TRACE_EMERG") || !strcmp(str, "EMERG")) {
331 return LTTNG_LOGLEVEL_EMERG;
332 } else if (!strcmp(str, "TRACE_ALERT") || !strcmp(str, "ALERT")) {
333 return LTTNG_LOGLEVEL_ALERT;
334 } else if (!strcmp(str, "TRACE_CRIT") || !strcmp(str, "CRIT")) {
335 return LTTNG_LOGLEVEL_CRIT;
336 } else if (!strcmp(str, "TRACE_ERR") || !strcmp(str, "ERR")) {
337 return LTTNG_LOGLEVEL_ERR;
338 } else if (!strcmp(str, "TRACE_WARNING") || !strcmp(str, "WARNING")) {
339 return LTTNG_LOGLEVEL_WARNING;
340 } else if (!strcmp(str, "TRACE_NOTICE") || !strcmp(str, "NOTICE")) {
341 return LTTNG_LOGLEVEL_NOTICE;
342 } else if (!strcmp(str, "TRACE_INFO") || !strcmp(str, "INFO")) {
343 return LTTNG_LOGLEVEL_INFO;
344 } else if (!strcmp(str, "TRACE_DEBUG_SYSTEM") || !strcmp(str, "DEBUG_SYSTEM") || !strcmp(str, "SYSTEM")) {
345 return LTTNG_LOGLEVEL_DEBUG_SYSTEM;
346 } else if (!strcmp(str, "TRACE_DEBUG_PROGRAM") || !strcmp(str, "DEBUG_PROGRAM") || !strcmp(str, "PROGRAM")) {
347 return LTTNG_LOGLEVEL_DEBUG_PROGRAM;
348 } else if (!strcmp(str, "TRACE_DEBUG_PROCESS") || !strcmp(str, "DEBUG_PROCESS") || !strcmp(str, "PROCESS")) {
349 return LTTNG_LOGLEVEL_DEBUG_PROCESS;
350 } else if (!strcmp(str, "TRACE_DEBUG_MODULE") || !strcmp(str, "DEBUG_MODULE") || !strcmp(str, "MODULE")) {
351 return LTTNG_LOGLEVEL_DEBUG_MODULE;
352 } else if (!strcmp(str, "TRACE_DEBUG_UNIT") || !strcmp(str, "DEBUG_UNIT") || !strcmp(str, "UNIT")) {
353 return LTTNG_LOGLEVEL_DEBUG_UNIT;
354 } else if (!strcmp(str, "TRACE_DEBUG_FUNCTION") || !strcmp(str, "DEBUG_FUNCTION") || !strcmp(str, "FUNCTION")) {
355 return LTTNG_LOGLEVEL_DEBUG_FUNCTION;
356 } else if (!strcmp(str, "TRACE_DEBUG_LINE") || !strcmp(str, "DEBUG_LINE") || !strcmp(str, "LINE")) {
357 return LTTNG_LOGLEVEL_DEBUG_LINE;
358 } else if (!strcmp(str, "TRACE_DEBUG") || !strcmp(str, "DEBUG")) {
359 return LTTNG_LOGLEVEL_DEBUG;
360 } else {
361 return -1;
362 }
363 }
364
365 static
366 const char *print_channel_name(const char *name)
367 {
368 return name ? : DEFAULT_CHANNEL_NAME;
369 }
370
371 static
372 const char *print_raw_channel_name(const char *name)
373 {
374 return name ? : "<default>";
375 }
376
377 /*
378 * Mi print exlcusion list
379 */
380 static
381 int mi_print_exclusion(char **names)
382 {
383 int i, ret;
384 int count = names ? strutils_array_of_strings_len(names) : 0;
385
386 assert(writer);
387
388 if (count == 0) {
389 ret = 0;
390 goto end;
391 }
392 ret = mi_lttng_writer_open_element(writer, config_element_exclusions);
393 if (ret) {
394 goto end;
395 }
396
397 for (i = 0; i < count; i++) {
398 ret = mi_lttng_writer_write_element_string(writer,
399 config_element_exclusion, names[i]);
400 if (ret) {
401 goto end;
402 }
403 }
404
405 /* Close exclusions element */
406 ret = mi_lttng_writer_close_element(writer);
407
408 end:
409 return ret;
410 }
411
412 /*
413 * Return allocated string for pretty-printing exclusion names.
414 */
415 static
416 char *print_exclusions(char **names)
417 {
418 int length = 0;
419 int i;
420 const char preamble[] = " excluding ";
421 char *ret;
422 int count = names ? strutils_array_of_strings_len(names) : 0;
423
424 if (count == 0) {
425 return strdup("");
426 }
427
428 /* calculate total required length */
429 for (i = 0; i < count; i++) {
430 length += strlen(names[i]) + 4;
431 }
432
433 length += sizeof(preamble);
434 ret = zmalloc(length);
435 if (!ret) {
436 return NULL;
437 }
438 strncpy(ret, preamble, length);
439 for (i = 0; i < count; i++) {
440 strcat(ret, "\"");
441 strcat(ret, names[i]);
442 strcat(ret, "\"");
443 if (i != count - 1) {
444 strcat(ret, ", ");
445 }
446 }
447
448 return ret;
449 }
450
451 static
452 int check_exclusion_subsets(const char *event_name, const char *exclusion)
453 {
454 bool warn = false;
455 int ret = 0;
456 const char *e = event_name;
457 const char *x = exclusion;
458
459 /* Scan both the excluder and the event letter by letter */
460 while (true) {
461 if (*e == '\\') {
462 if (*x != *e) {
463 warn = true;
464 goto end;
465 }
466
467 e++;
468 x++;
469 goto cmp_chars;
470 }
471
472 if (*x == '*') {
473 /* Event is a subset of the excluder */
474 ERR("Event %s: %s excludes all events from %s",
475 event_name, exclusion, event_name);
476 goto error;
477 }
478
479 if (*e == '*') {
480 /*
481 * Reached the end of the event name before the
482 * end of the exclusion: this is valid.
483 */
484 goto end;
485 }
486
487 cmp_chars:
488 if (*x != *e) {
489 warn = true;
490 break;
491 }
492
493 x++;
494 e++;
495 }
496
497 goto end;
498
499 error:
500 ret = -1;
501
502 end:
503 if (warn) {
504 WARN("Event %s: %s does not exclude any events from %s",
505 event_name, exclusion, event_name);
506 }
507
508 return ret;
509 }
510
511 LTTNG_HIDDEN
512 int create_exclusion_list_and_validate(const char *event_name,
513 const char *exclusions_arg,
514 char ***exclusion_list)
515 {
516 int ret = 0;
517 char **exclusions = NULL;
518
519 /* Event name must be a valid globbing pattern to allow exclusions. */
520 if (!strutils_is_star_glob_pattern(event_name)) {
521 ERR("Event %s: Exclusions can only be used with a globbing pattern",
522 event_name);
523 goto error;
524 }
525
526 /* Split exclusions. */
527 exclusions = strutils_split(exclusions_arg, ',', true);
528 if (!exclusions) {
529 goto error;
530 }
531
532 /*
533 * If the event name is a star-at-end only globbing pattern,
534 * then we can validate the individual exclusions. Otherwise
535 * all exclusions are passed to the session daemon.
536 */
537 if (strutils_is_star_at_the_end_only_glob_pattern(event_name)) {
538 char * const *exclusion;
539
540 for (exclusion = exclusions; *exclusion; exclusion++) {
541 if (!strutils_is_star_glob_pattern(*exclusion) ||
542 strutils_is_star_at_the_end_only_glob_pattern(*exclusion)) {
543 ret = check_exclusion_subsets(event_name, *exclusion);
544 if (ret) {
545 goto error;
546 }
547 }
548 }
549 }
550
551 *exclusion_list = exclusions;
552
553 goto end;
554
555 error:
556 ret = -1;
557 strutils_free_null_terminated_array_of_strings(exclusions);
558
559 end:
560 return ret;
561 }
562
563 static void warn_on_truncated_exclusion_names(char * const *exclusion_list,
564 int *warn)
565 {
566 char * const *exclusion;
567
568 for (exclusion = exclusion_list; *exclusion; exclusion++) {
569 if (strlen(*exclusion) >= LTTNG_SYMBOL_NAME_LEN) {
570 WARN("Event exclusion \"%s\" will be truncated",
571 *exclusion);
572 *warn = 1;
573 }
574 }
575 }
576
577 /*
578 * Enabling event using the lttng API.
579 * Note: in case of error only the last error code will be return.
580 */
581 static int enable_events(char *session_name)
582 {
583 int ret = CMD_SUCCESS, command_ret = CMD_SUCCESS;
584 int error_holder = CMD_SUCCESS, warn = 0, error = 0, success = 1;
585 char *event_name, *channel_name = NULL;
586 struct lttng_event *ev;
587 struct lttng_domain dom;
588 char **exclusion_list = NULL;
589 struct lttng_userspace_probe_location *uprobe_loc = NULL;
590
591 memset(&dom, 0, sizeof(dom));
592
593 ev = lttng_event_create();
594 if (!ev) {
595 ret = CMD_ERROR;
596 goto error;
597 }
598
599 if (opt_kernel) {
600 if (opt_loglevel) {
601 WARN("Kernel loglevels are not supported.");
602 }
603 }
604
605 /* Create lttng domain */
606 if (opt_kernel) {
607 dom.type = LTTNG_DOMAIN_KERNEL;
608 dom.buf_type = LTTNG_BUFFER_GLOBAL;
609 } else if (opt_userspace) {
610 dom.type = LTTNG_DOMAIN_UST;
611 /* Default. */
612 dom.buf_type = LTTNG_BUFFER_PER_UID;
613 } else if (opt_jul) {
614 dom.type = LTTNG_DOMAIN_JUL;
615 /* Default. */
616 dom.buf_type = LTTNG_BUFFER_PER_UID;
617 } else if (opt_log4j) {
618 dom.type = LTTNG_DOMAIN_LOG4J;
619 /* Default. */
620 dom.buf_type = LTTNG_BUFFER_PER_UID;
621 } else if (opt_python) {
622 dom.type = LTTNG_DOMAIN_PYTHON;
623 /* Default. */
624 dom.buf_type = LTTNG_BUFFER_PER_UID;
625 } else {
626 /* Checked by the caller. */
627 assert(0);
628 }
629
630 if (opt_exclude) {
631 switch (dom.type) {
632 case LTTNG_DOMAIN_KERNEL:
633 case LTTNG_DOMAIN_JUL:
634 case LTTNG_DOMAIN_LOG4J:
635 case LTTNG_DOMAIN_PYTHON:
636 ERR("Event name exclusions are not yet implemented for %s events",
637 get_domain_str(dom.type));
638 ret = CMD_ERROR;
639 goto error;
640 case LTTNG_DOMAIN_UST:
641 /* Exclusions supported */
642 break;
643 default:
644 assert(0);
645 }
646 }
647
648 /*
649 * Adding a filter to a probe, function or userspace-probe would be
650 * denied by the kernel tracer as it's not supported at the moment. We
651 * do an early check here to warn the user.
652 */
653 if (opt_filter && opt_kernel) {
654 switch (opt_event_type) {
655 case LTTNG_EVENT_ALL:
656 case LTTNG_EVENT_TRACEPOINT:
657 case LTTNG_EVENT_SYSCALL:
658 break;
659 case LTTNG_EVENT_PROBE:
660 case LTTNG_EVENT_USERSPACE_PROBE:
661 case LTTNG_EVENT_FUNCTION:
662 ERR("Filter expressions are not supported for %s events",
663 get_event_type_str(opt_event_type));
664 ret = CMD_ERROR;
665 goto error;
666 default:
667 ret = CMD_UNDEFINED;
668 goto error;
669 }
670 }
671
672 channel_name = opt_channel_name;
673
674 handle = lttng_create_handle(session_name, &dom);
675 if (handle == NULL) {
676 ret = -1;
677 goto error;
678 }
679
680 /* Prepare Mi */
681 if (lttng_opt_mi) {
682 /* Open a events element */
683 ret = mi_lttng_writer_open_element(writer, config_element_events);
684 if (ret) {
685 ret = CMD_ERROR;
686 goto error;
687 }
688 }
689
690 if (opt_enable_all) {
691 /* Default setup for enable all */
692 if (opt_kernel) {
693 ev->type = opt_event_type;
694 strcpy(ev->name, "*");
695 /* kernel loglevels not implemented */
696 ev->loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
697 } else {
698 ev->type = LTTNG_EVENT_TRACEPOINT;
699 strcpy(ev->name, "*");
700 ev->loglevel_type = opt_loglevel_type;
701 if (opt_loglevel) {
702 assert(opt_userspace || opt_jul || opt_log4j || opt_python);
703 if (opt_userspace) {
704 ev->loglevel = loglevel_str_to_value(opt_loglevel);
705 } else if (opt_jul) {
706 ev->loglevel = loglevel_jul_str_to_value(opt_loglevel);
707 } else if (opt_log4j) {
708 ev->loglevel = loglevel_log4j_str_to_value(opt_loglevel);
709 } else if (opt_python) {
710 ev->loglevel = loglevel_python_str_to_value(opt_loglevel);
711 }
712 if (ev->loglevel == -1) {
713 ERR("Unknown loglevel %s", opt_loglevel);
714 ret = -LTTNG_ERR_INVALID;
715 goto error;
716 }
717 } else {
718 assert(opt_userspace || opt_jul || opt_log4j || opt_python);
719 if (opt_userspace) {
720 ev->loglevel = -1;
721 } else if (opt_jul) {
722 ev->loglevel = LTTNG_LOGLEVEL_JUL_ALL;
723 } else if (opt_log4j) {
724 ev->loglevel = LTTNG_LOGLEVEL_LOG4J_ALL;
725 } else if (opt_python) {
726 ev->loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG;
727 }
728 }
729 }
730
731 if (opt_exclude) {
732 ret = create_exclusion_list_and_validate("*",
733 opt_exclude, &exclusion_list);
734 if (ret) {
735 ret = CMD_ERROR;
736 goto error;
737 }
738
739 ev->exclusion = 1;
740 warn_on_truncated_exclusion_names(exclusion_list,
741 &warn);
742 }
743 if (!opt_filter) {
744 ret = lttng_enable_event_with_exclusions(handle,
745 ev, channel_name,
746 NULL,
747 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
748 exclusion_list);
749 if (ret < 0) {
750 switch (-ret) {
751 case LTTNG_ERR_KERN_EVENT_EXIST:
752 WARN("Kernel events already enabled (channel %s, session %s)",
753 print_channel_name(channel_name), session_name);
754 warn = 1;
755 break;
756 case LTTNG_ERR_TRACE_ALREADY_STARTED:
757 {
758 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
759 ERR("Events: %s (channel %s, session %s)",
760 msg,
761 print_channel_name(channel_name),
762 session_name);
763 error = 1;
764 break;
765 }
766 default:
767 ERR("Events: %s (channel %s, session %s)",
768 lttng_strerror(ret),
769 ret == -LTTNG_ERR_NEED_CHANNEL_NAME
770 ? print_raw_channel_name(channel_name)
771 : print_channel_name(channel_name),
772 session_name);
773 error = 1;
774 break;
775 }
776 goto end;
777 }
778
779 switch (opt_event_type) {
780 case LTTNG_EVENT_TRACEPOINT:
781 if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) {
782 char *exclusion_string = print_exclusions(exclusion_list);
783
784 if (!exclusion_string) {
785 PERROR("Cannot allocate exclusion_string");
786 error = 1;
787 goto end;
788 }
789 MSG("All %s tracepoints%s are enabled in channel %s for loglevel %s",
790 get_domain_str(dom.type),
791 exclusion_string,
792 print_channel_name(channel_name),
793 opt_loglevel);
794 free(exclusion_string);
795 } else {
796 char *exclusion_string = print_exclusions(exclusion_list);
797
798 if (!exclusion_string) {
799 PERROR("Cannot allocate exclusion_string");
800 error = 1;
801 goto end;
802 }
803 MSG("All %s tracepoints%s are enabled in channel %s",
804 get_domain_str(dom.type),
805 exclusion_string,
806 print_channel_name(channel_name));
807 free(exclusion_string);
808 }
809 break;
810 case LTTNG_EVENT_SYSCALL:
811 if (opt_kernel) {
812 MSG("All %s system calls are enabled in channel %s",
813 get_domain_str(dom.type),
814 print_channel_name(channel_name));
815 }
816 break;
817 case LTTNG_EVENT_ALL:
818 if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) {
819 char *exclusion_string = print_exclusions(exclusion_list);
820
821 if (!exclusion_string) {
822 PERROR("Cannot allocate exclusion_string");
823 error = 1;
824 goto end;
825 }
826 MSG("All %s events%s are enabled in channel %s for loglevel %s",
827 get_domain_str(dom.type),
828 exclusion_string,
829 print_channel_name(channel_name),
830 opt_loglevel);
831 free(exclusion_string);
832 } else {
833 char *exclusion_string = print_exclusions(exclusion_list);
834
835 if (!exclusion_string) {
836 PERROR("Cannot allocate exclusion_string");
837 error = 1;
838 goto end;
839 }
840 MSG("All %s events%s are enabled in channel %s",
841 get_domain_str(dom.type),
842 exclusion_string,
843 print_channel_name(channel_name));
844 free(exclusion_string);
845 }
846 break;
847 default:
848 /*
849 * We should not be here since lttng_enable_event should have
850 * failed on the event type.
851 */
852 goto error;
853 }
854 }
855
856 if (opt_filter) {
857 command_ret = lttng_enable_event_with_exclusions(handle, ev, channel_name,
858 opt_filter,
859 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
860 exclusion_list);
861 if (command_ret < 0) {
862 switch (-command_ret) {
863 case LTTNG_ERR_FILTER_EXIST:
864 WARN("Filter on all events is already enabled"
865 " (channel %s, session %s)",
866 print_channel_name(channel_name), session_name);
867 warn = 1;
868 break;
869 case LTTNG_ERR_TRACE_ALREADY_STARTED:
870 {
871 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
872 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
873 msg,
874 print_channel_name(channel_name),
875 session_name, opt_filter);
876 error = 1;
877 break;
878 }
879 default:
880 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
881 lttng_strerror(command_ret),
882 command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
883 ? print_raw_channel_name(channel_name)
884 : print_channel_name(channel_name),
885 session_name, opt_filter);
886 error = 1;
887 break;
888 }
889 error_holder = command_ret;
890 } else {
891 ev->filter = 1;
892 MSG("Filter '%s' successfully set", opt_filter);
893 }
894 }
895
896 if (lttng_opt_mi) {
897 /* The wildcard * is used for kernel and ust domain to
898 * represent ALL. We copy * in event name to force the wildcard use
899 * for kernel domain
900 *
901 * Note: this is strictly for semantic and printing while in
902 * machine interface mode.
903 */
904 strcpy(ev->name, "*");
905
906 /* If we reach here the events are enabled */
907 if (!error && !warn) {
908 ev->enabled = 1;
909 } else {
910 ev->enabled = 0;
911 success = 0;
912 }
913 ret = mi_lttng_event(writer, ev, 1, handle->domain.type);
914 if (ret) {
915 ret = CMD_ERROR;
916 goto error;
917 }
918
919 /* print exclusion */
920 ret = mi_print_exclusion(exclusion_list);
921 if (ret) {
922 ret = CMD_ERROR;
923 goto error;
924 }
925
926 /* Success ? */
927 ret = mi_lttng_writer_write_element_bool(writer,
928 mi_lttng_element_command_success, success);
929 if (ret) {
930 ret = CMD_ERROR;
931 goto error;
932 }
933
934 /* Close event element */
935 ret = mi_lttng_writer_close_element(writer);
936 if (ret) {
937 ret = CMD_ERROR;
938 goto error;
939 }
940 }
941
942 goto end;
943 }
944
945 /* Strip event list */
946 event_name = strtok(opt_event_list, ",");
947 while (event_name != NULL) {
948 /* Copy name and type of the event */
949 strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN);
950 ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
951 ev->type = opt_event_type;
952
953 /* Kernel tracer action */
954 if (opt_kernel) {
955 DBG("Enabling kernel event %s for channel %s",
956 event_name,
957 print_channel_name(channel_name));
958
959 switch (opt_event_type) {
960 case LTTNG_EVENT_ALL: /* Enable tracepoints and syscalls */
961 /* If event name differs from *, select tracepoint. */
962 if (strcmp(ev->name, "*")) {
963 ev->type = LTTNG_EVENT_TRACEPOINT;
964 }
965 break;
966 case LTTNG_EVENT_TRACEPOINT:
967 break;
968 case LTTNG_EVENT_PROBE:
969 ret = parse_probe_opts(ev, opt_probe);
970 if (ret) {
971 ERR("Unable to parse probe options");
972 ret = CMD_ERROR;
973 goto error;
974 }
975 break;
976 case LTTNG_EVENT_USERSPACE_PROBE:
977 assert(ev->type == LTTNG_EVENT_USERSPACE_PROBE);
978
979 ret = parse_userspace_probe_opts(opt_userspace_probe, &uprobe_loc);
980 if (ret) {
981 switch (ret) {
982 case CMD_UNSUPPORTED:
983 /*
984 * Error message describing
985 * what is not supported was
986 * printed in the function.
987 */
988 break;
989 case CMD_ERROR:
990 default:
991 ERR("Unable to parse userspace probe options");
992 break;
993 }
994 goto error;
995 }
996
997 ret = lttng_event_set_userspace_probe_location(ev, uprobe_loc);
998 if (ret) {
999 WARN("Failed to set probe location on event");
1000 ret = CMD_ERROR;
1001 goto error;
1002 }
1003
1004 /* Ownership of the uprobe location was transferred to the event. */
1005 uprobe_loc = NULL;
1006 break;
1007 case LTTNG_EVENT_FUNCTION:
1008 ret = parse_probe_opts(ev, opt_function);
1009 if (ret) {
1010 ERR("Unable to parse function probe options");
1011 ret = CMD_ERROR;
1012 goto error;
1013 }
1014 break;
1015 case LTTNG_EVENT_SYSCALL:
1016 ev->type = LTTNG_EVENT_SYSCALL;
1017 break;
1018 default:
1019 ret = CMD_UNDEFINED;
1020 goto error;
1021 }
1022
1023 /* kernel loglevels not implemented */
1024 ev->loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
1025 } else if (opt_userspace) { /* User-space tracer action */
1026 DBG("Enabling UST event %s for channel %s, loglevel %s", event_name,
1027 print_channel_name(channel_name), opt_loglevel ? : "<all>");
1028
1029 switch (opt_event_type) {
1030 case LTTNG_EVENT_ALL: /* Default behavior is tracepoint */
1031 /* Fall-through */
1032 case LTTNG_EVENT_TRACEPOINT:
1033 /* Copy name and type of the event */
1034 ev->type = LTTNG_EVENT_TRACEPOINT;
1035 strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN);
1036 ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
1037 break;
1038 case LTTNG_EVENT_PROBE:
1039 case LTTNG_EVENT_FUNCTION:
1040 case LTTNG_EVENT_SYSCALL:
1041 case LTTNG_EVENT_USERSPACE_PROBE:
1042 default:
1043 ERR("Event type not available for user-space tracing");
1044 ret = CMD_UNSUPPORTED;
1045 goto error;
1046 }
1047
1048 if (opt_exclude) {
1049 ev->exclusion = 1;
1050 if (opt_event_type != LTTNG_EVENT_ALL && opt_event_type != LTTNG_EVENT_TRACEPOINT) {
1051 ERR("Exclusion option can only be used with tracepoint events");
1052 ret = CMD_ERROR;
1053 goto error;
1054 }
1055 /* Free previously allocated items */
1056 strutils_free_null_terminated_array_of_strings(
1057 exclusion_list);
1058 exclusion_list = NULL;
1059 ret = create_exclusion_list_and_validate(
1060 event_name, opt_exclude,
1061 &exclusion_list);
1062 if (ret) {
1063 ret = CMD_ERROR;
1064 goto error;
1065 }
1066
1067 warn_on_truncated_exclusion_names(
1068 exclusion_list, &warn);
1069 }
1070
1071 ev->loglevel_type = opt_loglevel_type;
1072 if (opt_loglevel) {
1073 ev->loglevel = loglevel_str_to_value(opt_loglevel);
1074 if (ev->loglevel == -1) {
1075 ERR("Unknown loglevel %s", opt_loglevel);
1076 ret = -LTTNG_ERR_INVALID;
1077 goto error;
1078 }
1079 } else {
1080 ev->loglevel = -1;
1081 }
1082 } else if (opt_jul || opt_log4j || opt_python) {
1083 if (opt_event_type != LTTNG_EVENT_ALL &&
1084 opt_event_type != LTTNG_EVENT_TRACEPOINT) {
1085 ERR("Event type not supported for domain.");
1086 ret = CMD_UNSUPPORTED;
1087 goto error;
1088 }
1089
1090 ev->loglevel_type = opt_loglevel_type;
1091 if (opt_loglevel) {
1092 if (opt_jul) {
1093 ev->loglevel = loglevel_jul_str_to_value(opt_loglevel);
1094 } else if (opt_log4j) {
1095 ev->loglevel = loglevel_log4j_str_to_value(opt_loglevel);
1096 } else if (opt_python) {
1097 ev->loglevel = loglevel_python_str_to_value(opt_loglevel);
1098 }
1099 if (ev->loglevel == -1) {
1100 ERR("Unknown loglevel %s", opt_loglevel);
1101 ret = -LTTNG_ERR_INVALID;
1102 goto error;
1103 }
1104 } else {
1105 if (opt_jul) {
1106 ev->loglevel = LTTNG_LOGLEVEL_JUL_ALL;
1107 } else if (opt_log4j) {
1108 ev->loglevel = LTTNG_LOGLEVEL_LOG4J_ALL;
1109 } else if (opt_python) {
1110 ev->loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG;
1111 }
1112 }
1113 ev->type = LTTNG_EVENT_TRACEPOINT;
1114 strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN);
1115 ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
1116 } else {
1117 assert(0);
1118 }
1119
1120 if (!opt_filter) {
1121 char *exclusion_string;
1122
1123 command_ret = lttng_enable_event_with_exclusions(handle,
1124 ev, channel_name,
1125 NULL,
1126 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
1127 exclusion_list);
1128 exclusion_string = print_exclusions(exclusion_list);
1129 if (!exclusion_string) {
1130 PERROR("Cannot allocate exclusion_string");
1131 error = 1;
1132 goto end;
1133 }
1134 if (command_ret < 0) {
1135 /* Turn ret to positive value to handle the positive error code */
1136 switch (-command_ret) {
1137 case LTTNG_ERR_KERN_EVENT_EXIST:
1138 WARN("Kernel event %s%s already enabled (channel %s, session %s)",
1139 event_name,
1140 exclusion_string,
1141 print_channel_name(channel_name), session_name);
1142 warn = 1;
1143 break;
1144 case LTTNG_ERR_TRACE_ALREADY_STARTED:
1145 {
1146 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
1147 ERR("Event %s%s: %s (channel %s, session %s)", event_name,
1148 exclusion_string,
1149 msg,
1150 print_channel_name(channel_name),
1151 session_name);
1152 error = 1;
1153 break;
1154 }
1155 case LTTNG_ERR_SDT_PROBE_SEMAPHORE:
1156 ERR("SDT probes %s guarded by semaphores are not supported (channel %s, session %s)",
1157 event_name, print_channel_name(channel_name),
1158 session_name);
1159 error = 1;
1160 break;
1161 default:
1162 ERR("Event %s%s: %s (channel %s, session %s)", event_name,
1163 exclusion_string,
1164 lttng_strerror(command_ret),
1165 command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
1166 ? print_raw_channel_name(channel_name)
1167 : print_channel_name(channel_name),
1168 session_name);
1169 error = 1;
1170 break;
1171 }
1172 error_holder = command_ret;
1173 } else {
1174 switch (dom.type) {
1175 case LTTNG_DOMAIN_KERNEL:
1176 case LTTNG_DOMAIN_UST:
1177 MSG("%s event %s%s created in channel %s",
1178 get_domain_str(dom.type),
1179 event_name,
1180 exclusion_string,
1181 print_channel_name(channel_name));
1182 break;
1183 case LTTNG_DOMAIN_JUL:
1184 case LTTNG_DOMAIN_LOG4J:
1185 case LTTNG_DOMAIN_PYTHON:
1186 /*
1187 * Don't print the default channel
1188 * name for agent domains.
1189 */
1190 MSG("%s event %s%s enabled",
1191 get_domain_str(dom.type),
1192 event_name,
1193 exclusion_string);
1194 break;
1195 default:
1196 assert(0);
1197 }
1198 }
1199 free(exclusion_string);
1200 }
1201
1202 if (opt_filter) {
1203 char *exclusion_string;
1204
1205 /* Filter present */
1206 ev->filter = 1;
1207
1208 command_ret = lttng_enable_event_with_exclusions(handle, ev, channel_name,
1209 opt_filter,
1210 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
1211 exclusion_list);
1212 exclusion_string = print_exclusions(exclusion_list);
1213 if (!exclusion_string) {
1214 PERROR("Cannot allocate exclusion_string");
1215 error = 1;
1216 goto end;
1217 }
1218 if (command_ret < 0) {
1219 switch (-command_ret) {
1220 case LTTNG_ERR_FILTER_EXIST:
1221 WARN("Filter on event %s%s is already enabled"
1222 " (channel %s, session %s)",
1223 event_name,
1224 exclusion_string,
1225 print_channel_name(channel_name), session_name);
1226 warn = 1;
1227 break;
1228 case LTTNG_ERR_TRACE_ALREADY_STARTED:
1229 {
1230 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
1231 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev->name,
1232 exclusion_string,
1233 msg,
1234 print_channel_name(channel_name),
1235 session_name, opt_filter);
1236 error = 1;
1237 break;
1238 }
1239 default:
1240 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev->name,
1241 exclusion_string,
1242 lttng_strerror(command_ret),
1243 command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
1244 ? print_raw_channel_name(channel_name)
1245 : print_channel_name(channel_name),
1246 session_name, opt_filter);
1247 error = 1;
1248 break;
1249 }
1250 error_holder = command_ret;
1251
1252 } else {
1253 MSG("Event %s%s: Filter '%s' successfully set",
1254 event_name, exclusion_string,
1255 opt_filter);
1256 }
1257 free(exclusion_string);
1258 }
1259
1260 if (lttng_opt_mi) {
1261 if (command_ret) {
1262 success = 0;
1263 ev->enabled = 0;
1264 } else {
1265 ev->enabled = 1;
1266 }
1267
1268 ret = mi_lttng_event(writer, ev, 1, handle->domain.type);
1269 if (ret) {
1270 ret = CMD_ERROR;
1271 goto error;
1272 }
1273
1274 /* print exclusion */
1275 ret = mi_print_exclusion(exclusion_list);
1276 if (ret) {
1277 ret = CMD_ERROR;
1278 goto error;
1279 }
1280
1281 /* Success ? */
1282 ret = mi_lttng_writer_write_element_bool(writer,
1283 mi_lttng_element_command_success, success);
1284 if (ret) {
1285 ret = CMD_ERROR;
1286 goto end;
1287 }
1288
1289 /* Close event element */
1290 ret = mi_lttng_writer_close_element(writer);
1291 if (ret) {
1292 ret = CMD_ERROR;
1293 goto end;
1294 }
1295 }
1296
1297 /* Next event */
1298 event_name = strtok(NULL, ",");
1299 /* Reset warn, error and success */
1300 success = 1;
1301 }
1302
1303 end:
1304 /* Close Mi */
1305 if (lttng_opt_mi) {
1306 /* Close events element */
1307 ret = mi_lttng_writer_close_element(writer);
1308 if (ret) {
1309 ret = CMD_ERROR;
1310 goto error;
1311 }
1312 }
1313 error:
1314 if (warn) {
1315 ret = CMD_WARNING;
1316 }
1317 if (error) {
1318 ret = CMD_ERROR;
1319 }
1320 lttng_destroy_handle(handle);
1321 strutils_free_null_terminated_array_of_strings(exclusion_list);
1322 lttng_userspace_probe_location_destroy(uprobe_loc);
1323
1324 /* Overwrite ret with error_holder if there was an actual error with
1325 * enabling an event.
1326 */
1327 ret = error_holder ? error_holder : ret;
1328
1329 lttng_event_destroy(ev);
1330 return ret;
1331 }
1332
1333 /*
1334 * Add event to trace session
1335 */
1336 int cmd_enable_events(int argc, const char **argv)
1337 {
1338 int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
1339 static poptContext pc;
1340 char *session_name = NULL;
1341 const char *leftover = NULL;
1342 int event_type = -1;
1343
1344 pc = poptGetContext(NULL, argc, argv, long_options, 0);
1345 poptReadDefaultConfig(pc, 0);
1346
1347 /* Default event type */
1348 opt_event_type = LTTNG_EVENT_ALL;
1349
1350 while ((opt = poptGetNextOpt(pc)) != -1) {
1351 switch (opt) {
1352 case OPT_HELP:
1353 SHOW_HELP();
1354 goto end;
1355 case OPT_TRACEPOINT:
1356 opt_event_type = LTTNG_EVENT_TRACEPOINT;
1357 break;
1358 case OPT_PROBE:
1359 opt_event_type = LTTNG_EVENT_PROBE;
1360 break;
1361 case OPT_USERSPACE_PROBE:
1362 opt_event_type = LTTNG_EVENT_USERSPACE_PROBE;
1363 break;
1364 case OPT_FUNCTION:
1365 opt_event_type = LTTNG_EVENT_FUNCTION;
1366 break;
1367 case OPT_SYSCALL:
1368 opt_event_type = LTTNG_EVENT_SYSCALL;
1369 break;
1370 case OPT_USERSPACE:
1371 opt_userspace = 1;
1372 break;
1373 case OPT_LOGLEVEL:
1374 opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_RANGE;
1375 opt_loglevel = poptGetOptArg(pc);
1376 break;
1377 case OPT_LOGLEVEL_ONLY:
1378 opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_SINGLE;
1379 opt_loglevel = poptGetOptArg(pc);
1380 break;
1381 case OPT_LIST_OPTIONS:
1382 list_cmd_options(stdout, long_options);
1383 goto end;
1384 case OPT_FILTER:
1385 break;
1386 case OPT_EXCLUDE:
1387 break;
1388 default:
1389 ret = CMD_UNDEFINED;
1390 goto end;
1391 }
1392
1393 /* Validate event type. Multiple event type are not supported. */
1394 if (event_type == -1) {
1395 event_type = opt_event_type;
1396 } else {
1397 if (event_type != opt_event_type) {
1398 ERR("Multiple event type not supported.");
1399 ret = CMD_ERROR;
1400 goto end;
1401 }
1402 }
1403 }
1404
1405 ret = print_missing_or_multiple_domains(
1406 opt_kernel + opt_userspace + opt_jul + opt_log4j + opt_python);
1407 if (ret) {
1408 ret = CMD_ERROR;
1409 goto end;
1410 }
1411
1412 /* Mi check */
1413 if (lttng_opt_mi) {
1414 writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
1415 if (!writer) {
1416 ret = -LTTNG_ERR_NOMEM;
1417 goto end;
1418 }
1419
1420 /* Open command element */
1421 ret = mi_lttng_writer_command_open(writer,
1422 mi_lttng_element_command_enable_event);
1423 if (ret) {
1424 ret = CMD_ERROR;
1425 goto end;
1426 }
1427
1428 /* Open output element */
1429 ret = mi_lttng_writer_open_element(writer,
1430 mi_lttng_element_command_output);
1431 if (ret) {
1432 ret = CMD_ERROR;
1433 goto end;
1434 }
1435 }
1436
1437 opt_event_list = (char*) poptGetArg(pc);
1438 if (opt_event_list == NULL && opt_enable_all == 0) {
1439 ERR("Missing event name(s).\n");
1440 ret = CMD_ERROR;
1441 goto end;
1442 }
1443
1444 leftover = poptGetArg(pc);
1445 if (leftover) {
1446 ERR("Unknown argument: %s", leftover);
1447 ret = CMD_ERROR;
1448 goto end;
1449 }
1450
1451 if (!opt_session_name) {
1452 session_name = get_session_name();
1453 if (session_name == NULL) {
1454 command_ret = CMD_ERROR;
1455 success = 0;
1456 goto mi_closing;
1457 }
1458 } else {
1459 session_name = opt_session_name;
1460 }
1461
1462 command_ret = enable_events(session_name);
1463 if (command_ret) {
1464 success = 0;
1465 goto mi_closing;
1466 }
1467
1468 mi_closing:
1469 /* Mi closing */
1470 if (lttng_opt_mi) {
1471 /* Close output element */
1472 ret = mi_lttng_writer_close_element(writer);
1473 if (ret) {
1474 ret = CMD_ERROR;
1475 goto end;
1476 }
1477
1478 ret = mi_lttng_writer_write_element_bool(writer,
1479 mi_lttng_element_command_success, success);
1480 if (ret) {
1481 ret = CMD_ERROR;
1482 goto end;
1483 }
1484
1485 /* Command element close */
1486 ret = mi_lttng_writer_command_close(writer);
1487 if (ret) {
1488 ret = CMD_ERROR;
1489 goto end;
1490 }
1491 }
1492
1493 end:
1494 /* Mi clean-up */
1495 if (writer && mi_lttng_writer_destroy(writer)) {
1496 /* Preserve original error code */
1497 ret = ret ? ret : LTTNG_ERR_MI_IO_FAIL;
1498 }
1499
1500 if (opt_session_name == NULL) {
1501 free(session_name);
1502 }
1503
1504 /* Overwrite ret if an error occurred in enable_events */
1505 ret = command_ret ? command_ret : ret;
1506
1507 poptFreeContext(pc);
1508 return ret;
1509 }
1510
This page took 0.100426 seconds and 5 git commands to generate.