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