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