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