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