Fix: syscall event rule: emission sites not compared in is_equal
[lttng-tools.git] / src / bin / lttng / commands / list_triggers.cpp
CommitLineData
0de2479d
SM
1/*
2 * Copyright (C) 2021 Simon Marchi <simon.marchi@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
c9e313bc 8#include "../command.hpp"
c9e313bc 9#include "common/argpar-utils/argpar-utils.hpp"
28ab034a 10#include "common/argpar/argpar.h"
c9e313bc
SM
11#include "common/dynamic-array.hpp"
12#include "common/mi-lttng.hpp"
2460203a 13#include "lttng/action/list-internal.hpp"
28ab034a 14
0de2479d 15/* For lttng_condition_type_str(). */
c9e313bc 16#include "lttng/condition/condition-internal.hpp"
c9e313bc 17#include "lttng/condition/event-rule-matches-internal.hpp"
28ab034a 18#include "lttng/condition/event-rule-matches.h"
2460203a 19
0de2479d 20/* For lttng_domain_type_str(). */
c9e313bc 21#include "lttng/domain-internal.hpp"
2460203a 22
4f7da553 23/* For lttng_event_rule_kernel_syscall_emission_site_str() */
c9e313bc 24#include "../loglevel.hpp"
28ab034a
JG
25#include "lttng/event-rule/kernel-syscall-internal.hpp"
26
709fb83f 27#include <lttng/lttng.h>
0de2479d
SM
28
29#ifdef LTTNG_EMBED_HELP
30static const char help_msg[] =
279eb769 31#include <lttng-list-triggers.1.h>
28ab034a 32 ;
0de2479d
SM
33#endif
34
63dd3d7b
JG
35#define INDENTATION_LEVEL_STR " "
36
e665dfbc
JG
37using event_rule_logging_get_name_pattern =
38 enum lttng_event_rule_status (*)(const struct lttng_event_rule *, const char **);
39using event_rule_logging_get_filter =
40 enum lttng_event_rule_status (*)(const struct lttng_event_rule *, const char **);
41using event_rule_logging_get_log_level_rule = enum lttng_event_rule_status (*)(
42 const struct lttng_event_rule *, const struct lttng_log_level_rule **);
695f7044 43
0de2479d
SM
44enum {
45 OPT_HELP,
46 OPT_LIST_OPTIONS,
47};
48
28ab034a 49static const struct argpar_opt_descr list_trigger_options[] = {
0de2479d
SM
50 { OPT_HELP, 'h', "help", false },
51 { OPT_LIST_OPTIONS, '\0', "list-options", false },
52 ARGPAR_OPT_DESCR_SENTINEL,
53};
54
28ab034a 55static void print_condition_session_consumed_size(const struct lttng_condition *condition)
19904669
SM
56{
57 enum lttng_condition_status condition_status;
58 const char *session_name;
59 uint64_t threshold;
60
61 condition_status =
28ab034a 62 lttng_condition_session_consumed_size_get_session_name(condition, &session_name);
a0377dfe 63 LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
19904669 64
28ab034a 65 lttng_condition_session_consumed_size_get_threshold(condition, &threshold);
a0377dfe 66 LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
19904669
SM
67
68 MSG(" session name: %s", session_name);
69 MSG(" threshold: %" PRIu64 " bytes", threshold);
70}
71
28ab034a 72static void print_condition_buffer_usage(const struct lttng_condition *condition)
19904669
SM
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
28ab034a 79 condition_status = lttng_condition_buffer_usage_get_session_name(condition, &session_name);
a0377dfe 80 LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
19904669 81
28ab034a 82 condition_status = lttng_condition_buffer_usage_get_channel_name(condition, &channel_name);
a0377dfe 83 LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
19904669 84
28ab034a 85 condition_status = lttng_condition_buffer_usage_get_domain_type(condition, &domain_type);
a0377dfe 86 LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
19904669
SM
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
28ab034a 92 condition_status = lttng_condition_buffer_usage_get_threshold(condition, &threshold);
19904669
SM
93 if (condition_status == LTTNG_CONDITION_STATUS_OK) {
94 MSG(" threshold (bytes): %" PRIu64, threshold);
95 } else {
96 double threshold_ratio;
97
a0377dfe 98 LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_UNSET);
19904669 99
28ab034a
JG
100 condition_status = lttng_condition_buffer_usage_get_threshold_ratio(
101 condition, &threshold_ratio);
a0377dfe 102 LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
19904669
SM
103
104 MSG(" threshold (ratio): %.2f", threshold_ratio);
105 }
106}
107
28ab034a 108static void print_condition_session_rotation(const struct lttng_condition *condition)
19904669
SM
109{
110 enum lttng_condition_status condition_status;
111 const char *session_name;
112
28ab034a
JG
113 condition_status =
114 lttng_condition_session_rotation_get_session_name(condition, &session_name);
a0377dfe 115 LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
19904669
SM
116
117 MSG(" session name: %s", session_name);
118}
119
85b05318
JR
120/*
121 * Returns the human-readable log level name associated with a numerical value
695f7044 122 * if there is one. The Log4j and JUL event rule have discontinuous log level
85b05318
JR
123 * values (a value can fall between two labels). In those cases, NULL is
124 * returned.
125 */
28ab034a
JG
126static const char *get_pretty_loglevel_name(enum lttng_event_rule_type event_rule_type,
127 int loglevel)
85b05318 128{
cd9adb8b 129 const char *name = nullptr;
85b05318 130
695f7044
JR
131 switch (event_rule_type) {
132 case LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT:
85b05318
JR
133 name = loglevel_value_to_name(loglevel);
134 break;
695f7044 135 case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
85b05318
JR
136 name = loglevel_log4j_value_to_name(loglevel);
137 break;
695f7044 138 case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
85b05318
JR
139 name = loglevel_jul_value_to_name(loglevel);
140 break;
695f7044 141 case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
85b05318
JR
142 name = loglevel_python_value_to_name(loglevel);
143 break;
144 default:
145 break;
146 }
147
148 return name;
149}
150
28ab034a 151static void print_event_rule_user_tracepoint(const struct lttng_event_rule *event_rule)
0de2479d
SM
152{
153 enum lttng_event_rule_status event_rule_status;
0de2479d
SM
154 const char *pattern;
155 const char *filter;
156 int log_level;
cd9adb8b 157 const struct lttng_log_level_rule *log_level_rule = nullptr;
0de2479d
SM
158 unsigned int exclusions_count;
159 int i;
160
28ab034a 161 event_rule_status = lttng_event_rule_user_tracepoint_get_name_pattern(event_rule, &pattern);
a0377dfe 162 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
0de2479d 163
695f7044 164 _MSG(" rule: %s (type: user tracepoint", pattern);
0de2479d 165
28ab034a 166 event_rule_status = lttng_event_rule_user_tracepoint_get_filter(event_rule, &filter);
0de2479d
SM
167 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
168 _MSG(", filter: %s", filter);
169 } else {
a0377dfe 170 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
0de2479d
SM
171 }
172
28ab034a
JG
173 event_rule_status =
174 lttng_event_rule_user_tracepoint_get_log_level_rule(event_rule, &log_level_rule);
0de2479d 175 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
85b05318 176 enum lttng_log_level_rule_status llr_status;
0de2479d 177 const char *log_level_op;
85b05318
JR
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";
28ab034a
JG
183 llr_status =
184 lttng_log_level_rule_exactly_get_level(log_level_rule, &log_level);
85b05318
JR
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(
28ab034a 189 log_level_rule, &log_level);
85b05318
JR
190 break;
191 default:
192 abort();
193 }
194
a0377dfe 195 LTTNG_ASSERT(llr_status == LTTNG_LOG_LEVEL_RULE_STATUS_OK);
85b05318 196
28ab034a
JG
197 pretty_loglevel_name =
198 get_pretty_loglevel_name(LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT, log_level);
85b05318 199 if (pretty_loglevel_name) {
28ab034a 200 _MSG(", log level %s %s", log_level_op, pretty_loglevel_name);
85b05318
JR
201 } else {
202 _MSG(", log level %s %d", log_level_op, log_level);
203 }
0de2479d 204 } else {
a0377dfe 205 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
0de2479d
SM
206 }
207
695f7044 208 event_rule_status = lttng_event_rule_user_tracepoint_get_name_pattern_exclusion_count(
28ab034a 209 event_rule, &exclusions_count);
a0377dfe 210 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
0de2479d
SM
211 if (exclusions_count > 0) {
212 _MSG(", exclusions: ");
213 for (i = 0; i < exclusions_count; i++) {
214 const char *exclusion;
215
28ab034a
JG
216 event_rule_status =
217 lttng_event_rule_user_tracepoint_get_name_pattern_exclusion_at_index(
0de2479d 218 event_rule, i, &exclusion);
a0377dfe 219 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
0de2479d
SM
220
221 _MSG("%s%s", i > 0 ? "," : "", exclusion);
222 }
223 }
224
225 MSG(")");
226}
227
28ab034a 228static void print_event_rule_kernel_tracepoint(const struct lttng_event_rule *event_rule)
695f7044
JR
229{
230 enum lttng_event_rule_status event_rule_status;
231 const char *pattern;
232 const char *filter;
233
28ab034a
JG
234 event_rule_status =
235 lttng_event_rule_kernel_tracepoint_get_name_pattern(event_rule, &pattern);
a0377dfe 236 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
695f7044
JR
237
238 _MSG(" rule: %s (type: kernel tracepoint", pattern);
239
28ab034a 240 event_rule_status = lttng_event_rule_kernel_tracepoint_get_filter(event_rule, &filter);
695f7044
JR
241 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
242 _MSG(", filter: %s", filter);
243 } else {
a0377dfe 244 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
695f7044
JR
245 }
246
247 MSG(")");
248}
249
28ab034a 250static void print_event_rule_logging(const struct lttng_event_rule *event_rule)
695f7044
JR
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;
cd9adb8b
JG
257 const struct lttng_log_level_rule *log_level_rule = nullptr;
258 const char *type_str = nullptr;
695f7044
JR
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:
28ab034a 266 logging_get_name_pattern = lttng_event_rule_jul_logging_get_name_pattern;
695f7044 267 logging_get_filter = lttng_event_rule_jul_logging_get_filter;
28ab034a 268 logging_get_log_level_rule = lttng_event_rule_jul_logging_get_log_level_rule;
695f7044
JR
269 type_str = "jul";
270 break;
271 case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
28ab034a 272 logging_get_name_pattern = lttng_event_rule_log4j_logging_get_name_pattern;
695f7044 273 logging_get_filter = lttng_event_rule_log4j_logging_get_filter;
28ab034a 274 logging_get_log_level_rule = lttng_event_rule_log4j_logging_get_log_level_rule;
695f7044
JR
275 type_str = "log4j";
276 break;
277 case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
28ab034a 278 logging_get_name_pattern = lttng_event_rule_python_logging_get_name_pattern;
695f7044 279 logging_get_filter = lttng_event_rule_python_logging_get_filter;
28ab034a 280 logging_get_log_level_rule = lttng_event_rule_python_logging_get_log_level_rule;
695f7044
JR
281 type_str = "python";
282 break;
283 default:
284 abort();
285 break;
286 }
287
28ab034a 288 event_rule_status = logging_get_name_pattern(event_rule, &pattern);
a0377dfe 289 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
695f7044
JR
290
291 _MSG(" rule: %s (type: %s:logging", pattern, type_str);
292
28ab034a 293 event_rule_status = logging_get_filter(event_rule, &filter);
695f7044
JR
294 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
295 _MSG(", filter: %s", filter);
296 } else {
a0377dfe 297 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
695f7044
JR
298 }
299
28ab034a 300 event_rule_status = logging_get_log_level_rule(event_rule, &log_level_rule);
695f7044
JR
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";
28ab034a
JG
309 llr_status =
310 lttng_log_level_rule_exactly_get_level(log_level_rule, &log_level);
695f7044
JR
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(
28ab034a 315 log_level_rule, &log_level);
695f7044
JR
316 break;
317 default:
318 abort();
319 }
320
a0377dfe 321 LTTNG_ASSERT(llr_status == LTTNG_LOG_LEVEL_RULE_STATUS_OK);
695f7044 322
28ab034a 323 pretty_loglevel_name = get_pretty_loglevel_name(event_rule_type, log_level);
695f7044 324 if (pretty_loglevel_name) {
28ab034a 325 _MSG(", log level %s %s", log_level_op, pretty_loglevel_name);
695f7044
JR
326 } else {
327 _MSG(", log level %s %d", log_level_op, log_level);
328 }
329 } else {
a0377dfe 330 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
695f7044
JR
331 }
332
333 MSG(")");
334}
335
28ab034a 336static void print_kernel_probe_location(const struct lttng_kernel_probe_location *location)
0de2479d
SM
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
28ab034a 344 status = lttng_kernel_probe_location_address_get_address(location, &address);
0de2479d
SM
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
28ab034a 359 symbol_name = lttng_kernel_probe_location_symbol_get_name(location);
0de2479d
SM
360 if (!symbol_name) {
361 ERR("Getting kernel probe location symbol name failed.");
362 goto end;
363 }
364
28ab034a 365 status = lttng_kernel_probe_location_symbol_get_offset(location, &offset);
0de2479d
SM
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 };
382end:
383 return;
384}
385
28ab034a 386static void print_event_rule_kernel_probe(const struct lttng_event_rule *event_rule)
0de2479d
SM
387{
388 enum lttng_event_rule_status event_rule_status;
389 const char *name;
390 const struct lttng_kernel_probe_location *location;
391
a0377dfe 392 LTTNG_ASSERT(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE);
0de2479d 393
85522de5 394 event_rule_status = lttng_event_rule_kernel_kprobe_get_event_name(event_rule, &name);
0de2479d
SM
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
28ab034a 400 event_rule_status = lttng_event_rule_kernel_kprobe_get_location(event_rule, &location);
0de2479d
SM
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
85522de5 406 _MSG(" rule: %s (type: kernel:kprobe, location: ", name);
0de2479d
SM
407
408 print_kernel_probe_location(location);
409
410 MSG(")");
411
412end:
413 return;
414}
415
28ab034a 416static void print_event_rule_userspace_probe(const struct lttng_event_rule *event_rule)
0de2479d
SM
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
a0377dfe 423 LTTNG_ASSERT(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_KERNEL_UPROBE);
0de2479d 424
28ab034a 425 event_rule_status = lttng_event_rule_kernel_uprobe_get_event_name(event_rule, &name);
0de2479d
SM
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
28ab034a 431 event_rule_status = lttng_event_rule_kernel_uprobe_get_location(event_rule, &location);
0de2479d
SM
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
46fd07ac 437 _MSG(" rule: %s (type: kernel:uprobe, ", name);
0de2479d 438
28ab034a 439 userspace_probe_location_type = lttng_userspace_probe_location_get_type(location);
0de2479d
SM
440
441 switch (userspace_probe_location_type) {
442 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION:
443 {
444 const char *binary_path, *function_name;
445
28ab034a
JG
446 binary_path = lttng_userspace_probe_location_function_get_binary_path(location);
447 function_name = lttng_userspace_probe_location_function_get_function_name(location);
0de2479d 448
8a917ae8 449 _MSG("location type: ELF, location: %s:%s", binary_path, function_name);
0de2479d
SM
450 break;
451 }
452 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT:
8a917ae8
FD
453 {
454 const char *binary_path, *provider_name, *probe_name;
455
28ab034a
JG
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);
0de2479d 464 break;
8a917ae8 465 }
0de2479d
SM
466 default:
467 abort();
468 }
469
470 MSG(")");
471
472end:
473 return;
474}
475
28ab034a 476static void print_event_rule_syscall(const struct lttng_event_rule *event_rule)
0de2479d
SM
477{
478 const char *pattern, *filter;
479 enum lttng_event_rule_status event_rule_status;
4f7da553 480 enum lttng_event_rule_kernel_syscall_emission_site emission_site;
0de2479d 481
a0377dfe 482 LTTNG_ASSERT(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL);
0de2479d 483
28ab034a 484 emission_site = lttng_event_rule_kernel_syscall_get_emission_site(event_rule);
57739a6b 485
28ab034a 486 event_rule_status = lttng_event_rule_kernel_syscall_get_name_pattern(event_rule, &pattern);
a0377dfe 487 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
0de2479d 488
28ab034a
JG
489 _MSG(" rule: %s (type: kernel:syscall:%s",
490 pattern,
491 lttng_event_rule_kernel_syscall_emission_site_str(emission_site));
0de2479d 492
28ab034a 493 event_rule_status = lttng_event_rule_kernel_syscall_get_filter(event_rule, &filter);
0de2479d
SM
494 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
495 _MSG(", filter: %s", filter);
496 } else {
a0377dfe 497 LTTNG_ASSERT(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
0de2479d
SM
498 }
499
500 MSG(")");
501}
502
28ab034a 503static void print_event_rule(const struct lttng_event_rule *event_rule)
0de2479d 504{
28ab034a 505 const enum lttng_event_rule_type event_rule_type = lttng_event_rule_get_type(event_rule);
0de2479d
SM
506
507 switch (event_rule_type) {
695f7044
JR
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);
0de2479d 518 break;
85522de5 519 case LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE:
f2791161 520 print_event_rule_kernel_probe(event_rule);
0de2479d 521 break;
46fd07ac 522 case LTTNG_EVENT_RULE_TYPE_KERNEL_UPROBE:
1f1567a5 523 print_event_rule_userspace_probe(event_rule);
0de2479d 524 break;
4f7da553 525 case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL:
0de2479d
SM
526 print_event_rule_syscall(event_rule);
527 break;
528 default:
529 abort();
530 }
531}
532
28ab034a 533static void print_one_event_expr(const struct lttng_event_expr *event_expr)
b203b4b0
SM
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
28ab034a 544 name = lttng_event_expr_event_payload_field_get_name(event_expr);
b203b4b0
SM
545 _MSG("%s", name);
546
547 break;
548 }
549 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
550 {
551 const char *name;
552
28ab034a 553 name = lttng_event_expr_channel_context_field_get_name(event_expr);
b203b4b0
SM
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
28ab034a
JG
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);
b203b4b0
SM
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
28ab034a 577 parent_expr = lttng_event_expr_array_field_element_get_parent_expr(event_expr);
cd9adb8b 578 LTTNG_ASSERT(parent_expr != nullptr);
b203b4b0
SM
579
580 print_one_event_expr(parent_expr);
581
28ab034a 582 status = lttng_event_expr_array_field_element_get_index(event_expr, &index);
a0377dfe 583 LTTNG_ASSERT(status == LTTNG_EVENT_EXPR_STATUS_OK);
b203b4b0
SM
584
585 _MSG("[%u]", index);
586
587 break;
588 }
589 default:
590 abort();
591 }
592}
593
28ab034a 594static void print_indentation(unsigned int indentation_level)
63dd3d7b
JG
595{
596 unsigned int i;
597
598 for (i = 0; i < indentation_level; i++) {
599 _MSG(INDENTATION_LEVEL_STR);
600 }
601}
602
28ab034a
JG
603static void print_error_query_results(struct lttng_error_query_results *results,
604 unsigned int base_indentation_level)
63dd3d7b
JG
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);
a0377dfe 610 LTTNG_ASSERT(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
63dd3d7b 611
a0377dfe 612 LTTNG_ASSERT(results);
63dd3d7b
JG
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
28ab034a 624 results_status = lttng_error_query_results_get_result(results, &result, i);
a0377dfe 625 LTTNG_ASSERT(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
63dd3d7b 626
28ab034a 627 result_status = lttng_error_query_result_get_name(result, &result_name);
a0377dfe 628 LTTNG_ASSERT(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
28ab034a
JG
629 result_status =
630 lttng_error_query_result_get_description(result, &result_description);
a0377dfe 631 LTTNG_ASSERT(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
63dd3d7b 632
63dd3d7b 633 if (lttng_error_query_result_get_type(result) ==
28ab034a
JG
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);
63dd3d7b
JG
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)",
28ab034a
JG
651 result_name,
652 result_description);
63dd3d7b
JG
653 continue;
654 }
655 }
656
657 if (printed_errors_count == 0) {
658 _MSG(" none");
659 }
660}
661
28ab034a 662static void print_condition_event_rule_matches(const struct lttng_condition *condition)
0de2479d
SM
663{
664 const struct lttng_event_rule *event_rule;
665 enum lttng_condition_status condition_status;
b203b4b0 666 unsigned int cap_desc_count, i;
0de2479d 667
28ab034a 668 condition_status = lttng_condition_event_rule_matches_get_rule(condition, &event_rule);
a0377dfe 669 LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
0de2479d
SM
670
671 print_event_rule(event_rule);
b203b4b0 672
28ab034a
JG
673 condition_status = lttng_condition_event_rule_matches_get_capture_descriptor_count(
674 condition, &cap_desc_count);
a0377dfe 675 LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
b203b4b0
SM
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 =
28ab034a
JG
682 lttng_condition_event_rule_matches_get_capture_descriptor_at_index(
683 condition, i);
b203b4b0
SM
684
685 _MSG(" - ");
686 print_one_event_expr(cap_desc);
687 MSG("");
688 }
689 }
0de2479d
SM
690}
691
cb9222ff 692static void print_action_errors(const struct lttng_trigger *trigger,
28ab034a
JG
693 const uint64_t *action_path_indexes,
694 size_t action_path_length)
709fb83f 695{
709fb83f 696 enum lttng_error_code error_query_ret;
cd9adb8b 697 struct lttng_error_query_results *results = nullptr;
709fb83f
JG
698 const char *trigger_name;
699 uid_t trigger_uid;
700 enum lttng_trigger_status trigger_status;
cb9222ff 701 struct lttng_error_query *query;
28ab034a
JG
702 struct lttng_action_path *action_path =
703 lttng_action_path_create(action_path_indexes, action_path_length);
cb9222ff 704
a0377dfe 705 LTTNG_ASSERT(action_path);
709fb83f 706
cb9222ff 707 query = lttng_error_query_action_create(trigger, action_path);
a0377dfe 708 LTTNG_ASSERT(query);
709fb83f
JG
709
710 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
0efb2ad7
JG
711 /*
712 * Anonymous triggers are not listed; this would be an internal error.
713 */
a0377dfe 714 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
709fb83f
JG
715
716 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
a0377dfe 717 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
709fb83f 718
28ab034a
JG
719 error_query_ret =
720 lttng_error_query_execute(query, lttng_session_daemon_command_endpoint, &results);
709fb83f
JG
721 if (error_query_ret != LTTNG_OK) {
722 ERR("Failed to query errors of trigger '%s' (owner uid: %d): %s",
28ab034a
JG
723 trigger_name,
724 (int) trigger_uid,
725 lttng_strerror(-error_query_ret));
709fb83f
JG
726 goto end;
727 }
728
63dd3d7b 729 print_error_query_results(results, 3);
709fb83f
JG
730
731end:
732 MSG("");
733 lttng_error_query_destroy(query);
734 lttng_error_query_results_destroy(results);
cb9222ff 735 lttng_action_path_destroy(action_path);
709fb83f
JG
736}
737
28ab034a
JG
738static 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)
0de2479d
SM
742{
743 enum lttng_action_type action_type;
744 enum lttng_action_status action_status;
cd9adb8b 745 const struct lttng_rate_policy *policy = nullptr;
0de2479d
SM
746 const char *value;
747
748 action_type = lttng_action_get_type(action);
a0377dfe 749 LTTNG_ASSERT(action_type != LTTNG_ACTION_TYPE_LIST);
0de2479d
SM
750
751 switch (action_type) {
752 case LTTNG_ACTION_TYPE_NOTIFY:
e45dd625
JR
753 _MSG("notify");
754
28ab034a 755 action_status = lttng_action_notify_get_rate_policy(action, &policy);
e45dd625 756 if (action_status != LTTNG_ACTION_STATUS_OK) {
7f4d5b07 757 ERR("Failed to retrieve rate policy.");
e45dd625
JR
758 goto end;
759 }
0de2479d
SM
760 break;
761 case LTTNG_ACTION_TYPE_START_SESSION:
28ab034a 762 action_status = lttng_action_start_session_get_session_name(action, &value);
a0377dfe 763 LTTNG_ASSERT(action_status == LTTNG_ACTION_STATUS_OK);
e45dd625
JR
764 _MSG("start session `%s`", value);
765
28ab034a 766 action_status = lttng_action_start_session_get_rate_policy(action, &policy);
e45dd625 767 if (action_status != LTTNG_ACTION_STATUS_OK) {
7f4d5b07 768 ERR("Failed to retrieve rate policy.");
e45dd625
JR
769 goto end;
770 }
0de2479d
SM
771 break;
772 case LTTNG_ACTION_TYPE_STOP_SESSION:
28ab034a 773 action_status = lttng_action_stop_session_get_session_name(action, &value);
a0377dfe 774 LTTNG_ASSERT(action_status == LTTNG_ACTION_STATUS_OK);
e45dd625
JR
775 _MSG("stop session `%s`", value);
776
28ab034a 777 action_status = lttng_action_stop_session_get_rate_policy(action, &policy);
e45dd625 778 if (action_status != LTTNG_ACTION_STATUS_OK) {
7f4d5b07 779 ERR("Failed to retrieve rate policy.");
e45dd625
JR
780 goto end;
781 }
0de2479d
SM
782 break;
783 case LTTNG_ACTION_TYPE_ROTATE_SESSION:
28ab034a 784 action_status = lttng_action_rotate_session_get_session_name(action, &value);
a0377dfe 785 LTTNG_ASSERT(action_status == LTTNG_ACTION_STATUS_OK);
e45dd625
JR
786 _MSG("rotate session `%s`", value);
787
28ab034a 788 action_status = lttng_action_rotate_session_get_rate_policy(action, &policy);
e45dd625 789 if (action_status != LTTNG_ACTION_STATUS_OK) {
7f4d5b07 790 ERR("Failed to retrieve rate policy.");
e45dd625
JR
791 goto end;
792 }
0de2479d
SM
793 break;
794 case LTTNG_ACTION_TYPE_SNAPSHOT_SESSION:
795 {
796 const struct lttng_snapshot_output *output;
797
28ab034a 798 action_status = lttng_action_snapshot_session_get_session_name(action, &value);
a0377dfe 799 LTTNG_ASSERT(action_status == LTTNG_ACTION_STATUS_OK);
0de2479d
SM
800 _MSG("snapshot session `%s`", value);
801
28ab034a 802 action_status = lttng_action_snapshot_session_get_output(action, &output);
0de2479d
SM
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);
a0377dfe 810 LTTNG_ASSERT(ctrl_url && strlen(ctrl_url) > 0);
0de2479d
SM
811
812 data_url = lttng_snapshot_output_get_data_url(output);
a0377dfe 813 LTTNG_ASSERT(data_url);
0de2479d
SM
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 {
a0377dfe 828 LTTNG_ASSERT(strlen(data_url) > 0);
0de2479d
SM
829
830 _MSG(", control url: %s, data url: %s", ctrl_url, data_url);
831 }
832
833 name = lttng_snapshot_output_get_name(output);
a0377dfe 834 LTTNG_ASSERT(name);
0de2479d
SM
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
28ab034a 845 action_status = lttng_action_snapshot_session_get_rate_policy(action, &policy);
e45dd625 846 if (action_status != LTTNG_ACTION_STATUS_OK) {
7f4d5b07 847 ERR("Failed to retrieve rate policy.");
e45dd625
JR
848 goto end;
849 }
0de2479d
SM
850 break;
851 }
0de2479d
SM
852 default:
853 abort();
854 }
e45dd625
JR
855
856 if (policy) {
7f4d5b07
JR
857 enum lttng_rate_policy_type policy_type;
858 enum lttng_rate_policy_status policy_status;
e45dd625
JR
859 uint64_t policy_value = 0;
860
7f4d5b07 861 policy_type = lttng_rate_policy_get_type(policy);
e45dd625
JR
862
863 switch (policy_type) {
7f4d5b07 864 case LTTNG_RATE_POLICY_TYPE_EVERY_N:
28ab034a
JG
865 policy_status =
866 lttng_rate_policy_every_n_get_interval(policy, &policy_value);
7f4d5b07
JR
867 if (policy_status != LTTNG_RATE_POLICY_STATUS_OK) {
868 ERR("Failed to get action rate policy interval");
e45dd625
JR
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 */
28ab034a 875 _MSG(", rate policy: every %" PRIu64 " occurrences", policy_value);
e45dd625
JR
876 }
877 break;
7f4d5b07 878 case LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N:
28ab034a
JG
879 policy_status =
880 lttng_rate_policy_once_after_n_get_threshold(policy, &policy_value);
7f4d5b07
JR
881 if (policy_status != LTTNG_RATE_POLICY_STATUS_OK) {
882 ERR("Failed to get action rate policy interval");
e45dd625
JR
883 goto end;
884 }
28ab034a 885 _MSG(", rate policy: once after %" PRIu64 " occurrences", policy_value);
e45dd625
JR
886 break;
887 default:
888 abort();
889 }
890 }
891
892 MSG("");
28ab034a 893 print_action_errors(trigger, action_path_indexes, action_path_length);
709fb83f 894
e45dd625
JR
895end:
896 return;
0de2479d
SM
897}
898
28ab034a 899static void print_trigger_errors(const struct lttng_trigger *trigger)
709fb83f 900{
709fb83f 901 enum lttng_error_code error_query_ret;
cd9adb8b 902 struct lttng_error_query_results *results = nullptr;
709fb83f
JG
903 enum lttng_trigger_status trigger_status;
904 const char *trigger_name;
905 uid_t trigger_uid;
28ab034a 906 struct lttng_error_query *query = lttng_error_query_trigger_create(trigger);
709fb83f 907
a0377dfe 908 LTTNG_ASSERT(query);
0efb2ad7
JG
909 /*
910 * Anonymous triggers are not listed; this would be an internal error.
911 */
709fb83f 912 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
a0377dfe 913 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
709fb83f
JG
914
915 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
a0377dfe 916 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
709fb83f 917
28ab034a
JG
918 error_query_ret =
919 lttng_error_query_execute(query, lttng_session_daemon_command_endpoint, &results);
709fb83f
JG
920 if (error_query_ret != LTTNG_OK) {
921 ERR("Failed to query errors of trigger '%s' (owner uid: %d): %s",
28ab034a
JG
922 trigger_name,
923 (int) trigger_uid,
924 lttng_strerror(-error_query_ret));
709fb83f
JG
925 goto end;
926 }
927
63dd3d7b 928 print_error_query_results(results, 1);
709fb83f 929
63dd3d7b
JG
930end:
931 MSG("");
932 lttng_error_query_destroy(query);
933 lttng_error_query_results_destroy(results);
934}
709fb83f 935
28ab034a 936static void print_condition_errors(const struct lttng_trigger *trigger)
63dd3d7b
JG
937{
938 enum lttng_error_code error_query_ret;
cd9adb8b 939 struct lttng_error_query_results *results = nullptr;
63dd3d7b
JG
940 enum lttng_trigger_status trigger_status;
941 const char *trigger_name;
942 uid_t trigger_uid;
28ab034a 943 struct lttng_error_query *query = lttng_error_query_condition_create(trigger);
709fb83f 944
a0377dfe 945 LTTNG_ASSERT(query);
63dd3d7b
JG
946 /*
947 * Anonymous triggers are not listed; this would be an internal error.
948 */
949 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
a0377dfe 950 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
709fb83f 951
63dd3d7b 952 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
a0377dfe 953 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
709fb83f 954
28ab034a
JG
955 error_query_ret =
956 lttng_error_query_execute(query, lttng_session_daemon_command_endpoint, &results);
63dd3d7b
JG
957 if (error_query_ret != LTTNG_OK) {
958 ERR("Failed to query errors of condition of trigger '%s' (owner uid: %d): %s",
28ab034a
JG
959 trigger_name,
960 (int) trigger_uid,
961 lttng_strerror(-error_query_ret));
63dd3d7b 962 goto end;
709fb83f
JG
963 }
964
63dd3d7b 965 print_error_query_results(results, 2);
709fb83f
JG
966
967end:
968 MSG("");
969 lttng_error_query_destroy(query);
970 lttng_error_query_results_destroy(results);
971}
972
28ab034a 973static void print_one_trigger(const struct lttng_trigger *trigger)
0de2479d
SM
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;
0de2479d
SM
981 uid_t trigger_uid;
982
0efb2ad7
JG
983 /*
984 * Anonymous triggers are not listed since they can't be specified nor
985 * referenced through the CLI.
986 */
0de2479d 987 trigger_status = lttng_trigger_get_name(trigger, &name);
0efb2ad7
JG
988 if (trigger_status == LTTNG_TRIGGER_STATUS_UNSET) {
989 goto end;
990 }
991
a0377dfe 992 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
0de2479d
SM
993
994 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
a0377dfe 995 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
0de2479d 996
1d4b59f2 997 MSG("- name: %s", name);
481c5310 998 MSG(" owner uid: %d", trigger_uid);
0de2479d 999
0de2479d
SM
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) {
19904669
SM
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;
8dbb86b8
JR
1015 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES:
1016 print_condition_event_rule_matches(condition);
0de2479d
SM
1017 break;
1018 default:
19904669 1019 abort();
0de2479d
SM
1020 }
1021
63dd3d7b
JG
1022 print_condition_errors(trigger);
1023
0de2479d
SM
1024 action = lttng_trigger_get_const_action(trigger);
1025 action_type = lttng_action_get_type(action);
7c2fae7c 1026 if (action_type == LTTNG_ACTION_TYPE_LIST) {
2460203a 1027 uint64_t action_path_index = 0;
0de2479d
SM
1028
1029 MSG(" actions:");
b17ed2ad 1030 for (auto subaction : lttng::ctl::const_action_list_view(action)) {
0de2479d 1031 _MSG(" ");
28ab034a 1032 print_one_action(trigger, subaction, &action_path_index, 1);
2460203a 1033 action_path_index++;
0de2479d
SM
1034 }
1035 } else {
1036 _MSG(" action:");
cd9adb8b 1037 print_one_action(trigger, action, nullptr, 0);
0de2479d
SM
1038 }
1039
709fb83f 1040 print_trigger_errors(trigger);
0efb2ad7
JG
1041end:
1042 return;
0de2479d
SM
1043}
1044
28ab034a 1045static int compare_triggers_by_name(const void *a, const void *b)
0de2479d
SM
1046{
1047 const struct lttng_trigger *trigger_a = *((const struct lttng_trigger **) a);
1048 const struct lttng_trigger *trigger_b = *((const struct lttng_trigger **) b);
1049 const char *name_a, *name_b;
1050 enum lttng_trigger_status trigger_status;
1051
0efb2ad7 1052 /* Anonymous triggers are not reachable here. */
0de2479d 1053 trigger_status = lttng_trigger_get_name(trigger_a, &name_a);
a0377dfe 1054 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
0de2479d
SM
1055
1056 trigger_status = lttng_trigger_get_name(trigger_b, &name_b);
a0377dfe 1057 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
0de2479d
SM
1058
1059 return strcmp(name_a, name_b);
1060}
1061
523c4f8c 1062static int print_sorted_triggers(const struct lttng_triggers *triggers)
0de2479d
SM
1063{
1064 int ret;
0de2479d
SM
1065 int i;
1066 struct lttng_dynamic_pointer_array sorted_triggers;
1067 enum lttng_trigger_status trigger_status;
1068 unsigned int num_triggers;
1069
cd9adb8b 1070 lttng_dynamic_pointer_array_init(&sorted_triggers, nullptr);
0de2479d 1071
523c4f8c
JR
1072 trigger_status = lttng_triggers_get_count(triggers, &num_triggers);
1073 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
1074 ERR("Failed to get trigger count.");
1075 goto error;
1076 }
1077
1078 for (i = 0; i < num_triggers; i++) {
1079 int add_ret;
1080 const char *unused_name;
28ab034a 1081 const struct lttng_trigger *trigger = lttng_triggers_get_at_index(triggers, i);
523c4f8c
JR
1082
1083 trigger_status = lttng_trigger_get_name(trigger, &unused_name);
1084 switch (trigger_status) {
1085 case LTTNG_TRIGGER_STATUS_OK:
1086 break;
1087 case LTTNG_TRIGGER_STATUS_UNSET:
1088 /* Don't list anonymous triggers. */
1089 continue;
1090 default:
1091 abort();
1092 }
1093
28ab034a
JG
1094 add_ret =
1095 lttng_dynamic_pointer_array_add_pointer(&sorted_triggers, (void *) trigger);
523c4f8c
JR
1096 if (add_ret) {
1097 ERR("Failed to allocate array of struct lttng_trigger *.");
1098 goto error;
1099 }
1100 }
1101
28ab034a
JG
1102 qsort(sorted_triggers.array.buffer.data,
1103 num_triggers,
1104 sizeof(struct lttng_trigger *),
1105 compare_triggers_by_name);
523c4f8c 1106
28ab034a
JG
1107 for (i = 0; i < lttng_dynamic_pointer_array_get_count(&sorted_triggers); i++) {
1108 const struct lttng_trigger *trigger_to_print =
1109 (const struct lttng_trigger *) lttng_dynamic_pointer_array_get_pointer(
1110 &sorted_triggers, i);
523c4f8c
JR
1111
1112 print_one_trigger(trigger_to_print);
1113 }
1114
1115 ret = 0;
1116 goto end;
1117error:
1118 ret = 1;
1119
1120end:
1121 lttng_dynamic_pointer_array_reset(&sorted_triggers);
1122 return ret;
1123}
1124
28ab034a
JG
1125static enum lttng_error_code
1126mi_error_query_trigger_callback(const struct lttng_trigger *trigger,
1127 struct lttng_error_query_results **results)
523c4f8c
JR
1128{
1129 enum lttng_error_code ret_code;
28ab034a 1130 struct lttng_error_query *query = lttng_error_query_trigger_create(trigger);
523c4f8c 1131
a0377dfe
FD
1132 LTTNG_ASSERT(results);
1133 LTTNG_ASSERT(query);
523c4f8c 1134
28ab034a 1135 ret_code = lttng_error_query_execute(query, lttng_session_daemon_command_endpoint, results);
523c4f8c
JR
1136 if (ret_code != LTTNG_OK) {
1137 enum lttng_trigger_status trigger_status;
1138 const char *trigger_name;
1139 uid_t trigger_uid;
1140
1141 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
a0377dfe 1142 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
523c4f8c 1143
28ab034a 1144 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
a0377dfe 1145 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
523c4f8c
JR
1146
1147 ERR("Failed to query errors of trigger '%s' (owner uid: %d): %s",
28ab034a
JG
1148 trigger_name,
1149 (int) trigger_uid,
1150 lttng_strerror(-ret_code));
523c4f8c
JR
1151 }
1152
71637130 1153 lttng_error_query_destroy(query);
523c4f8c
JR
1154 return ret_code;
1155}
1156
28ab034a
JG
1157static enum lttng_error_code
1158mi_error_query_action_callback(const struct lttng_trigger *trigger,
1159 const struct lttng_action_path *action_path,
1160 struct lttng_error_query_results **results)
523c4f8c
JR
1161{
1162 enum lttng_error_code ret_code;
28ab034a 1163 struct lttng_error_query *query = lttng_error_query_action_create(trigger, action_path);
523c4f8c 1164
a0377dfe
FD
1165 LTTNG_ASSERT(results);
1166 LTTNG_ASSERT(query);
523c4f8c 1167
28ab034a 1168 ret_code = lttng_error_query_execute(query, lttng_session_daemon_command_endpoint, results);
523c4f8c
JR
1169 if (ret_code != LTTNG_OK) {
1170 enum lttng_trigger_status trigger_status;
1171 const char *trigger_name;
1172 uid_t trigger_uid;
1173
1174 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
a0377dfe 1175 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
523c4f8c 1176
28ab034a 1177 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
a0377dfe 1178 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
523c4f8c
JR
1179
1180 ERR("Failed to query errors of an action for trigger '%s' (owner uid: %d): %s",
28ab034a
JG
1181 trigger_name,
1182 (int) trigger_uid,
1183 lttng_strerror(-ret_code));
523c4f8c 1184 }
71637130
JG
1185
1186 lttng_error_query_destroy(query);
523c4f8c
JR
1187 return ret_code;
1188}
1189
28ab034a
JG
1190static enum lttng_error_code
1191mi_error_query_condition_callback(const struct lttng_trigger *trigger,
1192 struct lttng_error_query_results **results)
523c4f8c
JR
1193{
1194 enum lttng_error_code ret_code;
28ab034a 1195 struct lttng_error_query *query = lttng_error_query_condition_create(trigger);
523c4f8c 1196
a0377dfe
FD
1197 LTTNG_ASSERT(results);
1198 LTTNG_ASSERT(query);
523c4f8c 1199
28ab034a 1200 ret_code = lttng_error_query_execute(query, lttng_session_daemon_command_endpoint, results);
523c4f8c
JR
1201 if (ret_code != LTTNG_OK) {
1202 enum lttng_trigger_status trigger_status;
1203 const char *trigger_name;
1204 uid_t trigger_uid;
1205
1206 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
a0377dfe 1207 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
523c4f8c 1208
28ab034a 1209 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
a0377dfe 1210 LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
523c4f8c
JR
1211
1212 ERR("Failed to query errors of of condition for condition of trigger '%s' (owner uid: %d): %s",
28ab034a
JG
1213 trigger_name,
1214 (int) trigger_uid,
1215 lttng_strerror(-ret_code));
523c4f8c
JR
1216 }
1217
71637130 1218 lttng_error_query_destroy(query);
523c4f8c
JR
1219 return ret_code;
1220}
71637130 1221
523c4f8c
JR
1222int cmd_list_triggers(int argc, const char **argv)
1223{
1224 int ret;
cd9adb8b
JG
1225 struct argpar_iter *argpar_iter = nullptr;
1226 const struct argpar_item *argpar_item = nullptr;
1227 struct lttng_triggers *triggers = nullptr;
1228 struct mi_writer *mi_writer = nullptr;
523c4f8c 1229
d50d200a
SM
1230 argc--;
1231 argv++;
1232
1233 argpar_iter = argpar_iter_create(argc, argv, list_trigger_options);
1234 if (!argpar_iter) {
1235 ERR("Failed to allocate an argpar iter.");
0de2479d
SM
1236 goto error;
1237 }
1238
d50d200a
SM
1239 while (true) {
1240 enum parse_next_item_status status;
1241
cd9adb8b
JG
1242 status =
1243 parse_next_item(argpar_iter, &argpar_item, 1, argv, true, nullptr, nullptr);
ef9ff9cb 1244 if (status == PARSE_NEXT_ITEM_STATUS_ERROR ||
28ab034a 1245 status == PARSE_NEXT_ITEM_STATUS_ERROR_MEMORY) {
d50d200a
SM
1246 goto error;
1247 } else if (status == PARSE_NEXT_ITEM_STATUS_END) {
1248 break;
1249 }
1250
1251 assert(status == PARSE_NEXT_ITEM_STATUS_OK);
0de2479d 1252
d50d200a 1253 if (argpar_item_type(argpar_item) == ARGPAR_ITEM_TYPE_OPT) {
28ab034a 1254 const struct argpar_opt_descr *descr = argpar_item_opt_descr(argpar_item);
0de2479d 1255
d50d200a 1256 switch (descr->id) {
0de2479d
SM
1257 case OPT_HELP:
1258 SHOW_HELP();
1259 ret = 0;
1260 goto end;
1261
1262 case OPT_LIST_OPTIONS:
28ab034a 1263 list_cmd_options_argpar(stdout, list_trigger_options);
0de2479d
SM
1264 ret = 0;
1265 goto end;
1266
1267 default:
1268 abort();
1269 }
1270
1271 } else {
28ab034a 1272 ERR("Unexpected argument: %s", argpar_item_non_opt_arg(argpar_item));
0de2479d
SM
1273 }
1274 }
1275
1276 ret = lttng_list_triggers(&triggers);
1277 if (ret != LTTNG_OK) {
1278 ERR("Error listing triggers: %s.", lttng_strerror(-ret));
1279 goto error;
1280 }
1281
523c4f8c 1282 if (lttng_opt_mi) {
28ab034a 1283 mi_writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
523c4f8c
JR
1284 if (!mi_writer) {
1285 ret = CMD_ERROR;
1286 goto end;
1287 }
0efb2ad7 1288
523c4f8c
JR
1289 /* Open command element. */
1290 ret = mi_lttng_writer_command_open(mi_writer,
28ab034a 1291 mi_lttng_element_command_list_trigger);
523c4f8c
JR
1292 if (ret) {
1293 ret = CMD_ERROR;
1294 goto end;
0efb2ad7
JG
1295 }
1296
523c4f8c 1297 /* Open output element. */
28ab034a 1298 ret = mi_lttng_writer_open_element(mi_writer, mi_lttng_element_command_output);
523c4f8c
JR
1299 if (ret) {
1300 ret = CMD_ERROR;
1301 goto end;
1302 }
1303 }
0de2479d 1304
523c4f8c
JR
1305 if (lttng_opt_mi) {
1306 const struct mi_lttng_error_query_callbacks callbacks = {
1307 .trigger_cb = mi_error_query_trigger_callback,
523c4f8c 1308 .condition_cb = mi_error_query_condition_callback,
48a40005 1309 .action_cb = mi_error_query_action_callback,
523c4f8c
JR
1310 };
1311
28ab034a 1312 ret = lttng_triggers_mi_serialize(triggers, mi_writer, &callbacks);
523c4f8c 1313 if (ret != LTTNG_OK) {
28ab034a 1314 ERR("Error printing MI triggers: %s.", lttng_strerror(-ret));
523c4f8c
JR
1315 goto error;
1316 }
1317 } else {
1318 ret = print_sorted_triggers(triggers);
1319 if (ret) {
1320 ERR("Error printing triggers");
0de2479d
SM
1321 goto error;
1322 }
1323 }
1324
523c4f8c
JR
1325 /* Mi closing. */
1326 if (lttng_opt_mi) {
1327 /* Close output element. */
1328 ret = mi_lttng_writer_close_element(mi_writer);
1329 if (ret) {
1330 ret = CMD_ERROR;
1331 goto end;
1332 }
0de2479d 1333
523c4f8c
JR
1334 /* Command element close. */
1335 ret = mi_lttng_writer_command_close(mi_writer);
1336 if (ret) {
1337 ret = CMD_ERROR;
1338 goto end;
1339 }
0de2479d
SM
1340 }
1341
1342 ret = 0;
1343 goto end;
1344
1345error:
1346 ret = 1;
1347
1348end:
d50d200a
SM
1349 argpar_item_destroy(argpar_item);
1350 argpar_iter_destroy(argpar_iter);
0de2479d 1351 lttng_triggers_destroy(triggers);
523c4f8c
JR
1352 /* Mi clean-up. */
1353 if (mi_writer && mi_lttng_writer_destroy(mi_writer)) {
1354 /* Preserve original error code. */
1355 ret = ret ? ret : CMD_ERROR;
1356 }
0de2479d
SM
1357 return ret;
1358}
This page took 0.12469 seconds and 5 git commands to generate.