Rename lttng_event_rule_userspace_probe to lttng_event_rule_kernel_uprobe
[lttng-tools.git] / src / bin / lttng / commands / list_triggers.c
... / ...
CommitLineData
1/*
2 * Copyright (C) 2021 Simon Marchi <simon.marchi@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8#include <stdio.h>
9
10#include "../command.h"
11
12#include "common/argpar/argpar.h"
13#include "common/dynamic-array.h"
14#include "common/mi-lttng.h"
15/* For lttng_condition_type_str(). */
16#include "lttng/condition/condition-internal.h"
17#include "lttng/condition/event-rule-matches.h"
18#include "lttng/condition/event-rule-matches-internal.h"
19/* For lttng_domain_type_str(). */
20#include "lttng/domain-internal.h"
21/* For lttng_event_rule_kernel_syscall_emission_site_str() */
22#include "lttng/event-rule/kernel-syscall-internal.h"
23#include "../loglevel.h"
24#include <lttng/lttng.h>
25
26#ifdef LTTNG_EMBED_HELP
27static const char help_msg[] =
28#include <lttng-list-triggers.1.h>
29;
30#endif
31
32enum {
33 OPT_HELP,
34 OPT_LIST_OPTIONS,
35};
36
37static const
38struct argpar_opt_descr list_trigger_options[] = {
39 { OPT_HELP, 'h', "help", false },
40 { OPT_LIST_OPTIONS, '\0', "list-options", false },
41 ARGPAR_OPT_DESCR_SENTINEL,
42};
43
44static void print_condition_session_consumed_size(
45 const struct lttng_condition *condition)
46{
47 enum lttng_condition_status condition_status;
48 const char *session_name;
49 uint64_t threshold;
50
51 condition_status =
52 lttng_condition_session_consumed_size_get_session_name(
53 condition, &session_name);
54 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
55
56 lttng_condition_session_consumed_size_get_threshold(
57 condition, &threshold);
58 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
59
60 MSG(" session name: %s", session_name);
61 MSG(" threshold: %" PRIu64 " bytes", threshold);
62}
63
64static void print_condition_buffer_usage(
65 const struct lttng_condition *condition)
66{
67 enum lttng_condition_status condition_status;
68 const char *session_name, *channel_name;
69 enum lttng_domain_type domain_type;
70 uint64_t threshold;
71
72 condition_status = lttng_condition_buffer_usage_get_session_name(
73 condition, &session_name);
74 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
75
76 condition_status = lttng_condition_buffer_usage_get_channel_name(
77 condition, &channel_name);
78 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
79
80 condition_status = lttng_condition_buffer_usage_get_domain_type(
81 condition, &domain_type);
82 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
83
84 MSG(" session name: %s", session_name);
85 MSG(" channel name: %s", channel_name);
86 MSG(" domain: %s", lttng_domain_type_str(domain_type));
87
88 condition_status = lttng_condition_buffer_usage_get_threshold(
89 condition, &threshold);
90 if (condition_status == LTTNG_CONDITION_STATUS_OK) {
91 MSG(" threshold (bytes): %" PRIu64, threshold);
92 } else {
93 double threshold_ratio;
94
95 assert(condition_status == LTTNG_CONDITION_STATUS_UNSET);
96
97 condition_status =
98 lttng_condition_buffer_usage_get_threshold_ratio(
99 condition, &threshold_ratio);
100 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
101
102 MSG(" threshold (ratio): %.2f", threshold_ratio);
103 }
104}
105
106static void print_condition_session_rotation(
107 const struct lttng_condition *condition)
108{
109 enum lttng_condition_status condition_status;
110 const char *session_name;
111
112 condition_status = lttng_condition_session_rotation_get_session_name(
113 condition, &session_name);
114 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
115
116 MSG(" session name: %s", session_name);
117}
118
119/*
120 * Returns the human-readable log level name associated with a numerical value
121 * if there is one. The Log4j and JUL domains have discontinuous log level
122 * values (a value can fall between two labels). In those cases, NULL is
123 * returned.
124 */
125static const char *get_pretty_loglevel_name(
126 enum lttng_domain_type domain, int loglevel)
127{
128 const char *name = NULL;
129
130 switch (domain) {
131 case LTTNG_DOMAIN_UST:
132 name = loglevel_value_to_name(loglevel);
133 break;
134 case LTTNG_DOMAIN_LOG4J:
135 name = loglevel_log4j_value_to_name(loglevel);
136 break;
137 case LTTNG_DOMAIN_JUL:
138 name = loglevel_jul_value_to_name(loglevel);
139 break;
140 case LTTNG_DOMAIN_PYTHON:
141 name = loglevel_python_value_to_name(loglevel);
142 break;
143 default:
144 break;
145 }
146
147 return name;
148}
149
150static
151void print_event_rule_tracepoint(const struct lttng_event_rule *event_rule)
152{
153 enum lttng_event_rule_status event_rule_status;
154 enum lttng_domain_type domain_type;
155 const char *pattern;
156 const char *filter;
157 int log_level;
158 const struct lttng_log_level_rule *log_level_rule = NULL;
159 unsigned int exclusions_count;
160 int i;
161
162 event_rule_status = lttng_event_rule_tracepoint_get_name_pattern(
163 event_rule, &pattern);
164 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
165
166 event_rule_status = lttng_event_rule_tracepoint_get_domain_type(
167 event_rule, &domain_type);
168 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
169
170 _MSG(" rule: %s (type: tracepoint, domain: %s", pattern,
171 lttng_domain_type_str(domain_type));
172
173 event_rule_status = lttng_event_rule_tracepoint_get_filter(
174 event_rule, &filter);
175 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
176 _MSG(", filter: %s", filter);
177 } else {
178 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
179 }
180
181 event_rule_status = lttng_event_rule_tracepoint_get_log_level_rule(
182 event_rule, &log_level_rule);
183 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
184 enum lttng_log_level_rule_status llr_status;
185 const char *log_level_op;
186 const char *pretty_loglevel_name;
187
188 switch (lttng_log_level_rule_get_type(log_level_rule)) {
189 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
190 log_level_op = "is";
191 llr_status = lttng_log_level_rule_exactly_get_level(
192 log_level_rule, &log_level);
193 break;
194 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
195 log_level_op = "at least";
196 llr_status = lttng_log_level_rule_at_least_as_severe_as_get_level(
197 log_level_rule, &log_level);
198 break;
199 default:
200 abort();
201 }
202
203 assert(llr_status == LTTNG_LOG_LEVEL_RULE_STATUS_OK);
204
205 pretty_loglevel_name = get_pretty_loglevel_name(
206 domain_type, log_level);
207 if (pretty_loglevel_name) {
208 _MSG(", log level %s %s", log_level_op,
209 pretty_loglevel_name);
210 } else {
211 _MSG(", log level %s %d", log_level_op, log_level);
212 }
213 } else {
214 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
215 }
216
217 event_rule_status = lttng_event_rule_tracepoint_get_name_pattern_exclusion_count(
218 event_rule, &exclusions_count);
219 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
220 if (exclusions_count > 0) {
221 _MSG(", exclusions: ");
222 for (i = 0; i < exclusions_count; i++) {
223 const char *exclusion;
224
225 event_rule_status = lttng_event_rule_tracepoint_get_name_pattern_exclusion_at_index(
226 event_rule, i, &exclusion);
227 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
228
229 _MSG("%s%s", i > 0 ? "," : "", exclusion);
230 }
231 }
232
233 MSG(")");
234}
235
236static void print_kernel_probe_location(
237 const struct lttng_kernel_probe_location *location)
238{
239 enum lttng_kernel_probe_location_status status;
240 switch (lttng_kernel_probe_location_get_type(location)) {
241 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS:
242 {
243 uint64_t address;
244
245 status = lttng_kernel_probe_location_address_get_address(
246 location, &address);
247 if (status != LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK) {
248 ERR("Getting kernel probe location address failed.");
249 goto end;
250 }
251
252 _MSG("0x%" PRIx64, address);
253
254 break;
255 }
256 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET:
257 {
258 uint64_t offset;
259 const char *symbol_name;
260
261 symbol_name = lttng_kernel_probe_location_symbol_get_name(
262 location);
263 if (!symbol_name) {
264 ERR("Getting kernel probe location symbol name failed.");
265 goto end;
266 }
267
268 status = lttng_kernel_probe_location_symbol_get_offset(
269 location, &offset);
270 if (status != LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK) {
271 ERR("Getting kernel probe location address failed.");
272 goto end;
273 }
274
275 if (offset == 0) {
276 _MSG("%s", symbol_name);
277 } else {
278 _MSG("%s+0x%" PRIx64, symbol_name, offset);
279 }
280
281 break;
282 }
283 default:
284 abort();
285 };
286end:
287 return;
288}
289
290static
291void print_event_rule_kernel_probe(const struct lttng_event_rule *event_rule)
292{
293 enum lttng_event_rule_status event_rule_status;
294 const char *name;
295 const struct lttng_kernel_probe_location *location;
296
297 assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE);
298
299 event_rule_status = lttng_event_rule_kernel_probe_get_event_name(event_rule, &name);
300 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
301 ERR("Failed to get kprobe event rule's name.");
302 goto end;
303 }
304
305 event_rule_status = lttng_event_rule_kernel_probe_get_location(
306 event_rule, &location);
307 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
308 ERR("Failed to get kprobe event rule's location.");
309 goto end;
310 }
311
312 _MSG(" rule: %s (type: probe, location: ", name);
313
314 print_kernel_probe_location(location);
315
316 MSG(")");
317
318end:
319 return;
320}
321
322static
323void print_event_rule_userspace_probe(const struct lttng_event_rule *event_rule)
324{
325 enum lttng_event_rule_status event_rule_status;
326 const char *name;
327 const struct lttng_userspace_probe_location *location;
328 enum lttng_userspace_probe_location_type userspace_probe_location_type;
329
330 assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_KERNEL_UPROBE);
331
332 event_rule_status = lttng_event_rule_kernel_uprobe_get_event_name(
333 event_rule, &name);
334 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
335 ERR("Failed to get uprobe event rule's name.");
336 goto end;
337 }
338
339 event_rule_status = lttng_event_rule_kernel_uprobe_get_location(
340 event_rule, &location);
341 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
342 ERR("Failed to get uprobe event rule's location.");
343 goto end;
344 }
345
346 _MSG(" rule: %s (type: kernel:uprobe, ", name);
347
348 userspace_probe_location_type =
349 lttng_userspace_probe_location_get_type(location);
350
351 switch (userspace_probe_location_type) {
352 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION:
353 {
354 const char *binary_path, *function_name;
355
356 binary_path = lttng_userspace_probe_location_function_get_binary_path(
357 location);
358 function_name = lttng_userspace_probe_location_function_get_function_name(
359 location);
360
361 _MSG("location type: ELF, location: %s:%s", binary_path, function_name);
362 break;
363 }
364 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT:
365 {
366 const char *binary_path, *provider_name, *probe_name;
367
368 binary_path = lttng_userspace_probe_location_tracepoint_get_binary_path(
369 location);
370 provider_name = lttng_userspace_probe_location_tracepoint_get_provider_name(
371 location);
372 probe_name = lttng_userspace_probe_location_tracepoint_get_probe_name(
373 location);
374 _MSG("location type: SDT, location: %s:%s:%s", binary_path, provider_name, probe_name);
375 break;
376 }
377 default:
378 abort();
379 }
380
381 MSG(")");
382
383end:
384 return;
385}
386
387static
388void print_event_rule_syscall(const struct lttng_event_rule *event_rule)
389{
390 const char *pattern, *filter;
391 enum lttng_event_rule_status event_rule_status;
392 enum lttng_event_rule_kernel_syscall_emission_site emission_site;
393
394 assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL);
395
396 emission_site =
397 lttng_event_rule_kernel_syscall_get_emission_site(event_rule);
398
399 event_rule_status = lttng_event_rule_kernel_syscall_get_name_pattern(
400 event_rule, &pattern);
401 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
402
403 _MSG(" rule: %s (type: kernel:syscall:%s", pattern,
404 lttng_event_rule_kernel_syscall_emission_site_str(
405 emission_site));
406
407 event_rule_status = lttng_event_rule_kernel_syscall_get_filter(
408 event_rule, &filter);
409 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
410 _MSG(", filter: %s", filter);
411 } else {
412 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
413 }
414
415 MSG(")");
416}
417
418static
419void print_event_rule(const struct lttng_event_rule *event_rule)
420{
421 const enum lttng_event_rule_type event_rule_type =
422 lttng_event_rule_get_type(event_rule);
423
424 switch (event_rule_type) {
425 case LTTNG_EVENT_RULE_TYPE_TRACEPOINT:
426 print_event_rule_tracepoint(event_rule);
427 break;
428 case LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE:
429 print_event_rule_kernel_probe(event_rule);
430 break;
431 case LTTNG_EVENT_RULE_TYPE_KERNEL_UPROBE:
432 print_event_rule_userspace_probe(event_rule);
433 break;
434 case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL:
435 print_event_rule_syscall(event_rule);
436 break;
437 default:
438 abort();
439 }
440}
441
442static
443void print_one_event_expr(const struct lttng_event_expr *event_expr)
444{
445 enum lttng_event_expr_type type;
446
447 type = lttng_event_expr_get_type(event_expr);
448
449 switch (type) {
450 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
451 {
452 const char *name;
453
454 name = lttng_event_expr_event_payload_field_get_name(
455 event_expr);
456 _MSG("%s", name);
457
458 break;
459 }
460 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
461 {
462 const char *name;
463
464 name = lttng_event_expr_channel_context_field_get_name(
465 event_expr);
466 _MSG("$ctx.%s", name);
467
468 break;
469 }
470 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
471 {
472 const char *provider_name;
473 const char *type_name;
474
475 provider_name = lttng_event_expr_app_specific_context_field_get_provider_name(
476 event_expr);
477 type_name = lttng_event_expr_app_specific_context_field_get_type_name(
478 event_expr);
479
480 _MSG("$app.%s:%s", provider_name, type_name);
481
482 break;
483 }
484 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
485 {
486 unsigned int index;
487 const struct lttng_event_expr *parent_expr;
488 enum lttng_event_expr_status status;
489
490 parent_expr = lttng_event_expr_array_field_element_get_parent_expr(
491 event_expr);
492 assert(parent_expr != NULL);
493
494 print_one_event_expr(parent_expr);
495
496 status = lttng_event_expr_array_field_element_get_index(
497 event_expr, &index);
498 assert(status == LTTNG_EVENT_EXPR_STATUS_OK);
499
500 _MSG("[%u]", index);
501
502 break;
503 }
504 default:
505 abort();
506 }
507}
508
509static void print_condition_event_rule_matches(
510 const struct lttng_condition *condition)
511{
512 const struct lttng_event_rule *event_rule;
513 enum lttng_condition_status condition_status;
514 unsigned int cap_desc_count, i;
515
516 condition_status = lttng_condition_event_rule_matches_get_rule(
517 condition, &event_rule);
518 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
519
520 print_event_rule(event_rule);
521
522 condition_status =
523 lttng_condition_event_rule_matches_get_capture_descriptor_count(
524 condition, &cap_desc_count);
525 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
526
527 if (cap_desc_count > 0) {
528 MSG(" captures:");
529
530 for (i = 0; i < cap_desc_count; i++) {
531 const struct lttng_event_expr *cap_desc =
532 lttng_condition_event_rule_matches_get_capture_descriptor_at_index(
533 condition, i);
534
535 _MSG(" - ");
536 print_one_event_expr(cap_desc);
537 MSG("");
538 }
539 }
540}
541
542static void print_action_errors(const struct lttng_trigger *trigger,
543 const struct lttng_action *action,
544 const uint64_t *action_path_indexes,
545 size_t action_path_length)
546{
547 unsigned int i, count, printed_errors_count = 0;
548 enum lttng_error_code error_query_ret;
549 enum lttng_error_query_results_status results_status;
550 struct lttng_error_query_results *results = NULL;
551 const char *trigger_name;
552 uid_t trigger_uid;
553 enum lttng_trigger_status trigger_status;
554 struct lttng_error_query *query;
555 struct lttng_action_path *action_path = lttng_action_path_create(
556 action_path_indexes, action_path_length);
557
558 assert(action_path);
559
560 query = lttng_error_query_action_create(trigger, action_path);
561 assert(query);
562
563 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
564 /*
565 * Anonymous triggers are not listed; this would be an internal error.
566 */
567 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
568
569 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
570 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
571
572 error_query_ret = lttng_error_query_execute(
573 query, lttng_session_daemon_command_endpoint, &results);
574 if (error_query_ret != LTTNG_OK) {
575 ERR("Failed to query errors of trigger '%s' (owner uid: %d): %s",
576 trigger_name, (int) trigger_uid,
577 lttng_strerror(-error_query_ret));
578 goto end;
579 }
580
581 results_status = lttng_error_query_results_get_count(results, &count);
582 assert(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
583
584 _MSG(" errors:");
585
586 for (i = 0; i < count; i++) {
587 const struct lttng_error_query_result *result;
588 enum lttng_error_query_result_status result_status;
589 const char *result_name;
590 const char *result_description;
591 uint64_t result_value;
592
593 results_status = lttng_error_query_results_get_result(
594 results, &result, i);
595 assert(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
596
597 result_status = lttng_error_query_result_get_name(
598 result, &result_name);
599 assert(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
600 result_status = lttng_error_query_result_get_description(
601 result, &result_description);
602 assert(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
603
604 if (lttng_error_query_result_get_type(result) ==
605 LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER) {
606 result_status = lttng_error_query_result_counter_get_value(
607 result, &result_value);
608 assert(result_status ==
609 LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
610 if (result_value == 0) {
611 continue;
612 }
613
614 MSG("");
615 _MSG(" %s: %" PRIu64, result_name,
616 result_value);
617 printed_errors_count++;
618 } else {
619 _MSG(" Unknown error query result type for result '%s' (%s)",
620 result_name, result_description);
621 continue;
622 }
623 }
624
625 if (printed_errors_count == 0) {
626 _MSG(" none");
627 }
628
629end:
630 MSG("");
631 lttng_error_query_destroy(query);
632 lttng_error_query_results_destroy(results);
633 lttng_action_path_destroy(action_path);
634}
635
636static
637void print_one_action(const struct lttng_trigger *trigger,
638 const struct lttng_action *action,
639 const uint64_t *action_path_indexes,
640 size_t action_path_length)
641{
642 enum lttng_action_type action_type;
643 enum lttng_action_status action_status;
644 const struct lttng_rate_policy *policy = NULL;
645 const char *value;
646
647 action_type = lttng_action_get_type(action);
648 assert(action_type != LTTNG_ACTION_TYPE_LIST);
649
650 switch (action_type) {
651 case LTTNG_ACTION_TYPE_NOTIFY:
652 _MSG("notify");
653
654 action_status = lttng_action_notify_get_rate_policy(
655 action, &policy);
656 if (action_status != LTTNG_ACTION_STATUS_OK) {
657 ERR("Failed to retrieve rate policy.");
658 goto end;
659 }
660 break;
661 case LTTNG_ACTION_TYPE_START_SESSION:
662 action_status = lttng_action_start_session_get_session_name(
663 action, &value);
664 assert(action_status == LTTNG_ACTION_STATUS_OK);
665 _MSG("start session `%s`", value);
666
667 action_status = lttng_action_start_session_get_rate_policy(
668 action, &policy);
669 if (action_status != LTTNG_ACTION_STATUS_OK) {
670 ERR("Failed to retrieve rate policy.");
671 goto end;
672 }
673 break;
674 case LTTNG_ACTION_TYPE_STOP_SESSION:
675 action_status = lttng_action_stop_session_get_session_name(
676 action, &value);
677 assert(action_status == LTTNG_ACTION_STATUS_OK);
678 _MSG("stop session `%s`", value);
679
680 action_status = lttng_action_stop_session_get_rate_policy(
681 action, &policy);
682 if (action_status != LTTNG_ACTION_STATUS_OK) {
683 ERR("Failed to retrieve rate policy.");
684 goto end;
685 }
686 break;
687 case LTTNG_ACTION_TYPE_ROTATE_SESSION:
688 action_status = lttng_action_rotate_session_get_session_name(
689 action, &value);
690 assert(action_status == LTTNG_ACTION_STATUS_OK);
691 _MSG("rotate session `%s`", value);
692
693 action_status = lttng_action_rotate_session_get_rate_policy(
694 action, &policy);
695 if (action_status != LTTNG_ACTION_STATUS_OK) {
696 ERR("Failed to retrieve rate policy.");
697 goto end;
698 }
699 break;
700 case LTTNG_ACTION_TYPE_SNAPSHOT_SESSION:
701 {
702 const struct lttng_snapshot_output *output;
703
704 action_status = lttng_action_snapshot_session_get_session_name(
705 action, &value);
706 assert(action_status == LTTNG_ACTION_STATUS_OK);
707 _MSG("snapshot session `%s`", value);
708
709 action_status = lttng_action_snapshot_session_get_output(
710 action, &output);
711 if (action_status == LTTNG_ACTION_STATUS_OK) {
712 const char *name;
713 uint64_t max_size;
714 const char *ctrl_url, *data_url;
715 bool starts_with_file, starts_with_net, starts_with_net6;
716
717 ctrl_url = lttng_snapshot_output_get_ctrl_url(output);
718 assert(ctrl_url && strlen(ctrl_url) > 0);
719
720 data_url = lttng_snapshot_output_get_data_url(output);
721 assert(data_url);
722
723 starts_with_file = strncmp(ctrl_url, "file://", strlen("file://")) == 0;
724 starts_with_net = strncmp(ctrl_url, "net://", strlen("net://")) == 0;
725 starts_with_net6 = strncmp(ctrl_url, "net6://", strlen("net6://")) == 0;
726
727 if (ctrl_url[0] == '/' || starts_with_file) {
728 if (starts_with_file) {
729 ctrl_url += strlen("file://");
730 }
731
732 _MSG(", path: %s", ctrl_url);
733 } else if (starts_with_net || starts_with_net6) {
734 _MSG(", url: %s", ctrl_url);
735 } else {
736 assert(strlen(data_url) > 0);
737
738 _MSG(", control url: %s, data url: %s", ctrl_url, data_url);
739 }
740
741 name = lttng_snapshot_output_get_name(output);
742 assert(name);
743 if (strlen(name) > 0) {
744 _MSG(", name: %s", name);
745 }
746
747 max_size = lttng_snapshot_output_get_maxsize(output);
748 if (max_size != -1ULL) {
749 _MSG(", max size: %" PRIu64, max_size);
750 }
751 }
752
753 action_status = lttng_action_snapshot_session_get_rate_policy(
754 action, &policy);
755 if (action_status != LTTNG_ACTION_STATUS_OK) {
756 ERR("Failed to retrieve rate policy.");
757 goto end;
758 }
759 break;
760 }
761 default:
762 abort();
763 }
764
765 if (policy) {
766 enum lttng_rate_policy_type policy_type;
767 enum lttng_rate_policy_status policy_status;
768 uint64_t policy_value = 0;
769
770 policy_type = lttng_rate_policy_get_type(policy);
771
772 switch (policy_type) {
773 case LTTNG_RATE_POLICY_TYPE_EVERY_N:
774 policy_status = lttng_rate_policy_every_n_get_interval(
775 policy, &policy_value);
776 if (policy_status != LTTNG_RATE_POLICY_STATUS_OK) {
777 ERR("Failed to get action rate policy interval");
778 goto end;
779 }
780 if (policy_value > 1) {
781 /* The default is 1 so print only when it is a
782 * special case.
783 */
784 _MSG(", rate policy: every %" PRIu64
785 " occurrences",
786 policy_value);
787 }
788 break;
789 case LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N:
790 policy_status = lttng_rate_policy_once_after_n_get_threshold(
791 policy, &policy_value);
792 if (policy_status != LTTNG_RATE_POLICY_STATUS_OK) {
793 ERR("Failed to get action rate policy interval");
794 goto end;
795 }
796 _MSG(", rate policy: once after %" PRIu64
797 " occurrences",
798 policy_value);
799 break;
800 default:
801 abort();
802 }
803 }
804
805 MSG("");
806 print_action_errors(trigger, action, action_path_indexes,
807 action_path_length);
808
809end:
810 return;
811}
812
813static
814void print_trigger_errors(const struct lttng_trigger *trigger)
815{
816 unsigned int i, count, printed_errors_count = 0;
817 enum lttng_error_code error_query_ret;
818 enum lttng_error_query_results_status results_status;
819 struct lttng_error_query_results *results = NULL;
820 enum lttng_trigger_status trigger_status;
821 const char *trigger_name;
822 uid_t trigger_uid;
823 struct lttng_error_query *query =
824 lttng_error_query_trigger_create(trigger);
825
826 assert(query);
827 /*
828 * Anonymous triggers are not listed; this would be an internal error.
829 */
830 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
831 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
832
833 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
834 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
835
836 error_query_ret = lttng_error_query_execute(
837 query, lttng_session_daemon_command_endpoint, &results);
838 if (error_query_ret != LTTNG_OK) {
839 ERR("Failed to query errors of trigger '%s' (owner uid: %d): %s",
840 trigger_name, (int) trigger_uid,
841 lttng_strerror(-error_query_ret));
842 goto end;
843 }
844
845 results_status = lttng_error_query_results_get_count(results, &count);
846 assert(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
847
848 _MSG(" errors:");
849
850 for (i = 0; i < count; i++) {
851 const struct lttng_error_query_result *result;
852 enum lttng_error_query_result_status result_status;
853 const char *result_name;
854 const char *result_description;
855 uint64_t result_value;
856
857 results_status = lttng_error_query_results_get_result(
858 results, &result, i);
859 assert(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
860
861 result_status = lttng_error_query_result_get_name(
862 result, &result_name);
863 assert(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
864 result_status = lttng_error_query_result_get_description(
865 result, &result_description);
866 assert(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
867
868 if (lttng_error_query_result_get_type(result) ==
869 LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER) {
870 result_status = lttng_error_query_result_counter_get_value(
871 result, &result_value);
872 assert(result_status ==
873 LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
874 if (result_value == 0) {
875 continue;
876 }
877
878 MSG("");
879 _MSG(" %s: %" PRIu64, result_name,
880 result_value);
881 printed_errors_count++;
882 } else {
883 _MSG(" Unknown error query result type for result '%s' (%s)",
884 result_name, result_description);
885 continue;
886 }
887 }
888
889 if (printed_errors_count == 0) {
890 _MSG(" none");
891 }
892
893end:
894 MSG("");
895 lttng_error_query_destroy(query);
896 lttng_error_query_results_destroy(results);
897}
898
899static
900void print_one_trigger(const struct lttng_trigger *trigger)
901{
902 const struct lttng_condition *condition;
903 enum lttng_condition_type condition_type;
904 const struct lttng_action *action;
905 enum lttng_action_type action_type;
906 enum lttng_trigger_status trigger_status;
907 const char *name;
908 uid_t trigger_uid;
909
910 /*
911 * Anonymous triggers are not listed since they can't be specified nor
912 * referenced through the CLI.
913 */
914 trigger_status = lttng_trigger_get_name(trigger, &name);
915 if (trigger_status == LTTNG_TRIGGER_STATUS_UNSET) {
916 goto end;
917 }
918
919 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
920
921 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
922 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
923
924 MSG("- name: %s", name);
925 MSG(" owner uid: %d", trigger_uid);
926
927 condition = lttng_trigger_get_const_condition(trigger);
928 condition_type = lttng_condition_get_type(condition);
929 MSG(" condition: %s", lttng_condition_type_str(condition_type));
930 switch (condition_type) {
931 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE:
932 print_condition_session_consumed_size(condition);
933 break;
934 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH:
935 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
936 print_condition_buffer_usage(condition);
937 break;
938 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING:
939 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED:
940 print_condition_session_rotation(condition);
941 break;
942 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES:
943 print_condition_event_rule_matches(condition);
944 break;
945 default:
946 abort();
947 }
948
949 action = lttng_trigger_get_const_action(trigger);
950 action_type = lttng_action_get_type(action);
951 if (action_type == LTTNG_ACTION_TYPE_LIST) {
952 unsigned int count, i;
953 enum lttng_action_status action_status;
954
955 MSG(" actions:");
956
957 action_status = lttng_action_list_get_count(action, &count);
958 assert(action_status == LTTNG_ACTION_STATUS_OK);
959
960 for (i = 0; i < count; i++) {
961 const uint64_t action_path_index = i;
962 const struct lttng_action *subaction =
963 lttng_action_list_get_at_index(
964 action, i);
965
966 _MSG(" ");
967 print_one_action(trigger, subaction, &action_path_index,
968 1);
969 }
970 } else {
971 _MSG(" action:");
972 print_one_action(trigger, action, NULL, 0);
973 }
974
975 print_trigger_errors(trigger);
976end:
977 return;
978}
979
980static
981int compare_triggers_by_name(const void *a, const void *b)
982{
983 const struct lttng_trigger *trigger_a = *((const struct lttng_trigger **) a);
984 const struct lttng_trigger *trigger_b = *((const struct lttng_trigger **) b);
985 const char *name_a, *name_b;
986 enum lttng_trigger_status trigger_status;
987
988 /* Anonymous triggers are not reachable here. */
989 trigger_status = lttng_trigger_get_name(trigger_a, &name_a);
990 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
991
992 trigger_status = lttng_trigger_get_name(trigger_b, &name_b);
993 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
994
995 return strcmp(name_a, name_b);
996}
997
998int cmd_list_triggers(int argc, const char **argv)
999{
1000 int ret;
1001 struct argpar_parse_ret argpar_parse_ret = {};
1002 struct lttng_triggers *triggers = NULL;
1003 int i;
1004 struct lttng_dynamic_pointer_array sorted_triggers;
1005 enum lttng_trigger_status trigger_status;
1006 unsigned int num_triggers;
1007
1008 lttng_dynamic_pointer_array_init(&sorted_triggers, NULL);
1009
1010 argpar_parse_ret = argpar_parse(
1011 argc - 1, argv + 1, list_trigger_options, true);
1012 if (!argpar_parse_ret.items) {
1013 ERR("%s", argpar_parse_ret.error);
1014 goto error;
1015 }
1016
1017 for (i = 0; i < argpar_parse_ret.items->n_items; i++) {
1018 const struct argpar_item *item =
1019 argpar_parse_ret.items->items[i];
1020
1021 if (item->type == ARGPAR_ITEM_TYPE_OPT) {
1022 const struct argpar_item_opt *item_opt =
1023 (const struct argpar_item_opt *) item;
1024
1025 switch (item_opt->descr->id) {
1026 case OPT_HELP:
1027 SHOW_HELP();
1028 ret = 0;
1029 goto end;
1030
1031 case OPT_LIST_OPTIONS:
1032 list_cmd_options_argpar(stdout,
1033 list_trigger_options);
1034 ret = 0;
1035 goto end;
1036
1037 default:
1038 abort();
1039 }
1040
1041 } else {
1042 const struct argpar_item_non_opt *item_non_opt =
1043 (const struct argpar_item_non_opt *) item;
1044
1045 ERR("Unexpected argument: %s", item_non_opt->arg);
1046 }
1047 }
1048
1049 ret = lttng_list_triggers(&triggers);
1050 if (ret != LTTNG_OK) {
1051 ERR("Error listing triggers: %s.", lttng_strerror(-ret));
1052 goto error;
1053 }
1054
1055 trigger_status = lttng_triggers_get_count(triggers, &num_triggers);
1056 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
1057 ERR("Failed to get trigger count.");
1058 goto error;
1059 }
1060
1061 for (i = 0; i < num_triggers; i++) {
1062 int add_ret;
1063 const char *unused_name;
1064 const struct lttng_trigger *trigger =
1065 lttng_triggers_get_at_index(triggers, i);
1066
1067 trigger_status = lttng_trigger_get_name(trigger, &unused_name);
1068 switch (trigger_status) {
1069 case LTTNG_TRIGGER_STATUS_OK:
1070 break;
1071 case LTTNG_TRIGGER_STATUS_UNSET:
1072 /* Don't list anonymous triggers. */
1073 continue;
1074 default:
1075 abort();
1076 }
1077
1078 add_ret = lttng_dynamic_pointer_array_add_pointer(
1079 &sorted_triggers, (void *) trigger);
1080
1081 if (add_ret) {
1082 ERR("Failed to allocate array of struct lttng_trigger *.");
1083 goto error;
1084 }
1085 }
1086
1087 qsort(sorted_triggers.array.buffer.data, num_triggers,
1088 sizeof(struct lttng_trigger *),
1089 compare_triggers_by_name);
1090
1091 for (i = 0; i < num_triggers; i++) {
1092 const struct lttng_trigger *trigger_to_print =
1093 (const struct lttng_trigger *)
1094 lttng_dynamic_pointer_array_get_pointer(
1095 &sorted_triggers, i);
1096
1097 print_one_trigger(trigger_to_print);
1098 }
1099
1100 ret = 0;
1101 goto end;
1102
1103error:
1104 ret = 1;
1105
1106end:
1107 argpar_parse_ret_fini(&argpar_parse_ret);
1108 lttng_triggers_destroy(triggers);
1109 lttng_dynamic_pointer_array_reset(&sorted_triggers);
1110
1111 return ret;
1112}
This page took 0.027362 seconds and 4 git commands to generate.