lttng: fix argument numbers in add-trigger error messages
[lttng-tools.git] / src / bin / lttng / commands / list_triggers.cpp
CommitLineData
0de2479d
SM
1/*
2 * Copyright (C) 2021 Simon Marchi <simon.marchi@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8#include <stdio.h>
9
10#include "../command.h"
11
12#include "common/argpar/argpar.h"
d50d200a 13#include "common/argpar-utils/argpar-utils.h"
0de2479d
SM
14#include "common/dynamic-array.h"
15#include "common/mi-lttng.h"
16/* For lttng_condition_type_str(). */
17#include "lttng/condition/condition-internal.h"
670a26e4
JR
18#include "lttng/condition/event-rule-matches.h"
19#include "lttng/condition/event-rule-matches-internal.h"
0de2479d
SM
20/* For lttng_domain_type_str(). */
21#include "lttng/domain-internal.h"
4f7da553
JR
22/* For lttng_event_rule_kernel_syscall_emission_site_str() */
23#include "lttng/event-rule/kernel-syscall-internal.h"
85b05318 24#include "../loglevel.h"
709fb83f 25#include <lttng/lttng.h>
0de2479d
SM
26
27#ifdef LTTNG_EMBED_HELP
28static const char help_msg[] =
279eb769 29#include <lttng-list-triggers.1.h>
0de2479d
SM
30;
31#endif
32
63dd3d7b
JG
33#define INDENTATION_LEVEL_STR " "
34
695f7044
JR
35typedef enum lttng_event_rule_status (*event_rule_logging_get_name_pattern)(
36 const struct lttng_event_rule *rule, const char **pattern);
37typedef enum lttng_event_rule_status (*event_rule_logging_get_filter)(
38 const struct lttng_event_rule *rule, const char **expression);
39typedef enum lttng_event_rule_status (*event_rule_logging_get_log_level_rule)(
40 const struct lttng_event_rule *rule,
41 const struct lttng_log_level_rule **log_level_rule);
42
0de2479d
SM
43enum {
44 OPT_HELP,
45 OPT_LIST_OPTIONS,
46};
47
48static const
49struct argpar_opt_descr list_trigger_options[] = {
50 { OPT_HELP, 'h', "help", false },
51 { OPT_LIST_OPTIONS, '\0', "list-options", false },
52 ARGPAR_OPT_DESCR_SENTINEL,
53};
54
19904669
SM
55static void print_condition_session_consumed_size(
56 const struct lttng_condition *condition)
57{
58 enum lttng_condition_status condition_status;
59 const char *session_name;
60 uint64_t threshold;
61
62 condition_status =
63 lttng_condition_session_consumed_size_get_session_name(
64 condition, &session_name);
a0377dfe 65 LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
19904669
SM
66
67 lttng_condition_session_consumed_size_get_threshold(
68 condition, &threshold);
a0377dfe 69 LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
19904669
SM
70
71 MSG(" session name: %s", session_name);
72 MSG(" threshold: %" PRIu64 " bytes", threshold);
73}
74
75static void print_condition_buffer_usage(
76 const struct lttng_condition *condition)
77{
78 enum lttng_condition_status condition_status;
79 const char *session_name, *channel_name;
80 enum lttng_domain_type domain_type;
81 uint64_t threshold;
82
83 condition_status = lttng_condition_buffer_usage_get_session_name(
84 condition, &session_name);
a0377dfe 85 LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
19904669
SM
86
87 condition_status = lttng_condition_buffer_usage_get_channel_name(
88 condition, &channel_name);
a0377dfe 89 LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
19904669
SM
90
91 condition_status = lttng_condition_buffer_usage_get_domain_type(
92 condition, &domain_type);
a0377dfe 93 LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
19904669
SM
94
95 MSG(" session name: %s", session_name);
96 MSG(" channel name: %s", channel_name);
97 MSG(" domain: %s", lttng_domain_type_str(domain_type));
98
99 condition_status = lttng_condition_buffer_usage_get_threshold(
100 condition, &threshold);
101 if (condition_status == LTTNG_CONDITION_STATUS_OK) {
102 MSG(" threshold (bytes): %" PRIu64, threshold);
103 } else {
104 double threshold_ratio;
105
a0377dfe 106 LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_UNSET);
19904669
SM
107
108 condition_status =
109 lttng_condition_buffer_usage_get_threshold_ratio(
110 condition, &threshold_ratio);
a0377dfe 111 LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
19904669
SM
112
113 MSG(" threshold (ratio): %.2f", threshold_ratio);
114 }
115}
116
117static void print_condition_session_rotation(
118 const struct lttng_condition *condition)
119{
120 enum lttng_condition_status condition_status;
121 const char *session_name;
122
123 condition_status = lttng_condition_session_rotation_get_session_name(
124 condition, &session_name);
a0377dfe 125 LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
19904669
SM
126
127 MSG(" session name: %s", session_name);
128}
129
85b05318
JR
130/*
131 * Returns the human-readable log level name associated with a numerical value
695f7044 132 * if there is one. The Log4j and JUL event rule have discontinuous log level
85b05318
JR
133 * values (a value can fall between two labels). In those cases, NULL is
134 * returned.
135 */
136static const char *get_pretty_loglevel_name(
695f7044 137 enum lttng_event_rule_type event_rule_type, int loglevel)
85b05318
JR
138{
139 const char *name = NULL;
140
695f7044
JR
141 switch (event_rule_type) {
142 case LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT:
85b05318
JR
143 name = loglevel_value_to_name(loglevel);
144 break;
695f7044 145 case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
85b05318
JR
146 name = loglevel_log4j_value_to_name(loglevel);
147 break;
695f7044 148 case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
85b05318
JR
149 name = loglevel_jul_value_to_name(loglevel);
150 break;
695f7044 151 case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
85b05318
JR
152 name = loglevel_python_value_to_name(loglevel);
153 break;
154 default:
155 break;
156 }
157
158 return name;
159}
160
0de2479d 161static
695f7044 162void print_event_rule_user_tracepoint(const struct lttng_event_rule *event_rule)
0de2479d
SM
163{
164 enum lttng_event_rule_status event_rule_status;
0de2479d
SM
165 const char *pattern;
166 const char *filter;
167 int log_level;
85b05318 168 const struct lttng_log_level_rule *log_level_rule = NULL;
0de2479d
SM
169 unsigned int exclusions_count;
170 int i;
171
695f7044 172 event_rule_status = lttng_event_rule_user_tracepoint_get_name_pattern(
0de2479d 173 event_rule, &pattern);
a0377dfe 174 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
0de2479d 175
695f7044 176 _MSG(" rule: %s (type: user tracepoint", pattern);
0de2479d 177
695f7044 178 event_rule_status = lttng_event_rule_user_tracepoint_get_filter(
0de2479d
SM
179 event_rule, &filter);
180 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
181 _MSG(", filter: %s", filter);
182 } else {
a0377dfe 183 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
0de2479d
SM
184 }
185
695f7044 186 event_rule_status = lttng_event_rule_user_tracepoint_get_log_level_rule(
85b05318 187 event_rule, &log_level_rule);
0de2479d 188 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
85b05318 189 enum lttng_log_level_rule_status llr_status;
0de2479d 190 const char *log_level_op;
85b05318
JR
191 const char *pretty_loglevel_name;
192
193 switch (lttng_log_level_rule_get_type(log_level_rule)) {
194 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
195 log_level_op = "is";
196 llr_status = lttng_log_level_rule_exactly_get_level(
197 log_level_rule, &log_level);
198 break;
199 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
200 log_level_op = "at least";
201 llr_status = lttng_log_level_rule_at_least_as_severe_as_get_level(
202 log_level_rule, &log_level);
203 break;
204 default:
205 abort();
206 }
207
a0377dfe 208 LTTNG_ASSERT(llr_status == LTTNG_LOG_LEVEL_RULE_STATUS_OK);
85b05318
JR
209
210 pretty_loglevel_name = get_pretty_loglevel_name(
695f7044 211 LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT, log_level);
85b05318
JR
212 if (pretty_loglevel_name) {
213 _MSG(", log level %s %s", log_level_op,
214 pretty_loglevel_name);
215 } else {
216 _MSG(", log level %s %d", log_level_op, log_level);
217 }
0de2479d 218 } else {
a0377dfe 219 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
0de2479d
SM
220 }
221
695f7044 222 event_rule_status = lttng_event_rule_user_tracepoint_get_name_pattern_exclusion_count(
0de2479d 223 event_rule, &exclusions_count);
a0377dfe 224 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
0de2479d
SM
225 if (exclusions_count > 0) {
226 _MSG(", exclusions: ");
227 for (i = 0; i < exclusions_count; i++) {
228 const char *exclusion;
229
695f7044 230 event_rule_status = lttng_event_rule_user_tracepoint_get_name_pattern_exclusion_at_index(
0de2479d 231 event_rule, i, &exclusion);
a0377dfe 232 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
0de2479d
SM
233
234 _MSG("%s%s", i > 0 ? "," : "", exclusion);
235 }
236 }
237
238 MSG(")");
239}
240
695f7044
JR
241static
242void print_event_rule_kernel_tracepoint(const struct lttng_event_rule *event_rule)
243{
244 enum lttng_event_rule_status event_rule_status;
245 const char *pattern;
246 const char *filter;
247
248 event_rule_status = lttng_event_rule_kernel_tracepoint_get_name_pattern(
249 event_rule, &pattern);
a0377dfe 250 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
695f7044
JR
251
252 _MSG(" rule: %s (type: kernel tracepoint", pattern);
253
254 event_rule_status = lttng_event_rule_kernel_tracepoint_get_filter(
255 event_rule, &filter);
256 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
257 _MSG(", filter: %s", filter);
258 } else {
a0377dfe 259 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
695f7044
JR
260 }
261
262 MSG(")");
263}
264
265static
266void print_event_rule_logging(const struct lttng_event_rule *event_rule)
267{
268 enum lttng_event_rule_status event_rule_status;
269 enum lttng_event_rule_type event_rule_type = lttng_event_rule_get_type(event_rule);
270 const char *pattern;
271 const char *filter;
272 int log_level;
273 const struct lttng_log_level_rule *log_level_rule = NULL;
274 const char *type_str = NULL;
275
276 event_rule_logging_get_name_pattern logging_get_name_pattern;
277 event_rule_logging_get_filter logging_get_filter;
278 event_rule_logging_get_log_level_rule logging_get_log_level_rule;
279
280 switch (event_rule_type) {
281 case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
282 logging_get_name_pattern =
283 lttng_event_rule_jul_logging_get_name_pattern;
284 logging_get_filter = lttng_event_rule_jul_logging_get_filter;
285 logging_get_log_level_rule =
286 lttng_event_rule_jul_logging_get_log_level_rule;
287 type_str = "jul";
288 break;
289 case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
290 logging_get_name_pattern =
291 lttng_event_rule_log4j_logging_get_name_pattern;
292 logging_get_filter = lttng_event_rule_log4j_logging_get_filter;
293 logging_get_log_level_rule =
294 lttng_event_rule_log4j_logging_get_log_level_rule;
295 type_str = "log4j";
296 break;
297 case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
298 logging_get_name_pattern =
299 lttng_event_rule_python_logging_get_name_pattern;
300 logging_get_filter = lttng_event_rule_python_logging_get_filter;
301 logging_get_log_level_rule =
302 lttng_event_rule_python_logging_get_log_level_rule;
303 type_str = "python";
304 break;
305 default:
306 abort();
307 break;
308 }
309
310 event_rule_status = logging_get_name_pattern(
311 event_rule, &pattern);
a0377dfe 312 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
695f7044
JR
313
314 _MSG(" rule: %s (type: %s:logging", pattern, type_str);
315
316 event_rule_status = logging_get_filter(
317 event_rule, &filter);
318 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
319 _MSG(", filter: %s", filter);
320 } else {
a0377dfe 321 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
695f7044
JR
322 }
323
324 event_rule_status = logging_get_log_level_rule(
325 event_rule, &log_level_rule);
326 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
327 enum lttng_log_level_rule_status llr_status;
328 const char *log_level_op;
329 const char *pretty_loglevel_name;
330
331 switch (lttng_log_level_rule_get_type(log_level_rule)) {
332 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
333 log_level_op = "is";
334 llr_status = lttng_log_level_rule_exactly_get_level(
335 log_level_rule, &log_level);
336 break;
337 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
338 log_level_op = "at least";
339 llr_status = lttng_log_level_rule_at_least_as_severe_as_get_level(
340 log_level_rule, &log_level);
341 break;
342 default:
343 abort();
344 }
345
a0377dfe 346 LTTNG_ASSERT(llr_status == LTTNG_LOG_LEVEL_RULE_STATUS_OK);
695f7044
JR
347
348 pretty_loglevel_name = get_pretty_loglevel_name(
349 event_rule_type, log_level);
350 if (pretty_loglevel_name) {
351 _MSG(", log level %s %s", log_level_op,
352 pretty_loglevel_name);
353 } else {
354 _MSG(", log level %s %d", log_level_op, log_level);
355 }
356 } else {
a0377dfe 357 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
695f7044
JR
358 }
359
360 MSG(")");
361}
362
0de2479d
SM
363static void print_kernel_probe_location(
364 const struct lttng_kernel_probe_location *location)
365{
366 enum lttng_kernel_probe_location_status status;
367 switch (lttng_kernel_probe_location_get_type(location)) {
368 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS:
369 {
370 uint64_t address;
371
372 status = lttng_kernel_probe_location_address_get_address(
373 location, &address);
374 if (status != LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK) {
375 ERR("Getting kernel probe location address failed.");
376 goto end;
377 }
378
379 _MSG("0x%" PRIx64, address);
380
381 break;
382 }
383 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET:
384 {
385 uint64_t offset;
386 const char *symbol_name;
387
388 symbol_name = lttng_kernel_probe_location_symbol_get_name(
389 location);
390 if (!symbol_name) {
391 ERR("Getting kernel probe location symbol name failed.");
392 goto end;
393 }
394
395 status = lttng_kernel_probe_location_symbol_get_offset(
396 location, &offset);
397 if (status != LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK) {
398 ERR("Getting kernel probe location address failed.");
399 goto end;
400 }
401
402 if (offset == 0) {
403 _MSG("%s", symbol_name);
404 } else {
405 _MSG("%s+0x%" PRIx64, symbol_name, offset);
406 }
407
408 break;
409 }
410 default:
411 abort();
412 };
413end:
414 return;
415}
416
417static
f2791161 418void print_event_rule_kernel_probe(const struct lttng_event_rule *event_rule)
0de2479d
SM
419{
420 enum lttng_event_rule_status event_rule_status;
421 const char *name;
422 const struct lttng_kernel_probe_location *location;
423
a0377dfe 424 LTTNG_ASSERT(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE);
0de2479d 425
85522de5 426 event_rule_status = lttng_event_rule_kernel_kprobe_get_event_name(event_rule, &name);
0de2479d
SM
427 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
428 ERR("Failed to get kprobe event rule's name.");
429 goto end;
430 }
431
85522de5 432 event_rule_status = lttng_event_rule_kernel_kprobe_get_location(
0de2479d
SM
433 event_rule, &location);
434 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
435 ERR("Failed to get kprobe event rule's location.");
436 goto end;
437 }
438
85522de5 439 _MSG(" rule: %s (type: kernel:kprobe, location: ", name);
0de2479d
SM
440
441 print_kernel_probe_location(location);
442
443 MSG(")");
444
445end:
446 return;
447}
448
449static
1f1567a5 450void print_event_rule_userspace_probe(const struct lttng_event_rule *event_rule)
0de2479d
SM
451{
452 enum lttng_event_rule_status event_rule_status;
453 const char *name;
454 const struct lttng_userspace_probe_location *location;
455 enum lttng_userspace_probe_location_type userspace_probe_location_type;
456
a0377dfe 457 LTTNG_ASSERT(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_KERNEL_UPROBE);
0de2479d 458
46fd07ac 459 event_rule_status = lttng_event_rule_kernel_uprobe_get_event_name(
405f9e7d 460 event_rule, &name);
0de2479d
SM
461 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
462 ERR("Failed to get uprobe event rule's name.");
463 goto end;
464 }
465
46fd07ac 466 event_rule_status = lttng_event_rule_kernel_uprobe_get_location(
0de2479d
SM
467 event_rule, &location);
468 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
469 ERR("Failed to get uprobe event rule's location.");
470 goto end;
471 }
472
46fd07ac 473 _MSG(" rule: %s (type: kernel:uprobe, ", name);
0de2479d
SM
474
475 userspace_probe_location_type =
476 lttng_userspace_probe_location_get_type(location);
477
478 switch (userspace_probe_location_type) {
479 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION:
480 {
481 const char *binary_path, *function_name;
482
483 binary_path = lttng_userspace_probe_location_function_get_binary_path(
484 location);
485 function_name = lttng_userspace_probe_location_function_get_function_name(
486 location);
487
8a917ae8 488 _MSG("location type: ELF, location: %s:%s", binary_path, function_name);
0de2479d
SM
489 break;
490 }
491 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT:
8a917ae8
FD
492 {
493 const char *binary_path, *provider_name, *probe_name;
494
495 binary_path = lttng_userspace_probe_location_tracepoint_get_binary_path(
496 location);
497 provider_name = lttng_userspace_probe_location_tracepoint_get_provider_name(
498 location);
499 probe_name = lttng_userspace_probe_location_tracepoint_get_probe_name(
500 location);
501 _MSG("location type: SDT, location: %s:%s:%s", binary_path, provider_name, probe_name);
0de2479d 502 break;
8a917ae8 503 }
0de2479d
SM
504 default:
505 abort();
506 }
507
508 MSG(")");
509
510end:
511 return;
512}
513
514static
515void print_event_rule_syscall(const struct lttng_event_rule *event_rule)
516{
517 const char *pattern, *filter;
518 enum lttng_event_rule_status event_rule_status;
4f7da553 519 enum lttng_event_rule_kernel_syscall_emission_site emission_site;
0de2479d 520
a0377dfe 521 LTTNG_ASSERT(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL);
0de2479d 522
f6a5af19 523 emission_site =
4f7da553 524 lttng_event_rule_kernel_syscall_get_emission_site(event_rule);
57739a6b 525
4f7da553 526 event_rule_status = lttng_event_rule_kernel_syscall_get_name_pattern(
0de2479d 527 event_rule, &pattern);
a0377dfe 528 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
0de2479d 529
4f7da553
JR
530 _MSG(" rule: %s (type: kernel:syscall:%s", pattern,
531 lttng_event_rule_kernel_syscall_emission_site_str(
f6a5af19 532 emission_site));
0de2479d 533
4f7da553 534 event_rule_status = lttng_event_rule_kernel_syscall_get_filter(
0de2479d
SM
535 event_rule, &filter);
536 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
537 _MSG(", filter: %s", filter);
538 } else {
a0377dfe 539 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
0de2479d
SM
540 }
541
542 MSG(")");
543}
544
545static
546void print_event_rule(const struct lttng_event_rule *event_rule)
547{
548 const enum lttng_event_rule_type event_rule_type =
549 lttng_event_rule_get_type(event_rule);
550
551 switch (event_rule_type) {
695f7044
JR
552 case LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT:
553 print_event_rule_user_tracepoint(event_rule);
554 break;
555 case LTTNG_EVENT_RULE_TYPE_KERNEL_TRACEPOINT:
556 print_event_rule_kernel_tracepoint(event_rule);
557 break;
558 case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
559 case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
560 case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
561 print_event_rule_logging(event_rule);
0de2479d 562 break;
85522de5 563 case LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE:
f2791161 564 print_event_rule_kernel_probe(event_rule);
0de2479d 565 break;
46fd07ac 566 case LTTNG_EVENT_RULE_TYPE_KERNEL_UPROBE:
1f1567a5 567 print_event_rule_userspace_probe(event_rule);
0de2479d 568 break;
4f7da553 569 case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL:
0de2479d
SM
570 print_event_rule_syscall(event_rule);
571 break;
572 default:
573 abort();
574 }
575}
576
b203b4b0
SM
577static
578void print_one_event_expr(const struct lttng_event_expr *event_expr)
579{
580 enum lttng_event_expr_type type;
581
582 type = lttng_event_expr_get_type(event_expr);
583
584 switch (type) {
585 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
586 {
587 const char *name;
588
589 name = lttng_event_expr_event_payload_field_get_name(
590 event_expr);
591 _MSG("%s", name);
592
593 break;
594 }
595 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
596 {
597 const char *name;
598
599 name = lttng_event_expr_channel_context_field_get_name(
600 event_expr);
601 _MSG("$ctx.%s", name);
602
603 break;
604 }
605 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
606 {
607 const char *provider_name;
608 const char *type_name;
609
610 provider_name = lttng_event_expr_app_specific_context_field_get_provider_name(
611 event_expr);
612 type_name = lttng_event_expr_app_specific_context_field_get_type_name(
613 event_expr);
614
615 _MSG("$app.%s:%s", provider_name, type_name);
616
617 break;
618 }
619 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
620 {
621 unsigned int index;
622 const struct lttng_event_expr *parent_expr;
623 enum lttng_event_expr_status status;
624
625 parent_expr = lttng_event_expr_array_field_element_get_parent_expr(
626 event_expr);
a0377dfe 627 LTTNG_ASSERT(parent_expr != NULL);
b203b4b0
SM
628
629 print_one_event_expr(parent_expr);
630
631 status = lttng_event_expr_array_field_element_get_index(
632 event_expr, &index);
a0377dfe 633 LTTNG_ASSERT(status == LTTNG_EVENT_EXPR_STATUS_OK);
b203b4b0
SM
634
635 _MSG("[%u]", index);
636
637 break;
638 }
639 default:
640 abort();
641 }
642}
643
63dd3d7b
JG
644static
645void print_indentation(unsigned int indentation_level)
646{
647 unsigned int i;
648
649 for (i = 0; i < indentation_level; i++) {
650 _MSG(INDENTATION_LEVEL_STR);
651 }
652}
653
654static
655void print_error_query_results(struct lttng_error_query_results *results,
656 unsigned int base_indentation_level)
657{
658 unsigned int i, count, printed_errors_count = 0;
659 enum lttng_error_query_results_status results_status;
660
661 results_status = lttng_error_query_results_get_count(results, &count);
a0377dfe 662 LTTNG_ASSERT(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
63dd3d7b 663
a0377dfe 664 LTTNG_ASSERT(results);
63dd3d7b
JG
665
666 print_indentation(base_indentation_level);
667 _MSG("errors:");
668
669 for (i = 0; i < count; i++) {
670 const struct lttng_error_query_result *result;
671 enum lttng_error_query_result_status result_status;
672 const char *result_name;
673 const char *result_description;
674 uint64_t result_value;
675
676 results_status = lttng_error_query_results_get_result(
677 results, &result, i);
a0377dfe 678 LTTNG_ASSERT(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
63dd3d7b
JG
679
680 result_status = lttng_error_query_result_get_name(
681 result, &result_name);
a0377dfe 682 LTTNG_ASSERT(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
63dd3d7b
JG
683 result_status = lttng_error_query_result_get_description(
684 result, &result_description);
a0377dfe 685 LTTNG_ASSERT(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
63dd3d7b
JG
686
687
688 if (lttng_error_query_result_get_type(result) ==
689 LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER) {
690 result_status = lttng_error_query_result_counter_get_value(
691 result, &result_value);
a0377dfe 692 LTTNG_ASSERT(result_status ==
63dd3d7b
JG
693 LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
694 if (result_value == 0) {
695 continue;
696 }
697
698 MSG("");
699 print_indentation(base_indentation_level + 1);
700
701 _MSG("%s: %" PRIu64, result_name, result_value);
702 printed_errors_count++;
703 } else {
704 MSG("");
705 print_indentation(base_indentation_level + 1);
706 _MSG("Unknown error query result type for result '%s' (%s)",
707 result_name, result_description);
708 continue;
709 }
710 }
711
712 if (printed_errors_count == 0) {
713 _MSG(" none");
714 }
715}
716
8dbb86b8
JR
717static void print_condition_event_rule_matches(
718 const struct lttng_condition *condition)
0de2479d
SM
719{
720 const struct lttng_event_rule *event_rule;
721 enum lttng_condition_status condition_status;
b203b4b0 722 unsigned int cap_desc_count, i;
0de2479d 723
8dbb86b8
JR
724 condition_status = lttng_condition_event_rule_matches_get_rule(
725 condition, &event_rule);
a0377dfe 726 LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
0de2479d
SM
727
728 print_event_rule(event_rule);
b203b4b0
SM
729
730 condition_status =
8dbb86b8 731 lttng_condition_event_rule_matches_get_capture_descriptor_count(
b203b4b0 732 condition, &cap_desc_count);
a0377dfe 733 LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
b203b4b0
SM
734
735 if (cap_desc_count > 0) {
736 MSG(" captures:");
737
738 for (i = 0; i < cap_desc_count; i++) {
739 const struct lttng_event_expr *cap_desc =
8dbb86b8 740 lttng_condition_event_rule_matches_get_capture_descriptor_at_index(
b203b4b0
SM
741 condition, i);
742
743 _MSG(" - ");
744 print_one_event_expr(cap_desc);
745 MSG("");
746 }
747 }
0de2479d
SM
748}
749
cb9222ff
JG
750static void print_action_errors(const struct lttng_trigger *trigger,
751 const struct lttng_action *action,
752 const uint64_t *action_path_indexes,
753 size_t action_path_length)
709fb83f 754{
709fb83f 755 enum lttng_error_code error_query_ret;
709fb83f
JG
756 struct lttng_error_query_results *results = NULL;
757 const char *trigger_name;
758 uid_t trigger_uid;
759 enum lttng_trigger_status trigger_status;
cb9222ff
JG
760 struct lttng_error_query *query;
761 struct lttng_action_path *action_path = lttng_action_path_create(
762 action_path_indexes, action_path_length);
763
a0377dfe 764 LTTNG_ASSERT(action_path);
709fb83f 765
cb9222ff 766 query = lttng_error_query_action_create(trigger, action_path);
a0377dfe 767 LTTNG_ASSERT(query);
709fb83f
JG
768
769 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
0efb2ad7
JG
770 /*
771 * Anonymous triggers are not listed; this would be an internal error.
772 */
a0377dfe 773 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
709fb83f
JG
774
775 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
a0377dfe 776 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
709fb83f
JG
777
778 error_query_ret = lttng_error_query_execute(
779 query, lttng_session_daemon_command_endpoint, &results);
780 if (error_query_ret != LTTNG_OK) {
781 ERR("Failed to query errors of trigger '%s' (owner uid: %d): %s",
782 trigger_name, (int) trigger_uid,
783 lttng_strerror(-error_query_ret));
784 goto end;
785 }
786
63dd3d7b 787 print_error_query_results(results, 3);
709fb83f
JG
788
789end:
790 MSG("");
791 lttng_error_query_destroy(query);
792 lttng_error_query_results_destroy(results);
cb9222ff 793 lttng_action_path_destroy(action_path);
709fb83f
JG
794}
795
796static
797void print_one_action(const struct lttng_trigger *trigger,
cb9222ff
JG
798 const struct lttng_action *action,
799 const uint64_t *action_path_indexes,
800 size_t action_path_length)
0de2479d
SM
801{
802 enum lttng_action_type action_type;
803 enum lttng_action_status action_status;
7f4d5b07 804 const struct lttng_rate_policy *policy = NULL;
0de2479d
SM
805 const char *value;
806
807 action_type = lttng_action_get_type(action);
a0377dfe 808 LTTNG_ASSERT(action_type != LTTNG_ACTION_TYPE_LIST);
0de2479d
SM
809
810 switch (action_type) {
811 case LTTNG_ACTION_TYPE_NOTIFY:
e45dd625
JR
812 _MSG("notify");
813
7f4d5b07 814 action_status = lttng_action_notify_get_rate_policy(
e45dd625
JR
815 action, &policy);
816 if (action_status != LTTNG_ACTION_STATUS_OK) {
7f4d5b07 817 ERR("Failed to retrieve rate policy.");
e45dd625
JR
818 goto end;
819 }
0de2479d
SM
820 break;
821 case LTTNG_ACTION_TYPE_START_SESSION:
822 action_status = lttng_action_start_session_get_session_name(
823 action, &value);
a0377dfe 824 LTTNG_ASSERT(action_status == LTTNG_ACTION_STATUS_OK);
e45dd625
JR
825 _MSG("start session `%s`", value);
826
7f4d5b07 827 action_status = lttng_action_start_session_get_rate_policy(
e45dd625
JR
828 action, &policy);
829 if (action_status != LTTNG_ACTION_STATUS_OK) {
7f4d5b07 830 ERR("Failed to retrieve rate policy.");
e45dd625
JR
831 goto end;
832 }
0de2479d
SM
833 break;
834 case LTTNG_ACTION_TYPE_STOP_SESSION:
835 action_status = lttng_action_stop_session_get_session_name(
836 action, &value);
a0377dfe 837 LTTNG_ASSERT(action_status == LTTNG_ACTION_STATUS_OK);
e45dd625
JR
838 _MSG("stop session `%s`", value);
839
7f4d5b07 840 action_status = lttng_action_stop_session_get_rate_policy(
e45dd625
JR
841 action, &policy);
842 if (action_status != LTTNG_ACTION_STATUS_OK) {
7f4d5b07 843 ERR("Failed to retrieve rate policy.");
e45dd625
JR
844 goto end;
845 }
0de2479d
SM
846 break;
847 case LTTNG_ACTION_TYPE_ROTATE_SESSION:
848 action_status = lttng_action_rotate_session_get_session_name(
849 action, &value);
a0377dfe 850 LTTNG_ASSERT(action_status == LTTNG_ACTION_STATUS_OK);
e45dd625
JR
851 _MSG("rotate session `%s`", value);
852
7f4d5b07 853 action_status = lttng_action_rotate_session_get_rate_policy(
e45dd625
JR
854 action, &policy);
855 if (action_status != LTTNG_ACTION_STATUS_OK) {
7f4d5b07 856 ERR("Failed to retrieve rate policy.");
e45dd625
JR
857 goto end;
858 }
0de2479d
SM
859 break;
860 case LTTNG_ACTION_TYPE_SNAPSHOT_SESSION:
861 {
862 const struct lttng_snapshot_output *output;
863
864 action_status = lttng_action_snapshot_session_get_session_name(
865 action, &value);
a0377dfe 866 LTTNG_ASSERT(action_status == LTTNG_ACTION_STATUS_OK);
0de2479d
SM
867 _MSG("snapshot session `%s`", value);
868
869 action_status = lttng_action_snapshot_session_get_output(
870 action, &output);
871 if (action_status == LTTNG_ACTION_STATUS_OK) {
872 const char *name;
873 uint64_t max_size;
874 const char *ctrl_url, *data_url;
875 bool starts_with_file, starts_with_net, starts_with_net6;
876
877 ctrl_url = lttng_snapshot_output_get_ctrl_url(output);
a0377dfe 878 LTTNG_ASSERT(ctrl_url && strlen(ctrl_url) > 0);
0de2479d
SM
879
880 data_url = lttng_snapshot_output_get_data_url(output);
a0377dfe 881 LTTNG_ASSERT(data_url);
0de2479d
SM
882
883 starts_with_file = strncmp(ctrl_url, "file://", strlen("file://")) == 0;
884 starts_with_net = strncmp(ctrl_url, "net://", strlen("net://")) == 0;
885 starts_with_net6 = strncmp(ctrl_url, "net6://", strlen("net6://")) == 0;
886
887 if (ctrl_url[0] == '/' || starts_with_file) {
888 if (starts_with_file) {
889 ctrl_url += strlen("file://");
890 }
891
892 _MSG(", path: %s", ctrl_url);
893 } else if (starts_with_net || starts_with_net6) {
894 _MSG(", url: %s", ctrl_url);
895 } else {
a0377dfe 896 LTTNG_ASSERT(strlen(data_url) > 0);
0de2479d
SM
897
898 _MSG(", control url: %s, data url: %s", ctrl_url, data_url);
899 }
900
901 name = lttng_snapshot_output_get_name(output);
a0377dfe 902 LTTNG_ASSERT(name);
0de2479d
SM
903 if (strlen(name) > 0) {
904 _MSG(", name: %s", name);
905 }
906
907 max_size = lttng_snapshot_output_get_maxsize(output);
908 if (max_size != -1ULL) {
909 _MSG(", max size: %" PRIu64, max_size);
910 }
911 }
912
7f4d5b07 913 action_status = lttng_action_snapshot_session_get_rate_policy(
e45dd625
JR
914 action, &policy);
915 if (action_status != LTTNG_ACTION_STATUS_OK) {
7f4d5b07 916 ERR("Failed to retrieve rate policy.");
e45dd625
JR
917 goto end;
918 }
0de2479d
SM
919 break;
920 }
0de2479d
SM
921 default:
922 abort();
923 }
e45dd625
JR
924
925 if (policy) {
7f4d5b07
JR
926 enum lttng_rate_policy_type policy_type;
927 enum lttng_rate_policy_status policy_status;
e45dd625
JR
928 uint64_t policy_value = 0;
929
7f4d5b07 930 policy_type = lttng_rate_policy_get_type(policy);
e45dd625
JR
931
932 switch (policy_type) {
7f4d5b07
JR
933 case LTTNG_RATE_POLICY_TYPE_EVERY_N:
934 policy_status = lttng_rate_policy_every_n_get_interval(
e45dd625 935 policy, &policy_value);
7f4d5b07
JR
936 if (policy_status != LTTNG_RATE_POLICY_STATUS_OK) {
937 ERR("Failed to get action rate policy interval");
e45dd625
JR
938 goto end;
939 }
940 if (policy_value > 1) {
941 /* The default is 1 so print only when it is a
942 * special case.
943 */
4edabba8 944 _MSG(", rate policy: every %" PRIu64
e45dd625
JR
945 " occurrences",
946 policy_value);
947 }
948 break;
7f4d5b07
JR
949 case LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N:
950 policy_status = lttng_rate_policy_once_after_n_get_threshold(
e45dd625 951 policy, &policy_value);
7f4d5b07
JR
952 if (policy_status != LTTNG_RATE_POLICY_STATUS_OK) {
953 ERR("Failed to get action rate policy interval");
e45dd625
JR
954 goto end;
955 }
7f4d5b07 956 _MSG(", rate policy: once after %" PRIu64
e45dd625
JR
957 " occurrences",
958 policy_value);
959 break;
960 default:
961 abort();
962 }
963 }
964
965 MSG("");
cb9222ff
JG
966 print_action_errors(trigger, action, action_path_indexes,
967 action_path_length);
709fb83f 968
e45dd625
JR
969end:
970 return;
0de2479d
SM
971}
972
709fb83f
JG
973static
974void print_trigger_errors(const struct lttng_trigger *trigger)
975{
709fb83f 976 enum lttng_error_code error_query_ret;
709fb83f
JG
977 struct lttng_error_query_results *results = NULL;
978 enum lttng_trigger_status trigger_status;
979 const char *trigger_name;
980 uid_t trigger_uid;
981 struct lttng_error_query *query =
982 lttng_error_query_trigger_create(trigger);
983
a0377dfe 984 LTTNG_ASSERT(query);
0efb2ad7
JG
985 /*
986 * Anonymous triggers are not listed; this would be an internal error.
987 */
709fb83f 988 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
a0377dfe 989 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
709fb83f
JG
990
991 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
a0377dfe 992 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
709fb83f
JG
993
994 error_query_ret = lttng_error_query_execute(
995 query, lttng_session_daemon_command_endpoint, &results);
996 if (error_query_ret != LTTNG_OK) {
997 ERR("Failed to query errors of trigger '%s' (owner uid: %d): %s",
998 trigger_name, (int) trigger_uid,
999 lttng_strerror(-error_query_ret));
1000 goto end;
1001 }
1002
63dd3d7b 1003 print_error_query_results(results, 1);
709fb83f 1004
63dd3d7b
JG
1005end:
1006 MSG("");
1007 lttng_error_query_destroy(query);
1008 lttng_error_query_results_destroy(results);
1009}
709fb83f 1010
63dd3d7b
JG
1011static
1012void print_condition_errors(const struct lttng_trigger *trigger)
1013{
1014 enum lttng_error_code error_query_ret;
1015 struct lttng_error_query_results *results = NULL;
1016 enum lttng_trigger_status trigger_status;
1017 const char *trigger_name;
1018 uid_t trigger_uid;
1019 struct lttng_error_query *query =
1020 lttng_error_query_condition_create(trigger);
709fb83f 1021
a0377dfe 1022 LTTNG_ASSERT(query);
63dd3d7b
JG
1023 /*
1024 * Anonymous triggers are not listed; this would be an internal error.
1025 */
1026 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
a0377dfe 1027 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
709fb83f 1028
63dd3d7b 1029 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
a0377dfe 1030 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
709fb83f 1031
63dd3d7b
JG
1032 error_query_ret = lttng_error_query_execute(
1033 query, lttng_session_daemon_command_endpoint, &results);
1034 if (error_query_ret != LTTNG_OK) {
1035 ERR("Failed to query errors of condition of trigger '%s' (owner uid: %d): %s",
1036 trigger_name, (int) trigger_uid,
1037 lttng_strerror(-error_query_ret));
1038 goto end;
709fb83f
JG
1039 }
1040
63dd3d7b 1041 print_error_query_results(results, 2);
709fb83f
JG
1042
1043end:
1044 MSG("");
1045 lttng_error_query_destroy(query);
1046 lttng_error_query_results_destroy(results);
1047}
1048
0de2479d
SM
1049static
1050void print_one_trigger(const struct lttng_trigger *trigger)
1051{
1052 const struct lttng_condition *condition;
1053 enum lttng_condition_type condition_type;
1054 const struct lttng_action *action;
1055 enum lttng_action_type action_type;
1056 enum lttng_trigger_status trigger_status;
1057 const char *name;
0de2479d
SM
1058 uid_t trigger_uid;
1059
0efb2ad7
JG
1060 /*
1061 * Anonymous triggers are not listed since they can't be specified nor
1062 * referenced through the CLI.
1063 */
0de2479d 1064 trigger_status = lttng_trigger_get_name(trigger, &name);
0efb2ad7
JG
1065 if (trigger_status == LTTNG_TRIGGER_STATUS_UNSET) {
1066 goto end;
1067 }
1068
a0377dfe 1069 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
0de2479d
SM
1070
1071 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
a0377dfe 1072 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
0de2479d 1073
1d4b59f2 1074 MSG("- name: %s", name);
481c5310 1075 MSG(" owner uid: %d", trigger_uid);
0de2479d 1076
0de2479d
SM
1077 condition = lttng_trigger_get_const_condition(trigger);
1078 condition_type = lttng_condition_get_type(condition);
1079 MSG(" condition: %s", lttng_condition_type_str(condition_type));
1080 switch (condition_type) {
19904669
SM
1081 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE:
1082 print_condition_session_consumed_size(condition);
1083 break;
1084 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH:
1085 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
1086 print_condition_buffer_usage(condition);
1087 break;
1088 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING:
1089 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED:
1090 print_condition_session_rotation(condition);
1091 break;
8dbb86b8
JR
1092 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES:
1093 print_condition_event_rule_matches(condition);
0de2479d
SM
1094 break;
1095 default:
19904669 1096 abort();
0de2479d
SM
1097 }
1098
63dd3d7b
JG
1099 print_condition_errors(trigger);
1100
0de2479d
SM
1101 action = lttng_trigger_get_const_action(trigger);
1102 action_type = lttng_action_get_type(action);
7c2fae7c 1103 if (action_type == LTTNG_ACTION_TYPE_LIST) {
0de2479d
SM
1104 unsigned int count, i;
1105 enum lttng_action_status action_status;
1106
1107 MSG(" actions:");
1108
702f26c8 1109 action_status = lttng_action_list_get_count(action, &count);
a0377dfe 1110 LTTNG_ASSERT(action_status == LTTNG_ACTION_STATUS_OK);
0de2479d
SM
1111
1112 for (i = 0; i < count; i++) {
cb9222ff 1113 const uint64_t action_path_index = i;
0de2479d 1114 const struct lttng_action *subaction =
702f26c8 1115 lttng_action_list_get_at_index(
0de2479d
SM
1116 action, i);
1117
1118 _MSG(" ");
cb9222ff
JG
1119 print_one_action(trigger, subaction, &action_path_index,
1120 1);
0de2479d
SM
1121 }
1122 } else {
1123 _MSG(" action:");
cb9222ff 1124 print_one_action(trigger, action, NULL, 0);
0de2479d
SM
1125 }
1126
709fb83f 1127 print_trigger_errors(trigger);
0efb2ad7
JG
1128end:
1129 return;
0de2479d
SM
1130}
1131
1132static
1133int compare_triggers_by_name(const void *a, const void *b)
1134{
1135 const struct lttng_trigger *trigger_a = *((const struct lttng_trigger **) a);
1136 const struct lttng_trigger *trigger_b = *((const struct lttng_trigger **) b);
1137 const char *name_a, *name_b;
1138 enum lttng_trigger_status trigger_status;
1139
0efb2ad7 1140 /* Anonymous triggers are not reachable here. */
0de2479d 1141 trigger_status = lttng_trigger_get_name(trigger_a, &name_a);
a0377dfe 1142 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
0de2479d
SM
1143
1144 trigger_status = lttng_trigger_get_name(trigger_b, &name_b);
a0377dfe 1145 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
0de2479d
SM
1146
1147 return strcmp(name_a, name_b);
1148}
1149
523c4f8c 1150static int print_sorted_triggers(const struct lttng_triggers *triggers)
0de2479d
SM
1151{
1152 int ret;
0de2479d
SM
1153 int i;
1154 struct lttng_dynamic_pointer_array sorted_triggers;
1155 enum lttng_trigger_status trigger_status;
1156 unsigned int num_triggers;
1157
1158 lttng_dynamic_pointer_array_init(&sorted_triggers, NULL);
1159
523c4f8c
JR
1160 trigger_status = lttng_triggers_get_count(triggers, &num_triggers);
1161 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
1162 ERR("Failed to get trigger count.");
1163 goto error;
1164 }
1165
1166 for (i = 0; i < num_triggers; i++) {
1167 int add_ret;
1168 const char *unused_name;
1169 const struct lttng_trigger *trigger =
1170 lttng_triggers_get_at_index(triggers, i);
1171
1172 trigger_status = lttng_trigger_get_name(trigger, &unused_name);
1173 switch (trigger_status) {
1174 case LTTNG_TRIGGER_STATUS_OK:
1175 break;
1176 case LTTNG_TRIGGER_STATUS_UNSET:
1177 /* Don't list anonymous triggers. */
1178 continue;
1179 default:
1180 abort();
1181 }
1182
1183 add_ret = lttng_dynamic_pointer_array_add_pointer(
1184 &sorted_triggers, (void *) trigger);
1185 if (add_ret) {
1186 ERR("Failed to allocate array of struct lttng_trigger *.");
1187 goto error;
1188 }
1189 }
1190
1191 qsort(sorted_triggers.array.buffer.data, num_triggers,
1192 sizeof(struct lttng_trigger *),
1193 compare_triggers_by_name);
1194
9fa6c437
JR
1195 for (i = 0; i < lttng_dynamic_pointer_array_get_count(&sorted_triggers);
1196 i++) {
1197 const struct lttng_trigger *trigger_to_print = (const struct lttng_trigger
1198 *)
523c4f8c
JR
1199 lttng_dynamic_pointer_array_get_pointer(
1200 &sorted_triggers, i);
1201
1202 print_one_trigger(trigger_to_print);
1203 }
1204
1205 ret = 0;
1206 goto end;
1207error:
1208 ret = 1;
1209
1210end:
1211 lttng_dynamic_pointer_array_reset(&sorted_triggers);
1212 return ret;
1213}
1214
1215static enum lttng_error_code mi_error_query_trigger_callback(
1216 const struct lttng_trigger *trigger,
1217 struct lttng_error_query_results **results)
1218{
1219 enum lttng_error_code ret_code;
1220 struct lttng_error_query *query =
1221 lttng_error_query_trigger_create(trigger);
1222
a0377dfe
FD
1223 LTTNG_ASSERT(results);
1224 LTTNG_ASSERT(query);
523c4f8c
JR
1225
1226 ret_code = lttng_error_query_execute(
1227 query, lttng_session_daemon_command_endpoint, results);
1228 if (ret_code != LTTNG_OK) {
1229 enum lttng_trigger_status trigger_status;
1230 const char *trigger_name;
1231 uid_t trigger_uid;
1232
1233 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
a0377dfe 1234 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
523c4f8c
JR
1235
1236 trigger_status = lttng_trigger_get_owner_uid(
1237 trigger, &trigger_uid);
a0377dfe 1238 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
523c4f8c
JR
1239
1240 ERR("Failed to query errors of trigger '%s' (owner uid: %d): %s",
1241 trigger_name, (int) trigger_uid,
1242 lttng_strerror(-ret_code));
1243 }
1244
71637130 1245 lttng_error_query_destroy(query);
523c4f8c
JR
1246 return ret_code;
1247}
1248
1249static enum lttng_error_code mi_error_query_action_callback(
1250 const struct lttng_trigger *trigger,
1251 const struct lttng_action_path *action_path,
1252 struct lttng_error_query_results **results)
1253{
1254 enum lttng_error_code ret_code;
1255 struct lttng_error_query *query =
1256 lttng_error_query_action_create(trigger, action_path);
1257
a0377dfe
FD
1258 LTTNG_ASSERT(results);
1259 LTTNG_ASSERT(query);
523c4f8c
JR
1260
1261 ret_code = lttng_error_query_execute(
1262 query, lttng_session_daemon_command_endpoint, results);
1263 if (ret_code != LTTNG_OK) {
1264 enum lttng_trigger_status trigger_status;
1265 const char *trigger_name;
1266 uid_t trigger_uid;
1267
1268 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
a0377dfe 1269 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
523c4f8c
JR
1270
1271 trigger_status = lttng_trigger_get_owner_uid(
1272 trigger, &trigger_uid);
a0377dfe 1273 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
523c4f8c
JR
1274
1275 ERR("Failed to query errors of an action for trigger '%s' (owner uid: %d): %s",
1276 trigger_name, (int) trigger_uid,
1277 lttng_strerror(-ret_code));
1278 }
71637130
JG
1279
1280 lttng_error_query_destroy(query);
523c4f8c
JR
1281 return ret_code;
1282}
1283
1284static enum lttng_error_code mi_error_query_condition_callback(
1285 const struct lttng_trigger *trigger,
1286 struct lttng_error_query_results **results)
1287{
1288 enum lttng_error_code ret_code;
1289 struct lttng_error_query *query =
1290 lttng_error_query_condition_create(trigger);
1291
a0377dfe
FD
1292 LTTNG_ASSERT(results);
1293 LTTNG_ASSERT(query);
523c4f8c
JR
1294
1295 ret_code = lttng_error_query_execute(
1296 query, lttng_session_daemon_command_endpoint, results);
1297 if (ret_code != LTTNG_OK) {
1298 enum lttng_trigger_status trigger_status;
1299 const char *trigger_name;
1300 uid_t trigger_uid;
1301
1302 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
a0377dfe 1303 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
523c4f8c
JR
1304
1305 trigger_status = lttng_trigger_get_owner_uid(
1306 trigger, &trigger_uid);
a0377dfe 1307 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
523c4f8c
JR
1308
1309 ERR("Failed to query errors of of condition for condition of trigger '%s' (owner uid: %d): %s",
1310 trigger_name, (int) trigger_uid,
1311 lttng_strerror(-ret_code));
1312 }
1313
71637130 1314 lttng_error_query_destroy(query);
523c4f8c
JR
1315 return ret_code;
1316}
71637130 1317
523c4f8c
JR
1318int cmd_list_triggers(int argc, const char **argv)
1319{
1320 int ret;
d50d200a
SM
1321 struct argpar_iter *argpar_iter = NULL;
1322 const struct argpar_item *argpar_item = NULL;
523c4f8c 1323 struct lttng_triggers *triggers = NULL;
523c4f8c
JR
1324 struct mi_writer *mi_writer = NULL;
1325
d50d200a
SM
1326 argc--;
1327 argv++;
1328
1329 argpar_iter = argpar_iter_create(argc, argv, list_trigger_options);
1330 if (!argpar_iter) {
1331 ERR("Failed to allocate an argpar iter.");
0de2479d
SM
1332 goto error;
1333 }
1334
d50d200a
SM
1335 while (true) {
1336 enum parse_next_item_status status;
1337
35c4b2b3 1338 status = parse_next_item(argpar_iter, &argpar_item, 1, argv,
d50d200a
SM
1339 true, NULL);
1340 if (status == PARSE_NEXT_ITEM_STATUS_ERROR) {
1341 goto error;
1342 } else if (status == PARSE_NEXT_ITEM_STATUS_END) {
1343 break;
1344 }
1345
1346 assert(status == PARSE_NEXT_ITEM_STATUS_OK);
0de2479d 1347
d50d200a
SM
1348 if (argpar_item_type(argpar_item) == ARGPAR_ITEM_TYPE_OPT) {
1349 const struct argpar_opt_descr *descr =
1350 argpar_item_opt_descr(argpar_item);
0de2479d 1351
d50d200a 1352 switch (descr->id) {
0de2479d
SM
1353 case OPT_HELP:
1354 SHOW_HELP();
1355 ret = 0;
1356 goto end;
1357
1358 case OPT_LIST_OPTIONS:
523c4f8c
JR
1359 list_cmd_options_argpar(
1360 stdout, list_trigger_options);
0de2479d
SM
1361 ret = 0;
1362 goto end;
1363
1364 default:
1365 abort();
1366 }
1367
1368 } else {
d50d200a
SM
1369 ERR("Unexpected argument: %s",
1370 argpar_item_non_opt_arg(argpar_item));
0de2479d
SM
1371 }
1372 }
1373
1374 ret = lttng_list_triggers(&triggers);
1375 if (ret != LTTNG_OK) {
1376 ERR("Error listing triggers: %s.", lttng_strerror(-ret));
1377 goto error;
1378 }
1379
523c4f8c
JR
1380 if (lttng_opt_mi) {
1381 mi_writer = mi_lttng_writer_create(
1382 fileno(stdout), lttng_opt_mi);
1383 if (!mi_writer) {
1384 ret = CMD_ERROR;
1385 goto end;
1386 }
0efb2ad7 1387
523c4f8c
JR
1388 /* Open command element. */
1389 ret = mi_lttng_writer_command_open(mi_writer,
1390 mi_lttng_element_command_list_trigger);
1391 if (ret) {
1392 ret = CMD_ERROR;
1393 goto end;
0efb2ad7
JG
1394 }
1395
523c4f8c
JR
1396 /* Open output element. */
1397 ret = mi_lttng_writer_open_element(
1398 mi_writer, mi_lttng_element_command_output);
1399 if (ret) {
1400 ret = CMD_ERROR;
1401 goto end;
1402 }
1403 }
0de2479d 1404
523c4f8c
JR
1405 if (lttng_opt_mi) {
1406 const struct mi_lttng_error_query_callbacks callbacks = {
1407 .trigger_cb = mi_error_query_trigger_callback,
523c4f8c 1408 .condition_cb = mi_error_query_condition_callback,
48a40005 1409 .action_cb = mi_error_query_action_callback,
523c4f8c
JR
1410 };
1411
1412 ret = lttng_triggers_mi_serialize(
1413 triggers, mi_writer, &callbacks);
1414 if (ret != LTTNG_OK) {
1415 ERR("Error printing MI triggers: %s.",
1416 lttng_strerror(-ret));
1417 goto error;
1418 }
1419 } else {
1420 ret = print_sorted_triggers(triggers);
1421 if (ret) {
1422 ERR("Error printing triggers");
0de2479d
SM
1423 goto error;
1424 }
1425 }
1426
523c4f8c
JR
1427 /* Mi closing. */
1428 if (lttng_opt_mi) {
1429 /* Close output element. */
1430 ret = mi_lttng_writer_close_element(mi_writer);
1431 if (ret) {
1432 ret = CMD_ERROR;
1433 goto end;
1434 }
0de2479d 1435
523c4f8c
JR
1436 /* Command element close. */
1437 ret = mi_lttng_writer_command_close(mi_writer);
1438 if (ret) {
1439 ret = CMD_ERROR;
1440 goto end;
1441 }
0de2479d
SM
1442 }
1443
1444 ret = 0;
1445 goto end;
1446
1447error:
1448 ret = 1;
1449
1450end:
d50d200a
SM
1451 argpar_item_destroy(argpar_item);
1452 argpar_iter_destroy(argpar_iter);
0de2479d 1453 lttng_triggers_destroy(triggers);
523c4f8c
JR
1454 /* Mi clean-up. */
1455 if (mi_writer && mi_lttng_writer_destroy(mi_writer)) {
1456 /* Preserve original error code. */
1457 ret = ret ? ret : CMD_ERROR;
1458 }
0de2479d
SM
1459 return ret;
1460}
This page took 0.106959 seconds and 4 git commands to generate.