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