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