docs: Add supported versions and fix-backport policy
[lttng-tools.git] / src / bin / lttng / utils.cpp
CommitLineData
f3ed775e 1/*
21cf9b6b 2 * Copyright (C) 2011 EfficiOS Inc.
f3ed775e 3 *
ab5be9fa 4 * SPDX-License-Identifier: GPL-2.0-only
f3ed775e 5 *
f3ed775e
DG
6 */
7
6c1c0768 8#define _LGPL_SOURCE
28ab034a
JG
9#include "command.hpp"
10#include "conf.hpp"
0729ea55 11#include "exception.hpp"
28ab034a 12#include "utils.hpp"
f3ed775e 13
28ab034a 14#include <common/defaults.hpp>
c9e313bc 15#include <common/error.hpp>
ca938aa5
OD
16#include <common/exception.hpp>
17#include <common/make-unique-wrapper.hpp>
c9e313bc 18#include <common/utils.hpp>
f3ed775e 19
28ab034a
JG
20#include <arpa/inet.h>
21#include <ctype.h>
ca938aa5 22#include <fnmatch.h>
28ab034a 23#include <inttypes.h>
4d4c8b8e 24#include <iostream>
28ab034a
JG
25#include <limits.h>
26#include <netinet/in.h>
27#include <signal.h>
28#include <stdlib.h>
29#include <sys/socket.h>
30#include <sys/types.h>
31#include <unistd.h>
f3ed775e 32
4fd2697f
FD
33static const char *str_all = "ALL";
34static const char *str_tracepoint = "Tracepoint";
35static const char *str_syscall = "Syscall";
36static const char *str_probe = "Probe";
37static const char *str_userspace_probe = "Userspace Probe";
38static const char *str_function = "Function";
b9dfb167 39
28ab034a 40static char *_get_session_name(int quiet)
f3ed775e 41{
4f00620d 42 const char *path;
cd9adb8b 43 char *session_name = nullptr;
f3ed775e
DG
44
45 /* Get path to config file */
feb0f3e5 46 path = utils_get_home_dir();
cd9adb8b 47 if (path == nullptr) {
f3ed775e
DG
48 goto error;
49 }
50
51 /* Get session name from config */
1dac0189 52 session_name = quiet ? config_read_session_name_quiet(path) :
28ab034a 53 config_read_session_name(path);
cd9adb8b 54 if (session_name == nullptr) {
58a97671 55 goto error;
f3ed775e
DG
56 }
57
3183dbb0 58 DBG2("Config file path found: %s", path);
cd80958d 59 DBG("Session name found: %s", session_name);
f3ed775e 60 return session_name;
3183dbb0
DG
61
62error:
cd9adb8b 63 return nullptr;
f3ed775e 64}
679b4943 65
1dac0189
PPM
66/*
67 * get_session_name
68 *
69 * Return allocated string with the session name found in the config
70 * directory.
71 */
cd9adb8b 72char *get_session_name()
1dac0189
PPM
73{
74 return _get_session_name(0);
75}
76
77/*
78 * get_session_name_quiet (no warnings/errors emitted)
79 *
80 * Return allocated string with the session name found in the config
81 * directory.
82 */
cd9adb8b 83char *get_session_name_quiet()
1dac0189
PPM
84{
85 return _get_session_name(1);
86}
87
3c9bd23c
SM
88/*
89 * list_commands
90 *
91 * List commands line by line. This is mostly for bash auto completion and to
92 * avoid difficult parsing.
93 */
94void list_commands(struct cmd_struct *commands, FILE *ofp)
95{
96 int i = 0;
cd9adb8b 97 struct cmd_struct *cmd = nullptr;
3c9bd23c
SM
98
99 cmd = &commands[i];
cd9adb8b 100 while (cmd->name != nullptr) {
3c9bd23c
SM
101 fprintf(ofp, "%s\n", cmd->name);
102 i++;
103 cmd = &commands[i];
104 }
105}
679b4943
SM
106
107/*
108 * list_cmd_options
109 *
110 * Prints a simple list of the options available to a command. This is intended
111 * to be easily parsed for bash completion.
112 */
113void list_cmd_options(FILE *ofp, struct poptOption *options)
114{
115 int i;
cd9adb8b 116 struct poptOption *option = nullptr;
679b4943 117
cd9adb8b 118 for (i = 0; options[i].longName != nullptr; i++) {
679b4943
SM
119 option = &options[i];
120
121 fprintf(ofp, "--%s\n", option->longName);
122
123 if (isprint(option->shortName)) {
124 fprintf(ofp, "-%c\n", option->shortName);
125 }
126 }
127}
8ce58bad 128
b083f028
JR
129/*
130 * Same as list_cmd_options, but for options specified for argpar.
131 */
132void list_cmd_options_argpar(FILE *ofp, const struct argpar_opt_descr *options)
133{
134 int i;
135
cd9adb8b 136 for (i = 0; options[i].long_name != nullptr; i++) {
b083f028
JR
137 const struct argpar_opt_descr *option = &options[i];
138
139 fprintf(ofp, "--%s\n", option->long_name);
140
141 if (isprint(option->short_name)) {
142 fprintf(ofp, "-%c\n", option->short_name);
143 }
144 }
145}
146
8ce58bad
MD
147/*
148 * fls: returns the position of the most significant bit.
149 * Returns 0 if no bit is set, else returns the position of the most
150 * significant bit (from 1 to 32 on 32-bit, from 1 to 64 on 64-bit).
151 */
152#if defined(__i386) || defined(__x86_64)
28ab034a 153static inline unsigned int fls_u32(uint32_t x)
8ce58bad
MD
154{
155 int r;
156
157 asm("bsrl %1,%0\n\t"
158 "jnz 1f\n\t"
159 "movl $-1,%0\n\t"
160 "1:\n\t"
28ab034a
JG
161 : "=r"(r)
162 : "rm"(x));
8ce58bad
MD
163 return r + 1;
164}
165#define HAS_FLS_U32
166#endif
167
a1e4ab8b 168#if defined(__x86_64) && defined(__LP64__)
28ab034a 169static inline unsigned int fls_u64(uint64_t x)
8ce58bad
MD
170{
171 long r;
172
173 asm("bsrq %1,%0\n\t"
174 "jnz 1f\n\t"
175 "movq $-1,%0\n\t"
176 "1:\n\t"
28ab034a
JG
177 : "=r"(r)
178 : "rm"(x));
8ce58bad
MD
179 return r + 1;
180}
181#define HAS_FLS_U64
182#endif
183
184#ifndef HAS_FLS_U64
28ab034a 185static __attribute__((unused)) unsigned int fls_u64(uint64_t x)
8ce58bad
MD
186{
187 unsigned int r = 64;
188
189 if (!x)
190 return 0;
191
192 if (!(x & 0xFFFFFFFF00000000ULL)) {
193 x <<= 32;
194 r -= 32;
195 }
196 if (!(x & 0xFFFF000000000000ULL)) {
197 x <<= 16;
198 r -= 16;
199 }
200 if (!(x & 0xFF00000000000000ULL)) {
201 x <<= 8;
202 r -= 8;
203 }
204 if (!(x & 0xF000000000000000ULL)) {
205 x <<= 4;
206 r -= 4;
207 }
208 if (!(x & 0xC000000000000000ULL)) {
209 x <<= 2;
210 r -= 2;
211 }
212 if (!(x & 0x8000000000000000ULL)) {
213 x <<= 1;
214 r -= 1;
215 }
216 return r;
217}
218#endif
219
220#ifndef HAS_FLS_U32
28ab034a 221static __attribute__((unused)) unsigned int fls_u32(uint32_t x)
8ce58bad
MD
222{
223 unsigned int r = 32;
224
225 if (!x)
226 return 0;
227 if (!(x & 0xFFFF0000U)) {
228 x <<= 16;
229 r -= 16;
230 }
231 if (!(x & 0xFF000000U)) {
232 x <<= 8;
233 r -= 8;
234 }
235 if (!(x & 0xF0000000U)) {
236 x <<= 4;
237 r -= 4;
238 }
239 if (!(x & 0xC0000000U)) {
240 x <<= 2;
241 r -= 2;
242 }
243 if (!(x & 0x80000000U)) {
244 x <<= 1;
245 r -= 1;
246 }
247 return r;
248}
249#endif
250
28ab034a 251static unsigned int fls_ulong(unsigned long x)
8ce58bad
MD
252{
253#if (CAA_BITS_PER_LONG == 32)
254 return fls_u32(x);
255#else
256 return fls_u64(x);
257#endif
258}
259
260/*
261 * Return the minimum order for which x <= (1UL << order).
262 * Return -1 if x is 0.
263 */
264int get_count_order_u32(uint32_t x)
265{
266 if (!x)
267 return -1;
268
269 return fls_u32(x - 1);
270}
271
272/*
273 * Return the minimum order for which x <= (1UL << order).
274 * Return -1 if x is 0.
275 */
276int get_count_order_u64(uint64_t x)
277{
278 if (!x)
279 return -1;
280
281 return fls_u64(x - 1);
282}
283
284/*
285 * Return the minimum order for which x <= (1UL << order).
286 * Return -1 if x is 0.
287 */
288int get_count_order_ulong(unsigned long x)
289{
290 if (!x)
291 return -1;
292
293 return fls_ulong(x - 1);
294}
b9dfb167 295
4fd2697f
FD
296const char *get_event_type_str(enum lttng_event_type type)
297{
298 const char *str_event_type;
299
300 switch (type) {
301 case LTTNG_EVENT_ALL:
302 str_event_type = str_all;
303 break;
304 case LTTNG_EVENT_TRACEPOINT:
305 str_event_type = str_tracepoint;
306 break;
307 case LTTNG_EVENT_SYSCALL:
308 str_event_type = str_syscall;
309 break;
310 case LTTNG_EVENT_PROBE:
311 str_event_type = str_probe;
312 break;
313 case LTTNG_EVENT_USERSPACE_PROBE:
314 str_event_type = str_userspace_probe;
315 break;
316 case LTTNG_EVENT_FUNCTION:
317 str_event_type = str_function;
318 break;
319 default:
320 /* Should not have an unknown event type or else define it. */
a0377dfe 321 abort();
4fd2697f
FD
322 }
323
324 return str_event_type;
325}
326
8960e9cd
DG
327/*
328 * Spawn a lttng relayd daemon by forking and execv.
329 */
330int spawn_relayd(const char *pathname, int port)
331{
332 int ret = 0;
333 pid_t pid;
334 char url[255];
335
336 if (!port) {
337 port = DEFAULT_NETWORK_VIEWER_PORT;
338 }
339
340 ret = snprintf(url, sizeof(url), "tcp://localhost:%d", port);
341 if (ret < 0) {
342 goto end;
343 }
344
345 MSG("Spawning a relayd daemon");
346 pid = fork();
347 if (pid == 0) {
348 /*
349 * Spawn session daemon and tell
350 * it to signal us when ready.
351 */
352 execlp(pathname, "lttng-relayd", "-L", url, NULL);
353 /* execlp only returns if error happened */
354 if (errno == ENOENT) {
355 ERR("No relayd found. Use --relayd-path.");
356 } else {
6f04ed72 357 PERROR("execlp");
8960e9cd 358 }
28ab034a 359 kill(getppid(), SIGTERM); /* wake parent */
8960e9cd
DG
360 exit(EXIT_FAILURE);
361 } else if (pid > 0) {
362 goto end;
363 } else {
6f04ed72 364 PERROR("fork");
8960e9cd
DG
365 ret = -1;
366 goto end;
367 }
368
369end:
370 return ret;
371}
372
373/*
374 * Check if relayd is alive.
375 *
376 * Return 1 if found else 0 if NOT found. Negative value on error.
377 */
cd9adb8b 378int check_relayd()
8960e9cd
DG
379{
380 int ret, fd;
381 struct sockaddr_in sin;
382
383 fd = socket(AF_INET, SOCK_STREAM, 0);
384 if (fd < 0) {
6f04ed72 385 PERROR("socket check relayd");
dd02a4c1
DG
386 ret = -1;
387 goto error_socket;
8960e9cd
DG
388 }
389
390 sin.sin_family = AF_INET;
391 sin.sin_port = htons(DEFAULT_NETWORK_VIEWER_PORT);
392 ret = inet_pton(sin.sin_family, "127.0.0.1", &sin.sin_addr);
393 if (ret < 1) {
6f04ed72 394 PERROR("inet_pton check relayd");
dd02a4c1 395 ret = -1;
8960e9cd
DG
396 goto error;
397 }
398
399 /*
400 * A successful connect means the relayd exists thus returning 0 else a
401 * negative value means it does NOT exists.
402 */
56efeab3 403 ret = connect(fd, (struct sockaddr *) &sin, sizeof(sin));
8960e9cd
DG
404 if (ret < 0) {
405 /* Not found. */
406 ret = 0;
407 } else {
408 /* Already spawned. */
409 ret = 1;
410 }
411
8960e9cd 412error:
dd02a4c1 413 if (close(fd) < 0) {
6f04ed72 414 PERROR("close relayd fd");
dd02a4c1
DG
415 }
416error_socket:
417 return ret;
8960e9cd 418}
3ecec76a 419
28ab034a 420int print_missing_or_multiple_domains(unsigned int domain_count, bool include_agent_domains)
3ecec76a
PP
421{
422 int ret = 0;
423
3533d06b
JG
424 if (domain_count == 0) {
425 ERR("Please specify a domain (--kernel/--userspace%s).",
28ab034a 426 include_agent_domains ? "/--jul/--log4j/--python" : "");
3ecec76a 427 ret = -1;
3533d06b
JG
428 } else if (domain_count > 1) {
429 ERR("Only one domain must be specified.");
3ecec76a
PP
430 ret = -1;
431 }
432
433 return ret;
434}
20fb9e02
JD
435
436/*
437 * Get the discarded events and lost packet counts.
438 */
439void print_session_stats(const char *session_name)
440{
58f237ca
JG
441 char *str;
442 const int ret = get_session_stats_str(session_name, &str);
443
444 if (ret >= 0 && str) {
445 MSG("%s", str);
446 free(str);
447 }
448}
449
450int get_session_stats_str(const char *session_name, char **out_str)
451{
452 int count, nb_domains, domain_idx, channel_idx, session_idx, ret;
cd9adb8b
JG
453 struct lttng_domain *domains = nullptr;
454 struct lttng_channel *channels = nullptr;
3e8f2238 455 uint64_t discarded_events_total = 0, lost_packets_total = 0;
cd9adb8b
JG
456 struct lttng_session *sessions = nullptr;
457 const struct lttng_session *selected_session = nullptr;
458 char *stats_str = nullptr;
58f237ca 459 bool print_discarded_events = false, print_lost_packets = false;
3e8f2238
JG
460
461 count = lttng_list_sessions(&sessions);
462 if (count < 1) {
463 ERR("Failed to retrieve session descriptions while printing session statistics.");
58f237ca 464 ret = -1;
3e8f2238
JG
465 goto end;
466 }
467
468 /* Identify the currently-selected sessions. */
469 for (session_idx = 0; session_idx < count; session_idx++) {
470 if (!strcmp(session_name, sessions[session_idx].name)) {
471 selected_session = &sessions[session_idx];
472 break;
473 }
474 }
475 if (!selected_session) {
28ab034a
JG
476 ERR("Failed to retrieve session \"%s\" description while printing session statistics.",
477 session_name);
58f237ca 478 ret = -1;
3e8f2238
JG
479 goto end;
480 }
20fb9e02
JD
481
482 nb_domains = lttng_list_domains(session_name, &domains);
483 if (nb_domains < 0) {
58f237ca 484 ret = -1;
20fb9e02
JD
485 goto end;
486 }
487 for (domain_idx = 0; domain_idx < nb_domains; domain_idx++) {
28ab034a
JG
488 struct lttng_handle *handle =
489 lttng_create_handle(session_name, &domains[domain_idx]);
20fb9e02
JD
490
491 if (!handle) {
3e8f2238 492 ERR("Failed to create session handle while printing session statistics.");
58f237ca 493 ret = -1;
20fb9e02
JD
494 goto end;
495 }
496
092545c3 497 free(channels);
cd9adb8b 498 channels = nullptr;
20fb9e02
JD
499 count = lttng_list_channels(handle, &channels);
500 for (channel_idx = 0; channel_idx < count; channel_idx++) {
3e8f2238 501 uint64_t discarded_events = 0, lost_packets = 0;
20fb9e02
JD
502 struct lttng_channel *channel = &channels[channel_idx];
503
28ab034a 504 ret = lttng_channel_get_discarded_event_count(channel, &discarded_events);
20fb9e02
JD
505 if (ret) {
506 ERR("Failed to retrieve discarded event count from channel %s",
28ab034a 507 channel->name);
20fb9e02
JD
508 }
509
28ab034a 510 ret = lttng_channel_get_lost_packet_count(channel, &lost_packets);
20fb9e02
JD
511 if (ret) {
512 ERR("Failed to retrieve lost packet count from channel %s",
28ab034a 513 channel->name);
20fb9e02
JD
514 }
515
3e8f2238
JG
516 discarded_events_total += discarded_events;
517 lost_packets_total += lost_packets;
20fb9e02
JD
518 }
519 lttng_destroy_handle(handle);
520 }
58f237ca 521
28ab034a
JG
522 print_discarded_events = discarded_events_total > 0 && !selected_session->snapshot_mode;
523 print_lost_packets = lost_packets_total > 0 && !selected_session->snapshot_mode;
58f237ca
JG
524
525 if (print_discarded_events && print_lost_packets) {
526 ret = asprintf(&stats_str,
28ab034a
JG
527 "Warning: %" PRIu64 " events were discarded and %" PRIu64
528 " packets were lost, please refer to "
529 "the documentation on channel configuration.",
530 discarded_events_total,
531 lost_packets_total);
58f237ca
JG
532 } else if (print_discarded_events) {
533 ret = asprintf(&stats_str,
28ab034a
JG
534 "Warning: %" PRIu64 " events were discarded, please refer to "
535 "the documentation on channel configuration.",
536 discarded_events_total);
58f237ca
JG
537 } else if (print_lost_packets) {
538 ret = asprintf(&stats_str,
28ab034a
JG
539 "Warning: %" PRIu64 " packets were lost, please refer to "
540 "the documentation on channel configuration.",
541 lost_packets_total);
58f237ca
JG
542 } else {
543 ret = 0;
20fb9e02
JD
544 }
545
58f237ca
JG
546 if (ret < 0) {
547 ERR("Failed to format lost packet and discarded events statistics");
548 } else {
549 *out_str = stats_str;
550 ret = 0;
551 }
20fb9e02 552end:
3e8f2238 553 free(sessions);
092545c3
SM
554 free(channels);
555 free(domains);
58f237ca 556 return ret;
20fb9e02 557}
4ba92f18 558
4fc83d94 559int show_cmd_help(const char *cmd_name, const char *help_msg)
4ba92f18
PP
560{
561 int ret;
562 char page_name[32];
563
564 ret = sprintf(page_name, "lttng-%s", cmd_name);
a0377dfe 565 LTTNG_ASSERT(ret > 0 && ret < 32);
4fc83d94
PP
566 ret = utils_show_help(1, page_name, help_msg);
567 if (ret && !help_msg) {
568 ERR("Cannot view man page `lttng-%s(1)`", cmd_name);
569 perror("exec");
570 }
4ba92f18 571
4fc83d94 572 return ret;
4ba92f18 573}
bbbfd849 574
28ab034a
JG
575int print_trace_archive_location(const struct lttng_trace_archive_location *location,
576 const char *session_name)
bbbfd849
JG
577{
578 int ret = 0;
579 enum lttng_trace_archive_location_type location_type;
580 enum lttng_trace_archive_location_status status;
581 bool printed_location = false;
582
583 location_type = lttng_trace_archive_location_get_type(location);
584
28ab034a 585 _MSG("Trace chunk archive for session %s is now readable", session_name);
bbbfd849
JG
586 switch (location_type) {
587 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
588 {
589 const char *absolute_path;
590
28ab034a
JG
591 status = lttng_trace_archive_location_local_get_absolute_path(location,
592 &absolute_path);
bbbfd849
JG
593 if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) {
594 ret = -1;
595 goto end;
596 }
597 MSG(" at %s", absolute_path);
598 printed_location = true;
599 break;
600 }
601 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
602 {
603 uint16_t control_port, data_port;
604 const char *host, *relative_path, *protocol_str;
605 enum lttng_trace_archive_location_relay_protocol_type protocol;
606
607 /* Fetch all relay location parameters. */
28ab034a 608 status = lttng_trace_archive_location_relay_get_protocol_type(location, &protocol);
bbbfd849
JG
609 if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) {
610 ret = -1;
611 goto end;
612 }
613
28ab034a 614 status = lttng_trace_archive_location_relay_get_host(location, &host);
bbbfd849
JG
615 if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) {
616 ret = -1;
617 goto end;
618 }
619
28ab034a
JG
620 status = lttng_trace_archive_location_relay_get_control_port(location,
621 &control_port);
bbbfd849
JG
622 if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) {
623 ret = -1;
624 goto end;
625 }
626
28ab034a 627 status = lttng_trace_archive_location_relay_get_data_port(location, &data_port);
bbbfd849
JG
628 if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) {
629 ret = -1;
630 goto end;
631 }
632
28ab034a
JG
633 status = lttng_trace_archive_location_relay_get_relative_path(location,
634 &relative_path);
bbbfd849
JG
635 if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) {
636 ret = -1;
637 goto end;
638 }
639
640 switch (protocol) {
641 case LTTNG_TRACE_ARCHIVE_LOCATION_RELAY_PROTOCOL_TYPE_TCP:
642 protocol_str = "tcp";
643 break;
644 default:
645 protocol_str = "unknown";
646 break;
647 }
648
28ab034a
JG
649 MSG(" on relay %s://%s/%s [control port %" PRIu16 ", data port %" PRIu16 "]",
650 protocol_str,
651 host,
652 relative_path,
653 control_port,
654 data_port);
bbbfd849
JG
655 printed_location = true;
656 break;
657 }
658 default:
659 break;
660 }
661end:
662 if (!printed_location) {
663 MSG(" at an unknown location");
664 }
665 return ret;
666}
ca938aa5
OD
667
668namespace {
669template <typename FilterFunctionType>
6e11909e
JG
670lttng::cli::session_list get_sessions(const FilterFunctionType& filter,
671 bool return_first_match_only = false)
ca938aa5 672{
f74e820c 673 lttng::cli::session_list list = []() {
ca938aa5
OD
674 int list_ret;
675 struct lttng_session *psessions;
676
677 list_ret = lttng_list_sessions(&psessions);
678
679 if (list_ret < 0) {
680 LTTNG_THROW_CTL("Failed to list sessions",
681 static_cast<lttng_error_code>(list_ret));
682 }
683
f74e820c
JG
684 return lttng::cli::session_list(psessions, list_ret);
685 }();
ca938aa5
OD
686
687 std::size_t write_to = 0;
688 for (std::size_t read_from = 0; read_from < list.size(); ++read_from) {
689 if (!filter(list[read_from])) {
690 continue;
691 }
692
693 if (read_from != write_to) {
694 list[write_to] = list[read_from];
695 }
696
697 ++write_to;
698
699 if (return_first_match_only) {
6e11909e 700 return lttng::cli::session_list(std::move(list), 1);
ca938aa5
OD
701 }
702 }
703
704 list.resize(write_to);
705
706 return list;
707}
708} /* namespace */
709
6e11909e 710lttng::cli::session_list lttng::cli::list_sessions(const struct session_spec& spec)
ca938aa5 711{
42a11b8f 712 switch (spec.type_) {
6e11909e 713 case lttng::cli::session_spec::type::NAME:
ca938aa5
OD
714 if (spec.value == nullptr) {
715 const auto configured_name =
303ac4ed
JG
716 lttng::make_unique_wrapper<char, lttng::memory::free>(
717 get_session_name());
ca938aa5 718
0729ea55
JG
719 if (!configured_name) {
720 LTTNG_THROW_CLI_NO_DEFAULT_SESSION();
9cde3a4a 721 }
e8c353ad 722
0729ea55
JG
723 const struct lttng::cli::session_spec new_spec(
724 lttng::cli::session_spec::type::NAME, configured_name.get());
725
726 return list_sessions(new_spec);
ca938aa5
OD
727 }
728
729 return get_sessions(
730 [&spec](const lttng_session& session) {
731 return strcmp(session.name, spec.value) == 0;
732 },
733 true);
6e11909e 734 case lttng::cli::session_spec::type::GLOB_PATTERN:
ca938aa5
OD
735 return get_sessions([&spec](const lttng_session& session) {
736 return fnmatch(spec.value, session.name, 0) == 0;
737 });
6e11909e 738 case lttng::cli::session_spec::type::ALL:
ca938aa5
OD
739 return get_sessions([](const lttng_session&) { return true; });
740 }
741
6e11909e 742 return lttng::cli::session_list();
ca938aa5 743}
4d4c8b8e
JG
744
745void print_kernel_tracer_status_error()
746{
747 if (lttng_opt_mi) {
748 return;
749 }
750
751 enum lttng_kernel_tracer_status kernel_tracer_status;
752 const auto ret = lttng_get_kernel_tracer_status(&kernel_tracer_status);
753
754 if (ret < 0) {
755 ERR("Failed to get kernel tracer status: %s", lttng_strerror(ret));
756 } else {
757 switch (kernel_tracer_status) {
758 case LTTNG_KERNEL_TRACER_STATUS_INITIALIZED:
759 return;
760 case LTTNG_KERNEL_TRACER_STATUS_ERR_MODULES_UNKNOWN:
761 std::cerr << "\tKernel module loading failed" << std::endl;
762 break;
763 case LTTNG_KERNEL_TRACER_STATUS_ERR_MODULES_MISSING:
764 std::cerr << "\tMissing one or more required kernel modules" << std::endl;
765 break;
766 case LTTNG_KERNEL_TRACER_STATUS_ERR_MODULES_SIGNATURE:
767 std::cerr
768 << "\tKernel module signature error prevented loading of one or more required kernel modules"
769 << std::endl;
770 break;
771 case LTTNG_KERNEL_TRACER_STATUS_ERR_NEED_ROOT:
772 std::cerr << "\tlttng-sessiond isn't running as root" << std::endl;
773 break;
774 case LTTNG_KERNEL_TRACER_STATUS_ERR_NOTIFIER:
775 std::cerr << "\tFailed to setup notifiers" << std::endl;
776 break;
777 case LTTNG_KERNEL_TRACER_STATUS_ERR_OPEN_PROC_LTTNG:
778 std::cerr << "\tlttng-sessiond failed to open /proc/lttng" << std::endl;
779 break;
780 case LTTNG_KERNEL_TRACER_STATUS_ERR_VERSION_MISMATCH:
11927a78
JG
781 std::cerr << "\tVersion mismatch between kernel tracer and kernel tracer ABI"
782 << std::endl;
4d4c8b8e
JG
783 break;
784 default:
785 std::cerr << lttng::format("\t\tUnknown kernel tracer status (%d)",
786 static_cast<int>(kernel_tracer_status))
787 << std::endl;
788 break;
789 }
790
791 std::cerr << "\tConsult lttng-sessiond logs for more information" << std::endl;
792 }
793}
This page took 0.115703 seconds and 4 git commands to generate.