userspace-probe: Print error for unsupported instrumentation mode
[lttng-tools.git] / src / bin / lttng / commands / enable_events.c
CommitLineData
f3ed775e
DG
1/*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 *
d14d33bf
AM
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.
f3ed775e
DG
7 *
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.
12 *
d14d33bf
AM
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.
f3ed775e
DG
16 */
17
6c1c0768 18#define _LGPL_SOURCE
b2064f54 19#include <assert.h>
f3ed775e
DG
20#include <popt.h>
21#include <stdio.h>
22#include <stdlib.h>
f3ed775e
DG
23#include <sys/stat.h>
24#include <sys/types.h>
25#include <unistd.h>
5a0de755 26#include <inttypes.h>
8f0d098b 27#include <ctype.h>
f3ed775e 28
343af227 29#include <common/sessiond-comm/sessiond-comm.h>
f5436bfc 30#include <common/compat/string.h>
dbc478f3 31#include <common/compat/getenv.h>
9f449915 32#include <common/string-utils/string-utils.h>
dbc478f3 33#include <common/utils.h>
f3ed775e 34
dbc478f3 35#include <lttng/constant.h>
89476427
JRJ
36/* Mi dependancy */
37#include <common/mi-lttng.h>
38
39#include "../command.h"
40
8ab7c0d9
MD
41#if (LTTNG_SYMBOL_NAME_LEN == 256)
42#define LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "255"
43#endif
44
f3ed775e
DG
45static char *opt_event_list;
46static int opt_event_type;
0cda4f28
MD
47static const char *opt_loglevel;
48static int opt_loglevel_type;
6181537c 49static int opt_kernel;
5440dc42 50static char *opt_session_name;
f3ed775e 51static int opt_userspace;
b9dfb167 52static int opt_jul;
5cdb6027 53static int opt_log4j;
0e115563 54static int opt_python;
f3ed775e 55static int opt_enable_all;
cf0e5467 56static char *opt_probe;
dcabc190 57static char *opt_userspace_probe;
8f0d098b 58static char *opt_function;
f3ed775e 59static char *opt_channel_name;
53a80697 60static char *opt_filter;
fac3366c 61static char *opt_exclude;
f3ed775e 62
4fc83d94
PP
63#ifdef LTTNG_EMBED_HELP
64static const char help_msg[] =
65#include <lttng-enable-event.1.h>
66;
67#endif
68
f3ed775e
DG
69enum {
70 OPT_HELP = 1,
f3ed775e 71 OPT_TRACEPOINT,
cf0e5467 72 OPT_PROBE,
dcabc190 73 OPT_USERSPACE_PROBE,
f3ed775e 74 OPT_FUNCTION,
a54bd42d 75 OPT_SYSCALL,
eeac7d46 76 OPT_USERSPACE,
0cda4f28
MD
77 OPT_LOGLEVEL,
78 OPT_LOGLEVEL_ONLY,
679b4943 79 OPT_LIST_OPTIONS,
53a80697 80 OPT_FILTER,
fac3366c 81 OPT_EXCLUDE,
f3ed775e
DG
82};
83
cd80958d 84static struct lttng_handle *handle;
89476427 85static struct mi_writer *writer;
cd80958d 86
f3ed775e
DG
87static struct poptOption long_options[] = {
88 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
89 {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0},
5440dc42 90 {"session", 's', POPT_ARG_STRING, &opt_session_name, 0, 0, 0},
e14f64a8 91 {"all", 'a', POPT_ARG_VAL, &opt_enable_all, 1, 0, 0},
f3ed775e
DG
92 {"channel", 'c', POPT_ARG_STRING, &opt_channel_name, 0, 0, 0},
93 {"kernel", 'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0},
d78d6610 94 {"userspace", 'u', POPT_ARG_NONE, 0, OPT_USERSPACE, 0, 0},
b9dfb167 95 {"jul", 'j', POPT_ARG_VAL, &opt_jul, 1, 0, 0},
5cdb6027 96 {"log4j", 'l', POPT_ARG_VAL, &opt_log4j, 1, 0, 0},
0e115563 97 {"python", 'p', POPT_ARG_VAL, &opt_python, 1, 0, 0},
f3ed775e 98 {"tracepoint", 0, POPT_ARG_NONE, 0, OPT_TRACEPOINT, 0, 0},
7ebae521 99 {"probe", 0, POPT_ARG_STRING, &opt_probe, OPT_PROBE, 0, 0},
dcabc190 100 {"userspace-probe",0, POPT_ARG_STRING, &opt_userspace_probe, OPT_USERSPACE_PROBE, 0, 0},
40e9d5d3 101 {"function", 0, POPT_ARG_STRING, &opt_function, OPT_FUNCTION, 0, 0},
7ebae521 102 {"syscall", 0, POPT_ARG_NONE, 0, OPT_SYSCALL, 0, 0},
0cda4f28
MD
103 {"loglevel", 0, POPT_ARG_STRING, 0, OPT_LOGLEVEL, 0, 0},
104 {"loglevel-only", 0, POPT_ARG_STRING, 0, OPT_LOGLEVEL_ONLY, 0, 0},
679b4943 105 {"list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL},
53a80697 106 {"filter", 'f', POPT_ARG_STRING, &opt_filter, OPT_FILTER, 0, 0},
fac3366c 107 {"exclude", 'x', POPT_ARG_STRING, &opt_exclude, OPT_EXCLUDE, 0, 0},
f3ed775e
DG
108 {0, 0, 0, 0, 0, 0, 0}
109};
110
0d63dd19 111/*
6181537c 112 * Parse probe options.
0d63dd19 113 */
cf0e5467 114static int parse_probe_opts(struct lttng_event *ev, char *opt)
0d63dd19 115{
49d4e302
JRJ
116 int ret = CMD_SUCCESS;
117 int match;
8ff0bbd0 118 char s_hex[19];
8ab7c0d9 119#define S_HEX_LEN_SCANF_IS_A_BROKEN_API "18" /* 18 is (19 - 1) (\0 is extra) */
0d63dd19
DG
120 char name[LTTNG_SYMBOL_NAME_LEN];
121
122 if (opt == NULL) {
49d4e302 123 ret = CMD_ERROR;
8f0d098b 124 goto end;
0d63dd19
DG
125 }
126
127 /* Check for symbol+offset */
49d4e302 128 match = sscanf(opt, "%" LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API
8ab7c0d9 129 "[^'+']+%" S_HEX_LEN_SCANF_IS_A_BROKEN_API "s", name, s_hex);
49d4e302 130 if (match == 2) {
7d29a247 131 strncpy(ev->attr.probe.symbol_name, name, LTTNG_SYMBOL_NAME_LEN);
99497cd0 132 ev->attr.probe.symbol_name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
cf0e5467 133 DBG("probe symbol %s", ev->attr.probe.symbol_name);
9d035200 134 if (*s_hex == '\0') {
8ff0bbd0 135 ERR("Invalid probe offset %s", s_hex);
49d4e302 136 ret = CMD_ERROR;
8f0d098b 137 goto end;
0d63dd19 138 }
8ff0bbd0 139 ev->attr.probe.offset = strtoul(s_hex, NULL, 0);
cf0e5467 140 DBG("probe offset %" PRIu64, ev->attr.probe.offset);
3000dc78 141 ev->attr.probe.addr = 0;
8f0d098b
MD
142 goto end;
143 }
144
145 /* Check for symbol */
146 if (isalpha(name[0])) {
49d4e302 147 match = sscanf(opt, "%" LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "s",
8ab7c0d9 148 name);
49d4e302 149 if (match == 1) {
8f0d098b 150 strncpy(ev->attr.probe.symbol_name, name, LTTNG_SYMBOL_NAME_LEN);
99497cd0 151 ev->attr.probe.symbol_name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
8f0d098b
MD
152 DBG("probe symbol %s", ev->attr.probe.symbol_name);
153 ev->attr.probe.offset = 0;
154 DBG("probe offset %" PRIu64, ev->attr.probe.offset);
155 ev->attr.probe.addr = 0;
156 goto end;
157 }
0d63dd19
DG
158 }
159
160 /* Check for address */
49d4e302
JRJ
161 match = sscanf(opt, "%" S_HEX_LEN_SCANF_IS_A_BROKEN_API "s", s_hex);
162 if (match > 0) {
9d035200 163 if (*s_hex == '\0') {
8ff0bbd0 164 ERR("Invalid probe address %s", s_hex);
49d4e302 165 ret = CMD_ERROR;
8f0d098b 166 goto end;
0d63dd19 167 }
8ff0bbd0 168 ev->attr.probe.addr = strtoul(s_hex, NULL, 0);
cf0e5467 169 DBG("probe addr %" PRIu64, ev->attr.probe.addr);
3000dc78
DG
170 ev->attr.probe.offset = 0;
171 memset(ev->attr.probe.symbol_name, 0, LTTNG_SYMBOL_NAME_LEN);
8f0d098b 172 goto end;
0d63dd19
DG
173 }
174
175 /* No match */
49d4e302 176 ret = CMD_ERROR;
0d63dd19 177
8f0d098b 178end:
0d63dd19
DG
179 return ret;
180}
181
dbc478f3
FD
182/*
183 * Walk the directories in the PATH environment variable to find the target
184 * binary passed as parameter.
185 *
186 * On success, the full path of the binary is copied in binary_full_path out
187 * parameter. This buffer is allocated by the caller and must be at least
188 * LTTNG_PATH_MAX bytes long.
189 * On failure, returns -1;
190 */
191static int walk_command_search_path(const char *binary, char *binary_full_path)
192{
193 char *tentative_binary_path = NULL;
194 char *command_search_path = NULL;
195 char *curr_search_dir_end = NULL;
196 char *curr_search_dir = NULL;
197 struct stat stat_output;
198 int ret = 0;
199
200 command_search_path = lttng_secure_getenv("PATH");
201 if (!command_search_path) {
202 ret = -1;
203 goto end;
204 }
205
206 /*
207 * Duplicate the $PATH string as the char pointer returned by getenv() should
208 * not be modified.
209 */
210 command_search_path = strdup(command_search_path);
211 if (!command_search_path) {
212 ret = -1;
213 goto end;
214 }
215
216 /*
217 * This char array is used to concatenate path to binary to look for
218 * the binary.
219 */
220 tentative_binary_path = zmalloc(LTTNG_PATH_MAX * sizeof(char));
221 if (!tentative_binary_path) {
222 ret = -1;
223 goto alloc_error;
224 }
225
226 curr_search_dir = command_search_path;
227 do {
228 /*
229 * Split on ':'. The return value of this call points to the
230 * matching character.
231 */
232 curr_search_dir_end = strchr(curr_search_dir, ':');
233 if (curr_search_dir_end != NULL) {
234 /*
235 * Add a NULL byte to the end of the first token so it
236 * can be used as a string.
237 */
238 curr_search_dir_end[0] = '\0';
239 }
240
241 /* Empty the tentative path */
242 memset(tentative_binary_path, 0, LTTNG_PATH_MAX * sizeof(char));
243
244 /*
245 * Build the tentative path to the binary using the current
246 * search directory and the name of the binary.
247 */
248 ret = snprintf(tentative_binary_path, LTTNG_PATH_MAX, "%s/%s",
249 curr_search_dir, binary);
250 if (ret < 0) {
251 goto free_binary_path;
252 }
253 if (ret < LTTNG_PATH_MAX) {
254 /*
255 * Use STAT(2) to see if the file exists.
256 */
257 ret = stat(tentative_binary_path, &stat_output);
258 if (ret == 0) {
259 /*
260 * Verify that it is a regular file or a
261 * symlink and not a special file (e.g.
262 * device).
263 */
264 if (S_ISREG(stat_output.st_mode)
265 || S_ISLNK(stat_output.st_mode)) {
266 /*
267 * Found a match, set the out parameter
268 * and return success.
269 */
270 ret = lttng_strncpy(binary_full_path,
271 tentative_binary_path,
272 LTTNG_PATH_MAX);
273 if (ret == -1) {
274 ERR("Source path does not fit "
275 "in destination buffer.");
276 }
277 goto free_binary_path;
278 }
279 }
280 }
281 /* Go to the next entry in the $PATH variable. */
282 curr_search_dir = curr_search_dir_end + 1;
283 } while (curr_search_dir_end != NULL);
284
285free_binary_path:
286 free(tentative_binary_path);
287alloc_error:
288 free(command_search_path);
289end:
290 return ret;
291}
292
36aa2f64
FD
293/*
294 * Check if the symbol field passed by the user is in fact an address or an
295 * offset from a symbol. Those two instrumentation types are not supported yet.
296 * It's expected to be a common mistake because of the existing --probe option
297 * that does support these formats.
298 *
299 * Here are examples of these unsupported formats for the --userspace-probe
300 * option:
301 * elf:/path/to/binary:0x400430
302 * elf:/path/to/binary:4194364
303 * elf:/path/to/binary:my_symbol+0x323
304 * elf:/path/to/binary:my_symbol+43
305 */
306static int warn_userspace_probe_syntax(const char *symbol)
307{
308 unsigned long addr = 0;
309 size_t offset = 0;
310 int ret;
311
312 /* Check if the symbol field is an hex address. */
313 ret = sscanf(symbol, "0x%lx", &addr);
314 if (ret > 0) {
315 /* If there is a match, print a warning and return an error. */
316 ERR("Userspace probe on address not supported yet.");
317 ret = CMD_UNSUPPORTED;
318 goto error;
319 }
320
321 /* Check if the symbol field is an decimal address. */
322 ret = sscanf(symbol, "%lu", &addr);
323 if (ret > 0) {
324 /* If there is a match, print a warning and return an error. */
325 ERR("Userspace probe on address not supported yet.");
326 ret = CMD_UNSUPPORTED;
327 goto error;
328 }
329
330 /* Check if the symbol field is symbol+hex_offset. */
331 ret = sscanf(symbol, "%*[^+]+0x%lx", &offset);
332 if (ret > 0) {
333 /* If there is a match, print a warning and return an error. */
334 ERR("Userspace probe on symbol+offset not supported yet.");
335 ret = CMD_UNSUPPORTED;
336 goto error;
337 }
338
339 /* Check if the symbol field is symbol+decimal_offset. */
340 ret = sscanf(symbol, "%*[^+]+%lu", &offset);
341 if (ret > 0) {
342 /* If there is a match, print a warning and return an error. */
343 ERR("Userspace probe on symbol+offset not supported yet.");
344 ret = CMD_UNSUPPORTED;
345 goto error;
346 }
347
348 ret = 0;
349
350error:
351 return ret;
352}
353
dcabc190
FD
354/*
355 * Parse userspace probe options
356 * Set the userspace probe fields in the lttng_event struct and set the
357 * target_path to the path to the binary.
358 */
359static int parse_userspace_probe_opts(struct lttng_event *ev, char *opt)
360{
361 int ret = CMD_SUCCESS;
362 int num_token;
363 char **tokens;
364 char *target_path = NULL;
365 char *unescaped_target_path = NULL;
366 char *real_target_path = NULL;
367 char *symbol_name = NULL, *probe_name = NULL, *provider_name = NULL;
368 struct lttng_userspace_probe_location *probe_location = NULL;
369 struct lttng_userspace_probe_location_lookup_method *lookup_method =
370 NULL;
371
372 if (opt == NULL) {
373 ret = CMD_ERROR;
374 goto end;
375 }
376
ebbcac93
FD
377 switch (ev->type) {
378 case LTTNG_EVENT_USERSPACE_PROBE:
379 break;
380 default:
381 assert(0);
382 }
383
dcabc190
FD
384 /*
385 * userspace probe fields are separated by ':'.
386 */
387 tokens = strutils_split(opt, ':', 1);
388 num_token = strutils_array_of_strings_len(tokens);
389
390 /*
391 * Early sanity check that the number of parameter is between 2 and 4
392 * inclusively.
393 * elf:PATH:SYMBOL
394 * std:PATH:PROVIDER_NAME:PROBE_NAME
395 * PATH:SYMBOL (same behavior as ELF)
396 */
397 if (num_token < 2 || num_token > 4) {
398 ret = CMD_ERROR;
399 goto end_string;
400 }
401
402 /*
403 * Looking up the first parameter will tell the technique to use to
404 * interpret the userspace probe/function description.
405 */
406 switch (num_token) {
407 case 2:
408 /* When the probe type is omitted we assume ELF for now. */
409 case 3:
410 if (num_token == 3 && strcmp(tokens[0], "elf") == 0) {
411 target_path = tokens[1];
412 symbol_name = tokens[2];
413 } else if (num_token == 2) {
414 target_path = tokens[0];
415 symbol_name = tokens[1];
416 } else {
417 ret = CMD_ERROR;
418 goto end_string;
419 }
420 lookup_method =
421 lttng_userspace_probe_location_lookup_method_function_elf_create();
422 if (!lookup_method) {
423 WARN("Failed to create ELF lookup method");
424 ret = CMD_ERROR;
425 goto end_string;
426 }
427 break;
428 case 4:
429 if (strcmp(tokens[0], "sdt") == 0) {
430 target_path = tokens[1];
431 provider_name = tokens[2];
432 probe_name = tokens[3];
433 } else {
434 ret = CMD_ERROR;
435 goto end_string;
436 }
437 lookup_method =
438 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
439 if (!lookup_method) {
440 WARN("Failed to create ELF lookup method");
441 ret = CMD_ERROR;
442 goto end_string;
443 }
444 break;
445 default:
446 ret = CMD_ERROR;
447 goto end_string;
448 }
449
450 /* strutils_unescape_string allocates a new char *. */
451 unescaped_target_path = strutils_unescape_string(target_path, 0);
452 if (!unescaped_target_path) {
36aa2f64 453 ret = CMD_ERROR;
ebbcac93 454 goto end_destroy_lookup_method;
dcabc190
FD
455 }
456
457 /*
458 * If there is not forward slash in the path. Walk the $PATH else
459 * expand.
460 */
ebbcac93 461 if (strchr(unescaped_target_path, '/') == NULL) {
dcabc190
FD
462 /* Walk the $PATH variable to find the targeted binary. */
463 real_target_path = zmalloc(LTTNG_PATH_MAX * sizeof(char));
464 if (!real_target_path) {
465 PERROR("Error allocating path buffer");
466 ret = CMD_ERROR;
ebbcac93 467 goto end_destroy_lookup_method;
dcabc190 468 }
ebbcac93 469 ret = walk_command_search_path(unescaped_target_path, real_target_path);
dcabc190
FD
470 if (ret) {
471 ERR("Binary not found.");
472 ret = CMD_ERROR;
ebbcac93 473 goto end_destroy_lookup_method;
dcabc190
FD
474 }
475 } else {
476 /*
477 * Expand references to `/./` and `/../`. This function does not check
ebbcac93
FD
478 * if the file exists. This call returns an allocated buffer on
479 * success.
dcabc190 480 */
ebbcac93 481 real_target_path = utils_expand_path_keep_symlink(unescaped_target_path);
dcabc190
FD
482 if (!real_target_path) {
483 ERR("Error expanding the path to binary.");
484 ret = CMD_ERROR;
ebbcac93 485 goto end_destroy_lookup_method;
dcabc190
FD
486 }
487
488 /*
489 * Check if the file exists using access(2). If it does not, walk the
490 * $PATH.
491 */
492 ret = access(real_target_path, F_OK);
493 if (ret) {
494 ret = CMD_ERROR;
ebbcac93 495 goto end_destroy_lookup_method;
dcabc190
FD
496 }
497 }
498
499 switch (lttng_userspace_probe_location_lookup_method_get_type(lookup_method)) {
500 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF:
36aa2f64
FD
501 /*
502 * Check for common mistakes in userspace probe description syntax.
503 */
504 ret = warn_userspace_probe_syntax(symbol_name);
505 if (ret) {
506 goto end_destroy_lookup_method;
507 }
508
dcabc190
FD
509 probe_location = lttng_userspace_probe_location_function_create(
510 real_target_path, symbol_name, lookup_method);
511 if (!probe_location) {
512 WARN("Failed to create function probe location");
513 ret = CMD_ERROR;
514 goto end_destroy_lookup_method;
515 }
516
517 /* Ownership transferred to probe_location. */
518 lookup_method = NULL;
519
520 ret = lttng_event_set_userspace_probe_location(ev, probe_location);
521 if (ret) {
522 WARN("Failed to set probe location on event");
523 ret = CMD_ERROR;
524 goto end_destroy_location;
525 }
526 break;
527 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT:
528 probe_location = lttng_userspace_probe_location_tracepoint_create(
529 real_target_path, provider_name, probe_name, lookup_method);
530 if (!probe_location) {
531 WARN("Failed to create function probe location");
532 ret = CMD_ERROR;
533 goto end_destroy_lookup_method;
534 }
535
536 /* Ownership transferred to probe_location. */
537 lookup_method = NULL;
538
539 ret = lttng_event_set_userspace_probe_location(ev, probe_location);
540 if (ret) {
541 WARN("Failed to set probe location on event");
542 ret = CMD_ERROR;
543 goto end_destroy_location;
544 }
545 break;
546 default:
547 ret = CMD_ERROR;
ebbcac93 548 goto end_destroy_lookup_method;
dcabc190
FD
549 }
550
ebbcac93
FD
551 /* Successful parsing, now clean up everything and return. */
552 goto end_string;
dcabc190
FD
553
554end_destroy_location:
555 lttng_userspace_probe_location_destroy(probe_location);
556end_destroy_lookup_method:
557 lttng_userspace_probe_location_lookup_method_destroy(lookup_method);
ebbcac93
FD
558end_string:
559 strutils_free_null_terminated_array_of_strings(tokens);
dcabc190 560 /*
ebbcac93
FD
561 * Freeing both char * here makes the error handling simplier. free()
562 * performs not action if the pointer is NULL.
dcabc190
FD
563 */
564 free(real_target_path);
dcabc190 565 free(unescaped_target_path);
dcabc190
FD
566end:
567 return ret;
568}
569
5cdb6027
DG
570/*
571 * Maps LOG4j loglevel from string to value
572 */
573static int loglevel_log4j_str_to_value(const char *inputstr)
574{
575 int i = 0;
576 char str[LTTNG_SYMBOL_NAME_LEN];
577
3712b110
JG
578 if (!inputstr || strlen(inputstr) == 0) {
579 return -1;
580 }
581
5cdb6027
DG
582 /*
583 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
584 * added at the end of the loop so a the upper bound we avoid the overflow.
585 */
586 while (i < (LTTNG_SYMBOL_NAME_LEN - 1) && inputstr[i] != '\0') {
587 str[i] = toupper(inputstr[i]);
588 i++;
589 }
590 str[i] = '\0';
591
592 if (!strcmp(str, "LOG4J_OFF") || !strcmp(str, "OFF")) {
593 return LTTNG_LOGLEVEL_LOG4J_OFF;
594 } else if (!strcmp(str, "LOG4J_FATAL") || !strcmp(str, "FATAL")) {
595 return LTTNG_LOGLEVEL_LOG4J_FATAL;
596 } else if (!strcmp(str, "LOG4J_ERROR") || !strcmp(str, "ERROR")) {
597 return LTTNG_LOGLEVEL_LOG4J_ERROR;
598 } else if (!strcmp(str, "LOG4J_WARN") || !strcmp(str, "WARN")) {
599 return LTTNG_LOGLEVEL_LOG4J_WARN;
600 } else if (!strcmp(str, "LOG4J_INFO") || !strcmp(str, "INFO")) {
601 return LTTNG_LOGLEVEL_LOG4J_INFO;
602 } else if (!strcmp(str, "LOG4J_DEBUG") || !strcmp(str, "DEBUG")) {
603 return LTTNG_LOGLEVEL_LOG4J_DEBUG;
604 } else if (!strcmp(str, "LOG4J_TRACE") || !strcmp(str, "TRACE")) {
605 return LTTNG_LOGLEVEL_LOG4J_TRACE;
606 } else if (!strcmp(str, "LOG4J_ALL") || !strcmp(str, "ALL")) {
607 return LTTNG_LOGLEVEL_LOG4J_ALL;
608 } else {
609 return -1;
610 }
611}
612
b2064f54
DG
613/*
614 * Maps JUL loglevel from string to value
615 */
616static int loglevel_jul_str_to_value(const char *inputstr)
617{
618 int i = 0;
619 char str[LTTNG_SYMBOL_NAME_LEN];
620
3712b110
JG
621 if (!inputstr || strlen(inputstr) == 0) {
622 return -1;
623 }
624
b2064f54
DG
625 /*
626 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
627 * added at the end of the loop so a the upper bound we avoid the overflow.
628 */
629 while (i < (LTTNG_SYMBOL_NAME_LEN - 1) && inputstr[i] != '\0') {
630 str[i] = toupper(inputstr[i]);
631 i++;
632 }
633 str[i] = '\0';
634
635 if (!strcmp(str, "JUL_OFF") || !strcmp(str, "OFF")) {
636 return LTTNG_LOGLEVEL_JUL_OFF;
637 } else if (!strcmp(str, "JUL_SEVERE") || !strcmp(str, "SEVERE")) {
638 return LTTNG_LOGLEVEL_JUL_SEVERE;
639 } else if (!strcmp(str, "JUL_WARNING") || !strcmp(str, "WARNING")) {
640 return LTTNG_LOGLEVEL_JUL_WARNING;
641 } else if (!strcmp(str, "JUL_INFO") || !strcmp(str, "INFO")) {
642 return LTTNG_LOGLEVEL_JUL_INFO;
643 } else if (!strcmp(str, "JUL_CONFIG") || !strcmp(str, "CONFIG")) {
644 return LTTNG_LOGLEVEL_JUL_CONFIG;
645 } else if (!strcmp(str, "JUL_FINE") || !strcmp(str, "FINE")) {
646 return LTTNG_LOGLEVEL_JUL_FINE;
647 } else if (!strcmp(str, "JUL_FINER") || !strcmp(str, "FINER")) {
648 return LTTNG_LOGLEVEL_JUL_FINER;
649 } else if (!strcmp(str, "JUL_FINEST") || !strcmp(str, "FINEST")) {
650 return LTTNG_LOGLEVEL_JUL_FINEST;
651 } else if (!strcmp(str, "JUL_ALL") || !strcmp(str, "ALL")) {
652 return LTTNG_LOGLEVEL_JUL_ALL;
653 } else {
654 return -1;
655 }
656}
657
0e115563
DG
658/*
659 * Maps Python loglevel from string to value
660 */
661static int loglevel_python_str_to_value(const char *inputstr)
662{
663 int i = 0;
664 char str[LTTNG_SYMBOL_NAME_LEN];
665
3712b110
JG
666 if (!inputstr || strlen(inputstr) == 0) {
667 return -1;
668 }
669
0e115563
DG
670 /*
671 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
672 * added at the end of the loop so a the upper bound we avoid the overflow.
673 */
674 while (i < (LTTNG_SYMBOL_NAME_LEN - 1) && inputstr[i] != '\0') {
675 str[i] = toupper(inputstr[i]);
676 i++;
677 }
678 str[i] = '\0';
679
680 if (!strcmp(str, "PYTHON_CRITICAL") || !strcmp(str, "CRITICAL")) {
681 return LTTNG_LOGLEVEL_PYTHON_CRITICAL;
682 } else if (!strcmp(str, "PYTHON_ERROR") || !strcmp(str, "ERROR")) {
683 return LTTNG_LOGLEVEL_PYTHON_ERROR;
684 } else if (!strcmp(str, "PYTHON_WARNING") || !strcmp(str, "WARNING")) {
685 return LTTNG_LOGLEVEL_PYTHON_WARNING;
686 } else if (!strcmp(str, "PYTHON_INFO") || !strcmp(str, "INFO")) {
687 return LTTNG_LOGLEVEL_PYTHON_INFO;
688 } else if (!strcmp(str, "PYTNON_DEBUG") || !strcmp(str, "DEBUG")) {
689 return LTTNG_LOGLEVEL_PYTHON_DEBUG;
690 } else if (!strcmp(str, "PYTHON_NOTSET") || !strcmp(str, "NOTSET")) {
691 return LTTNG_LOGLEVEL_PYTHON_NOTSET;
692 } else {
693 return -1;
694 }
695}
696
8005f29a 697/*
0c8477c8 698 * Maps loglevel from string to value
8005f29a
MD
699 */
700static
46839cc2 701int loglevel_str_to_value(const char *inputstr)
8005f29a 702{
46839cc2
MD
703 int i = 0;
704 char str[LTTNG_SYMBOL_NAME_LEN];
705
3712b110
JG
706 if (!inputstr || strlen(inputstr) == 0) {
707 return -1;
708 }
709
e051e07c
DG
710 /*
711 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
712 * added at the end of the loop so a the upper bound we avoid the overflow.
713 */
714 while (i < (LTTNG_SYMBOL_NAME_LEN - 1) && inputstr[i] != '\0') {
46839cc2
MD
715 str[i] = toupper(inputstr[i]);
716 i++;
717 }
718 str[i] = '\0';
719 if (!strcmp(str, "TRACE_EMERG") || !strcmp(str, "EMERG")) {
720 return LTTNG_LOGLEVEL_EMERG;
721 } else if (!strcmp(str, "TRACE_ALERT") || !strcmp(str, "ALERT")) {
722 return LTTNG_LOGLEVEL_ALERT;
723 } else if (!strcmp(str, "TRACE_CRIT") || !strcmp(str, "CRIT")) {
724 return LTTNG_LOGLEVEL_CRIT;
725 } else if (!strcmp(str, "TRACE_ERR") || !strcmp(str, "ERR")) {
726 return LTTNG_LOGLEVEL_ERR;
727 } else if (!strcmp(str, "TRACE_WARNING") || !strcmp(str, "WARNING")) {
728 return LTTNG_LOGLEVEL_WARNING;
729 } else if (!strcmp(str, "TRACE_NOTICE") || !strcmp(str, "NOTICE")) {
730 return LTTNG_LOGLEVEL_NOTICE;
731 } else if (!strcmp(str, "TRACE_INFO") || !strcmp(str, "INFO")) {
732 return LTTNG_LOGLEVEL_INFO;
733 } else if (!strcmp(str, "TRACE_DEBUG_SYSTEM") || !strcmp(str, "DEBUG_SYSTEM") || !strcmp(str, "SYSTEM")) {
734 return LTTNG_LOGLEVEL_DEBUG_SYSTEM;
735 } else if (!strcmp(str, "TRACE_DEBUG_PROGRAM") || !strcmp(str, "DEBUG_PROGRAM") || !strcmp(str, "PROGRAM")) {
736 return LTTNG_LOGLEVEL_DEBUG_PROGRAM;
737 } else if (!strcmp(str, "TRACE_DEBUG_PROCESS") || !strcmp(str, "DEBUG_PROCESS") || !strcmp(str, "PROCESS")) {
738 return LTTNG_LOGLEVEL_DEBUG_PROCESS;
739 } else if (!strcmp(str, "TRACE_DEBUG_MODULE") || !strcmp(str, "DEBUG_MODULE") || !strcmp(str, "MODULE")) {
740 return LTTNG_LOGLEVEL_DEBUG_MODULE;
741 } else if (!strcmp(str, "TRACE_DEBUG_UNIT") || !strcmp(str, "DEBUG_UNIT") || !strcmp(str, "UNIT")) {
742 return LTTNG_LOGLEVEL_DEBUG_UNIT;
743 } else if (!strcmp(str, "TRACE_DEBUG_FUNCTION") || !strcmp(str, "DEBUG_FUNCTION") || !strcmp(str, "FUNCTION")) {
744 return LTTNG_LOGLEVEL_DEBUG_FUNCTION;
745 } else if (!strcmp(str, "TRACE_DEBUG_LINE") || !strcmp(str, "DEBUG_LINE") || !strcmp(str, "LINE")) {
746 return LTTNG_LOGLEVEL_DEBUG_LINE;
747 } else if (!strcmp(str, "TRACE_DEBUG") || !strcmp(str, "DEBUG")) {
748 return LTTNG_LOGLEVEL_DEBUG;
8005f29a
MD
749 } else {
750 return -1;
751 }
752}
753
85076754
MD
754static
755const char *print_channel_name(const char *name)
756{
757 return name ? : DEFAULT_CHANNEL_NAME;
758}
759
760static
761const char *print_raw_channel_name(const char *name)
762{
763 return name ? : "<default>";
764}
765
89476427
JRJ
766/*
767 * Mi print exlcusion list
768 */
769static
9f449915 770int mi_print_exclusion(char **names)
89476427
JRJ
771{
772 int i, ret;
9f449915 773 int count = names ? strutils_array_of_strings_len(names) : 0;
89476427
JRJ
774
775 assert(writer);
776
777 if (count == 0) {
778 ret = 0;
779 goto end;
780 }
781 ret = mi_lttng_writer_open_element(writer, config_element_exclusions);
782 if (ret) {
783 goto end;
784 }
785
786 for (i = 0; i < count; i++) {
787 ret = mi_lttng_writer_write_element_string(writer,
788 config_element_exclusion, names[i]);
789 if (ret) {
790 goto end;
791 }
792 }
793
794 /* Close exclusions element */
795 ret = mi_lttng_writer_close_element(writer);
796
797end:
798 return ret;
799}
800
9c48cab3
JI
801/*
802 * Return allocated string for pretty-printing exclusion names.
803 */
804static
9f449915 805char *print_exclusions(char **names)
9c48cab3
JI
806{
807 int length = 0;
808 int i;
809 const char *preamble = " excluding ";
810 char *ret;
9f449915 811 int count = names ? strutils_array_of_strings_len(names) : 0;
9c48cab3
JI
812
813 if (count == 0) {
814 return strdup("");
815 }
816
817 /* calculate total required length */
818 for (i = 0; i < count; i++) {
9f449915 819 length += strlen(names[i]) + 4;
9c48cab3
JI
820 }
821
822 /* add length of preamble + one for NUL - one for last (missing) comma */
823 length += strlen(preamble);
9f449915 824 ret = zmalloc(length + 1);
fd591b18
MD
825 if (!ret) {
826 return NULL;
827 }
9c48cab3
JI
828 strncpy(ret, preamble, length);
829 for (i = 0; i < count; i++) {
9f449915 830 strcat(ret, "\"");
9c48cab3 831 strcat(ret, names[i]);
9f449915 832 strcat(ret, "\"");
9c48cab3 833 if (i != count - 1) {
9f449915 834 strcat(ret, ", ");
9c48cab3
JI
835 }
836 }
89476427 837
9c48cab3
JI
838 return ret;
839}
840
748bde76 841static
9f449915 842int check_exclusion_subsets(const char *event_name, const char *exclusion)
748bde76 843{
9f449915
PP
844 bool warn = false;
845 int ret = 0;
846 const char *e = event_name;
847 const char *x = exclusion;
848
849 /* Scan both the excluder and the event letter by letter */
850 while (true) {
851 if (*e == '\\') {
852 if (*x != *e) {
853 warn = true;
854 goto end;
855 }
748bde76 856
9f449915
PP
857 e++;
858 x++;
859 goto cmp_chars;
860 }
861
862 if (*x == '*') {
863 /* Event is a subset of the excluder */
864 ERR("Event %s: %s excludes all events from %s",
865 event_name, exclusion, event_name);
866 goto error;
867 }
868
869 if (*e == '*') {
870 /*
871 * Reached the end of the event name before the
872 * end of the exclusion: this is valid.
873 */
874 goto end;
875 }
876
877cmp_chars:
878 if (*x != *e) {
879 warn = true;
880 break;
881 }
882
883 x++;
884 e++;
748bde76
JI
885 }
886
9f449915 887 goto end;
748bde76 888
9f449915
PP
889error:
890 ret = -1;
748bde76 891
9f449915
PP
892end:
893 if (warn) {
894 WARN("Event %s: %s does not exclude any events from %s",
895 event_name, exclusion, event_name);
896 }
748bde76 897
9f449915
PP
898 return ret;
899}
900
9f449915
PP
901static
902int create_exclusion_list_and_validate(const char *event_name,
903 const char *exclusions_arg,
904 char ***exclusion_list)
905{
906 int ret = 0;
907 char **exclusions = NULL;
908
909 /* Event name must be a valid globbing pattern to allow exclusions. */
910 if (!strutils_is_star_glob_pattern(event_name)) {
911 ERR("Event %s: Exclusions can only be used with a globbing pattern",
912 event_name);
913 goto error;
914 }
915
916 /* Split exclusions. */
917 exclusions = strutils_split(exclusions_arg, ',', true);
918 if (!exclusions) {
919 goto error;
920 }
921
922 /*
923 * If the event name is a star-at-end only globbing pattern,
924 * then we can validate the individual exclusions. Otherwise
925 * all exclusions are passed to the session daemon.
926 */
927 if (strutils_is_star_at_the_end_only_glob_pattern(event_name)) {
928 char * const *exclusion;
929
930 for (exclusion = exclusions; *exclusion; exclusion++) {
931 if (!strutils_is_star_glob_pattern(*exclusion) ||
932 strutils_is_star_at_the_end_only_glob_pattern(*exclusion)) {
8aa579d4 933 ret = check_exclusion_subsets(event_name, *exclusion);
9f449915 934 if (ret) {
5ef79758
MD
935 goto error;
936 }
748bde76 937 }
748bde76
JI
938 }
939 }
9f449915
PP
940
941 *exclusion_list = exclusions;
942
748bde76 943 goto end;
9f449915 944
748bde76 945error:
9f449915
PP
946 ret = -1;
947 strutils_free_null_terminated_array_of_strings(exclusions);
948
748bde76 949end:
748bde76
JI
950 return ret;
951}
502bbe89 952
9f449915
PP
953static void warn_on_truncated_exclusion_names(char * const *exclusion_list,
954 int *warn)
502bbe89 955{
9f449915 956 char * const *exclusion;
502bbe89 957
9f449915
PP
958 for (exclusion = exclusion_list; *exclusion; exclusion++) {
959 if (strlen(*exclusion) >= LTTNG_SYMBOL_NAME_LEN) {
502bbe89 960 WARN("Event exclusion \"%s\" will be truncated",
9f449915 961 *exclusion);
502bbe89
PP
962 *warn = 1;
963 }
964 }
965}
966
f3ed775e 967/*
6181537c 968 * Enabling event using the lttng API.
89476427 969 * Note: in case of error only the last error code will be return.
f3ed775e 970 */
cd80958d 971static int enable_events(char *session_name)
f3ed775e 972{
89476427
JRJ
973 int ret = CMD_SUCCESS, command_ret = CMD_SUCCESS;
974 int error_holder = CMD_SUCCESS, warn = 0, error = 0, success = 1;
b73d0b29 975 char *event_name, *channel_name = NULL;
91744e14 976 struct lttng_event *ev;
7d29a247 977 struct lttng_domain dom;
7ed70bc9 978 char **exclusion_list = NULL;
f3ed775e 979
441c16a7
MD
980 memset(&dom, 0, sizeof(dom));
981
91744e14
FD
982 ev = lttng_event_create();
983 if (!ev) {
984 ret = CMD_ERROR;
985 goto error;
986 }
987
53a80697 988 if (opt_kernel) {
67b58630
JG
989 if (opt_loglevel) {
990 WARN("Kernel loglevels are not supported.");
991 }
53a80697
MD
992 }
993
7d29a247
DG
994 /* Create lttng domain */
995 if (opt_kernel) {
996 dom.type = LTTNG_DOMAIN_KERNEL;
7972aab2 997 dom.buf_type = LTTNG_BUFFER_GLOBAL;
d78d6610 998 } else if (opt_userspace) {
2bdd86d4 999 dom.type = LTTNG_DOMAIN_UST;
7972aab2 1000 /* Default. */
8692d4e5 1001 dom.buf_type = LTTNG_BUFFER_PER_UID;
b9dfb167
DG
1002 } else if (opt_jul) {
1003 dom.type = LTTNG_DOMAIN_JUL;
1004 /* Default. */
1005 dom.buf_type = LTTNG_BUFFER_PER_UID;
5cdb6027
DG
1006 } else if (opt_log4j) {
1007 dom.type = LTTNG_DOMAIN_LOG4J;
1008 /* Default. */
1009 dom.buf_type = LTTNG_BUFFER_PER_UID;
0e115563
DG
1010 } else if (opt_python) {
1011 dom.type = LTTNG_DOMAIN_PYTHON;
1012 /* Default. */
1013 dom.buf_type = LTTNG_BUFFER_PER_UID;
6181537c 1014 } else {
3ecec76a
PP
1015 /* Checked by the caller. */
1016 assert(0);
2bdd86d4 1017 }
7d29a247 1018
8b08c525
AB
1019 if (opt_exclude) {
1020 switch (dom.type) {
1021 case LTTNG_DOMAIN_KERNEL:
1022 case LTTNG_DOMAIN_JUL:
1023 case LTTNG_DOMAIN_LOG4J:
1024 case LTTNG_DOMAIN_PYTHON:
1025 ERR("Event name exclusions are not yet implemented for %s events",
1026 get_domain_str(dom.type));
1027 ret = CMD_ERROR;
1028 goto error;
1029 case LTTNG_DOMAIN_UST:
1030 /* Exclusions supported */
1031 break;
1032 default:
1033 assert(0);
1034 }
d5dd17fd
JI
1035 }
1036
4fd2697f
FD
1037 /*
1038 * Adding a filter to a probe, function or userspace-probe would be
1039 * denied by the kernel tracer as it's not supported at the moment. We
1040 * do an early check here to warn the user.
1041 */
1042 if (opt_filter && opt_kernel) {
1043 switch (opt_event_type) {
1044 case LTTNG_EVENT_ALL:
1045 case LTTNG_EVENT_TRACEPOINT:
1046 case LTTNG_EVENT_SYSCALL:
1047 break;
1048 case LTTNG_EVENT_PROBE:
1049 case LTTNG_EVENT_USERSPACE_PROBE:
1050 case LTTNG_EVENT_FUNCTION:
1051 ERR("Filter expressions are not supported for %s events",
1052 get_event_type_str(opt_event_type));
1053 ret = CMD_ERROR;
1054 goto error;
1055 default:
1056 ret = CMD_UNDEFINED;
1057 goto error;
1058 }
1059 }
1060
85076754 1061 channel_name = opt_channel_name;
ae856491 1062
cd80958d
DG
1063 handle = lttng_create_handle(session_name, &dom);
1064 if (handle == NULL) {
1065 ret = -1;
1066 goto error;
1067 }
1aef21b6 1068
89476427
JRJ
1069 /* Prepare Mi */
1070 if (lttng_opt_mi) {
1071 /* Open a events element */
1072 ret = mi_lttng_writer_open_element(writer, config_element_events);
1073 if (ret) {
1074 ret = CMD_ERROR;
1075 goto error;
1076 }
1077 }
1078
cd80958d 1079 if (opt_enable_all) {
8c9ae521 1080 /* Default setup for enable all */
75e8c5ab 1081 if (opt_kernel) {
91744e14
FD
1082 ev->type = opt_event_type;
1083 strcpy(ev->name, "*");
300b8fd5 1084 /* kernel loglevels not implemented */
91744e14 1085 ev->loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
75e8c5ab 1086 } else {
91744e14
FD
1087 ev->type = LTTNG_EVENT_TRACEPOINT;
1088 strcpy(ev->name, "*");
1089 ev->loglevel_type = opt_loglevel_type;
300b8fd5 1090 if (opt_loglevel) {
0e115563 1091 assert(opt_userspace || opt_jul || opt_log4j || opt_python);
b2064f54 1092 if (opt_userspace) {
91744e14 1093 ev->loglevel = loglevel_str_to_value(opt_loglevel);
b2064f54 1094 } else if (opt_jul) {
91744e14 1095 ev->loglevel = loglevel_jul_str_to_value(opt_loglevel);
5cdb6027 1096 } else if (opt_log4j) {
91744e14 1097 ev->loglevel = loglevel_log4j_str_to_value(opt_loglevel);
0e115563 1098 } else if (opt_python) {
91744e14 1099 ev->loglevel = loglevel_python_str_to_value(opt_loglevel);
b2064f54 1100 }
91744e14 1101 if (ev->loglevel == -1) {
300b8fd5 1102 ERR("Unknown loglevel %s", opt_loglevel);
2f70b271 1103 ret = -LTTNG_ERR_INVALID;
300b8fd5
MD
1104 goto error;
1105 }
22e25b71 1106 } else {
0e115563 1107 assert(opt_userspace || opt_jul || opt_log4j || opt_python);
b2064f54 1108 if (opt_userspace) {
91744e14 1109 ev->loglevel = -1;
34aa3685 1110 } else if (opt_jul) {
91744e14 1111 ev->loglevel = LTTNG_LOGLEVEL_JUL_ALL;
34aa3685 1112 } else if (opt_log4j) {
91744e14 1113 ev->loglevel = LTTNG_LOGLEVEL_LOG4J_ALL;
0e115563 1114 } else if (opt_python) {
91744e14 1115 ev->loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG;
b2064f54 1116 }
300b8fd5 1117 }
75e8c5ab 1118 }
8c9ae521 1119
7ed70bc9 1120 if (opt_exclude) {
9f449915
PP
1121 ret = create_exclusion_list_and_validate("*",
1122 opt_exclude, &exclusion_list);
1123 if (ret) {
1124 ret = CMD_ERROR;
7ed70bc9
JI
1125 goto error;
1126 }
502bbe89 1127
91744e14 1128 ev->exclusion = 1;
502bbe89 1129 warn_on_truncated_exclusion_names(exclusion_list,
9f449915 1130 &warn);
7ed70bc9 1131 }
025faf73 1132 if (!opt_filter) {
7ed70bc9 1133 ret = lttng_enable_event_with_exclusions(handle,
91744e14 1134 ev, channel_name,
7ed70bc9 1135 NULL,
9f449915
PP
1136 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
1137 exclusion_list);
025faf73
DG
1138 if (ret < 0) {
1139 switch (-ret) {
1140 case LTTNG_ERR_KERN_EVENT_EXIST:
1141 WARN("Kernel events already enabled (channel %s, session %s)",
85076754 1142 print_channel_name(channel_name), session_name);
89476427 1143 warn = 1;
025faf73 1144 break;
45d5d421
CB
1145 case LTTNG_ERR_TRACE_ALREADY_STARTED:
1146 {
1147 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
1148 ERR("Events: %s (channel %s, session %s)",
1149 msg,
1150 print_channel_name(channel_name),
1151 session_name);
1152 error = 1;
1153 break;
1154 }
025faf73
DG
1155 default:
1156 ERR("Events: %s (channel %s, session %s)",
85076754
MD
1157 lttng_strerror(ret),
1158 ret == -LTTNG_ERR_NEED_CHANNEL_NAME
1159 ? print_raw_channel_name(channel_name)
1160 : print_channel_name(channel_name),
1161 session_name);
89476427 1162 error = 1;
025faf73
DG
1163 break;
1164 }
1165 goto end;
42224349 1166 }
8c9ae521 1167
025faf73
DG
1168 switch (opt_event_type) {
1169 case LTTNG_EVENT_TRACEPOINT:
67b58630 1170 if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) {
9f449915 1171 char *exclusion_string = print_exclusions(exclusion_list);
5ef79758
MD
1172
1173 if (!exclusion_string) {
1174 PERROR("Cannot allocate exclusion_string");
1175 error = 1;
1176 goto end;
1177 }
9c48cab3 1178 MSG("All %s tracepoints%s are enabled in channel %s for loglevel %s",
b9dfb167 1179 get_domain_str(dom.type),
9c48cab3 1180 exclusion_string,
85076754 1181 print_channel_name(channel_name),
025faf73 1182 opt_loglevel);
9c48cab3 1183 free(exclusion_string);
025faf73 1184 } else {
9f449915 1185 char *exclusion_string = print_exclusions(exclusion_list);
5ef79758
MD
1186
1187 if (!exclusion_string) {
1188 PERROR("Cannot allocate exclusion_string");
1189 error = 1;
1190 goto end;
1191 }
9c48cab3 1192 MSG("All %s tracepoints%s are enabled in channel %s",
b9dfb167 1193 get_domain_str(dom.type),
9c48cab3 1194 exclusion_string,
85076754 1195 print_channel_name(channel_name));
9c48cab3 1196 free(exclusion_string);
025faf73
DG
1197 }
1198 break;
1199 case LTTNG_EVENT_SYSCALL:
1200 if (opt_kernel) {
6e911cad
MD
1201 MSG("All %s system calls are enabled in channel %s",
1202 get_domain_str(dom.type),
85076754 1203 print_channel_name(channel_name));
025faf73
DG
1204 }
1205 break;
1206 case LTTNG_EVENT_ALL:
67b58630 1207 if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) {
9f449915 1208 char *exclusion_string = print_exclusions(exclusion_list);
5ef79758
MD
1209
1210 if (!exclusion_string) {
1211 PERROR("Cannot allocate exclusion_string");
1212 error = 1;
1213 goto end;
1214 }
9c48cab3 1215 MSG("All %s events%s are enabled in channel %s for loglevel %s",
b9dfb167 1216 get_domain_str(dom.type),
9c48cab3 1217 exclusion_string,
85076754 1218 print_channel_name(channel_name),
025faf73 1219 opt_loglevel);
9c48cab3 1220 free(exclusion_string);
025faf73 1221 } else {
9f449915 1222 char *exclusion_string = print_exclusions(exclusion_list);
5ef79758
MD
1223
1224 if (!exclusion_string) {
1225 PERROR("Cannot allocate exclusion_string");
1226 error = 1;
1227 goto end;
1228 }
9c48cab3 1229 MSG("All %s events%s are enabled in channel %s",
b9dfb167 1230 get_domain_str(dom.type),
9c48cab3 1231 exclusion_string,
85076754 1232 print_channel_name(channel_name));
9c48cab3 1233 free(exclusion_string);
025faf73
DG
1234 }
1235 break;
1236 default:
1237 /*
1238 * We should not be here since lttng_enable_event should have
1239 * failed on the event type.
1240 */
1241 goto error;
57064ada 1242 }
f3ed775e 1243 }
89476427 1244
025faf73 1245 if (opt_filter) {
91744e14 1246 command_ret = lttng_enable_event_with_exclusions(handle, ev, channel_name,
9f449915
PP
1247 opt_filter,
1248 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
1249 exclusion_list);
89476427
JRJ
1250 if (command_ret < 0) {
1251 switch (-command_ret) {
16363652 1252 case LTTNG_ERR_FILTER_EXIST:
85076754 1253 WARN("Filter on all events is already enabled"
16363652 1254 " (channel %s, session %s)",
85076754 1255 print_channel_name(channel_name), session_name);
89476427 1256 warn = 1;
16363652 1257 break;
45d5d421
CB
1258 case LTTNG_ERR_TRACE_ALREADY_STARTED:
1259 {
1260 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
1261 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
1262 msg,
1263 print_channel_name(channel_name),
1264 session_name, opt_filter);
1265 error = 1;
1266 break;
1267 }
16363652 1268 default:
85076754 1269 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
da3d7d0e
JRJ
1270 lttng_strerror(command_ret),
1271 command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
85076754
MD
1272 ? print_raw_channel_name(channel_name)
1273 : print_channel_name(channel_name),
1274 session_name, opt_filter);
89476427 1275 error = 1;
16363652
DG
1276 break;
1277 }
89476427 1278 error_holder = command_ret;
16363652 1279 } else {
91744e14 1280 ev->filter = 1;
16363652
DG
1281 MSG("Filter '%s' successfully set", opt_filter);
1282 }
1283 }
89476427
JRJ
1284
1285 if (lttng_opt_mi) {
1286 /* The wildcard * is used for kernel and ust domain to
1287 * represent ALL. We copy * in event name to force the wildcard use
1288 * for kernel domain
1289 *
1290 * Note: this is strictly for semantic and printing while in
1291 * machine interface mode.
1292 */
91744e14 1293 strcpy(ev->name, "*");
89476427
JRJ
1294
1295 /* If we reach here the events are enabled */
1296 if (!error && !warn) {
91744e14 1297 ev->enabled = 1;
89476427 1298 } else {
91744e14 1299 ev->enabled = 0;
89476427
JRJ
1300 success = 0;
1301 }
91744e14 1302 ret = mi_lttng_event(writer, ev, 1, handle->domain.type);
89476427
JRJ
1303 if (ret) {
1304 ret = CMD_ERROR;
1305 goto error;
1306 }
1307
1308 /* print exclusion */
9f449915 1309 ret = mi_print_exclusion(exclusion_list);
89476427
JRJ
1310 if (ret) {
1311 ret = CMD_ERROR;
1312 goto error;
1313 }
1314
1315 /* Success ? */
1316 ret = mi_lttng_writer_write_element_bool(writer,
1317 mi_lttng_element_command_success, success);
1318 if (ret) {
1319 ret = CMD_ERROR;
1320 goto error;
1321 }
1322
1323 /* Close event element */
1324 ret = mi_lttng_writer_close_element(writer);
1325 if (ret) {
1326 ret = CMD_ERROR;
1327 goto error;
1328 }
1329 }
1330
8c9ae521 1331 goto end;
f3ed775e
DG
1332 }
1333
1334 /* Strip event list */
1335 event_name = strtok(opt_event_list, ",");
1336 while (event_name != NULL) {
6181537c 1337 /* Copy name and type of the event */
91744e14
FD
1338 strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN);
1339 ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
1340 ev->type = opt_event_type;
6181537c 1341
f3ed775e
DG
1342 /* Kernel tracer action */
1343 if (opt_kernel) {
1344 DBG("Enabling kernel event %s for channel %s",
85076754
MD
1345 event_name,
1346 print_channel_name(channel_name));
f3ed775e
DG
1347
1348 switch (opt_event_type) {
29c62722
MD
1349 case LTTNG_EVENT_ALL: /* Enable tracepoints and syscalls */
1350 /* If event name differs from *, select tracepoint. */
91744e14
FD
1351 if (strcmp(ev->name, "*")) {
1352 ev->type = LTTNG_EVENT_TRACEPOINT;
29c62722
MD
1353 }
1354 break;
e6ddca71 1355 case LTTNG_EVENT_TRACEPOINT:
f3ed775e 1356 break;
7d29a247 1357 case LTTNG_EVENT_PROBE:
91744e14 1358 ret = parse_probe_opts(ev, opt_probe);
49d4e302 1359 if (ret) {
cf0e5467 1360 ERR("Unable to parse probe options");
91744e14 1361 ret = CMD_ERROR;
0d63dd19
DG
1362 goto error;
1363 }
f3ed775e 1364 break;
dcabc190
FD
1365 case LTTNG_EVENT_USERSPACE_PROBE:
1366 ret = parse_userspace_probe_opts(ev, opt_userspace_probe);
1367 if (ret) {
36aa2f64
FD
1368 switch (ret) {
1369 case CMD_UNSUPPORTED:
1370 /*
1371 * Error message describing
1372 * what is not supported was
1373 * printed in the function.
1374 */
1375 break;
1376 case CMD_ERROR:
1377 default:
1378 ERR("Unable to parse userspace probe options");
1379 break;
1380 }
dcabc190
FD
1381 goto error;
1382 }
1383 break;
f3ed775e 1384 case LTTNG_EVENT_FUNCTION:
91744e14 1385 ret = parse_probe_opts(ev, opt_function);
49d4e302 1386 if (ret) {
8f0d098b 1387 ERR("Unable to parse function probe options");
91744e14 1388 ret = CMD_ERROR;
8f0d098b
MD
1389 goto error;
1390 }
1391 break;
a54bd42d 1392 case LTTNG_EVENT_SYSCALL:
91744e14 1393 ev->type = LTTNG_EVENT_SYSCALL;
c6aa2d41 1394 break;
f3ed775e 1395 default:
1ab1ea0b 1396 ret = CMD_UNDEFINED;
f3ed775e
DG
1397 goto error;
1398 }
0cda4f28 1399
0cda4f28 1400 /* kernel loglevels not implemented */
91744e14 1401 ev->loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
f3ed775e 1402 } else if (opt_userspace) { /* User-space tracer action */
300b8fd5 1403 DBG("Enabling UST event %s for channel %s, loglevel %s", event_name,
85076754 1404 print_channel_name(channel_name), opt_loglevel ? : "<all>");
2bdd86d4
MD
1405
1406 switch (opt_event_type) {
1407 case LTTNG_EVENT_ALL: /* Default behavior is tracepoint */
2bdd86d4
MD
1408 /* Fall-through */
1409 case LTTNG_EVENT_TRACEPOINT:
e4baff1e 1410 /* Copy name and type of the event */
91744e14
FD
1411 ev->type = LTTNG_EVENT_TRACEPOINT;
1412 strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN);
1413 ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
2bdd86d4
MD
1414 break;
1415 case LTTNG_EVENT_PROBE:
1416 case LTTNG_EVENT_FUNCTION:
2bdd86d4 1417 case LTTNG_EVENT_SYSCALL:
dcabc190 1418 case LTTNG_EVENT_USERSPACE_PROBE:
2bdd86d4 1419 default:
cc62c0c0 1420 ERR("Event type not available for user-space tracing");
4ce78777 1421 ret = CMD_UNSUPPORTED;
2bdd86d4
MD
1422 goto error;
1423 }
0cda4f28 1424
7ed70bc9 1425 if (opt_exclude) {
91744e14 1426 ev->exclusion = 1;
d5dd17fd
JI
1427 if (opt_event_type != LTTNG_EVENT_ALL && opt_event_type != LTTNG_EVENT_TRACEPOINT) {
1428 ERR("Exclusion option can only be used with tracepoint events");
1429 ret = CMD_ERROR;
1430 goto error;
1431 }
7ed70bc9 1432 /* Free previously allocated items */
9f449915
PP
1433 strutils_free_null_terminated_array_of_strings(
1434 exclusion_list);
1435 exclusion_list = NULL;
1436 ret = create_exclusion_list_and_validate(
1437 event_name, opt_exclude,
1438 &exclusion_list);
1439 if (ret) {
1440 ret = CMD_ERROR;
7ed70bc9
JI
1441 goto error;
1442 }
502bbe89
PP
1443
1444 warn_on_truncated_exclusion_names(
9f449915 1445 exclusion_list, &warn);
7ed70bc9
JI
1446 }
1447
91744e14 1448 ev->loglevel_type = opt_loglevel_type;
ed7f4083 1449 if (opt_loglevel) {
91744e14
FD
1450 ev->loglevel = loglevel_str_to_value(opt_loglevel);
1451 if (ev->loglevel == -1) {
8005f29a 1452 ERR("Unknown loglevel %s", opt_loglevel);
2f70b271 1453 ret = -LTTNG_ERR_INVALID;
8005f29a
MD
1454 goto error;
1455 }
22e25b71 1456 } else {
91744e14 1457 ev->loglevel = -1;
ed7f4083 1458 }
0e115563 1459 } else if (opt_jul || opt_log4j || opt_python) {
b9dfb167
DG
1460 if (opt_event_type != LTTNG_EVENT_ALL &&
1461 opt_event_type != LTTNG_EVENT_TRACEPOINT) {
5cdb6027 1462 ERR("Event type not supported for domain.");
b9dfb167
DG
1463 ret = CMD_UNSUPPORTED;
1464 goto error;
1465 }
b2064f54 1466
91744e14 1467 ev->loglevel_type = opt_loglevel_type;
b2064f54 1468 if (opt_loglevel) {
5cdb6027 1469 if (opt_jul) {
91744e14 1470 ev->loglevel = loglevel_jul_str_to_value(opt_loglevel);
5cdb6027 1471 } else if (opt_log4j) {
91744e14 1472 ev->loglevel = loglevel_log4j_str_to_value(opt_loglevel);
0e115563 1473 } else if (opt_python) {
91744e14 1474 ev->loglevel = loglevel_python_str_to_value(opt_loglevel);
5cdb6027 1475 }
91744e14 1476 if (ev->loglevel == -1) {
b2064f54
DG
1477 ERR("Unknown loglevel %s", opt_loglevel);
1478 ret = -LTTNG_ERR_INVALID;
1479 goto error;
1480 }
1481 } else {
5cdb6027 1482 if (opt_jul) {
91744e14 1483 ev->loglevel = LTTNG_LOGLEVEL_JUL_ALL;
5cdb6027 1484 } else if (opt_log4j) {
91744e14 1485 ev->loglevel = LTTNG_LOGLEVEL_LOG4J_ALL;
0e115563 1486 } else if (opt_python) {
91744e14 1487 ev->loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG;
5cdb6027 1488 }
b2064f54 1489 }
91744e14
FD
1490 ev->type = LTTNG_EVENT_TRACEPOINT;
1491 strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN);
1492 ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
f3ed775e 1493 } else {
3ecec76a 1494 assert(0);
f3ed775e
DG
1495 }
1496
025faf73 1497 if (!opt_filter) {
9c48cab3
JI
1498 char *exclusion_string;
1499
89476427 1500 command_ret = lttng_enable_event_with_exclusions(handle,
91744e14 1501 ev, channel_name,
9f449915
PP
1502 NULL,
1503 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
1504 exclusion_list);
1505 exclusion_string = print_exclusions(exclusion_list);
5ef79758
MD
1506 if (!exclusion_string) {
1507 PERROR("Cannot allocate exclusion_string");
1508 error = 1;
1509 goto end;
1510 }
89476427 1511 if (command_ret < 0) {
025faf73 1512 /* Turn ret to positive value to handle the positive error code */
89476427 1513 switch (-command_ret) {
025faf73 1514 case LTTNG_ERR_KERN_EVENT_EXIST:
9c48cab3 1515 WARN("Kernel event %s%s already enabled (channel %s, session %s)",
85076754 1516 event_name,
9c48cab3 1517 exclusion_string,
85076754 1518 print_channel_name(channel_name), session_name);
89476427 1519 warn = 1;
025faf73 1520 break;
45d5d421
CB
1521 case LTTNG_ERR_TRACE_ALREADY_STARTED:
1522 {
1523 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
1524 ERR("Event %s%s: %s (channel %s, session %s)", event_name,
1525 exclusion_string,
1526 msg,
1527 print_channel_name(channel_name),
1528 session_name);
1529 error = 1;
1530 break;
1531 }
dcabc190
FD
1532 case LTTNG_ERR_SDT_PROBE_SEMAPHORE:
1533 ERR("SDT probes %s guarded by semaphores are not supported (channel %s, session %s)",
1534 event_name, print_channel_name(channel_name),
1535 session_name);
1536 error = 1;
1537 break;
025faf73 1538 default:
9c48cab3
JI
1539 ERR("Event %s%s: %s (channel %s, session %s)", event_name,
1540 exclusion_string,
da3d7d0e
JRJ
1541 lttng_strerror(command_ret),
1542 command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
85076754
MD
1543 ? print_raw_channel_name(channel_name)
1544 : print_channel_name(channel_name),
1545 session_name);
89476427 1546 error = 1;
025faf73
DG
1547 break;
1548 }
89476427 1549 error_holder = command_ret;
025faf73 1550 } else {
8274eeba
AB
1551 switch (dom.type) {
1552 case LTTNG_DOMAIN_KERNEL:
1553 case LTTNG_DOMAIN_UST:
49ceaa70 1554 MSG("%s event %s%s created in channel %s",
8274eeba
AB
1555 get_domain_str(dom.type),
1556 event_name,
1557 exclusion_string,
1558 print_channel_name(channel_name));
1559 break;
1560 case LTTNG_DOMAIN_JUL:
1561 case LTTNG_DOMAIN_LOG4J:
1562 case LTTNG_DOMAIN_PYTHON:
1563 /*
1564 * Don't print the default channel
1565 * name for agent domains.
1566 */
895707da 1567 MSG("%s event %s%s enabled",
8274eeba
AB
1568 get_domain_str(dom.type),
1569 event_name,
1570 exclusion_string);
1571 break;
1572 default:
1573 assert(0);
49ceaa70 1574 }
42224349 1575 }
9c48cab3 1576 free(exclusion_string);
6181537c 1577 }
025faf73
DG
1578
1579 if (opt_filter) {
9c48cab3
JI
1580 char *exclusion_string;
1581
89476427 1582 /* Filter present */
91744e14 1583 ev->filter = 1;
89476427 1584
91744e14 1585 command_ret = lttng_enable_event_with_exclusions(handle, ev, channel_name,
9f449915
PP
1586 opt_filter,
1587 exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0,
1588 exclusion_list);
1589 exclusion_string = print_exclusions(exclusion_list);
5ef79758
MD
1590 if (!exclusion_string) {
1591 PERROR("Cannot allocate exclusion_string");
1592 error = 1;
1593 goto end;
1594 }
89476427
JRJ
1595 if (command_ret < 0) {
1596 switch (-command_ret) {
7671f53c 1597 case LTTNG_ERR_FILTER_EXIST:
9c48cab3 1598 WARN("Filter on event %s%s is already enabled"
7671f53c 1599 " (channel %s, session %s)",
85076754 1600 event_name,
9c48cab3 1601 exclusion_string,
85076754 1602 print_channel_name(channel_name), session_name);
89476427 1603 warn = 1;
7671f53c 1604 break;
45d5d421
CB
1605 case LTTNG_ERR_TRACE_ALREADY_STARTED:
1606 {
1607 const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once.";
91744e14 1608 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev->name,
45d5d421
CB
1609 exclusion_string,
1610 msg,
1611 print_channel_name(channel_name),
1612 session_name, opt_filter);
1613 error = 1;
1614 break;
1615 }
7671f53c 1616 default:
91744e14 1617 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev->name,
9c48cab3 1618 exclusion_string,
da3d7d0e
JRJ
1619 lttng_strerror(command_ret),
1620 command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
85076754
MD
1621 ? print_raw_channel_name(channel_name)
1622 : print_channel_name(channel_name),
1623 session_name, opt_filter);
89476427 1624 error = 1;
7671f53c
CB
1625 break;
1626 }
89476427
JRJ
1627 error_holder = command_ret;
1628
16363652 1629 } else {
9c48cab3
JI
1630 MSG("Event %s%s: Filter '%s' successfully set",
1631 event_name, exclusion_string,
1632 opt_filter);
53a80697 1633 }
9c48cab3 1634 free(exclusion_string);
53a80697 1635 }
6181537c 1636
89476427
JRJ
1637 if (lttng_opt_mi) {
1638 if (command_ret) {
1639 success = 0;
91744e14 1640 ev->enabled = 0;
89476427 1641 } else {
91744e14 1642 ev->enabled = 1;
89476427
JRJ
1643 }
1644
91744e14 1645 ret = mi_lttng_event(writer, ev, 1, handle->domain.type);
89476427
JRJ
1646 if (ret) {
1647 ret = CMD_ERROR;
1648 goto error;
1649 }
1650
1651 /* print exclusion */
9f449915 1652 ret = mi_print_exclusion(exclusion_list);
89476427
JRJ
1653 if (ret) {
1654 ret = CMD_ERROR;
1655 goto error;
1656 }
1657
1658 /* Success ? */
1659 ret = mi_lttng_writer_write_element_bool(writer,
1660 mi_lttng_element_command_success, success);
1661 if (ret) {
1662 ret = CMD_ERROR;
1663 goto end;
1664 }
1665
1666 /* Close event element */
1667 ret = mi_lttng_writer_close_element(writer);
1668 if (ret) {
1669 ret = CMD_ERROR;
1670 goto end;
1671 }
1672 }
1673
f3ed775e
DG
1674 /* Next event */
1675 event_name = strtok(NULL, ",");
89476427
JRJ
1676 /* Reset warn, error and success */
1677 success = 1;
f3ed775e
DG
1678 }
1679
8c9ae521 1680end:
89476427
JRJ
1681 /* Close Mi */
1682 if (lttng_opt_mi) {
1683 /* Close events element */
1684 ret = mi_lttng_writer_close_element(writer);
1685 if (ret) {
1686 ret = CMD_ERROR;
1687 goto error;
1688 }
1689 }
f3ed775e 1690error:
ae856491
DG
1691 if (warn) {
1692 ret = CMD_WARNING;
1693 }
89476427
JRJ
1694 if (error) {
1695 ret = CMD_ERROR;
1696 }
cd80958d 1697 lttng_destroy_handle(handle);
9f449915 1698 strutils_free_null_terminated_array_of_strings(exclusion_list);
7ed70bc9 1699
89476427
JRJ
1700 /* Overwrite ret with error_holder if there was an actual error with
1701 * enabling an event.
1702 */
1703 ret = error_holder ? error_holder : ret;
1704
91744e14 1705 lttng_event_destroy(ev);
f3ed775e
DG
1706 return ret;
1707}
1708
1709/*
6181537c 1710 * Add event to trace session
f3ed775e
DG
1711 */
1712int cmd_enable_events(int argc, const char **argv)
1713{
89476427 1714 int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
f3ed775e 1715 static poptContext pc;
cd80958d 1716 char *session_name = NULL;
68c7f6e5 1717 const char *leftover = NULL;
de044b7a 1718 int event_type = -1;
f3ed775e
DG
1719
1720 pc = poptGetContext(NULL, argc, argv, long_options, 0);
1721 poptReadDefaultConfig(pc, 0);
1722
1723 /* Default event type */
7a3d1328 1724 opt_event_type = LTTNG_EVENT_ALL;
f3ed775e
DG
1725
1726 while ((opt = poptGetNextOpt(pc)) != -1) {
1727 switch (opt) {
1728 case OPT_HELP:
4ba92f18 1729 SHOW_HELP();
f3ed775e 1730 goto end;
f3ed775e 1731 case OPT_TRACEPOINT:
e6ddca71 1732 opt_event_type = LTTNG_EVENT_TRACEPOINT;
f3ed775e 1733 break;
cf0e5467 1734 case OPT_PROBE:
7d29a247 1735 opt_event_type = LTTNG_EVENT_PROBE;
f3ed775e 1736 break;
dcabc190
FD
1737 case OPT_USERSPACE_PROBE:
1738 opt_event_type = LTTNG_EVENT_USERSPACE_PROBE;
1739 break;
f3ed775e
DG
1740 case OPT_FUNCTION:
1741 opt_event_type = LTTNG_EVENT_FUNCTION;
8f0d098b 1742 break;
a54bd42d
MD
1743 case OPT_SYSCALL:
1744 opt_event_type = LTTNG_EVENT_SYSCALL;
0133c199 1745 break;
eeac7d46
MD
1746 case OPT_USERSPACE:
1747 opt_userspace = 1;
eeac7d46 1748 break;
0cda4f28 1749 case OPT_LOGLEVEL:
8005f29a 1750 opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_RANGE;
0cda4f28
MD
1751 opt_loglevel = poptGetOptArg(pc);
1752 break;
1753 case OPT_LOGLEVEL_ONLY:
8005f29a 1754 opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_SINGLE;
0cda4f28 1755 opt_loglevel = poptGetOptArg(pc);
13dce3b7 1756 break;
679b4943
SM
1757 case OPT_LIST_OPTIONS:
1758 list_cmd_options(stdout, long_options);
679b4943 1759 goto end;
53a80697
MD
1760 case OPT_FILTER:
1761 break;
fac3366c
JI
1762 case OPT_EXCLUDE:
1763 break;
f3ed775e 1764 default:
f3ed775e
DG
1765 ret = CMD_UNDEFINED;
1766 goto end;
1767 }
de044b7a
DG
1768
1769 /* Validate event type. Multiple event type are not supported. */
1770 if (event_type == -1) {
1771 event_type = opt_event_type;
1772 } else {
1773 if (event_type != opt_event_type) {
1774 ERR("Multiple event type not supported.");
1775 ret = CMD_ERROR;
1776 goto end;
1777 }
1778 }
f3ed775e
DG
1779 }
1780
3ecec76a
PP
1781 ret = print_missing_or_multiple_domains(
1782 opt_kernel + opt_userspace + opt_jul + opt_log4j + opt_python);
1783 if (ret) {
1784 ret = CMD_ERROR;
1785 goto end;
1786 }
1787
89476427
JRJ
1788 /* Mi check */
1789 if (lttng_opt_mi) {
1790 writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
1791 if (!writer) {
1792 ret = -LTTNG_ERR_NOMEM;
1793 goto end;
1794 }
1795
1796 /* Open command element */
1797 ret = mi_lttng_writer_command_open(writer,
1798 mi_lttng_element_command_enable_event);
1799 if (ret) {
1800 ret = CMD_ERROR;
1801 goto end;
1802 }
1803
1804 /* Open output element */
1805 ret = mi_lttng_writer_open_element(writer,
1806 mi_lttng_element_command_output);
1807 if (ret) {
1808 ret = CMD_ERROR;
1809 goto end;
1810 }
1811 }
1812
f3ed775e
DG
1813 opt_event_list = (char*) poptGetArg(pc);
1814 if (opt_event_list == NULL && opt_enable_all == 0) {
1815 ERR("Missing event name(s).\n");
ca1c3607 1816 ret = CMD_ERROR;
f3ed775e
DG
1817 goto end;
1818 }
1819
68c7f6e5
JD
1820 leftover = poptGetArg(pc);
1821 if (leftover) {
1822 ERR("Unknown argument: %s", leftover);
1823 ret = CMD_ERROR;
1824 goto end;
1825 }
1826
cd80958d
DG
1827 if (!opt_session_name) {
1828 session_name = get_session_name();
1829 if (session_name == NULL) {
89476427
JRJ
1830 command_ret = CMD_ERROR;
1831 success = 0;
1832 goto mi_closing;
cd80958d
DG
1833 }
1834 } else {
1835 session_name = opt_session_name;
1836 }
1837
89476427
JRJ
1838 command_ret = enable_events(session_name);
1839 if (command_ret) {
1840 success = 0;
1841 goto mi_closing;
1842 }
1843
1844mi_closing:
1845 /* Mi closing */
1846 if (lttng_opt_mi) {
1847 /* Close output element */
1848 ret = mi_lttng_writer_close_element(writer);
1849 if (ret) {
1850 ret = CMD_ERROR;
1851 goto end;
1852 }
1853
1854 ret = mi_lttng_writer_write_element_bool(writer,
1855 mi_lttng_element_command_success, success);
1856 if (ret) {
1857 ret = CMD_ERROR;
1858 goto end;
1859 }
1860
1861 /* Command element close */
1862 ret = mi_lttng_writer_command_close(writer);
1863 if (ret) {
1864 ret = CMD_ERROR;
1865 goto end;
1866 }
1867 }
f3ed775e
DG
1868
1869end:
89476427
JRJ
1870 /* Mi clean-up */
1871 if (writer && mi_lttng_writer_destroy(writer)) {
1872 /* Preserve original error code */
1873 ret = ret ? ret : LTTNG_ERR_MI_IO_FAIL;
1874 }
1875
cd80958d
DG
1876 if (opt_session_name == NULL) {
1877 free(session_name);
1878 }
1879
89476427
JRJ
1880 /* Overwrite ret if an error occurred in enable_events */
1881 ret = command_ret ? command_ret : ret;
1882
ca1c3607 1883 poptFreeContext(pc);
f3ed775e
DG
1884 return ret;
1885}
9f449915 1886
This page took 0.147631 seconds and 4 git commands to generate.