Fix: add_trigger.c: `goto error` with a wrong UID for `--owner-uid`
[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_syscall_emission_site_str() */
22#include "lttng/event-rule/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_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_exclusions_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_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_USERSPACE_PROBE);
331
332 event_rule_status = lttng_event_rule_userspace_probe_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_userspace_probe_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: userspace probe, ", 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_syscall_emission_site_type emission_site_type;
393
394 assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_SYSCALL);
395
396 emission_site_type =
397 lttng_event_rule_syscall_get_emission_site_type(event_rule);
398
399 event_rule_status = lttng_event_rule_syscall_get_pattern(
400 event_rule, &pattern);
401 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
402
403 _MSG(" rule: %s (type: syscall:%s", pattern,
404 lttng_event_rule_syscall_emission_site_str(
405 emission_site_type));
406
407 event_rule_status = lttng_event_rule_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_USERSPACE_PROBE:
432 print_event_rule_userspace_probe(event_rule);
433 break;
434 case LTTNG_EVENT_RULE_TYPE_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
543void print_action_errors(const struct lttng_trigger *trigger,
544 const struct lttng_action *action)
545{
546 unsigned int i, count, printed_errors_count = 0;
547 enum lttng_error_code error_query_ret;
548 enum lttng_error_query_results_status results_status;
549 struct lttng_error_query_results *results = NULL;
550 const char *trigger_name;
551 uid_t trigger_uid;
552 enum lttng_trigger_status trigger_status;
553 struct lttng_error_query *query =
554 lttng_error_query_action_create(trigger, action);
555
556 assert(query);
557
558 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
559 /*
560 * Anonymous triggers are not listed; this would be an internal error.
561 */
562 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
563
564 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
565 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
566
567 error_query_ret = lttng_error_query_execute(
568 query, lttng_session_daemon_command_endpoint, &results);
569 if (error_query_ret != LTTNG_OK) {
570 ERR("Failed to query errors of trigger '%s' (owner uid: %d): %s",
571 trigger_name, (int) trigger_uid,
572 lttng_strerror(-error_query_ret));
573 goto end;
574 }
575
576 results_status = lttng_error_query_results_get_count(results, &count);
577 assert(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
578
579 _MSG(" errors:");
580
581 for (i = 0; i < count; i++) {
582 const struct lttng_error_query_result *result;
583 enum lttng_error_query_result_status result_status;
584 const char *result_name;
585 const char *result_description;
586 uint64_t result_value;
587
588 results_status = lttng_error_query_results_get_result(
589 results, &result, i);
590 assert(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
591
592 result_status = lttng_error_query_result_get_name(
593 result, &result_name);
594 assert(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
595 result_status = lttng_error_query_result_get_description(
596 result, &result_description);
597 assert(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
598
599 if (lttng_error_query_result_get_type(result) ==
600 LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER) {
601 result_status = lttng_error_query_result_counter_get_value(
602 result, &result_value);
603 assert(result_status ==
604 LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
605 if (result_value == 0) {
606 continue;
607 }
608
609 MSG("");
610 _MSG(" %s: %" PRIu64, result_name,
611 result_value);
612 printed_errors_count++;
613 } else {
614 _MSG(" Unknown error query result type for result '%s' (%s)",
615 result_name, result_description);
616 continue;
617 }
618 }
619
620 if (printed_errors_count == 0) {
621 _MSG(" none");
622 }
623
624end:
625 MSG("");
626 lttng_error_query_destroy(query);
627 lttng_error_query_results_destroy(results);
628}
629
630static
631void print_one_action(const struct lttng_trigger *trigger,
632 const struct lttng_action *action)
633{
634 enum lttng_action_type action_type;
635 enum lttng_action_status action_status;
636 const struct lttng_rate_policy *policy = NULL;
637 const char *value;
638
639 action_type = lttng_action_get_type(action);
640 assert(action_type != LTTNG_ACTION_TYPE_LIST);
641
642 switch (action_type) {
643 case LTTNG_ACTION_TYPE_NOTIFY:
644 _MSG("notify");
645
646 action_status = lttng_action_notify_get_rate_policy(
647 action, &policy);
648 if (action_status != LTTNG_ACTION_STATUS_OK) {
649 ERR("Failed to retrieve rate policy.");
650 goto end;
651 }
652 break;
653 case LTTNG_ACTION_TYPE_START_SESSION:
654 action_status = lttng_action_start_session_get_session_name(
655 action, &value);
656 assert(action_status == LTTNG_ACTION_STATUS_OK);
657 _MSG("start session `%s`", value);
658
659 action_status = lttng_action_start_session_get_rate_policy(
660 action, &policy);
661 if (action_status != LTTNG_ACTION_STATUS_OK) {
662 ERR("Failed to retrieve rate policy.");
663 goto end;
664 }
665 break;
666 case LTTNG_ACTION_TYPE_STOP_SESSION:
667 action_status = lttng_action_stop_session_get_session_name(
668 action, &value);
669 assert(action_status == LTTNG_ACTION_STATUS_OK);
670 _MSG("stop session `%s`", value);
671
672 action_status = lttng_action_stop_session_get_rate_policy(
673 action, &policy);
674 if (action_status != LTTNG_ACTION_STATUS_OK) {
675 ERR("Failed to retrieve rate policy.");
676 goto end;
677 }
678 break;
679 case LTTNG_ACTION_TYPE_ROTATE_SESSION:
680 action_status = lttng_action_rotate_session_get_session_name(
681 action, &value);
682 assert(action_status == LTTNG_ACTION_STATUS_OK);
683 _MSG("rotate session `%s`", value);
684
685 action_status = lttng_action_rotate_session_get_rate_policy(
686 action, &policy);
687 if (action_status != LTTNG_ACTION_STATUS_OK) {
688 ERR("Failed to retrieve rate policy.");
689 goto end;
690 }
691 break;
692 case LTTNG_ACTION_TYPE_SNAPSHOT_SESSION:
693 {
694 const struct lttng_snapshot_output *output;
695
696 action_status = lttng_action_snapshot_session_get_session_name(
697 action, &value);
698 assert(action_status == LTTNG_ACTION_STATUS_OK);
699 _MSG("snapshot session `%s`", value);
700
701 action_status = lttng_action_snapshot_session_get_output(
702 action, &output);
703 if (action_status == LTTNG_ACTION_STATUS_OK) {
704 const char *name;
705 uint64_t max_size;
706 const char *ctrl_url, *data_url;
707 bool starts_with_file, starts_with_net, starts_with_net6;
708
709 ctrl_url = lttng_snapshot_output_get_ctrl_url(output);
710 assert(ctrl_url && strlen(ctrl_url) > 0);
711
712 data_url = lttng_snapshot_output_get_data_url(output);
713 assert(data_url);
714
715 starts_with_file = strncmp(ctrl_url, "file://", strlen("file://")) == 0;
716 starts_with_net = strncmp(ctrl_url, "net://", strlen("net://")) == 0;
717 starts_with_net6 = strncmp(ctrl_url, "net6://", strlen("net6://")) == 0;
718
719 if (ctrl_url[0] == '/' || starts_with_file) {
720 if (starts_with_file) {
721 ctrl_url += strlen("file://");
722 }
723
724 _MSG(", path: %s", ctrl_url);
725 } else if (starts_with_net || starts_with_net6) {
726 _MSG(", url: %s", ctrl_url);
727 } else {
728 assert(strlen(data_url) > 0);
729
730 _MSG(", control url: %s, data url: %s", ctrl_url, data_url);
731 }
732
733 name = lttng_snapshot_output_get_name(output);
734 assert(name);
735 if (strlen(name) > 0) {
736 _MSG(", name: %s", name);
737 }
738
739 max_size = lttng_snapshot_output_get_maxsize(output);
740 if (max_size != -1ULL) {
741 _MSG(", max size: %" PRIu64, max_size);
742 }
743 }
744
745 action_status = lttng_action_snapshot_session_get_rate_policy(
746 action, &policy);
747 if (action_status != LTTNG_ACTION_STATUS_OK) {
748 ERR("Failed to retrieve rate policy.");
749 goto end;
750 }
751 break;
752 }
753 default:
754 abort();
755 }
756
757 if (policy) {
758 enum lttng_rate_policy_type policy_type;
759 enum lttng_rate_policy_status policy_status;
760 uint64_t policy_value = 0;
761
762 policy_type = lttng_rate_policy_get_type(policy);
763
764 switch (policy_type) {
765 case LTTNG_RATE_POLICY_TYPE_EVERY_N:
766 policy_status = lttng_rate_policy_every_n_get_interval(
767 policy, &policy_value);
768 if (policy_status != LTTNG_RATE_POLICY_STATUS_OK) {
769 ERR("Failed to get action rate policy interval");
770 goto end;
771 }
772 if (policy_value > 1) {
773 /* The default is 1 so print only when it is a
774 * special case.
775 */
776 _MSG(", rate policy: after every %" PRIu64
777 " occurrences",
778 policy_value);
779 }
780 break;
781 case LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N:
782 policy_status = lttng_rate_policy_once_after_n_get_threshold(
783 policy, &policy_value);
784 if (policy_status != LTTNG_RATE_POLICY_STATUS_OK) {
785 ERR("Failed to get action rate policy interval");
786 goto end;
787 }
788 _MSG(", rate policy: once after %" PRIu64
789 " occurrences",
790 policy_value);
791 break;
792 default:
793 abort();
794 }
795 }
796
797 MSG("");
798 print_action_errors(trigger, action);
799
800end:
801 return;
802}
803
804static
805void print_trigger_errors(const struct lttng_trigger *trigger)
806{
807 unsigned int i, count, printed_errors_count = 0;
808 enum lttng_error_code error_query_ret;
809 enum lttng_error_query_results_status results_status;
810 struct lttng_error_query_results *results = NULL;
811 enum lttng_trigger_status trigger_status;
812 const char *trigger_name;
813 uid_t trigger_uid;
814 struct lttng_error_query *query =
815 lttng_error_query_trigger_create(trigger);
816
817 assert(query);
818 /*
819 * Anonymous triggers are not listed; this would be an internal error.
820 */
821 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
822 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
823
824 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
825 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
826
827 error_query_ret = lttng_error_query_execute(
828 query, lttng_session_daemon_command_endpoint, &results);
829 if (error_query_ret != LTTNG_OK) {
830 ERR("Failed to query errors of trigger '%s' (owner uid: %d): %s",
831 trigger_name, (int) trigger_uid,
832 lttng_strerror(-error_query_ret));
833 goto end;
834 }
835
836 results_status = lttng_error_query_results_get_count(results, &count);
837 assert(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
838
839 _MSG(" errors:");
840
841 for (i = 0; i < count; i++) {
842 const struct lttng_error_query_result *result;
843 enum lttng_error_query_result_status result_status;
844 const char *result_name;
845 const char *result_description;
846 uint64_t result_value;
847
848 results_status = lttng_error_query_results_get_result(
849 results, &result, i);
850 assert(results_status == LTTNG_ERROR_QUERY_RESULTS_STATUS_OK);
851
852 result_status = lttng_error_query_result_get_name(
853 result, &result_name);
854 assert(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
855 result_status = lttng_error_query_result_get_description(
856 result, &result_description);
857 assert(result_status == LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
858
859 if (lttng_error_query_result_get_type(result) ==
860 LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER) {
861 result_status = lttng_error_query_result_counter_get_value(
862 result, &result_value);
863 assert(result_status ==
864 LTTNG_ERROR_QUERY_RESULT_STATUS_OK);
865 if (result_value == 0) {
866 continue;
867 }
868
869 MSG("");
870 _MSG(" %s: %" PRIu64, result_name,
871 result_value);
872 printed_errors_count++;
873 } else {
874 _MSG(" Unknown error query result type for result '%s' (%s)",
875 result_name, result_description);
876 continue;
877 }
878 }
879
880 if (printed_errors_count == 0) {
881 _MSG(" none");
882 }
883
884end:
885 MSG("");
886 lttng_error_query_destroy(query);
887 lttng_error_query_results_destroy(results);
888}
889
890static
891void print_one_trigger(const struct lttng_trigger *trigger)
892{
893 const struct lttng_condition *condition;
894 enum lttng_condition_type condition_type;
895 const struct lttng_action *action;
896 enum lttng_action_type action_type;
897 enum lttng_trigger_status trigger_status;
898 const char *name;
899 uid_t trigger_uid;
900
901 /*
902 * Anonymous triggers are not listed since they can't be specified nor
903 * referenced through the CLI.
904 */
905 trigger_status = lttng_trigger_get_name(trigger, &name);
906 if (trigger_status == LTTNG_TRIGGER_STATUS_UNSET) {
907 goto end;
908 }
909
910 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
911
912 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
913 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
914
915 MSG("- name: %s", name);
916 MSG(" owner uid: %d", trigger_uid);
917
918 condition = lttng_trigger_get_const_condition(trigger);
919 condition_type = lttng_condition_get_type(condition);
920 MSG(" condition: %s", lttng_condition_type_str(condition_type));
921 switch (condition_type) {
922 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE:
923 print_condition_session_consumed_size(condition);
924 break;
925 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH:
926 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
927 print_condition_buffer_usage(condition);
928 break;
929 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING:
930 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED:
931 print_condition_session_rotation(condition);
932 break;
933 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES:
934 print_condition_event_rule_matches(condition);
935 break;
936 default:
937 abort();
938 }
939
940 action = lttng_trigger_get_const_action(trigger);
941 action_type = lttng_action_get_type(action);
942 if (action_type == LTTNG_ACTION_TYPE_LIST) {
943 unsigned int count, i;
944 enum lttng_action_status action_status;
945
946 MSG(" actions:");
947
948 action_status = lttng_action_list_get_count(action, &count);
949 assert(action_status == LTTNG_ACTION_STATUS_OK);
950
951 for (i = 0; i < count; i++) {
952 const struct lttng_action *subaction =
953 lttng_action_list_get_at_index(
954 action, i);
955
956 _MSG(" ");
957 print_one_action(trigger, subaction);
958 }
959 } else {
960 _MSG(" action:");
961 print_one_action(trigger, action);
962 }
963
964 print_trigger_errors(trigger);
965end:
966 return;
967}
968
969static
970int compare_triggers_by_name(const void *a, const void *b)
971{
972 const struct lttng_trigger *trigger_a = *((const struct lttng_trigger **) a);
973 const struct lttng_trigger *trigger_b = *((const struct lttng_trigger **) b);
974 const char *name_a, *name_b;
975 enum lttng_trigger_status trigger_status;
976
977 /* Anonymous triggers are not reachable here. */
978 trigger_status = lttng_trigger_get_name(trigger_a, &name_a);
979 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
980
981 trigger_status = lttng_trigger_get_name(trigger_b, &name_b);
982 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
983
984 return strcmp(name_a, name_b);
985}
986
987int cmd_list_triggers(int argc, const char **argv)
988{
989 int ret;
990 struct argpar_parse_ret argpar_parse_ret = {};
991 struct lttng_triggers *triggers = NULL;
992 int i;
993 struct lttng_dynamic_pointer_array sorted_triggers;
994 enum lttng_trigger_status trigger_status;
995 unsigned int num_triggers;
996
997 lttng_dynamic_pointer_array_init(&sorted_triggers, NULL);
998
999 argpar_parse_ret = argpar_parse(
1000 argc - 1, argv + 1, list_trigger_options, true);
1001 if (!argpar_parse_ret.items) {
1002 ERR("%s", argpar_parse_ret.error);
1003 goto error;
1004 }
1005
1006 for (i = 0; i < argpar_parse_ret.items->n_items; i++) {
1007 const struct argpar_item *item =
1008 argpar_parse_ret.items->items[i];
1009
1010 if (item->type == ARGPAR_ITEM_TYPE_OPT) {
1011 const struct argpar_item_opt *item_opt =
1012 (const struct argpar_item_opt *) item;
1013
1014 switch (item_opt->descr->id) {
1015 case OPT_HELP:
1016 SHOW_HELP();
1017 ret = 0;
1018 goto end;
1019
1020 case OPT_LIST_OPTIONS:
1021 list_cmd_options_argpar(stdout,
1022 list_trigger_options);
1023 ret = 0;
1024 goto end;
1025
1026 default:
1027 abort();
1028 }
1029
1030 } else {
1031 const struct argpar_item_non_opt *item_non_opt =
1032 (const struct argpar_item_non_opt *) item;
1033
1034 ERR("Unexpected argument: %s", item_non_opt->arg);
1035 }
1036 }
1037
1038 ret = lttng_list_triggers(&triggers);
1039 if (ret != LTTNG_OK) {
1040 ERR("Error listing triggers: %s.", lttng_strerror(-ret));
1041 goto error;
1042 }
1043
1044 trigger_status = lttng_triggers_get_count(triggers, &num_triggers);
1045 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
1046 ERR("Failed to get trigger count.");
1047 goto error;
1048 }
1049
1050 for (i = 0; i < num_triggers; i++) {
1051 int add_ret;
1052 const char *unused_name;
1053 const struct lttng_trigger *trigger =
1054 lttng_triggers_get_at_index(triggers, i);
1055
1056 trigger_status = lttng_trigger_get_name(trigger, &unused_name);
1057 switch (trigger_status) {
1058 case LTTNG_TRIGGER_STATUS_OK:
1059 break;
1060 case LTTNG_TRIGGER_STATUS_UNSET:
1061 /* Don't list anonymous triggers. */
1062 continue;
1063 default:
1064 abort();
1065 }
1066
1067 add_ret = lttng_dynamic_pointer_array_add_pointer(
1068 &sorted_triggers, (void *) trigger);
1069
1070 if (add_ret) {
1071 ERR("Failed to allocate array of struct lttng_trigger *.");
1072 goto error;
1073 }
1074 }
1075
1076 qsort(sorted_triggers.array.buffer.data, num_triggers,
1077 sizeof(struct lttng_trigger *),
1078 compare_triggers_by_name);
1079
1080 for (i = 0; i < num_triggers; i++) {
1081 const struct lttng_trigger *trigger_to_print =
1082 (const struct lttng_trigger *)
1083 lttng_dynamic_pointer_array_get_pointer(
1084 &sorted_triggers, i);
1085
1086 print_one_trigger(trigger_to_print);
1087 }
1088
1089 ret = 0;
1090 goto end;
1091
1092error:
1093 ret = 1;
1094
1095end:
1096 argpar_parse_ret_fini(&argpar_parse_ret);
1097 lttng_triggers_destroy(triggers);
1098 lttng_dynamic_pointer_array_reset(&sorted_triggers);
1099
1100 return ret;
1101}
This page took 0.044428 seconds and 4 git commands to generate.