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