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