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