action-executor: consider action firing policy on action execution
[lttng-tools.git] / src / bin / lttng / commands / list_triggers.c
CommitLineData
0de2479d
SM
1/*
2 * Copyright (C) 2021 Simon Marchi <simon.marchi@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8#include <stdio.h>
9
10#include "../command.h"
11
12#include "common/argpar/argpar.h"
13#include "common/dynamic-array.h"
14#include "common/mi-lttng.h"
15/* For lttng_condition_type_str(). */
16#include "lttng/condition/condition-internal.h"
90aa04a1
FD
17#include "lttng/condition/on-event.h"
18#include "lttng/condition/on-event-internal.h"
0de2479d
SM
19/* For lttng_domain_type_str(). */
20#include "lttng/domain-internal.h"
85b05318 21#include "../loglevel.h"
0de2479d
SM
22
23#ifdef LTTNG_EMBED_HELP
24static const char help_msg[] =
279eb769 25#include <lttng-list-triggers.1.h>
0de2479d
SM
26;
27#endif
28
29enum {
30 OPT_HELP,
31 OPT_LIST_OPTIONS,
32};
33
34static const
35struct argpar_opt_descr list_trigger_options[] = {
36 { OPT_HELP, 'h', "help", false },
37 { OPT_LIST_OPTIONS, '\0', "list-options", false },
38 ARGPAR_OPT_DESCR_SENTINEL,
39};
40
85b05318
JR
41/*
42 * Returns the human-readable log level name associated with a numerical value
43 * if there is one. The Log4j and JUL domains have discontinuous log level
44 * values (a value can fall between two labels). In those cases, NULL is
45 * returned.
46 */
47static const char *get_pretty_loglevel_name(
48 enum lttng_domain_type domain, int loglevel)
49{
50 const char *name = NULL;
51
52 switch (domain) {
53 case LTTNG_DOMAIN_UST:
54 name = loglevel_value_to_name(loglevel);
55 break;
56 case LTTNG_DOMAIN_LOG4J:
57 name = loglevel_log4j_value_to_name(loglevel);
58 break;
59 case LTTNG_DOMAIN_JUL:
60 name = loglevel_jul_value_to_name(loglevel);
61 break;
62 case LTTNG_DOMAIN_PYTHON:
63 name = loglevel_python_value_to_name(loglevel);
64 break;
65 default:
66 break;
67 }
68
69 return name;
70}
71
0de2479d
SM
72static
73void print_event_rule_tracepoint(const struct lttng_event_rule *event_rule)
74{
75 enum lttng_event_rule_status event_rule_status;
76 enum lttng_domain_type domain_type;
77 const char *pattern;
78 const char *filter;
79 int log_level;
85b05318 80 const struct lttng_log_level_rule *log_level_rule = NULL;
0de2479d
SM
81 unsigned int exclusions_count;
82 int i;
83
84 event_rule_status = lttng_event_rule_tracepoint_get_pattern(
85 event_rule, &pattern);
86 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
87
88 event_rule_status = lttng_event_rule_tracepoint_get_domain_type(
89 event_rule, &domain_type);
90 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
91
92 _MSG(" rule: %s (type: tracepoint, domain: %s", pattern,
93 lttng_domain_type_str(domain_type));
94
95 event_rule_status = lttng_event_rule_tracepoint_get_filter(
96 event_rule, &filter);
97 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
98 _MSG(", filter: %s", filter);
99 } else {
100 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
101 }
102
85b05318
JR
103 event_rule_status = lttng_event_rule_tracepoint_get_log_level_rule(
104 event_rule, &log_level_rule);
0de2479d 105 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
85b05318 106 enum lttng_log_level_rule_status llr_status;
0de2479d 107 const char *log_level_op;
85b05318
JR
108 const char *pretty_loglevel_name;
109
110 switch (lttng_log_level_rule_get_type(log_level_rule)) {
111 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
112 log_level_op = "is";
113 llr_status = lttng_log_level_rule_exactly_get_level(
114 log_level_rule, &log_level);
115 break;
116 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
117 log_level_op = "at least";
118 llr_status = lttng_log_level_rule_at_least_as_severe_as_get_level(
119 log_level_rule, &log_level);
120 break;
121 default:
122 abort();
123 }
124
125 assert(llr_status == LTTNG_LOG_LEVEL_RULE_STATUS_OK);
126
127 pretty_loglevel_name = get_pretty_loglevel_name(
128 domain_type, log_level);
129 if (pretty_loglevel_name) {
130 _MSG(", log level %s %s", log_level_op,
131 pretty_loglevel_name);
132 } else {
133 _MSG(", log level %s %d", log_level_op, log_level);
134 }
0de2479d
SM
135 } else {
136 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
137 }
138
139 event_rule_status = lttng_event_rule_tracepoint_get_exclusions_count(
140 event_rule, &exclusions_count);
141 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
142 if (exclusions_count > 0) {
143 _MSG(", exclusions: ");
144 for (i = 0; i < exclusions_count; i++) {
145 const char *exclusion;
146
147 event_rule_status = lttng_event_rule_tracepoint_get_exclusion_at_index(
148 event_rule, i, &exclusion);
149 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
150
151 _MSG("%s%s", i > 0 ? "," : "", exclusion);
152 }
153 }
154
155 MSG(")");
156}
157
158static void print_kernel_probe_location(
159 const struct lttng_kernel_probe_location *location)
160{
161 enum lttng_kernel_probe_location_status status;
162 switch (lttng_kernel_probe_location_get_type(location)) {
163 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS:
164 {
165 uint64_t address;
166
167 status = lttng_kernel_probe_location_address_get_address(
168 location, &address);
169 if (status != LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK) {
170 ERR("Getting kernel probe location address failed.");
171 goto end;
172 }
173
174 _MSG("0x%" PRIx64, address);
175
176 break;
177 }
178 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET:
179 {
180 uint64_t offset;
181 const char *symbol_name;
182
183 symbol_name = lttng_kernel_probe_location_symbol_get_name(
184 location);
185 if (!symbol_name) {
186 ERR("Getting kernel probe location symbol name failed.");
187 goto end;
188 }
189
190 status = lttng_kernel_probe_location_symbol_get_offset(
191 location, &offset);
192 if (status != LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK) {
193 ERR("Getting kernel probe location address failed.");
194 goto end;
195 }
196
197 if (offset == 0) {
198 _MSG("%s", symbol_name);
199 } else {
200 _MSG("%s+0x%" PRIx64, symbol_name, offset);
201 }
202
203 break;
204 }
205 default:
206 abort();
207 };
208end:
209 return;
210}
211
212static
f2791161 213void print_event_rule_kernel_probe(const struct lttng_event_rule *event_rule)
0de2479d
SM
214{
215 enum lttng_event_rule_status event_rule_status;
216 const char *name;
217 const struct lttng_kernel_probe_location *location;
218
f2791161 219 assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE);
0de2479d 220
d891bb52 221 event_rule_status = lttng_event_rule_kernel_probe_get_event_name(event_rule, &name);
0de2479d
SM
222 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
223 ERR("Failed to get kprobe event rule's name.");
224 goto end;
225 }
226
f2791161 227 event_rule_status = lttng_event_rule_kernel_probe_get_location(
0de2479d
SM
228 event_rule, &location);
229 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
230 ERR("Failed to get kprobe event rule's location.");
231 goto end;
232 }
233
234 _MSG(" rule: %s (type: probe, location: ", name);
235
236 print_kernel_probe_location(location);
237
238 MSG(")");
239
240end:
241 return;
242}
243
244static
1f1567a5 245void print_event_rule_userspace_probe(const struct lttng_event_rule *event_rule)
0de2479d
SM
246{
247 enum lttng_event_rule_status event_rule_status;
248 const char *name;
249 const struct lttng_userspace_probe_location *location;
250 enum lttng_userspace_probe_location_type userspace_probe_location_type;
251
1f1567a5 252 assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_USERSPACE_PROBE);
0de2479d 253
405f9e7d
JR
254 event_rule_status = lttng_event_rule_userspace_probe_get_event_name(
255 event_rule, &name);
0de2479d
SM
256 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
257 ERR("Failed to get uprobe event rule's name.");
258 goto end;
259 }
260
1f1567a5 261 event_rule_status = lttng_event_rule_userspace_probe_get_location(
0de2479d
SM
262 event_rule, &location);
263 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
264 ERR("Failed to get uprobe event rule's location.");
265 goto end;
266 }
267
268 _MSG(" rule: %s (type: userspace probe, location: ", name);
269
270 userspace_probe_location_type =
271 lttng_userspace_probe_location_get_type(location);
272
273 switch (userspace_probe_location_type) {
274 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION:
275 {
276 const char *binary_path, *function_name;
277
278 binary_path = lttng_userspace_probe_location_function_get_binary_path(
279 location);
280 function_name = lttng_userspace_probe_location_function_get_function_name(
281 location);
282
283 _MSG("%s:%s", binary_path, function_name);
284 break;
285 }
286 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT:
287 _MSG("SDT not implemented yet");
288 break;
289 default:
290 abort();
291 }
292
293 MSG(")");
294
295end:
296 return;
297}
298
299static
300void print_event_rule_syscall(const struct lttng_event_rule *event_rule)
301{
302 const char *pattern, *filter;
303 enum lttng_event_rule_status event_rule_status;
304
305 assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_SYSCALL);
306
307 event_rule_status = lttng_event_rule_syscall_get_pattern(
308 event_rule, &pattern);
309 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
310
311 _MSG(" rule: %s (type: syscall", pattern);
312
313 event_rule_status = lttng_event_rule_syscall_get_filter(
314 event_rule, &filter);
315 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
316 _MSG(", filter: %s", filter);
317 } else {
318 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
319 }
320
321 MSG(")");
322}
323
324static
325void print_event_rule(const struct lttng_event_rule *event_rule)
326{
327 const enum lttng_event_rule_type event_rule_type =
328 lttng_event_rule_get_type(event_rule);
329
330 switch (event_rule_type) {
331 case LTTNG_EVENT_RULE_TYPE_TRACEPOINT:
332 print_event_rule_tracepoint(event_rule);
333 break;
f2791161
JR
334 case LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE:
335 print_event_rule_kernel_probe(event_rule);
0de2479d 336 break;
1f1567a5
JR
337 case LTTNG_EVENT_RULE_TYPE_USERSPACE_PROBE:
338 print_event_rule_userspace_probe(event_rule);
0de2479d
SM
339 break;
340 case LTTNG_EVENT_RULE_TYPE_SYSCALL:
341 print_event_rule_syscall(event_rule);
342 break;
343 default:
344 abort();
345 }
346}
347
b203b4b0
SM
348static
349void print_one_event_expr(const struct lttng_event_expr *event_expr)
350{
351 enum lttng_event_expr_type type;
352
353 type = lttng_event_expr_get_type(event_expr);
354
355 switch (type) {
356 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
357 {
358 const char *name;
359
360 name = lttng_event_expr_event_payload_field_get_name(
361 event_expr);
362 _MSG("%s", name);
363
364 break;
365 }
366 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
367 {
368 const char *name;
369
370 name = lttng_event_expr_channel_context_field_get_name(
371 event_expr);
372 _MSG("$ctx.%s", name);
373
374 break;
375 }
376 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
377 {
378 const char *provider_name;
379 const char *type_name;
380
381 provider_name = lttng_event_expr_app_specific_context_field_get_provider_name(
382 event_expr);
383 type_name = lttng_event_expr_app_specific_context_field_get_type_name(
384 event_expr);
385
386 _MSG("$app.%s:%s", provider_name, type_name);
387
388 break;
389 }
390 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
391 {
392 unsigned int index;
393 const struct lttng_event_expr *parent_expr;
394 enum lttng_event_expr_status status;
395
396 parent_expr = lttng_event_expr_array_field_element_get_parent_expr(
397 event_expr);
398 assert(parent_expr != NULL);
399
400 print_one_event_expr(parent_expr);
401
402 status = lttng_event_expr_array_field_element_get_index(
403 event_expr, &index);
404 assert(status == LTTNG_EVENT_EXPR_STATUS_OK);
405
406 _MSG("[%u]", index);
407
408 break;
409 }
410 default:
411 abort();
412 }
413}
414
0de2479d 415static
d602bd6a 416void print_condition_on_event(const struct lttng_condition *condition)
0de2479d
SM
417{
418 const struct lttng_event_rule *event_rule;
419 enum lttng_condition_status condition_status;
b203b4b0 420 unsigned int cap_desc_count, i;
90aa04a1 421 uint64_t error_count;
0de2479d
SM
422
423 condition_status =
d602bd6a 424 lttng_condition_on_event_get_rule(condition, &event_rule);
0de2479d
SM
425 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
426
427 print_event_rule(event_rule);
b203b4b0
SM
428
429 condition_status =
d602bd6a 430 lttng_condition_on_event_get_capture_descriptor_count(
b203b4b0
SM
431 condition, &cap_desc_count);
432 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
433
90aa04a1 434 error_count = lttng_condition_on_event_get_error_count(condition);
71f3b9c7 435 MSG(" tracer notifications discarded: %" PRIu64, error_count);
90aa04a1 436
b203b4b0
SM
437 if (cap_desc_count > 0) {
438 MSG(" captures:");
439
440 for (i = 0; i < cap_desc_count; i++) {
441 const struct lttng_event_expr *cap_desc =
d602bd6a 442 lttng_condition_on_event_get_capture_descriptor_at_index(
b203b4b0
SM
443 condition, i);
444
445 _MSG(" - ");
446 print_one_event_expr(cap_desc);
447 MSG("");
448 }
449 }
0de2479d
SM
450}
451
452static
453void print_one_action(const struct lttng_action *action)
454{
455 enum lttng_action_type action_type;
456 enum lttng_action_status action_status;
457 const char *value;
458
459 action_type = lttng_action_get_type(action);
460 assert(action_type != LTTNG_ACTION_TYPE_GROUP);
461
462 switch (action_type) {
463 case LTTNG_ACTION_TYPE_NOTIFY:
464 MSG("notify");
465 break;
466 case LTTNG_ACTION_TYPE_START_SESSION:
467 action_status = lttng_action_start_session_get_session_name(
468 action, &value);
469 assert(action_status == LTTNG_ACTION_STATUS_OK);
470 MSG("start session `%s`", value);
471 break;
472 case LTTNG_ACTION_TYPE_STOP_SESSION:
473 action_status = lttng_action_stop_session_get_session_name(
474 action, &value);
475 assert(action_status == LTTNG_ACTION_STATUS_OK);
476 MSG("stop session `%s`", value);
477 break;
478 case LTTNG_ACTION_TYPE_ROTATE_SESSION:
479 action_status = lttng_action_rotate_session_get_session_name(
480 action, &value);
481 assert(action_status == LTTNG_ACTION_STATUS_OK);
482 MSG("rotate session `%s`", value);
483 break;
484 case LTTNG_ACTION_TYPE_SNAPSHOT_SESSION:
485 {
486 const struct lttng_snapshot_output *output;
487
488 action_status = lttng_action_snapshot_session_get_session_name(
489 action, &value);
490 assert(action_status == LTTNG_ACTION_STATUS_OK);
491 _MSG("snapshot session `%s`", value);
492
493 action_status = lttng_action_snapshot_session_get_output(
494 action, &output);
495 if (action_status == LTTNG_ACTION_STATUS_OK) {
496 const char *name;
497 uint64_t max_size;
498 const char *ctrl_url, *data_url;
499 bool starts_with_file, starts_with_net, starts_with_net6;
500
501 ctrl_url = lttng_snapshot_output_get_ctrl_url(output);
502 assert(ctrl_url && strlen(ctrl_url) > 0);
503
504 data_url = lttng_snapshot_output_get_data_url(output);
505 assert(data_url);
506
507 starts_with_file = strncmp(ctrl_url, "file://", strlen("file://")) == 0;
508 starts_with_net = strncmp(ctrl_url, "net://", strlen("net://")) == 0;
509 starts_with_net6 = strncmp(ctrl_url, "net6://", strlen("net6://")) == 0;
510
511 if (ctrl_url[0] == '/' || starts_with_file) {
512 if (starts_with_file) {
513 ctrl_url += strlen("file://");
514 }
515
516 _MSG(", path: %s", ctrl_url);
517 } else if (starts_with_net || starts_with_net6) {
518 _MSG(", url: %s", ctrl_url);
519 } else {
520 assert(strlen(data_url) > 0);
521
522 _MSG(", control url: %s, data url: %s", ctrl_url, data_url);
523 }
524
525 name = lttng_snapshot_output_get_name(output);
526 assert(name);
527 if (strlen(name) > 0) {
528 _MSG(", name: %s", name);
529 }
530
531 max_size = lttng_snapshot_output_get_maxsize(output);
532 if (max_size != -1ULL) {
533 _MSG(", max size: %" PRIu64, max_size);
534 }
535 }
536
537 MSG("");
538 break;
539 }
540
541 default:
542 abort();
543 }
544}
545
546static
547void print_one_trigger(const struct lttng_trigger *trigger)
548{
549 const struct lttng_condition *condition;
550 enum lttng_condition_type condition_type;
551 const struct lttng_action *action;
552 enum lttng_action_type action_type;
553 enum lttng_trigger_status trigger_status;
554 const char *name;
555 enum lttng_trigger_firing_policy firing_policy_type;
556 uint64_t threshold;
557 uid_t trigger_uid;
558
559 trigger_status = lttng_trigger_get_name(trigger, &name);
560 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
561
562 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
563 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
564
565 MSG("- id: %s", name);
566 MSG(" user id: %d", trigger_uid);
567
568 trigger_status = lttng_trigger_get_firing_policy(
569 trigger, &firing_policy_type, &threshold);
570 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
571 ERR("Failed to get trigger's policy.");
572 goto end;
573 }
574
575 switch (firing_policy_type) {
576 case LTTNG_TRIGGER_FIRING_POLICY_EVERY_N:
577 if (threshold > 1) {
578 MSG(" firing policy: after every %" PRIu64 " occurences", threshold);
579 }
580 break;
581 case LTTNG_TRIGGER_FIRING_POLICY_ONCE_AFTER_N:
582 MSG(" firing policy: once after %" PRIu64 " occurences", threshold);
583 break;
584 default:
585 abort();
586 }
587
588 condition = lttng_trigger_get_const_condition(trigger);
589 condition_type = lttng_condition_get_type(condition);
590 MSG(" condition: %s", lttng_condition_type_str(condition_type));
591 switch (condition_type) {
d602bd6a
JR
592 case LTTNG_CONDITION_TYPE_ON_EVENT:
593 print_condition_on_event(condition);
0de2479d
SM
594 break;
595 default:
596 MSG(" (condition type not handled in %s)", __func__);
597 break;
598 }
599
600 action = lttng_trigger_get_const_action(trigger);
601 action_type = lttng_action_get_type(action);
602 if (action_type == LTTNG_ACTION_TYPE_GROUP) {
603 unsigned int count, i;
604 enum lttng_action_status action_status;
605
606 MSG(" actions:");
607
608 action_status = lttng_action_group_get_count(action, &count);
609 assert(action_status == LTTNG_ACTION_STATUS_OK);
610
611 for (i = 0; i < count; i++) {
612 const struct lttng_action *subaction =
613 lttng_action_group_get_at_index(
614 action, i);
615
616 _MSG(" ");
617 print_one_action(subaction);
618 }
619 } else {
620 _MSG(" action:");
621 print_one_action(action);
622 }
623
624end:
625 return;
626}
627
628static
629int compare_triggers_by_name(const void *a, const void *b)
630{
631 const struct lttng_trigger *trigger_a = *((const struct lttng_trigger **) a);
632 const struct lttng_trigger *trigger_b = *((const struct lttng_trigger **) b);
633 const char *name_a, *name_b;
634 enum lttng_trigger_status trigger_status;
635
636 trigger_status = lttng_trigger_get_name(trigger_a, &name_a);
637 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
638
639 trigger_status = lttng_trigger_get_name(trigger_b, &name_b);
640 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
641
642 return strcmp(name_a, name_b);
643}
644
645int cmd_list_triggers(int argc, const char **argv)
646{
647 int ret;
648 struct argpar_parse_ret argpar_parse_ret = {};
649 struct lttng_triggers *triggers = NULL;
650 int i;
651 struct lttng_dynamic_pointer_array sorted_triggers;
652 enum lttng_trigger_status trigger_status;
653 unsigned int num_triggers;
654
655 lttng_dynamic_pointer_array_init(&sorted_triggers, NULL);
656
657 argpar_parse_ret = argpar_parse(
658 argc - 1, argv + 1, list_trigger_options, true);
659 if (!argpar_parse_ret.items) {
660 ERR("%s", argpar_parse_ret.error);
661 goto error;
662 }
663
664 for (i = 0; i < argpar_parse_ret.items->n_items; i++) {
665 const struct argpar_item *item =
666 argpar_parse_ret.items->items[i];
667
668 if (item->type == ARGPAR_ITEM_TYPE_OPT) {
669 const struct argpar_item_opt *item_opt =
670 (const struct argpar_item_opt *) item;
671
672 switch (item_opt->descr->id) {
673 case OPT_HELP:
674 SHOW_HELP();
675 ret = 0;
676 goto end;
677
678 case OPT_LIST_OPTIONS:
679 list_cmd_options_argpar(stdout,
680 list_trigger_options);
681 ret = 0;
682 goto end;
683
684 default:
685 abort();
686 }
687
688 } else {
689 const struct argpar_item_non_opt *item_non_opt =
690 (const struct argpar_item_non_opt *) item;
691
692 ERR("Unexpected argument: %s", item_non_opt->arg);
693 }
694 }
695
696 ret = lttng_list_triggers(&triggers);
697 if (ret != LTTNG_OK) {
698 ERR("Error listing triggers: %s.", lttng_strerror(-ret));
699 goto error;
700 }
701
702 trigger_status = lttng_triggers_get_count(triggers, &num_triggers);
703 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
704 ERR("Failed to get trigger count.");
705 goto error;
706 }
707
708 for (i = 0; i < num_triggers; i++) {
709 const int add_ret = lttng_dynamic_pointer_array_add_pointer(
710 &sorted_triggers,
711 (void *) lttng_triggers_get_at_index(triggers, i));
712
713 if (add_ret) {
714 ERR("Failed to allocate array of struct lttng_trigger *.");
715 goto error;
716 }
717 }
718
719 qsort(sorted_triggers.array.buffer.data, num_triggers,
720 sizeof(struct lttng_trigger *),
721 compare_triggers_by_name);
722
723 for (i = 0; i < num_triggers; i++) {
724 const struct lttng_trigger *trigger_to_print =
725 (const struct lttng_trigger *)
726 lttng_dynamic_pointer_array_get_pointer(
727 &sorted_triggers, i);
728
729 print_one_trigger(trigger_to_print);
730 }
731
732 ret = 0;
733 goto end;
734
735error:
736 ret = 1;
737
738end:
739 argpar_parse_ret_fini(&argpar_parse_ret);
740 lttng_triggers_destroy(triggers);
741 lttng_dynamic_pointer_array_reset(&sorted_triggers);
742
743 return ret;
744}
This page took 0.052091 seconds and 4 git commands to generate.