event-rule: userspace probe: rename get/set_name to get/set_event_name
[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/* For lttng_domain_type_str(). */
18#include "lttng/domain-internal.h"
19
20#ifdef LTTNG_EMBED_HELP
21static const char help_msg[] =
22#include <lttng-list-triggers.1.h>
23;
24#endif
25
26enum {
27 OPT_HELP,
28 OPT_LIST_OPTIONS,
29};
30
31static const
32struct argpar_opt_descr list_trigger_options[] = {
33 { OPT_HELP, 'h', "help", false },
34 { OPT_LIST_OPTIONS, '\0', "list-options", false },
35 ARGPAR_OPT_DESCR_SENTINEL,
36};
37
38static
39void print_event_rule_tracepoint(const struct lttng_event_rule *event_rule)
40{
41 enum lttng_event_rule_status event_rule_status;
42 enum lttng_domain_type domain_type;
43 const char *pattern;
44 const char *filter;
45 int log_level;
46 unsigned int exclusions_count;
47 int i;
48
49 event_rule_status = lttng_event_rule_tracepoint_get_pattern(
50 event_rule, &pattern);
51 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
52
53 event_rule_status = lttng_event_rule_tracepoint_get_domain_type(
54 event_rule, &domain_type);
55 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
56
57 _MSG(" rule: %s (type: tracepoint, domain: %s", pattern,
58 lttng_domain_type_str(domain_type));
59
60 event_rule_status = lttng_event_rule_tracepoint_get_filter(
61 event_rule, &filter);
62 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
63 _MSG(", filter: %s", filter);
64 } else {
65 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
66 }
67
68 event_rule_status = lttng_event_rule_tracepoint_get_log_level(
69 event_rule, &log_level);
70 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
71 enum lttng_loglevel_type log_level_type;
72 const char *log_level_op;
73
74 event_rule_status = lttng_event_rule_tracepoint_get_log_level_type(
75 event_rule, &log_level_type);
76 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
77 assert(log_level_type == LTTNG_EVENT_LOGLEVEL_RANGE ||
78 log_level_type == LTTNG_EVENT_LOGLEVEL_SINGLE);
79
80 log_level_op = (log_level_type == LTTNG_EVENT_LOGLEVEL_RANGE ? "<=" : "==");
81
82 _MSG(", log level %s %s", log_level_op,
83 mi_lttng_loglevel_string(
84 log_level, domain_type));
85 } else {
86 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
87 }
88
89 event_rule_status = lttng_event_rule_tracepoint_get_exclusions_count(
90 event_rule, &exclusions_count);
91 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
92 if (exclusions_count > 0) {
93 _MSG(", exclusions: ");
94 for (i = 0; i < exclusions_count; i++) {
95 const char *exclusion;
96
97 event_rule_status = lttng_event_rule_tracepoint_get_exclusion_at_index(
98 event_rule, i, &exclusion);
99 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
100
101 _MSG("%s%s", i > 0 ? "," : "", exclusion);
102 }
103 }
104
105 MSG(")");
106}
107
108static void print_kernel_probe_location(
109 const struct lttng_kernel_probe_location *location)
110{
111 enum lttng_kernel_probe_location_status status;
112 switch (lttng_kernel_probe_location_get_type(location)) {
113 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS:
114 {
115 uint64_t address;
116
117 status = lttng_kernel_probe_location_address_get_address(
118 location, &address);
119 if (status != LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK) {
120 ERR("Getting kernel probe location address failed.");
121 goto end;
122 }
123
124 _MSG("0x%" PRIx64, address);
125
126 break;
127 }
128 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET:
129 {
130 uint64_t offset;
131 const char *symbol_name;
132
133 symbol_name = lttng_kernel_probe_location_symbol_get_name(
134 location);
135 if (!symbol_name) {
136 ERR("Getting kernel probe location symbol name failed.");
137 goto end;
138 }
139
140 status = lttng_kernel_probe_location_symbol_get_offset(
141 location, &offset);
142 if (status != LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK) {
143 ERR("Getting kernel probe location address failed.");
144 goto end;
145 }
146
147 if (offset == 0) {
148 _MSG("%s", symbol_name);
149 } else {
150 _MSG("%s+0x%" PRIx64, symbol_name, offset);
151 }
152
153 break;
154 }
155 default:
156 abort();
157 };
158end:
159 return;
160}
161
162static
163void print_event_rule_kernel_probe(const struct lttng_event_rule *event_rule)
164{
165 enum lttng_event_rule_status event_rule_status;
166 const char *name;
167 const struct lttng_kernel_probe_location *location;
168
169 assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE);
170
171 event_rule_status = lttng_event_rule_kernel_probe_get_event_name(event_rule, &name);
172 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
173 ERR("Failed to get kprobe event rule's name.");
174 goto end;
175 }
176
177 event_rule_status = lttng_event_rule_kernel_probe_get_location(
178 event_rule, &location);
179 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
180 ERR("Failed to get kprobe event rule's location.");
181 goto end;
182 }
183
184 _MSG(" rule: %s (type: probe, location: ", name);
185
186 print_kernel_probe_location(location);
187
188 MSG(")");
189
190end:
191 return;
192}
193
194static
195void print_event_rule_userspace_probe(const struct lttng_event_rule *event_rule)
196{
197 enum lttng_event_rule_status event_rule_status;
198 const char *name;
199 const struct lttng_userspace_probe_location *location;
200 enum lttng_userspace_probe_location_type userspace_probe_location_type;
201
202 assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_USERSPACE_PROBE);
203
204 event_rule_status = lttng_event_rule_userspace_probe_get_event_name(
205 event_rule, &name);
206 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
207 ERR("Failed to get uprobe event rule's name.");
208 goto end;
209 }
210
211 event_rule_status = lttng_event_rule_userspace_probe_get_location(
212 event_rule, &location);
213 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
214 ERR("Failed to get uprobe event rule's location.");
215 goto end;
216 }
217
218 _MSG(" rule: %s (type: userspace probe, location: ", name);
219
220 userspace_probe_location_type =
221 lttng_userspace_probe_location_get_type(location);
222
223 switch (userspace_probe_location_type) {
224 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION:
225 {
226 const char *binary_path, *function_name;
227
228 binary_path = lttng_userspace_probe_location_function_get_binary_path(
229 location);
230 function_name = lttng_userspace_probe_location_function_get_function_name(
231 location);
232
233 _MSG("%s:%s", binary_path, function_name);
234 break;
235 }
236 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT:
237 _MSG("SDT not implemented yet");
238 break;
239 default:
240 abort();
241 }
242
243 MSG(")");
244
245end:
246 return;
247}
248
249static
250void print_event_rule_syscall(const struct lttng_event_rule *event_rule)
251{
252 const char *pattern, *filter;
253 enum lttng_event_rule_status event_rule_status;
254
255 assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_SYSCALL);
256
257 event_rule_status = lttng_event_rule_syscall_get_pattern(
258 event_rule, &pattern);
259 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
260
261 _MSG(" rule: %s (type: syscall", pattern);
262
263 event_rule_status = lttng_event_rule_syscall_get_filter(
264 event_rule, &filter);
265 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
266 _MSG(", filter: %s", filter);
267 } else {
268 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
269 }
270
271 MSG(")");
272}
273
274static
275void print_event_rule(const struct lttng_event_rule *event_rule)
276{
277 const enum lttng_event_rule_type event_rule_type =
278 lttng_event_rule_get_type(event_rule);
279
280 switch (event_rule_type) {
281 case LTTNG_EVENT_RULE_TYPE_TRACEPOINT:
282 print_event_rule_tracepoint(event_rule);
283 break;
284 case LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE:
285 print_event_rule_kernel_probe(event_rule);
286 break;
287 case LTTNG_EVENT_RULE_TYPE_USERSPACE_PROBE:
288 print_event_rule_userspace_probe(event_rule);
289 break;
290 case LTTNG_EVENT_RULE_TYPE_SYSCALL:
291 print_event_rule_syscall(event_rule);
292 break;
293 default:
294 abort();
295 }
296}
297
298static
299void print_one_event_expr(const struct lttng_event_expr *event_expr)
300{
301 enum lttng_event_expr_type type;
302
303 type = lttng_event_expr_get_type(event_expr);
304
305 switch (type) {
306 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
307 {
308 const char *name;
309
310 name = lttng_event_expr_event_payload_field_get_name(
311 event_expr);
312 _MSG("%s", name);
313
314 break;
315 }
316 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
317 {
318 const char *name;
319
320 name = lttng_event_expr_channel_context_field_get_name(
321 event_expr);
322 _MSG("$ctx.%s", name);
323
324 break;
325 }
326 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
327 {
328 const char *provider_name;
329 const char *type_name;
330
331 provider_name = lttng_event_expr_app_specific_context_field_get_provider_name(
332 event_expr);
333 type_name = lttng_event_expr_app_specific_context_field_get_type_name(
334 event_expr);
335
336 _MSG("$app.%s:%s", provider_name, type_name);
337
338 break;
339 }
340 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
341 {
342 unsigned int index;
343 const struct lttng_event_expr *parent_expr;
344 enum lttng_event_expr_status status;
345
346 parent_expr = lttng_event_expr_array_field_element_get_parent_expr(
347 event_expr);
348 assert(parent_expr != NULL);
349
350 print_one_event_expr(parent_expr);
351
352 status = lttng_event_expr_array_field_element_get_index(
353 event_expr, &index);
354 assert(status == LTTNG_EVENT_EXPR_STATUS_OK);
355
356 _MSG("[%u]", index);
357
358 break;
359 }
360 default:
361 abort();
362 }
363}
364
365static
366void print_condition_on_event(const struct lttng_condition *condition)
367{
368 const struct lttng_event_rule *event_rule;
369 enum lttng_condition_status condition_status;
370 unsigned int cap_desc_count, i;
371
372 condition_status =
373 lttng_condition_on_event_get_rule(condition, &event_rule);
374 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
375
376 print_event_rule(event_rule);
377
378 condition_status =
379 lttng_condition_on_event_get_capture_descriptor_count(
380 condition, &cap_desc_count);
381 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
382
383 if (cap_desc_count > 0) {
384 MSG(" captures:");
385
386 for (i = 0; i < cap_desc_count; i++) {
387 const struct lttng_event_expr *cap_desc =
388 lttng_condition_on_event_get_capture_descriptor_at_index(
389 condition, i);
390
391 _MSG(" - ");
392 print_one_event_expr(cap_desc);
393 MSG("");
394 }
395 }
396}
397
398static
399void print_one_action(const struct lttng_action *action)
400{
401 enum lttng_action_type action_type;
402 enum lttng_action_status action_status;
403 const char *value;
404
405 action_type = lttng_action_get_type(action);
406 assert(action_type != LTTNG_ACTION_TYPE_GROUP);
407
408 switch (action_type) {
409 case LTTNG_ACTION_TYPE_NOTIFY:
410 MSG("notify");
411 break;
412 case LTTNG_ACTION_TYPE_START_SESSION:
413 action_status = lttng_action_start_session_get_session_name(
414 action, &value);
415 assert(action_status == LTTNG_ACTION_STATUS_OK);
416 MSG("start session `%s`", value);
417 break;
418 case LTTNG_ACTION_TYPE_STOP_SESSION:
419 action_status = lttng_action_stop_session_get_session_name(
420 action, &value);
421 assert(action_status == LTTNG_ACTION_STATUS_OK);
422 MSG("stop session `%s`", value);
423 break;
424 case LTTNG_ACTION_TYPE_ROTATE_SESSION:
425 action_status = lttng_action_rotate_session_get_session_name(
426 action, &value);
427 assert(action_status == LTTNG_ACTION_STATUS_OK);
428 MSG("rotate session `%s`", value);
429 break;
430 case LTTNG_ACTION_TYPE_SNAPSHOT_SESSION:
431 {
432 const struct lttng_snapshot_output *output;
433
434 action_status = lttng_action_snapshot_session_get_session_name(
435 action, &value);
436 assert(action_status == LTTNG_ACTION_STATUS_OK);
437 _MSG("snapshot session `%s`", value);
438
439 action_status = lttng_action_snapshot_session_get_output(
440 action, &output);
441 if (action_status == LTTNG_ACTION_STATUS_OK) {
442 const char *name;
443 uint64_t max_size;
444 const char *ctrl_url, *data_url;
445 bool starts_with_file, starts_with_net, starts_with_net6;
446
447 ctrl_url = lttng_snapshot_output_get_ctrl_url(output);
448 assert(ctrl_url && strlen(ctrl_url) > 0);
449
450 data_url = lttng_snapshot_output_get_data_url(output);
451 assert(data_url);
452
453 starts_with_file = strncmp(ctrl_url, "file://", strlen("file://")) == 0;
454 starts_with_net = strncmp(ctrl_url, "net://", strlen("net://")) == 0;
455 starts_with_net6 = strncmp(ctrl_url, "net6://", strlen("net6://")) == 0;
456
457 if (ctrl_url[0] == '/' || starts_with_file) {
458 if (starts_with_file) {
459 ctrl_url += strlen("file://");
460 }
461
462 _MSG(", path: %s", ctrl_url);
463 } else if (starts_with_net || starts_with_net6) {
464 _MSG(", url: %s", ctrl_url);
465 } else {
466 assert(strlen(data_url) > 0);
467
468 _MSG(", control url: %s, data url: %s", ctrl_url, data_url);
469 }
470
471 name = lttng_snapshot_output_get_name(output);
472 assert(name);
473 if (strlen(name) > 0) {
474 _MSG(", name: %s", name);
475 }
476
477 max_size = lttng_snapshot_output_get_maxsize(output);
478 if (max_size != -1ULL) {
479 _MSG(", max size: %" PRIu64, max_size);
480 }
481 }
482
483 MSG("");
484 break;
485 }
486
487 default:
488 abort();
489 }
490}
491
492static
493void print_one_trigger(const struct lttng_trigger *trigger)
494{
495 const struct lttng_condition *condition;
496 enum lttng_condition_type condition_type;
497 const struct lttng_action *action;
498 enum lttng_action_type action_type;
499 enum lttng_trigger_status trigger_status;
500 const char *name;
501 enum lttng_trigger_firing_policy firing_policy_type;
502 uint64_t threshold;
503 uid_t trigger_uid;
504
505 trigger_status = lttng_trigger_get_name(trigger, &name);
506 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
507
508 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
509 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
510
511 MSG("- id: %s", name);
512 MSG(" user id: %d", trigger_uid);
513
514 trigger_status = lttng_trigger_get_firing_policy(
515 trigger, &firing_policy_type, &threshold);
516 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
517 ERR("Failed to get trigger's policy.");
518 goto end;
519 }
520
521 switch (firing_policy_type) {
522 case LTTNG_TRIGGER_FIRING_POLICY_EVERY_N:
523 if (threshold > 1) {
524 MSG(" firing policy: after every %" PRIu64 " occurences", threshold);
525 }
526 break;
527 case LTTNG_TRIGGER_FIRING_POLICY_ONCE_AFTER_N:
528 MSG(" firing policy: once after %" PRIu64 " occurences", threshold);
529 break;
530 default:
531 abort();
532 }
533
534 condition = lttng_trigger_get_const_condition(trigger);
535 condition_type = lttng_condition_get_type(condition);
536 MSG(" condition: %s", lttng_condition_type_str(condition_type));
537 switch (condition_type) {
538 case LTTNG_CONDITION_TYPE_ON_EVENT:
539 print_condition_on_event(condition);
540 break;
541 default:
542 MSG(" (condition type not handled in %s)", __func__);
543 break;
544 }
545
546 action = lttng_trigger_get_const_action(trigger);
547 action_type = lttng_action_get_type(action);
548 if (action_type == LTTNG_ACTION_TYPE_GROUP) {
549 unsigned int count, i;
550 enum lttng_action_status action_status;
551
552 MSG(" actions:");
553
554 action_status = lttng_action_group_get_count(action, &count);
555 assert(action_status == LTTNG_ACTION_STATUS_OK);
556
557 for (i = 0; i < count; i++) {
558 const struct lttng_action *subaction =
559 lttng_action_group_get_at_index(
560 action, i);
561
562 _MSG(" ");
563 print_one_action(subaction);
564 }
565 } else {
566 _MSG(" action:");
567 print_one_action(action);
568 }
569
570end:
571 return;
572}
573
574static
575int compare_triggers_by_name(const void *a, const void *b)
576{
577 const struct lttng_trigger *trigger_a = *((const struct lttng_trigger **) a);
578 const struct lttng_trigger *trigger_b = *((const struct lttng_trigger **) b);
579 const char *name_a, *name_b;
580 enum lttng_trigger_status trigger_status;
581
582 trigger_status = lttng_trigger_get_name(trigger_a, &name_a);
583 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
584
585 trigger_status = lttng_trigger_get_name(trigger_b, &name_b);
586 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
587
588 return strcmp(name_a, name_b);
589}
590
591int cmd_list_triggers(int argc, const char **argv)
592{
593 int ret;
594 struct argpar_parse_ret argpar_parse_ret = {};
595 struct lttng_triggers *triggers = NULL;
596 int i;
597 struct lttng_dynamic_pointer_array sorted_triggers;
598 enum lttng_trigger_status trigger_status;
599 unsigned int num_triggers;
600
601 lttng_dynamic_pointer_array_init(&sorted_triggers, NULL);
602
603 argpar_parse_ret = argpar_parse(
604 argc - 1, argv + 1, list_trigger_options, true);
605 if (!argpar_parse_ret.items) {
606 ERR("%s", argpar_parse_ret.error);
607 goto error;
608 }
609
610 for (i = 0; i < argpar_parse_ret.items->n_items; i++) {
611 const struct argpar_item *item =
612 argpar_parse_ret.items->items[i];
613
614 if (item->type == ARGPAR_ITEM_TYPE_OPT) {
615 const struct argpar_item_opt *item_opt =
616 (const struct argpar_item_opt *) item;
617
618 switch (item_opt->descr->id) {
619 case OPT_HELP:
620 SHOW_HELP();
621 ret = 0;
622 goto end;
623
624 case OPT_LIST_OPTIONS:
625 list_cmd_options_argpar(stdout,
626 list_trigger_options);
627 ret = 0;
628 goto end;
629
630 default:
631 abort();
632 }
633
634 } else {
635 const struct argpar_item_non_opt *item_non_opt =
636 (const struct argpar_item_non_opt *) item;
637
638 ERR("Unexpected argument: %s", item_non_opt->arg);
639 }
640 }
641
642 ret = lttng_list_triggers(&triggers);
643 if (ret != LTTNG_OK) {
644 ERR("Error listing triggers: %s.", lttng_strerror(-ret));
645 goto error;
646 }
647
648 trigger_status = lttng_triggers_get_count(triggers, &num_triggers);
649 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
650 ERR("Failed to get trigger count.");
651 goto error;
652 }
653
654 for (i = 0; i < num_triggers; i++) {
655 const int add_ret = lttng_dynamic_pointer_array_add_pointer(
656 &sorted_triggers,
657 (void *) lttng_triggers_get_at_index(triggers, i));
658
659 if (add_ret) {
660 ERR("Failed to allocate array of struct lttng_trigger *.");
661 goto error;
662 }
663 }
664
665 qsort(sorted_triggers.array.buffer.data, num_triggers,
666 sizeof(struct lttng_trigger *),
667 compare_triggers_by_name);
668
669 for (i = 0; i < num_triggers; i++) {
670 const struct lttng_trigger *trigger_to_print =
671 (const struct lttng_trigger *)
672 lttng_dynamic_pointer_array_get_pointer(
673 &sorted_triggers, i);
674
675 print_one_trigger(trigger_to_print);
676 }
677
678 ret = 0;
679 goto end;
680
681error:
682 ret = 1;
683
684end:
685 argpar_parse_ret_fini(&argpar_parse_ret);
686 lttng_triggers_destroy(triggers);
687 lttng_dynamic_pointer_array_reset(&sorted_triggers);
688
689 return ret;
690}
This page took 0.024576 seconds and 4 git commands to generate.