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