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