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