vscode: Add configurations to run the executables under the debugger
[lttng-tools.git] / src / lib / lttng-ctl / lttng-ctl.cpp
CommitLineData
826d496d 1/*
eb5c4f4e 2 * lttng-ctl.c
82a3637f
DG
3 *
4 * Linux Trace Toolkit Control Library
5 *
21cf9b6b 6 * Copyright (C) 2011 EfficiOS Inc.
ab5be9fa 7 * Copyright (C) 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
fac6795d 8 *
ab5be9fa 9 * SPDX-License-Identifier: LGPL-2.1-only
82a3637f 10 *
fac6795d
DG
11 */
12
6c1c0768 13#define _LGPL_SOURCE
28ab034a 14#include "lttng-ctl-helper.hpp"
fac6795d 15
c9e313bc 16#include <common/align.hpp>
28ab034a 17#include <common/bytecode/bytecode.hpp>
c9e313bc
SM
18#include <common/common.hpp>
19#include <common/compat/errno.hpp>
20#include <common/compat/string.hpp>
21#include <common/defaults.hpp>
22#include <common/dynamic-array.hpp>
23#include <common/dynamic-buffer.hpp>
28ab034a
JG
24#include <common/filter/filter-ast.hpp>
25#include <common/filter/filter-parser.hpp>
26#include <common/filter/memstream.hpp>
d93bbc2a 27#include <common/make-unique-wrapper.hpp>
c9e313bc
SM
28#include <common/payload-view.hpp>
29#include <common/payload.hpp>
30#include <common/sessiond-comm/sessiond-comm.hpp>
31#include <common/tracker.hpp>
32#include <common/unix.hpp>
33#include <common/uri.hpp>
34#include <common/utils.hpp>
28ab034a 35
c9e313bc 36#include <lttng/channel-internal.hpp>
159b042f
JG
37#include <lttng/destruction-handle.h>
38#include <lttng/endpoint.h>
c9e313bc
SM
39#include <lttng/error-query-internal.hpp>
40#include <lttng/event-internal.hpp>
41#include <lttng/health-internal.hpp>
b99a0cb3 42#include <lttng/lttng-error.h>
159b042f 43#include <lttng/lttng.h>
c9e313bc
SM
44#include <lttng/session-descriptor-internal.hpp>
45#include <lttng/session-internal.hpp>
46#include <lttng/trigger/trigger-internal.hpp>
47#include <lttng/userspace-probe-internal.hpp>
fac6795d 48
28ab034a
JG
49#include <grp.h>
50#include <stdint.h>
51#include <stdio.h>
52#include <stdlib.h>
53#include <string.h>
54#include <unistd.h>
53a80697 55
5c7248cd
JG
56#define COPY_DOMAIN_PACKED(dst, src) \
57 do { \
58 struct lttng_domain _tmp_domain; \
59 \
60 lttng_ctl_copy_lttng_domain(&_tmp_domain, &(src)); \
61 (dst) = _tmp_domain; \
28ab034a 62 } while (0)
53a80697 63
fac6795d 64/* Socket to session daemon for communication */
3e3665b8 65static int sessiond_socket = -1;
fac6795d
DG
66static char sessiond_sock_path[PATH_MAX];
67
fac6795d
DG
68/* Variables */
69static char *tracing_group;
70static int connected;
71
97e19046
DG
72/* Global */
73
74/*
75 * Those two variables are used by error.h to silent or control the verbosity of
76 * error message. They are global to the library so application linking with it
77 * are able to compile correctly and also control verbosity of the library.
97e19046 78 */
4bd69c5f
SM
79LTTNG_EXPORT int lttng_opt_quiet;
80LTTNG_EXPORT int lttng_opt_verbose;
81LTTNG_EXPORT int lttng_opt_mi;
97e19046 82
fac6795d 83/*
cd80958d 84 * Copy domain to lttcomm_session_msg domain.
fac6795d 85 *
cd80958d
DG
86 * If domain is unknown, default domain will be the kernel.
87 */
28ab034a 88void lttng_ctl_copy_lttng_domain(struct lttng_domain *dst, struct lttng_domain *src)
cd80958d
DG
89{
90 if (src && dst) {
91 switch (src->type) {
00e2e675
DG
92 case LTTNG_DOMAIN_KERNEL:
93 case LTTNG_DOMAIN_UST:
b9dfb167 94 case LTTNG_DOMAIN_JUL:
5cdb6027 95 case LTTNG_DOMAIN_LOG4J:
0e115563 96 case LTTNG_DOMAIN_PYTHON:
00e2e675
DG
97 memcpy(dst, src, sizeof(struct lttng_domain));
98 break;
99 default:
100 memset(dst, 0, sizeof(struct lttng_domain));
00e2e675 101 break;
cd80958d
DG
102 }
103 }
104}
105
106/*
107 * Send lttcomm_session_msg to the session daemon.
fac6795d 108 *
1c8d13c8
TD
109 * On success, returns the number of bytes sent (>=0)
110 * On error, returns -1
fac6795d 111 */
cd80958d 112static int send_session_msg(struct lttcomm_session_msg *lsm)
fac6795d
DG
113{
114 int ret;
115
116 if (!connected) {
2f70b271 117 ret = -LTTNG_ERR_NO_SESSIOND;
e065084a 118 goto end;
fac6795d
DG
119 }
120
28ab034a
JG
121 DBG("LSM cmd type: '%s' (%d)",
122 lttcomm_sessiond_command_str((lttcomm_sessiond_command) lsm->cmd_type),
123 lsm->cmd_type);
a4b92340 124
28ab034a
JG
125 ret = lttcomm_send_creds_unix_sock(
126 sessiond_socket, lsm, sizeof(struct lttcomm_session_msg));
2f70b271
DG
127 if (ret < 0) {
128 ret = -LTTNG_ERR_FATAL;
129 }
e065084a
DG
130
131end:
132 return ret;
133}
134
53a80697
MD
135/*
136 * Send var len data to the session daemon.
137 *
138 * On success, returns the number of bytes sent (>=0)
139 * On error, returns -1
140 */
c2d69327 141static int send_session_varlen(const void *data, size_t len)
53a80697
MD
142{
143 int ret;
144
145 if (!connected) {
2f70b271 146 ret = -LTTNG_ERR_NO_SESSIOND;
53a80697
MD
147 goto end;
148 }
a4b92340 149
53a80697
MD
150 if (!data || !len) {
151 ret = 0;
152 goto end;
153 }
154
155 ret = lttcomm_send_unix_sock(sessiond_socket, data, len);
2f70b271
DG
156 if (ret < 0) {
157 ret = -LTTNG_ERR_FATAL;
158 }
53a80697
MD
159
160end:
161 return ret;
162}
163
a04d53fc
FD
164/*
165 * Send file descriptors to the session daemon.
166 *
167 * On success, returns the number of bytes sent (>=0)
168 * On error, returns -1
169 */
170static int send_session_fds(const int *fds, size_t nb_fd)
171{
172 int ret;
173
174 if (!connected) {
175 ret = -LTTNG_ERR_NO_SESSIOND;
176 goto end;
177 }
178
179 if (!fds || !nb_fd) {
180 ret = 0;
181 goto end;
182 }
183
184 ret = lttcomm_send_fds_unix_sock(sessiond_socket, fds, nb_fd);
185 if (ret < 0) {
186 ret = -LTTNG_ERR_FATAL;
187 }
188
189end:
190 return ret;
191}
192
e065084a 193/*
cd80958d 194 * Receive data from the sessiond socket.
e065084a 195 *
1c8d13c8 196 * On success, returns the number of bytes received (>=0)
e368fb43 197 * On error, returns a negative lttng_error_code.
e065084a 198 */
ca95a216 199static int recv_data_sessiond(void *buf, size_t len)
e065084a
DG
200{
201 int ret;
202
a0377dfe 203 LTTNG_ASSERT(len > 0);
bacc41cc 204
e065084a 205 if (!connected) {
2f70b271 206 ret = -LTTNG_ERR_NO_SESSIOND;
e065084a 207 goto end;
fac6795d
DG
208 }
209
ca95a216 210 ret = lttcomm_recv_unix_sock(sessiond_socket, buf, len);
2f70b271
DG
211 if (ret < 0) {
212 ret = -LTTNG_ERR_FATAL;
bacc41cc
FD
213 } else if (ret == 0) {
214 ret = -LTTNG_ERR_NO_SESSIOND;
2f70b271 215 }
fac6795d 216
e065084a 217end:
fac6795d
DG
218 return ret;
219}
220
e368fb43
JG
221/*
222 * Receive a payload from the session daemon by appending to an existing
223 * payload.
224 * On success, returns the number of bytes received (>=0)
225 * On error, returns a negative lttng_error_code.
226 */
227static int recv_payload_sessiond(struct lttng_payload *payload, size_t len)
228{
229 int ret;
230 const size_t original_payload_size = payload->buffer.size;
231
28ab034a 232 ret = lttng_dynamic_buffer_set_size(&payload->buffer, payload->buffer.size + len);
e368fb43
JG
233 if (ret) {
234 ret = -LTTNG_ERR_NOMEM;
235 goto end;
236 }
237
28ab034a 238 ret = recv_data_sessiond(payload->buffer.data + original_payload_size, len);
e368fb43
JG
239end:
240 return ret;
241}
242
fac6795d 243/*
9ae110e2 244 * Check if we are in the specified group.
65beb5ff 245 *
9ae110e2 246 * If yes return 1, else return -1.
947308c4 247 */
cd9adb8b 248int lttng_check_tracing_group()
947308c4 249{
28ab59d0 250 gid_t *grp_list, tracing_gid;
947308c4
DG
251 int grp_list_size, grp_id, i;
252 int ret = -1;
6c71277b 253 const char *grp_name = tracing_group;
947308c4
DG
254
255 /* Get GID of group 'tracing' */
28ab59d0 256 if (utils_get_group_id(grp_name, false, &tracing_gid)) {
b4d8603b 257 /* If grp_tracing is NULL, the group does not exist. */
947308c4
DG
258 goto end;
259 }
260
261 /* Get number of supplementary group IDs */
cd9adb8b 262 grp_list_size = getgroups(0, nullptr);
947308c4 263 if (grp_list_size < 0) {
6f04ed72 264 PERROR("getgroups");
947308c4
DG
265 goto end;
266 }
267
268 /* Alloc group list of the right size */
64803277 269 grp_list = calloc<gid_t>(grp_list_size);
00795392 270 if (!grp_list) {
6f04ed72 271 PERROR("malloc");
00795392
MD
272 goto end;
273 }
947308c4 274 grp_id = getgroups(grp_list_size, grp_list);
1c8d13c8 275 if (grp_id < 0) {
6f04ed72 276 PERROR("getgroups");
947308c4
DG
277 goto free_list;
278 }
279
280 for (i = 0; i < grp_list_size; i++) {
28ab59d0 281 if (grp_list[i] == tracing_gid) {
2269e89e 282 ret = 1;
947308c4
DG
283 break;
284 }
285 }
286
287free_list:
288 free(grp_list);
289
290end:
291 return ret;
292}
293
28ab034a 294static enum lttng_error_code check_enough_available_memory(uint64_t num_bytes_requested_per_cpu)
09b72f7a
FD
295{
296 int ret;
13dd7782 297 enum lttng_error_code ret_code;
09b72f7a 298 long num_cpu;
13dd7782
JR
299 uint64_t best_mem_info;
300 uint64_t num_bytes_requested_total;
09b72f7a
FD
301
302 /*
303 * Get the number of CPU currently online to compute the amount of
304 * memory needed to create a buffer for every CPU.
305 */
306 num_cpu = sysconf(_SC_NPROCESSORS_ONLN);
307 if (num_cpu == -1) {
13dd7782
JR
308 ret_code = LTTNG_ERR_FATAL;
309 goto end;
310 }
311
312 if (num_bytes_requested_per_cpu > UINT64_MAX / (uint64_t) num_cpu) {
313 /* Overflow */
314 ret_code = LTTNG_ERR_OVERFLOW;
315 goto end;
09b72f7a
FD
316 }
317
28ab034a 318 num_bytes_requested_total = num_bytes_requested_per_cpu * (uint64_t) num_cpu;
09b72f7a
FD
319
320 /*
321 * Try to get the `MemAvail` field of `/proc/meminfo`. This is the most
322 * reliable estimate we can get but it is only exposed by the kernel
323 * since 3.14. (See Linux kernel commit:
324 * 34e431b0ae398fc54ea69ff85ec700722c9da773)
325 */
326 ret = utils_get_memory_available(&best_mem_info);
327 if (ret >= 0) {
328 goto success;
329 }
330
331 /*
332 * As a backup plan, use `MemTotal` field of `/proc/meminfo`. This
333 * is a sanity check for obvious user error.
334 */
335 ret = utils_get_memory_total(&best_mem_info);
336 if (ret >= 0) {
337 goto success;
338 }
339
13dd7782
JR
340 /* No valid source of information. */
341 ret_code = LTTNG_ERR_NOMEM;
342 goto end;
343
09b72f7a 344success:
13dd7782
JR
345 if (best_mem_info >= num_bytes_requested_total) {
346 ret_code = LTTNG_OK;
347 } else {
348 ret_code = LTTNG_ERR_NOMEM;
349 }
350end:
351 return ret_code;
09b72f7a
FD
352}
353
947308c4 354/*
2269e89e
DG
355 * Try connect to session daemon with sock_path.
356 *
357 * Return 0 on success, else -1
358 */
359static int try_connect_sessiond(const char *sock_path)
360{
361 int ret;
362
363 /* If socket exist, we check if the daemon listens for connect. */
364 ret = access(sock_path, F_OK);
365 if (ret < 0) {
366 /* Not alive */
2f70b271 367 goto error;
2269e89e
DG
368 }
369
370 ret = lttcomm_connect_unix_sock(sock_path);
371 if (ret < 0) {
9ae110e2 372 /* Not alive. */
2f70b271 373 goto error;
2269e89e
DG
374 }
375
376 ret = lttcomm_close_unix_sock(ret);
377 if (ret < 0) {
6f04ed72 378 PERROR("lttcomm_close_unix_sock");
2269e89e
DG
379 }
380
381 return 0;
2f70b271
DG
382
383error:
384 return -1;
2269e89e
DG
385}
386
387/*
2f70b271
DG
388 * Set sessiond socket path by putting it in the global sessiond_sock_path
389 * variable.
390 *
391 * Returns 0 on success, negative value on failure (the sessiond socket path
392 * is somehow too long or ENOMEM).
947308c4 393 */
cd9adb8b 394static int set_session_daemon_path()
947308c4 395{
28ab034a 396 int in_tgroup = 0; /* In tracing group. */
2269e89e
DG
397 uid_t uid;
398
399 uid = getuid();
947308c4 400
2269e89e
DG
401 if (uid != 0) {
402 /* Are we in the tracing group ? */
6c71277b 403 in_tgroup = lttng_check_tracing_group();
2269e89e
DG
404 }
405
c295ec41 406 if ((uid == 0) || in_tgroup == 1) {
e1b624d0 407 const int ret = lttng_strncpy(sessiond_sock_path,
28ab034a
JG
408 DEFAULT_GLOBAL_CLIENT_UNIX_SOCK,
409 sizeof(sessiond_sock_path));
e1b624d0
JG
410
411 if (ret) {
412 goto error;
413 }
08a9c49f 414 }
2269e89e 415
08a9c49f 416 if (uid != 0) {
c617c0c6
MD
417 int ret;
418
08a9c49f 419 if (in_tgroup) {
9ae110e2 420 /* Tracing group. */
08a9c49f
TD
421 ret = try_connect_sessiond(sessiond_sock_path);
422 if (ret >= 0) {
423 goto end;
2269e89e 424 }
08a9c49f 425 /* Global session daemon not available... */
2269e89e 426 }
08a9c49f
TD
427 /* ...or not in tracing group (and not root), default */
428
429 /*
9ae110e2
JG
430 * With GNU C < 2.1, snprintf returns -1 if the target buffer
431 * is too small;
432 * With GNU C >= 2.1, snprintf returns the required size
433 * (excluding closing null)
08a9c49f 434 */
28ab034a
JG
435 ret = snprintf(sessiond_sock_path,
436 sizeof(sessiond_sock_path),
437 DEFAULT_HOME_CLIENT_UNIX_SOCK,
438 utils_get_home_dir());
08a9c49f 439 if ((ret < 0) || (ret >= sizeof(sessiond_sock_path))) {
2f70b271 440 goto error;
947308c4 441 }
947308c4 442 }
08a9c49f 443end:
947308c4 444 return 0;
2f70b271
DG
445
446error:
447 return -1;
947308c4
DG
448}
449
65beb5ff 450/*
9ae110e2 451 * Connect to the LTTng session daemon.
65beb5ff 452 *
3e3665b8 453 * On success, return the socket's file descriptor. On error, return -1.
65beb5ff 454 */
cd9adb8b 455int connect_sessiond()
65beb5ff
DG
456{
457 int ret;
458
459 ret = set_session_daemon_path();
460 if (ret < 0) {
2f70b271 461 goto error;
65beb5ff
DG
462 }
463
9ae110e2 464 /* Connect to the sesssion daemon. */
65beb5ff
DG
465 ret = lttcomm_connect_unix_sock(sessiond_sock_path);
466 if (ret < 0) {
2f70b271 467 goto error;
65beb5ff
DG
468 }
469
3e3665b8 470 return ret;
2f70b271
DG
471
472error:
473 return -1;
65beb5ff
DG
474}
475
cd9adb8b 476static void reset_global_sessiond_connection_state()
3e3665b8
JG
477{
478 sessiond_socket = -1;
479 connected = 0;
480}
481
65beb5ff 482/*
1c8d13c8 483 * Clean disconnect from the session daemon.
9ae110e2 484 *
1c8d13c8 485 * On success, return 0. On error, return -1.
65beb5ff 486 */
cd9adb8b 487static int disconnect_sessiond()
65beb5ff
DG
488{
489 int ret = 0;
490
491 if (connected) {
492 ret = lttcomm_close_unix_sock(sessiond_socket);
3e3665b8 493 reset_global_sessiond_connection_state();
65beb5ff
DG
494 }
495
496 return ret;
497}
498
28ab034a 499static int recv_sessiond_optional_data(size_t len, void **user_buf, size_t *user_len)
795a978d
PP
500{
501 int ret = 0;
cd9adb8b 502 char *buf = nullptr;
795a978d
PP
503
504 if (len) {
505 if (!user_len) {
506 ret = -LTTNG_ERR_INVALID;
507 goto end;
508 }
509
64803277 510 buf = zmalloc<char>(len);
795a978d
PP
511 if (!buf) {
512 ret = -ENOMEM;
513 goto end;
514 }
515
516 ret = recv_data_sessiond(buf, len);
517 if (ret < 0) {
518 goto end;
519 }
520
521 if (!user_buf) {
522 ret = -LTTNG_ERR_INVALID;
523 goto end;
524 }
525
526 /* Move ownership of command header buffer to user. */
527 *user_buf = buf;
cd9adb8b 528 buf = nullptr;
795a978d
PP
529 *user_len = len;
530 } else {
531 /* No command header. */
532 if (user_len) {
533 *user_len = 0;
534 }
535
536 if (user_buf) {
cd9adb8b 537 *user_buf = nullptr;
795a978d
PP
538 }
539 }
540
541end:
542 free(buf);
543 return ret;
544}
545
35a6fdb7 546/*
cd80958d 547 * Ask the session daemon a specific command and put the data into buf.
a04d53fc
FD
548 * Takes extra var. len. data and file descriptors as input to send to the
549 * session daemon.
65beb5ff 550 *
af87c45a 551 * Return size of data (only payload, not header) or a negative error code.
65beb5ff 552 */
a04d53fc 553int lttng_ctl_ask_sessiond_fds_varlen(struct lttcomm_session_msg *lsm,
28ab034a
JG
554 const int *fds,
555 size_t nb_fd,
556 const void *vardata,
557 size_t vardata_len,
558 void **user_payload_buf,
559 void **user_cmd_header_buf,
560 size_t *user_cmd_header_len)
65beb5ff
DG
561{
562 int ret;
795a978d 563 size_t payload_len;
cd80958d 564 struct lttcomm_lttng_msg llm;
65beb5ff
DG
565
566 ret = connect_sessiond();
567 if (ret < 0) {
2f70b271 568 ret = -LTTNG_ERR_NO_SESSIOND;
65beb5ff 569 goto end;
3e3665b8
JG
570 } else {
571 sessiond_socket = ret;
572 connected = 1;
65beb5ff
DG
573 }
574
cd80958d 575 ret = send_session_msg(lsm);
65beb5ff 576 if (ret < 0) {
2f70b271 577 /* Ret value is a valid lttng error code. */
65beb5ff
DG
578 goto end;
579 }
53a80697 580 /* Send var len data */
795a978d 581 ret = send_session_varlen(vardata, vardata_len);
53a80697 582 if (ret < 0) {
2f70b271 583 /* Ret value is a valid lttng error code. */
53a80697
MD
584 goto end;
585 }
65beb5ff 586
a04d53fc
FD
587 /* Send fds */
588 ret = send_session_fds(fds, nb_fd);
589 if (ret < 0) {
590 /* Ret value is a valid lttng error code. */
591 goto end;
592 }
593
65beb5ff
DG
594 /* Get header from data transmission */
595 ret = recv_data_sessiond(&llm, sizeof(llm));
596 if (ret < 0) {
2f70b271 597 /* Ret value is a valid lttng error code. */
65beb5ff
DG
598 goto end;
599 }
600
601 /* Check error code if OK */
f73fabfd 602 if (llm.ret_code != LTTNG_OK) {
65beb5ff
DG
603 ret = -llm.ret_code;
604 goto end;
605 }
606
795a978d 607 /* Get command header from data transmission */
28ab034a
JG
608 ret = recv_sessiond_optional_data(
609 llm.cmd_header_size, user_cmd_header_buf, user_cmd_header_len);
65beb5ff 610 if (ret < 0) {
65beb5ff
DG
611 goto end;
612 }
613
795a978d 614 /* Get payload from data transmission */
28ab034a 615 ret = recv_sessiond_optional_data(llm.data_size, user_payload_buf, &payload_len);
795a978d 616 if (ret < 0) {
83009e5e
DG
617 goto end;
618 }
619
795a978d 620 ret = llm.data_size;
65beb5ff
DG
621
622end:
623 disconnect_sessiond();
624 return ret;
625}
626
28ab034a 627int lttng_ctl_ask_sessiond_payload(struct lttng_payload_view *message, struct lttng_payload *reply)
e368fb43
JG
628{
629 int ret;
630 struct lttcomm_lttng_msg llm;
fe489250 631 const int fd_count = lttng_payload_view_get_fd_handle_count(message);
e368fb43 632
a0377dfe
FD
633 LTTNG_ASSERT(reply->buffer.size == 0);
634 LTTNG_ASSERT(lttng_dynamic_pointer_array_get_count(&reply->_fd_handles) == 0);
e368fb43
JG
635
636 ret = connect_sessiond();
637 if (ret < 0) {
638 ret = -LTTNG_ERR_NO_SESSIOND;
639 goto end;
640 } else {
641 sessiond_socket = ret;
642 connected = 1;
643 }
644
645 /* Send command to session daemon */
28ab034a
JG
646 ret = lttcomm_send_creds_unix_sock(
647 sessiond_socket, message->buffer.data, message->buffer.size);
e368fb43
JG
648 if (ret < 0) {
649 ret = -LTTNG_ERR_FATAL;
650 goto end;
651 }
652
fe489250 653 if (fd_count > 0) {
28ab034a 654 ret = lttcomm_send_payload_view_fds_unix_sock(sessiond_socket, message);
fe489250
JG
655 if (ret < 0) {
656 ret = -LTTNG_ERR_FATAL;
657 goto end;
658 }
e368fb43
JG
659 }
660
661 /* Get header from data transmission */
662 ret = recv_payload_sessiond(reply, sizeof(llm));
663 if (ret < 0) {
664 /* Ret value is a valid lttng error code. */
665 goto end;
666 }
667
668 llm = *((typeof(llm) *) reply->buffer.data);
669
670 /* Check error code if OK */
671 if (llm.ret_code != LTTNG_OK) {
eb441106
JG
672 if (llm.ret_code < LTTNG_OK || llm.ret_code >= LTTNG_ERR_NR) {
673 /* Invalid error code received. */
674 ret = -LTTNG_ERR_UNK;
675 } else {
676 ret = -llm.ret_code;
677 }
e368fb43
JG
678 goto end;
679 }
680
681 if (llm.cmd_header_size > 0) {
682 ret = recv_payload_sessiond(reply, llm.cmd_header_size);
683 if (ret < 0) {
684 goto end;
685 }
686 }
687
688 /* Get command header from data transmission */
689 if (llm.data_size > 0) {
690 ret = recv_payload_sessiond(reply, llm.data_size);
691 if (ret < 0) {
692 goto end;
693 }
694 }
695
696 if (llm.fd_count > 0) {
28ab034a 697 ret = lttcomm_recv_payload_fds_unix_sock(sessiond_socket, llm.fd_count, reply);
fe489250 698 if (ret < 0) {
e368fb43
JG
699 goto end;
700 }
701 }
702
703 /* Don't return the llm header to the caller. */
28ab034a
JG
704 memmove(reply->buffer.data,
705 reply->buffer.data + sizeof(llm),
706 reply->buffer.size - sizeof(llm));
707 ret = lttng_dynamic_buffer_set_size(&reply->buffer, reply->buffer.size - sizeof(llm));
e368fb43
JG
708 if (ret) {
709 /* Can't happen as size is reduced. */
710 abort();
711 }
712
713 ret = reply->buffer.size;
714
715end:
716 disconnect_sessiond();
717 return ret;
718}
719
9f19cc17 720/*
cd80958d 721 * Create lttng handle and return pointer.
9ae110e2 722 *
1c8d13c8 723 * The returned pointer will be NULL in case of malloc() error.
9f19cc17 724 */
28ab034a 725struct lttng_handle *lttng_create_handle(const char *session_name, struct lttng_domain *domain)
9f19cc17 726{
e1b624d0 727 int ret;
cd9adb8b 728 struct lttng_handle *handle = nullptr;
2f70b271 729
64803277 730 handle = zmalloc<lttng_handle>();
cd9adb8b 731 if (handle == nullptr) {
2f70b271 732 PERROR("malloc handle");
cd80958d
DG
733 goto end;
734 }
735
736 /* Copy session name */
28ab034a 737 ret = lttng_strncpy(handle->session_name, session_name ?: "", sizeof(handle->session_name));
e1b624d0
JG
738 if (ret) {
739 goto error;
740 }
cd80958d 741
95681498
JG
742 /* Copy lttng domain or leave initialized to 0. */
743 if (domain) {
744 lttng_ctl_copy_lttng_domain(&handle->domain, domain);
745 }
cd80958d
DG
746
747end:
748 return handle;
e1b624d0
JG
749error:
750 free(handle);
cd9adb8b 751 return nullptr;
cd80958d
DG
752}
753
754/*
755 * Destroy handle by free(3) the pointer.
756 */
757void lttng_destroy_handle(struct lttng_handle *handle)
758{
0e428499 759 free(handle);
eb354453
DG
760}
761
d9800920
DG
762/*
763 * Register an outside consumer.
9ae110e2 764 *
1c8d13c8 765 * Returns size of returned session payload data or a negative error code.
d9800920 766 */
28ab034a 767int lttng_register_consumer(struct lttng_handle *handle, const char *socket_path)
d9800920 768{
e1b624d0 769 int ret;
d9800920
DG
770 struct lttcomm_session_msg lsm;
771
cd9adb8b 772 if (handle == nullptr || socket_path == nullptr) {
e1b624d0
JG
773 ret = -LTTNG_ERR_INVALID;
774 goto end;
2f70b271
DG
775 }
776
53efb85a 777 memset(&lsm, 0, sizeof(lsm));
37a5ef39 778 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_REGISTER_CONSUMER;
28ab034a 779 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
e1b624d0
JG
780 if (ret) {
781 ret = -LTTNG_ERR_INVALID;
782 goto end;
783 }
784
60160d2a 785 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
d9800920 786
28ab034a 787 ret = lttng_strncpy(lsm.u.reg.path, socket_path, sizeof(lsm.u.reg.path));
e1b624d0
JG
788 if (ret) {
789 ret = -LTTNG_ERR_INVALID;
790 goto end;
791 }
d9800920 792
cd9adb8b 793 ret = lttng_ctl_ask_sessiond(&lsm, nullptr);
e1b624d0
JG
794end:
795 return ret;
d9800920
DG
796}
797
1df4dedd 798/*
9ae110e2
JG
799 * Start tracing for all traces of the session.
800 *
801 * Returns size of returned session payload data or a negative error code.
1df4dedd 802 */
6a4f824d 803int lttng_start_tracing(const char *session_name)
f3ed775e 804{
e1b624d0 805 int ret;
cd80958d
DG
806 struct lttcomm_session_msg lsm;
807
cd9adb8b 808 if (session_name == nullptr) {
e1b624d0
JG
809 ret = -LTTNG_ERR_INVALID;
810 goto end;
cd80958d
DG
811 }
812
53efb85a 813 memset(&lsm, 0, sizeof(lsm));
37a5ef39 814 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_START_TRACE;
6a4f824d 815
28ab034a 816 ret = lttng_strncpy(lsm.session.name, session_name, sizeof(lsm.session.name));
e1b624d0
JG
817 if (ret) {
818 ret = -LTTNG_ERR_INVALID;
819 goto end;
820 }
cd80958d 821
cd9adb8b 822 ret = lttng_ctl_ask_sessiond(&lsm, nullptr);
e1b624d0
JG
823end:
824 return ret;
f3ed775e 825}
1df4dedd
DG
826
827/*
38ee087f 828 * Stop tracing for all traces of the session.
f3ed775e 829 */
38ee087f 830static int _lttng_stop_tracing(const char *session_name, int wait)
f3ed775e 831{
38ee087f 832 int ret, data_ret;
cd80958d
DG
833 struct lttcomm_session_msg lsm;
834
cd9adb8b 835 if (session_name == nullptr) {
e1b624d0
JG
836 ret = -LTTNG_ERR_INVALID;
837 goto error;
6a4f824d
DG
838 }
839
53efb85a 840 memset(&lsm, 0, sizeof(lsm));
37a5ef39 841 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_STOP_TRACE;
6a4f824d 842
28ab034a 843 ret = lttng_strncpy(lsm.session.name, session_name, sizeof(lsm.session.name));
e1b624d0
JG
844 if (ret) {
845 ret = -LTTNG_ERR_INVALID;
846 goto error;
847 }
cd80958d 848
cd9adb8b 849 ret = lttng_ctl_ask_sessiond(&lsm, nullptr);
38ee087f
DG
850 if (ret < 0 && ret != -LTTNG_ERR_TRACE_ALREADY_STOPPED) {
851 goto error;
852 }
853
854 if (!wait) {
855 goto end;
856 }
857
38ee087f
DG
858 /* Check for data availability */
859 do {
6d805429 860 data_ret = lttng_data_pending(session_name);
38ee087f
DG
861 if (data_ret < 0) {
862 /* Return the data available call error. */
863 ret = data_ret;
864 goto error;
865 }
866
867 /*
9ae110e2
JG
868 * Data sleep time before retrying (in usec). Don't sleep if the
869 * call returned value indicates availability.
38ee087f 870 */
6d805429 871 if (data_ret) {
c8f61fd4 872 usleep(DEFAULT_DATA_AVAILABILITY_WAIT_TIME_US);
38ee087f 873 }
6d805429 874 } while (data_ret != 0);
38ee087f 875
38ee087f
DG
876end:
877error:
878 return ret;
879}
880
881/*
882 * Stop tracing and wait for data availability.
883 */
884int lttng_stop_tracing(const char *session_name)
885{
886 return _lttng_stop_tracing(session_name, 1);
887}
888
889/*
890 * Stop tracing but _don't_ wait for data availability.
891 */
892int lttng_stop_tracing_no_wait(const char *session_name)
893{
894 return _lttng_stop_tracing(session_name, 0);
f3ed775e
DG
895}
896
897/*
601d5acf
DG
898 * Add context to a channel.
899 *
900 * If the given channel is NULL, add the contexts to all channels.
901 * The event_name param is ignored.
af87c45a
DG
902 *
903 * Returns the size of the returned payload data or a negative error code.
1df4dedd 904 */
cd80958d 905int lttng_add_context(struct lttng_handle *handle,
28ab034a
JG
906 struct lttng_event_context *ctx,
907 const char *event_name __attribute__((unused)),
908 const char *channel_name)
d65106b1 909{
2001793c 910 int ret;
1c9a0b0e 911 struct lttcomm_session_msg lsm = {
37a5ef39 912 .cmd_type = LTTCOMM_SESSIOND_COMMAND_ADD_CONTEXT,
1c9a0b0e
MJ
913 .session = {},
914 .domain = {},
915 .u = {},
916 .fd_count = 0,
917 };
26e1c61f
JR
918 struct lttng_payload payload;
919
920 lttng_payload_init(&payload);
cd80958d 921
9ae110e2 922 /* Safety check. Both are mandatory. */
cd9adb8b 923 if (handle == nullptr || ctx == nullptr) {
2001793c
JG
924 ret = -LTTNG_ERR_INVALID;
925 goto end;
cd80958d
DG
926 }
927
26e1c61f
JR
928 ret = lttng_dynamic_buffer_set_size(&payload.buffer, sizeof(lsm));
929 if (ret) {
930 ret = -LTTNG_ERR_NOMEM;
931 goto end;
932 }
cd80958d 933
85076754 934 /* If no channel name, send empty string. */
28ab034a
JG
935 ret = lttng_strncpy(
936 lsm.u.context.channel_name, channel_name ?: "", sizeof(lsm.u.context.channel_name));
e1b624d0
JG
937 if (ret) {
938 ret = -LTTNG_ERR_INVALID;
939 goto end;
85076754 940 }
cd80958d 941
60160d2a 942 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
28ab034a 943 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
e1b624d0
JG
944 if (ret) {
945 ret = -LTTNG_ERR_INVALID;
946 goto end;
947 }
cd80958d 948
26e1c61f
JR
949 ret = lttng_event_context_serialize(ctx, &payload);
950 if (ret) {
951 ret = -LTTNG_ERR_INVALID;
952 goto end;
953 }
2001793c 954
26e1c61f 955 lsm.u.context.length = payload.buffer.size - sizeof(lsm);
2001793c 956
26e1c61f
JR
957 /* Update message header. */
958 memcpy(payload.buffer.data, &lsm, sizeof(lsm));
2001793c 959
26e1c61f
JR
960 {
961 struct lttng_payload reply;
962 struct lttng_payload_view payload_view =
28ab034a 963 lttng_payload_view_from_payload(&payload, 0, -1);
2001793c 964
26e1c61f
JR
965 lttng_payload_init(&reply);
966 ret = lttng_ctl_ask_sessiond_payload(&payload_view, &reply);
967 lttng_payload_reset(&reply);
968 if (ret) {
2001793c
JG
969 goto end;
970 }
2001793c 971 }
46f44e2a 972
2001793c 973end:
26e1c61f 974 lttng_payload_reset(&payload);
2001793c 975 return ret;
d65106b1
DG
976}
977
f3ed775e 978/*
9ae110e2
JG
979 * Enable event(s) for a channel.
980 *
981 * If no event name is specified, all events are enabled.
982 * If no channel name is specified, the default 'channel0' is used.
983 *
984 * Returns size of returned session payload data or a negative error code.
f3ed775e 985 */
cd80958d 986int lttng_enable_event(struct lttng_handle *handle,
28ab034a
JG
987 struct lttng_event *ev,
988 const char *channel_name)
1df4dedd 989{
cd9adb8b 990 return lttng_enable_event_with_exclusions(handle, ev, channel_name, nullptr, 0, nullptr);
1df4dedd
DG
991}
992
53a80697 993/*
025faf73 994 * Create or enable an event with a filter expression.
178191b3 995 *
53a80697
MD
996 * Return negative error value on error.
997 * Return size of returned session payload data if OK.
998 */
025faf73 999int lttng_enable_event_with_filter(struct lttng_handle *handle,
28ab034a
JG
1000 struct lttng_event *event,
1001 const char *channel_name,
1002 const char *filter_expression)
53a80697 1003{
28ab034a 1004 return lttng_enable_event_with_exclusions(
cd9adb8b 1005 handle, event, channel_name, filter_expression, 0, nullptr);
53a80697
MD
1006}
1007
347c5ab5 1008/*
0e115563 1009 * Depending on the event, return a newly allocated agent filter expression or
347c5ab5
DG
1010 * NULL if not applicable.
1011 *
1012 * An event with NO loglevel and the name is * will return NULL.
1013 */
0e115563 1014static char *set_agent_filter(const char *filter, struct lttng_event *ev)
347c5ab5
DG
1015{
1016 int err;
cd9adb8b 1017 char *agent_filter = nullptr;
347c5ab5 1018
a0377dfe 1019 LTTNG_ASSERT(ev);
347c5ab5
DG
1020
1021 /* Don't add filter for the '*' event. */
9f449915 1022 if (strcmp(ev->name, "*") != 0) {
347c5ab5 1023 if (filter) {
28ab034a
JG
1024 err = asprintf(
1025 &agent_filter, "(%s) && (logger_name == \"%s\")", filter, ev->name);
347c5ab5 1026 } else {
0e115563 1027 err = asprintf(&agent_filter, "logger_name == \"%s\"", ev->name);
347c5ab5
DG
1028 }
1029 if (err < 0) {
1030 PERROR("asprintf");
6a556f7b 1031 goto error;
347c5ab5
DG
1032 }
1033 }
1034
1035 /* Add loglevel filtering if any for the JUL domain. */
1036 if (ev->loglevel_type != LTTNG_EVENT_LOGLEVEL_ALL) {
b53d4e59 1037 const char *op;
347c5ab5
DG
1038
1039 if (ev->loglevel_type == LTTNG_EVENT_LOGLEVEL_RANGE) {
1040 op = ">=";
1041 } else {
1042 op = "==";
1043 }
1044
0e115563 1045 if (filter || agent_filter) {
6a556f7b
JG
1046 char *new_filter;
1047
28ab034a
JG
1048 err = asprintf(&new_filter,
1049 "(%s) && (int_loglevel %s %d)",
1050 agent_filter ? agent_filter : filter,
1051 op,
1052 ev->loglevel);
0e115563
DG
1053 if (agent_filter) {
1054 free(agent_filter);
6a556f7b 1055 }
0e115563 1056 agent_filter = new_filter;
347c5ab5 1057 } else {
28ab034a 1058 err = asprintf(&agent_filter, "int_loglevel %s %d", op, ev->loglevel);
347c5ab5
DG
1059 }
1060 if (err < 0) {
1061 PERROR("asprintf");
6a556f7b 1062 goto error;
347c5ab5
DG
1063 }
1064 }
1065
0e115563 1066 return agent_filter;
6a556f7b 1067error:
0e115563 1068 free(agent_filter);
cd9adb8b 1069 return nullptr;
347c5ab5
DG
1070}
1071
93deb080
JI
1072/*
1073 * Enable event(s) for a channel, possibly with exclusions and a filter.
1074 * If no event name is specified, all events are enabled.
1075 * If no channel name is specified, the default name is used.
1076 * If filter expression is not NULL, the filter is set for the event.
1077 * If exclusion count is not zero, the exclusions are set for the event.
1078 * Returns size of returned session payload data or a negative error code.
1079 */
1080int lttng_enable_event_with_exclusions(struct lttng_handle *handle,
28ab034a
JG
1081 struct lttng_event *ev,
1082 const char *channel_name,
1083 const char *original_filter_expression,
1084 int exclusion_count,
1085 char **exclusion_list)
93deb080 1086{
1c9a0b0e 1087 struct lttcomm_session_msg lsm = {
37a5ef39 1088 .cmd_type = LTTCOMM_SESSIOND_COMMAND_ENABLE_EVENT,
1c9a0b0e
MJ
1089 .session = {},
1090 .domain = {},
1091 .u = {},
1092 .fd_count = 0,
1093 };
e368fb43 1094 struct lttng_payload payload;
8ddd72ef 1095 int ret = 0;
137b9942 1096 unsigned int free_filter_expression = 0;
cd9adb8b 1097 struct filter_parser_ctx *ctx = nullptr;
8ddd72ef 1098 size_t bytecode_len = 0;
ec005ec6 1099
6a0838b7
YL
1100 /*
1101 * We have either a filter or some exclusions, so we need to set up
e368fb43 1102 * a variable-length payload from where to send the data.
6a0838b7 1103 */
e368fb43 1104 lttng_payload_init(&payload);
ec005ec6 1105
e9efbcd3
JG
1106 /*
1107 * Cast as non-const since we may replace the filter expression
1108 * by a dynamically allocated string. Otherwise, the original
1109 * string is not modified.
1110 */
1111 char *filter_expression = (char *) original_filter_expression;
93deb080 1112
cd9adb8b 1113 if (handle == nullptr || ev == nullptr) {
137b9942
DG
1114 ret = -LTTNG_ERR_INVALID;
1115 goto error;
93deb080
JI
1116 }
1117
9ae110e2
JG
1118 /*
1119 * Empty filter string will always be rejected by the parser
93deb080
JI
1120 * anyway, so treat this corner-case early to eliminate
1121 * lttng_fmemopen error for 0-byte allocation.
1122 */
1123 if (filter_expression && filter_expression[0] == '\0') {
137b9942
DG
1124 ret = -LTTNG_ERR_INVALID;
1125 goto error;
93deb080
JI
1126 }
1127
18a720cd 1128 if (ev->name[0] == '\0') {
e1b624d0
JG
1129 /* Enable all events. */
1130 ret = lttng_strncpy(ev->name, "*", sizeof(ev->name));
a0377dfe 1131 LTTNG_ASSERT(ret == 0);
6565421f 1132 }
93deb080 1133
9ae110e2 1134 /* Parse filter expression. */
cd9adb8b 1135 if (filter_expression != nullptr || handle->domain.type == LTTNG_DOMAIN_JUL ||
28ab034a
JG
1136 handle->domain.type == LTTNG_DOMAIN_LOG4J ||
1137 handle->domain.type == LTTNG_DOMAIN_PYTHON) {
5cdb6027 1138 if (handle->domain.type == LTTNG_DOMAIN_JUL ||
28ab034a
JG
1139 handle->domain.type == LTTNG_DOMAIN_LOG4J ||
1140 handle->domain.type == LTTNG_DOMAIN_PYTHON) {
0e115563 1141 char *agent_filter;
64226865 1142
8ddd72ef 1143 /* Setup agent filter if needed. */
0e115563
DG
1144 agent_filter = set_agent_filter(filter_expression, ev);
1145 if (!agent_filter) {
137b9942 1146 if (!filter_expression) {
9ae110e2
JG
1147 /*
1148 * No JUL and no filter, just skip
1149 * everything below.
1150 */
8ddd72ef 1151 goto serialize;
137b9942 1152 }
64226865
DG
1153 } else {
1154 /*
9ae110e2
JG
1155 * With an agent filter, the original filter has
1156 * been added to it thus replace the filter
1157 * expression.
64226865 1158 */
0e115563 1159 filter_expression = agent_filter;
e9efbcd3 1160 free_filter_expression = 1;
9b21e6d5 1161 }
9b21e6d5 1162 }
93deb080 1163
28ab034a 1164 if (strnlen(filter_expression, LTTNG_FILTER_MAX_LEN) == LTTNG_FILTER_MAX_LEN) {
8ddd72ef
JR
1165 ret = -LTTNG_ERR_FILTER_INVAL;
1166 goto error;
1167 }
1168
e4d2f27a 1169 ret = filter_parser_ctx_create_from_filter_expression(filter_expression, &ctx);
93deb080 1170 if (ret) {
8ddd72ef 1171 goto error;
93deb080 1172 }
e4d2f27a 1173
28ab034a 1174 bytecode_len = bytecode_get_len(&ctx->bytecode->b) + sizeof(ctx->bytecode->b);
8ddd72ef
JR
1175 if (bytecode_len > LTTNG_FILTER_MAX_LEN) {
1176 ret = -LTTNG_ERR_FILTER_INVAL;
1177 goto error;
1178 }
6b453b5e
JG
1179 }
1180
8ddd72ef 1181serialize:
28ab034a
JG
1182 ret = lttng_event_serialize(ev,
1183 exclusion_count,
1e0019bb 1184 exclusion_list,
28ab034a
JG
1185 filter_expression,
1186 bytecode_len,
cd9adb8b 1187 (ctx && bytecode_len) ? &ctx->bytecode->b : nullptr,
28ab034a 1188 &payload);
15e37663 1189 if (ret) {
8ddd72ef
JR
1190 ret = -LTTNG_ERR_INVALID;
1191 goto error;
6b453b5e 1192 }
137b9942 1193
8ddd72ef 1194 /* If no channel name, send empty string. */
28ab034a
JG
1195 ret = lttng_strncpy(
1196 lsm.u.enable.channel_name, channel_name ?: "", sizeof(lsm.u.enable.channel_name));
8ddd72ef
JR
1197 if (ret) {
1198 ret = -LTTNG_ERR_INVALID;
1199 goto error;
6b453b5e 1200 }
15e37663 1201
8ddd72ef
JR
1202 /* Domain */
1203 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
15e37663 1204
8ddd72ef 1205 /* Session name */
28ab034a 1206 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
8ddd72ef
JR
1207 if (ret) {
1208 ret = -LTTNG_ERR_INVALID;
1209 goto error;
93deb080
JI
1210 }
1211
8ddd72ef
JR
1212 /* Length of the serialized event. */
1213 lsm.u.enable.length = (uint32_t) payload.buffer.size;
1214
e368fb43 1215 {
28ab034a 1216 struct lttng_payload_view view = lttng_payload_view_from_payload(&payload, 0, -1);
fe489250 1217 int fd_count = lttng_payload_view_get_fd_handle_count(&view);
e368fb43
JG
1218 int fd_to_send;
1219
1220 if (fd_count < 0) {
8ddd72ef 1221 goto error;
e368fb43
JG
1222 }
1223
a0377dfe 1224 LTTNG_ASSERT(fd_count == 0 || fd_count == 1);
e368fb43 1225 if (fd_count == 1) {
28ab034a 1226 struct fd_handle *h = lttng_payload_view_pop_fd_handle(&view);
fe489250 1227
e2fc8e9d 1228 if (!h) {
8ddd72ef 1229 goto error;
e368fb43
JG
1230 }
1231
e2fc8e9d
SM
1232 fd_to_send = fd_handle_get_fd(h);
1233 fd_handle_put(h);
e368fb43
JG
1234 }
1235
8ddd72ef
JR
1236 lsm.fd_count = fd_count;
1237
e368fb43 1238 ret = lttng_ctl_ask_sessiond_fds_varlen(&lsm,
cd9adb8b 1239 fd_count ? &fd_to_send : nullptr,
28ab034a 1240 fd_count,
cd9adb8b
JG
1241 view.buffer.size ? view.buffer.data :
1242 nullptr,
28ab034a 1243 view.buffer.size,
cd9adb8b
JG
1244 nullptr,
1245 nullptr,
1246 nullptr);
e368fb43 1247 }
93deb080 1248
8ddd72ef 1249error:
7ca1dc6f 1250 if (filter_expression && ctx) {
93deb080
JI
1251 filter_bytecode_free(ctx);
1252 filter_ir_free(ctx);
1253 filter_parser_ctx_free(ctx);
7ca1dc6f 1254 }
7ca1dc6f
DG
1255 if (free_filter_expression) {
1256 /*
9ae110e2
JG
1257 * The filter expression has been replaced and must be freed as
1258 * it is not the original filter expression received as a
1259 * parameter.
7ca1dc6f
DG
1260 */
1261 free(filter_expression);
93deb080 1262 }
137b9942 1263 /*
9ae110e2
JG
1264 * Return directly to the caller and don't ask the sessiond since
1265 * something went wrong in the parsing of data above.
137b9942 1266 */
e368fb43 1267 lttng_payload_reset(&payload);
93deb080
JI
1268 return ret;
1269}
1270
6e911cad 1271int lttng_disable_event_ext(struct lttng_handle *handle,
28ab034a
JG
1272 struct lttng_event *ev,
1273 const char *channel_name,
1274 const char *original_filter_expression)
1df4dedd 1275{
1c9a0b0e 1276 struct lttcomm_session_msg lsm = {
37a5ef39 1277 .cmd_type = LTTCOMM_SESSIOND_COMMAND_DISABLE_EVENT,
1c9a0b0e
MJ
1278 .session = {},
1279 .domain = {},
1280 .u = {},
1281 .fd_count = 0,
1282 };
8ddd72ef 1283 struct lttng_payload payload;
6e911cad
MD
1284 int ret = 0;
1285 unsigned int free_filter_expression = 0;
cd9adb8b 1286 struct filter_parser_ctx *ctx = nullptr;
8ddd72ef
JR
1287 size_t bytecode_len = 0;
1288
1289 /*
1290 * We have either a filter or some exclusions, so we need to set up
1291 * a variable-length payload from where to send the data.
1292 */
1293 lttng_payload_init(&payload);
1294
6e911cad
MD
1295 /*
1296 * Cast as non-const since we may replace the filter expression
1297 * by a dynamically allocated string. Otherwise, the original
1298 * string is not modified.
1299 */
1300 char *filter_expression = (char *) original_filter_expression;
1df4dedd 1301
cd9adb8b 1302 if (handle == nullptr || ev == nullptr) {
6e911cad
MD
1303 ret = -LTTNG_ERR_INVALID;
1304 goto error;
1305 }
1306
9ae110e2
JG
1307 /*
1308 * Empty filter string will always be rejected by the parser
6e911cad
MD
1309 * anyway, so treat this corner-case early to eliminate
1310 * lttng_fmemopen error for 0-byte allocation.
1311 */
1312 if (filter_expression && filter_expression[0] == '\0') {
1313 ret = -LTTNG_ERR_INVALID;
1314 goto error;
cd80958d
DG
1315 }
1316
8ddd72ef 1317 /* Parse filter expression. */
cd9adb8b 1318 if (filter_expression != nullptr || handle->domain.type == LTTNG_DOMAIN_JUL ||
28ab034a
JG
1319 handle->domain.type == LTTNG_DOMAIN_LOG4J ||
1320 handle->domain.type == LTTNG_DOMAIN_PYTHON) {
6e911cad 1321 if (handle->domain.type == LTTNG_DOMAIN_JUL ||
28ab034a
JG
1322 handle->domain.type == LTTNG_DOMAIN_LOG4J ||
1323 handle->domain.type == LTTNG_DOMAIN_PYTHON) {
0e115563 1324 char *agent_filter;
6e911cad 1325
8ddd72ef 1326 /* Setup agent filter if needed. */
0e115563
DG
1327 agent_filter = set_agent_filter(filter_expression, ev);
1328 if (!agent_filter) {
6e911cad 1329 if (!filter_expression) {
9ae110e2
JG
1330 /*
1331 * No JUL and no filter, just skip
1332 * everything below.
1333 */
8ddd72ef 1334 goto serialize;
6e911cad
MD
1335 }
1336 } else {
1337 /*
8ddd72ef 1338 * With an agent filter, the original filter has
9ae110e2
JG
1339 * been added to it thus replace the filter
1340 * expression.
6e911cad 1341 */
0e115563 1342 filter_expression = agent_filter;
6e911cad
MD
1343 free_filter_expression = 1;
1344 }
1345 }
1346
28ab034a 1347 if (strnlen(filter_expression, LTTNG_FILTER_MAX_LEN) == LTTNG_FILTER_MAX_LEN) {
8ddd72ef
JR
1348 ret = -LTTNG_ERR_FILTER_INVAL;
1349 goto error;
1350 }
1351
e4d2f27a 1352 ret = filter_parser_ctx_create_from_filter_expression(filter_expression, &ctx);
6e911cad 1353 if (ret) {
8ddd72ef 1354 goto error;
6e911cad 1355 }
e4d2f27a 1356
28ab034a 1357 bytecode_len = bytecode_get_len(&ctx->bytecode->b) + sizeof(ctx->bytecode->b);
8ddd72ef
JR
1358 if (bytecode_len > LTTNG_FILTER_MAX_LEN) {
1359 ret = -LTTNG_ERR_FILTER_INVAL;
1360 goto error;
1361 }
6e911cad
MD
1362 }
1363
8ddd72ef 1364serialize:
28ab034a
JG
1365 ret = lttng_event_serialize(ev,
1366 0,
cd9adb8b 1367 nullptr,
28ab034a
JG
1368 filter_expression,
1369 bytecode_len,
cd9adb8b 1370 (ctx && bytecode_len) ? &ctx->bytecode->b : nullptr,
28ab034a 1371 &payload);
8ddd72ef
JR
1372 if (ret) {
1373 ret = -LTTNG_ERR_INVALID;
1374 goto error;
6e911cad
MD
1375 }
1376
8ddd72ef 1377 /* If no channel name, send empty string. */
28ab034a
JG
1378 ret = lttng_strncpy(
1379 lsm.u.disable.channel_name, channel_name ?: "", sizeof(lsm.u.disable.channel_name));
8ddd72ef
JR
1380 if (ret) {
1381 ret = -LTTNG_ERR_INVALID;
1382 goto error;
6e911cad 1383 }
8ddd72ef
JR
1384
1385 /* Domain */
1386 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
1387
1388 /* Session name */
28ab034a 1389 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
8ddd72ef
JR
1390 if (ret) {
1391 ret = -LTTNG_ERR_INVALID;
1392 goto error;
6e911cad
MD
1393 }
1394
8ddd72ef
JR
1395 /* Length of the serialized event. */
1396 lsm.u.disable.length = (uint32_t) payload.buffer.size;
1397
1398 {
28ab034a 1399 struct lttng_payload_view view = lttng_payload_view_from_payload(&payload, 0, -1);
8ddd72ef
JR
1400 int fd_count = lttng_payload_view_get_fd_handle_count(&view);
1401 int fd_to_send;
1402
1403 if (fd_count < 0) {
1404 goto error;
1405 }
1406
1407 LTTNG_ASSERT(fd_count == 0 || fd_count == 1);
1408 if (fd_count == 1) {
28ab034a 1409 struct fd_handle *h = lttng_payload_view_pop_fd_handle(&view);
6e911cad 1410
8ddd72ef
JR
1411 if (!h) {
1412 goto error;
1413 }
1414
1415 fd_to_send = fd_handle_get_fd(h);
1416 fd_handle_put(h);
1417 }
1418
1419 ret = lttng_ctl_ask_sessiond_fds_varlen(&lsm,
cd9adb8b 1420 fd_count ? &fd_to_send : nullptr,
28ab034a 1421 fd_count,
cd9adb8b
JG
1422 view.buffer.size ? view.buffer.data :
1423 nullptr,
28ab034a 1424 view.buffer.size,
cd9adb8b
JG
1425 nullptr,
1426 nullptr,
1427 nullptr);
8ddd72ef
JR
1428 }
1429
1430error:
6e911cad
MD
1431 if (filter_expression && ctx) {
1432 filter_bytecode_free(ctx);
1433 filter_ir_free(ctx);
1434 filter_parser_ctx_free(ctx);
1435 }
6e911cad
MD
1436 if (free_filter_expression) {
1437 /*
9ae110e2
JG
1438 * The filter expression has been replaced and must be freed as
1439 * it is not the original filter expression received as a
1440 * parameter.
6e911cad
MD
1441 */
1442 free(filter_expression);
1443 }
6e911cad 1444 /*
9ae110e2
JG
1445 * Return directly to the caller and don't ask the sessiond since
1446 * something went wrong in the parsing of data above.
6e911cad 1447 */
8ddd72ef 1448 lttng_payload_reset(&payload);
6e911cad
MD
1449 return ret;
1450}
1451
1452/*
9ae110e2
JG
1453 * Disable event(s) of a channel and domain.
1454 * If no event name is specified, all events are disabled.
1455 * If no channel name is specified, the default 'channel0' is used.
1456 * Returns size of returned session payload data or a negative error code.
6e911cad 1457 */
28ab034a 1458int lttng_disable_event(struct lttng_handle *handle, const char *name, const char *channel_name)
6e911cad 1459{
e1b624d0 1460 int ret;
6e911cad
MD
1461 struct lttng_event ev;
1462
1463 memset(&ev, 0, sizeof(ev));
9b7431cf 1464 ev.loglevel = -1;
6e911cad 1465 ev.type = LTTNG_EVENT_ALL;
e1b624d0
JG
1466 ret = lttng_strncpy(ev.name, name ?: "", sizeof(ev.name));
1467 if (ret) {
1468 ret = -LTTNG_ERR_INVALID;
1469 goto end;
1470 }
1471
cd9adb8b 1472 ret = lttng_disable_event_ext(handle, &ev, channel_name, nullptr);
e1b624d0
JG
1473end:
1474 return ret;
1df4dedd
DG
1475}
1476
cf0bcb51
JG
1477struct lttng_channel *lttng_channel_create(struct lttng_domain *domain)
1478{
cd9adb8b 1479 struct lttng_channel *channel = nullptr;
cf0bcb51
JG
1480
1481 if (!domain) {
999af9c1 1482 goto end;
cf0bcb51
JG
1483 }
1484
1485 /* Validate domain. */
1486 switch (domain->type) {
1487 case LTTNG_DOMAIN_UST:
1488 switch (domain->buf_type) {
1489 case LTTNG_BUFFER_PER_UID:
1490 case LTTNG_BUFFER_PER_PID:
1491 break;
1492 default:
999af9c1 1493 goto end;
cf0bcb51
JG
1494 }
1495 break;
1496 case LTTNG_DOMAIN_KERNEL:
1497 if (domain->buf_type != LTTNG_BUFFER_GLOBAL) {
999af9c1 1498 goto end;
cf0bcb51
JG
1499 }
1500 break;
1501 default:
999af9c1 1502 goto end;
cf0bcb51
JG
1503 }
1504
999af9c1 1505 channel = lttng_channel_create_internal();
cf0bcb51 1506 if (!channel) {
999af9c1 1507 goto end;
cf0bcb51
JG
1508 }
1509
cf0bcb51 1510 lttng_channel_set_default_attr(domain, &channel->attr);
999af9c1 1511end:
cf0bcb51 1512 return channel;
cf0bcb51
JG
1513}
1514
1515void lttng_channel_destroy(struct lttng_channel *channel)
1516{
1517 if (!channel) {
1518 return;
1519 }
1520
1521 if (channel->attr.extended.ptr) {
1522 free(channel->attr.extended.ptr);
1523 }
1524 free(channel);
1525}
1526
1df4dedd 1527/*
9ae110e2
JG
1528 * Enable channel per domain
1529 * Returns size of returned session payload data or a negative error code.
a5c5a2bd 1530 */
28ab034a 1531int lttng_enable_channel(struct lttng_handle *handle, struct lttng_channel *in_chan)
a5c5a2bd 1532{
13dd7782 1533 enum lttng_error_code ret_code;
e1b624d0 1534 int ret;
999af9c1 1535 struct lttng_dynamic_buffer buffer;
cd80958d 1536 struct lttcomm_session_msg lsm;
13dd7782 1537 uint64_t total_buffer_size_needed_per_cpu = 0;
cd9adb8b 1538 struct lttng_channel *channel = nullptr;
999af9c1
JR
1539
1540 lttng_dynamic_buffer_init(&buffer);
cd80958d 1541
9ae110e2 1542 /* NULL arguments are forbidden. No default values. */
cd9adb8b 1543 if (handle == nullptr || in_chan == nullptr) {
999af9c1
JR
1544 ret = -LTTNG_ERR_INVALID;
1545 goto end;
cf0bcb51 1546 }
cd80958d 1547
09b72f7a
FD
1548 /*
1549 * Verify that the amount of memory required to create the requested
1550 * buffer is available on the system at the moment.
1551 */
28ab034a 1552 if (in_chan->attr.num_subbuf > UINT64_MAX / in_chan->attr.subbuf_size) {
13dd7782
JR
1553 /* Overflow */
1554 ret = -LTTNG_ERR_OVERFLOW;
1555 goto end;
1556 }
1557
28ab034a
JG
1558 total_buffer_size_needed_per_cpu = in_chan->attr.num_subbuf * in_chan->attr.subbuf_size;
1559 ret_code = check_enough_available_memory(total_buffer_size_needed_per_cpu);
13dd7782
JR
1560 if (ret_code != LTTNG_OK) {
1561 ret = -ret_code;
1562 goto end;
09b72f7a
FD
1563 }
1564
999af9c1
JR
1565 /* Copy the channel for easier manipulation. */
1566 channel = lttng_channel_copy(in_chan);
1567 if (!channel) {
1568 ret = -LTTNG_ERR_NOMEM;
1569 goto end;
1570 }
1571
1572 /* Populate the channel extended attribute if necessary. */
1573 if (!channel->attr.extended.ptr) {
28ab034a 1574 struct lttng_channel_extended *extended = zmalloc<lttng_channel_extended>();
999af9c1
JR
1575
1576 if (!extended) {
1577 ret = -LTTNG_ERR_NOMEM;
1578 goto end;
1579 }
64803277 1580
28ab034a 1581 lttng_channel_set_default_extended_attr(&handle->domain, extended);
999af9c1
JR
1582 channel->attr.extended.ptr = extended;
1583 }
1584
1585 /* Prepare the payload */
1586 memset(&lsm, 0, sizeof(lsm));
1587
37a5ef39 1588 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_ENABLE_CHANNEL;
60160d2a 1589 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
7d29a247 1590
28ab034a 1591 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
e1b624d0
JG
1592 if (ret) {
1593 ret = -LTTNG_ERR_INVALID;
1594 goto end;
1595 }
cd80958d 1596
999af9c1
JR
1597 ret = lttng_channel_serialize(channel, &buffer);
1598 if (ret) {
1599 ret = -LTTNG_ERR_FATAL;
1600 goto end;
1601 }
1602
1603 lsm.u.channel.length = buffer.size;
1604
cd9adb8b 1605 ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(&lsm, buffer.data, buffer.size, nullptr);
e1b624d0 1606end:
999af9c1
JR
1607 lttng_channel_destroy(channel);
1608 lttng_dynamic_buffer_reset(&buffer);
e1b624d0 1609 return ret;
8c0faa1d 1610}
1df4dedd 1611
2ef84c95 1612/*
9ae110e2
JG
1613 * All tracing will be stopped for registered events of the channel.
1614 * Returns size of returned session payload data or a negative error code.
2ef84c95 1615 */
cd80958d 1616int lttng_disable_channel(struct lttng_handle *handle, const char *name)
2ef84c95 1617{
e1b624d0 1618 int ret;
cd80958d
DG
1619 struct lttcomm_session_msg lsm;
1620
9ae110e2 1621 /* Safety check. Both are mandatory. */
cd9adb8b 1622 if (handle == nullptr || name == nullptr) {
2f70b271 1623 return -LTTNG_ERR_INVALID;
cd80958d
DG
1624 }
1625
441c16a7
MD
1626 memset(&lsm, 0, sizeof(lsm));
1627
37a5ef39 1628 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_DISABLE_CHANNEL;
1df4dedd 1629
28ab034a 1630 ret = lttng_strncpy(lsm.u.disable.channel_name, name, sizeof(lsm.u.disable.channel_name));
e1b624d0
JG
1631 if (ret) {
1632 ret = -LTTNG_ERR_INVALID;
1633 goto end;
1634 }
9d697d3d 1635
60160d2a 1636 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
cd80958d 1637
28ab034a 1638 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
e1b624d0
JG
1639 if (ret) {
1640 ret = -LTTNG_ERR_INVALID;
1641 goto end;
1642 }
cd80958d 1643
cd9adb8b 1644 ret = lttng_ctl_ask_sessiond(&lsm, nullptr);
e1b624d0
JG
1645end:
1646 return ret;
ca95a216
DG
1647}
1648
fac6795d 1649/*
9ae110e2
JG
1650 * Lists all available tracepoints of domain.
1651 * Sets the contents of the events array.
1652 * Returns the number of lttng_event entries in events;
1653 * on error, returns a negative value.
fac6795d 1654 */
28ab034a 1655int lttng_list_tracepoints(struct lttng_handle *handle, struct lttng_event **events)
fac6795d 1656{
28ab034a
JG
1657 enum lttng_error_code ret_code;
1658 int ret, total_payload_received;
cd9adb8b 1659 char *reception_buffer = nullptr;
28ab034a 1660 struct lttcomm_session_msg lsm = {
37a5ef39 1661 .cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_TRACEPOINTS,
1c9a0b0e
MJ
1662 .session = {},
1663 .domain = {},
1664 .u = {},
1665 .fd_count = 0,
1666 };
cd9adb8b 1667 struct lttcomm_list_command_header *cmd_header = nullptr;
28ab034a
JG
1668 size_t cmd_header_len;
1669 unsigned int nb_events = 0;
8ddd72ef 1670
cd9adb8b 1671 if (handle == nullptr) {
28ab034a
JG
1672 ret = -LTTNG_ERR_INVALID;
1673 goto end;
1674 }
8ddd72ef 1675
28ab034a 1676 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
8ddd72ef 1677
28ab034a 1678 ret = lttng_ctl_ask_sessiond_fds_varlen(&lsm,
cd9adb8b 1679 nullptr,
28ab034a 1680 0,
cd9adb8b 1681 nullptr,
28ab034a
JG
1682 0,
1683 (void **) &reception_buffer,
1684 (void **) &cmd_header,
1685 &cmd_header_len);
1686 if (ret < 0) {
1687 goto end;
1688 }
8ddd72ef 1689
28ab034a 1690 total_payload_received = ret;
8ddd72ef 1691
28ab034a
JG
1692 if (!cmd_header) {
1693 ret = -LTTNG_ERR_UNK;
1694 goto end;
1695 }
8ddd72ef 1696
28ab034a
JG
1697 if (cmd_header->count > INT_MAX) {
1698 ret = -LTTNG_ERR_OVERFLOW;
1699 goto end;
1700 }
8ddd72ef 1701
28ab034a 1702 nb_events = (unsigned int) cmd_header->count;
fac6795d 1703
8ddd72ef
JR
1704 {
1705 struct lttng_buffer_view events_view =
28ab034a 1706 lttng_buffer_view_init(reception_buffer, 0, total_payload_received);
8ddd72ef 1707 struct lttng_payload_view events_payload_view =
28ab034a 1708 lttng_payload_view_from_buffer_view(&events_view, 0, -1);
2a71efd5 1709
8ddd72ef 1710 ret_code = lttng_events_create_and_flatten_from_payload(
28ab034a 1711 &events_payload_view, nb_events, events);
8ddd72ef
JR
1712 if (ret_code != LTTNG_OK) {
1713 ret = -ret_code;
1714 goto end;
1715 }
eb354453 1716 }
fac6795d 1717
8ddd72ef
JR
1718 ret = (int) nb_events;
1719
1720end:
28ab034a
JG
1721 free(cmd_header);
1722 free(reception_buffer);
1723 return ret;
fac6795d
DG
1724}
1725
f37d259d 1726/*
9ae110e2
JG
1727 * Lists all available tracepoint fields of domain.
1728 * Sets the contents of the event field array.
1729 * Returns the number of lttng_event_field entries in events;
1730 * on error, returns a negative value.
f37d259d 1731 */
28ab034a 1732int lttng_list_tracepoint_fields(struct lttng_handle *handle, struct lttng_event_field **fields)
f37d259d 1733{
b2d68839 1734 enum lttng_error_code ret_code;
f37d259d
MD
1735 int ret;
1736 struct lttcomm_session_msg lsm;
cd9adb8b 1737 const struct lttcomm_list_command_header *cmd_header = nullptr;
b2d68839
JR
1738 unsigned int nb_event_fields = 0;
1739 struct lttng_payload reply;
f37d259d 1740
5c5c6942
JG
1741 lttng_payload_init(&reply);
1742
cd9adb8b 1743 if (handle == nullptr) {
b2d68839
JR
1744 ret = -LTTNG_ERR_INVALID;
1745 goto end;
f37d259d
MD
1746 }
1747
53efb85a 1748 memset(&lsm, 0, sizeof(lsm));
37a5ef39 1749 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_TRACEPOINT_FIELDS;
60160d2a 1750 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
f37d259d 1751
b2d68839
JR
1752 {
1753 lttng_payload_view message_view =
28ab034a 1754 lttng_payload_view_init_from_buffer((const char *) &lsm, 0, sizeof(lsm));
b2d68839
JR
1755
1756 ret = lttng_ctl_ask_sessiond_payload(&message_view, &reply);
1757 if (ret < 0) {
1758 goto end;
1759 }
1760 }
1761
1762 {
28ab034a
JG
1763 const lttng_buffer_view cmd_header_view = lttng_buffer_view_from_dynamic_buffer(
1764 &reply.buffer, 0, sizeof(*cmd_header));
b2d68839
JR
1765
1766 if (!lttng_buffer_view_is_valid(&cmd_header_view)) {
1767 ret = -LTTNG_ERR_INVALID_PROTOCOL;
1768 goto end;
1769 }
1770
28ab034a 1771 cmd_header = (struct lttcomm_list_command_header *) cmd_header_view.data;
b2d68839
JR
1772 }
1773
1774 if (cmd_header->count > INT_MAX) {
1775 ret = -LTTNG_ERR_OVERFLOW;
1776 goto end;
f37d259d
MD
1777 }
1778
b2d68839
JR
1779 nb_event_fields = cmd_header->count;
1780
1781 {
1782 lttng_payload_view reply_view =
28ab034a 1783 lttng_payload_view_from_payload(&reply, sizeof(*cmd_header), -1);
b2d68839
JR
1784
1785 ret_code = lttng_event_fields_create_and_flatten_from_payload(
28ab034a 1786 &reply_view, nb_event_fields, fields);
b2d68839
JR
1787 if (ret_code != LTTNG_OK) {
1788 ret = -ret_code;
1789 goto end;
1790 }
1791 }
1792
1793 ret = nb_event_fields;
1794
1795end:
5c5c6942 1796 lttng_payload_reset(&reply);
b2d68839 1797 return ret;
f37d259d
MD
1798}
1799
834978fd 1800/*
9ae110e2
JG
1801 * Lists all available kernel system calls. Allocates and sets the contents of
1802 * the events array.
834978fd 1803 *
9ae110e2
JG
1804 * Returns the number of lttng_event entries in events; on error, returns a
1805 * negative value.
834978fd
DG
1806 */
1807int lttng_list_syscalls(struct lttng_event **events)
1808{
28ab034a
JG
1809 enum lttng_error_code ret_code;
1810 int ret, total_payload_received;
cd9adb8b 1811 char *reception_buffer = nullptr;
28ab034a 1812 struct lttcomm_session_msg lsm = {};
cd9adb8b 1813 struct lttcomm_list_command_header *cmd_header = nullptr;
28ab034a
JG
1814 size_t cmd_header_len;
1815 uint32_t nb_events = 0;
1816
1817 if (!events) {
1818 ret = -LTTNG_ERR_INVALID;
1819 goto end;
1820 }
1821
1822 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_SYSCALLS;
1823 /* Force kernel domain for system calls. */
1824 lsm.domain.type = LTTNG_DOMAIN_KERNEL;
1825
1826 ret = lttng_ctl_ask_sessiond_fds_varlen(&lsm,
cd9adb8b 1827 nullptr,
28ab034a 1828 0,
cd9adb8b 1829 nullptr,
28ab034a
JG
1830 0,
1831 (void **) &reception_buffer,
1832 (void **) &cmd_header,
1833 &cmd_header_len);
1834 if (ret < 0) {
1835 goto end;
1836 }
1837 total_payload_received = ret;
1838
1839 if (!cmd_header) {
1840 ret = -LTTNG_ERR_UNK;
1841 goto end;
1842 }
1843
1844 if (cmd_header->count > INT_MAX) {
1845 ret = -LTTNG_ERR_OVERFLOW;
1846 goto end;
1847 }
1848
1849 nb_events = (unsigned int) cmd_header->count;
1850
1851 {
1852 const struct lttng_buffer_view events_view =
1853 lttng_buffer_view_init(reception_buffer, 0, total_payload_received);
8ddd72ef 1854 struct lttng_payload_view events_payload_view =
28ab034a 1855 lttng_payload_view_from_buffer_view(&events_view, 0, -1);
8ddd72ef 1856
28ab034a
JG
1857 ret_code = lttng_events_create_and_flatten_from_payload(
1858 &events_payload_view, nb_events, events);
1859 if (ret_code != LTTNG_OK) {
1860 ret = -ret_code;
1861 goto end;
1862 }
1863 }
8ddd72ef 1864
28ab034a 1865 ret = (int) nb_events;
834978fd 1866
8ddd72ef 1867end:
28ab034a
JG
1868 free(reception_buffer);
1869 free(cmd_header);
1870 return ret;
834978fd
DG
1871}
1872
1657e9bb 1873/*
9ae110e2 1874 * Returns a human readable string describing
8346beb6 1875 * the error code (positive or negative value).
1657e9bb 1876 */
9a745bc7 1877const char *lttng_strerror(int code)
1657e9bb 1878{
8346beb6
PP
1879 if (code > 0) {
1880 code = -code;
1881 }
1882
f73fabfd 1883 return error_get_str(code);
1657e9bb
DG
1884}
1885
28ab034a 1886enum lttng_error_code lttng_create_session_ext(struct lttng_session_descriptor *session_descriptor)
b178f53e
JG
1887{
1888 enum lttng_error_code ret_code;
1889 struct lttcomm_session_msg lsm = {
37a5ef39 1890 .cmd_type = LTTCOMM_SESSIOND_COMMAND_CREATE_SESSION_EXT,
1c9a0b0e
MJ
1891 .session = {},
1892 .domain = {},
1893 .u = {},
1894 .fd_count = 0,
b178f53e 1895 };
cd9adb8b 1896 void *reply = nullptr;
b178f53e
JG
1897 struct lttng_buffer_view reply_view;
1898 int reply_ret;
1899 bool sessiond_must_generate_ouput;
1900 struct lttng_dynamic_buffer payload;
1901 int ret;
1902 size_t descriptor_size;
cd9adb8b 1903 struct lttng_session_descriptor *descriptor_reply = nullptr;
b178f53e
JG
1904
1905 lttng_dynamic_buffer_init(&payload);
1906 if (!session_descriptor) {
1907 ret_code = LTTNG_ERR_INVALID;
1908 goto end;
1909 }
1910
1911 sessiond_must_generate_ouput =
28ab034a 1912 !lttng_session_descriptor_is_output_destination_initialized(session_descriptor);
b178f53e
JG
1913 if (sessiond_must_generate_ouput) {
1914 const char *home_dir = utils_get_home_dir();
1915 size_t home_dir_len = home_dir ? strlen(home_dir) + 1 : 0;
1916
1917 if (!home_dir || home_dir_len > LTTNG_PATH_MAX) {
1918 ret_code = LTTNG_ERR_FATAL;
1919 goto end;
1920 }
1921
1922 lsm.u.create_session.home_dir_size = (uint16_t) home_dir_len;
28ab034a 1923 ret = lttng_dynamic_buffer_append(&payload, home_dir, home_dir_len);
b178f53e
JG
1924 if (ret) {
1925 ret_code = LTTNG_ERR_NOMEM;
1926 goto end;
1927 }
1928 }
1929
1930 descriptor_size = payload.size;
28ab034a 1931 ret = lttng_session_descriptor_serialize(session_descriptor, &payload);
b178f53e
JG
1932 if (ret) {
1933 ret_code = LTTNG_ERR_INVALID;
1934 goto end;
1935 }
1936 descriptor_size = payload.size - descriptor_size;
1937 lsm.u.create_session.session_descriptor_size = descriptor_size;
1938
1939 /* Command returns a session descriptor on success. */
28ab034a
JG
1940 reply_ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(
1941 &lsm, payload.data, payload.size, &reply);
b178f53e 1942 if (reply_ret < 0) {
4bd69c5f 1943 ret_code = (lttng_error_code) -reply_ret;
b178f53e
JG
1944 goto end;
1945 } else if (reply_ret == 0) {
1946 /* Socket unexpectedly closed by the session daemon. */
1947 ret_code = LTTNG_ERR_FATAL;
1948 goto end;
1949 }
1950
4bd69c5f 1951 reply_view = lttng_buffer_view_init((const char *) reply, 0, reply_ret);
28ab034a 1952 ret = lttng_session_descriptor_create_from_buffer(&reply_view, &descriptor_reply);
b178f53e
JG
1953 if (ret < 0) {
1954 ret_code = LTTNG_ERR_FATAL;
1955 goto end;
1956 }
1957 ret_code = LTTNG_OK;
1958 lttng_session_descriptor_assign(session_descriptor, descriptor_reply);
1959end:
1960 free(reply);
1961 lttng_dynamic_buffer_reset(&payload);
1962 lttng_session_descriptor_destroy(descriptor_reply);
1963 return ret_code;
1964}
1965
aaf97519 1966/*
b178f53e 1967 * Create a new session using name and url for destination.
a4b92340 1968 *
780d4bb8 1969 * Return 0 on success else a negative LTTng error code.
00e2e675 1970 */
a4b92340 1971int lttng_create_session(const char *name, const char *url)
00e2e675 1972{
3dd05a85 1973 int ret;
a4b92340 1974 ssize_t size;
cd9adb8b
JG
1975 struct lttng_uri *uris = nullptr;
1976 struct lttng_session_descriptor *descriptor = nullptr;
b178f53e 1977 enum lttng_error_code ret_code;
00e2e675 1978
b178f53e
JG
1979 if (!name) {
1980 ret = -LTTNG_ERR_INVALID;
1981 goto end;
00e2e675
DG
1982 }
1983
cd9adb8b 1984 size = uri_parse_str_urls(url, nullptr, &uris);
a4b92340 1985 if (size < 0) {
b178f53e
JG
1986 ret = -LTTNG_ERR_INVALID;
1987 goto end;
1988 }
1989 switch (size) {
1990 case 0:
1991 descriptor = lttng_session_descriptor_create(name);
1992 break;
1993 case 1:
1994 if (uris[0].dtype != LTTNG_DST_PATH) {
1995 ret = -LTTNG_ERR_INVALID;
1996 goto end;
1997 }
28ab034a 1998 descriptor = lttng_session_descriptor_local_create(name, uris[0].dst.path);
b178f53e
JG
1999 break;
2000 case 2:
cd9adb8b 2001 descriptor = lttng_session_descriptor_network_create(name, url, nullptr);
b178f53e
JG
2002 break;
2003 default:
2004 ret = -LTTNG_ERR_INVALID;
2005 goto end;
2006 }
2007 if (!descriptor) {
2008 ret = -LTTNG_ERR_INVALID;
2009 goto end;
00e2e675 2010 }
b178f53e
JG
2011 ret_code = lttng_create_session_ext(descriptor);
2012 ret = ret_code == LTTNG_OK ? 0 : -ret_code;
2013end:
2014 lttng_session_descriptor_destroy(descriptor);
2015 free(uris);
2016 return ret;
2017}
00e2e675 2018
b178f53e
JG
2019/*
2020 * Create a session exclusively used for snapshot.
2021 *
780d4bb8 2022 * Return 0 on success else a negative LTTng error code.
b178f53e
JG
2023 */
2024int lttng_create_session_snapshot(const char *name, const char *snapshot_url)
2025{
2026 int ret;
2027 enum lttng_error_code ret_code;
2028 ssize_t size;
cd9adb8b
JG
2029 struct lttng_uri *uris = nullptr;
2030 struct lttng_session_descriptor *descriptor = nullptr;
a4b92340 2031
b178f53e
JG
2032 if (!name) {
2033 ret = -LTTNG_ERR_INVALID;
2034 goto end;
2035 }
2036
cd9adb8b 2037 size = uri_parse_str_urls(snapshot_url, nullptr, &uris);
b178f53e
JG
2038 if (size < 0) {
2039 ret = -LTTNG_ERR_INVALID;
2040 goto end;
2041 }
2042 /*
2043 * If the user does not specify a custom subdir, use the session name.
2044 */
28ab034a
JG
2045 if (size > 0 && uris[0].dtype != LTTNG_DST_PATH && strlen(uris[0].subdir) == 0) {
2046 ret = snprintf(uris[0].subdir, sizeof(uris[0].subdir), "%s", name);
b178f53e
JG
2047 if (ret < 0) {
2048 PERROR("Failed to set session name as network destination sub-directory");
2049 ret = -LTTNG_ERR_FATAL;
2050 goto end;
2051 } else if (ret >= sizeof(uris[0].subdir)) {
2052 /* Truncated output. */
2053 ret = -LTTNG_ERR_INVALID;
2054 goto end;
2055 }
2056 }
3dd05a85 2057
b178f53e
JG
2058 switch (size) {
2059 case 0:
2060 descriptor = lttng_session_descriptor_snapshot_create(name);
2061 break;
2062 case 1:
2063 if (uris[0].dtype != LTTNG_DST_PATH) {
2064 ret = -LTTNG_ERR_INVALID;
2065 goto end;
2066 }
28ab034a 2067 descriptor = lttng_session_descriptor_snapshot_local_create(name, uris[0].dst.path);
b178f53e
JG
2068 break;
2069 case 2:
cd9adb8b
JG
2070 descriptor = lttng_session_descriptor_snapshot_network_create(
2071 name, snapshot_url, nullptr);
b178f53e
JG
2072 break;
2073 default:
2074 ret = -LTTNG_ERR_INVALID;
2075 goto end;
2076 }
2077 if (!descriptor) {
2078 ret = -LTTNG_ERR_INVALID;
2079 goto end;
2080 }
2081 ret_code = lttng_create_session_ext(descriptor);
2082 ret = ret_code == LTTNG_OK ? 0 : -ret_code;
2083end:
2084 lttng_session_descriptor_destroy(descriptor);
3dd05a85
DG
2085 free(uris);
2086 return ret;
00e2e675
DG
2087}
2088
b178f53e
JG
2089/*
2090 * Create a session exclusively used for live.
2091 *
780d4bb8 2092 * Return 0 on success else a negative LTTng error code.
b178f53e 2093 */
28ab034a 2094int lttng_create_session_live(const char *name, const char *url, unsigned int timer_interval)
b178f53e
JG
2095{
2096 int ret;
2097 enum lttng_error_code ret_code;
cd9adb8b 2098 struct lttng_session_descriptor *descriptor = nullptr;
b178f53e
JG
2099
2100 if (!name) {
2101 ret = -LTTNG_ERR_INVALID;
2102 goto end;
2103 }
2104
2105 if (url) {
2106 descriptor = lttng_session_descriptor_live_network_create(
cd9adb8b 2107 name, url, nullptr, timer_interval);
b178f53e 2108 } else {
28ab034a 2109 descriptor = lttng_session_descriptor_live_create(name, timer_interval);
b178f53e
JG
2110 }
2111 if (!descriptor) {
2112 ret = -LTTNG_ERR_INVALID;
2113 goto end;
2114 }
2115 ret_code = lttng_create_session_ext(descriptor);
2116 ret = ret_code == LTTNG_OK ? 0 : -ret_code;
2117end:
2118 lttng_session_descriptor_destroy(descriptor);
2119 return ret;
2120}
2121
e20ee7c2
JD
2122/*
2123 * Stop the session and wait for the data before destroying it
780d4bb8
MD
2124 *
2125 * Return 0 on success else a negative LTTng error code.
e20ee7c2
JD
2126 */
2127int lttng_destroy_session(const char *session_name)
2128{
2129 int ret;
3e3665b8
JG
2130 enum lttng_error_code ret_code;
2131 enum lttng_destruction_handle_status status;
cd9adb8b 2132 struct lttng_destruction_handle *handle = nullptr;
e20ee7c2
JD
2133
2134 /*
3e3665b8
JG
2135 * Stop the tracing and wait for the data to be
2136 * consumed.
e20ee7c2
JD
2137 */
2138 ret = _lttng_stop_tracing(session_name, 1);
2139 if (ret && ret != -LTTNG_ERR_TRACE_ALREADY_STOPPED) {
2140 goto end;
2141 }
2142
3e3665b8
JG
2143 ret_code = lttng_destroy_session_ext(session_name, &handle);
2144 if (ret_code != LTTNG_OK) {
2145 ret = (int) -ret_code;
2146 goto end;
2147 }
a0377dfe 2148 LTTNG_ASSERT(handle);
3e3665b8
JG
2149
2150 /* Block until the completion of the destruction of the session. */
2151 status = lttng_destruction_handle_wait_for_completion(handle, -1);
2152 if (status != LTTNG_DESTRUCTION_HANDLE_STATUS_COMPLETED) {
2153 ret = -LTTNG_ERR_UNK;
2154 goto end;
2155 }
2156
2157 status = lttng_destruction_handle_get_result(handle, &ret_code);
2158 if (status != LTTNG_DESTRUCTION_HANDLE_STATUS_OK) {
2159 ret = -LTTNG_ERR_UNK;
2160 goto end;
2161 }
780d4bb8 2162 ret = ret_code == LTTNG_OK ? 0 : -ret_code;
e20ee7c2 2163end:
3e3665b8 2164 lttng_destruction_handle_destroy(handle);
e20ee7c2
JD
2165 return ret;
2166}
2167
2168/*
2169 * Destroy the session without waiting for the data.
2170 */
2171int lttng_destroy_session_no_wait(const char *session_name)
2172{
3e3665b8 2173 enum lttng_error_code ret_code;
e20ee7c2 2174
cd9adb8b 2175 ret_code = lttng_destroy_session_ext(session_name, nullptr);
3204017e 2176 return ret_code == LTTNG_OK ? 0 : -ret_code;
e20ee7c2
JD
2177}
2178
57167058 2179/*
9ae110e2
JG
2180 * Ask the session daemon for all available sessions.
2181 * Sets the contents of the sessions array.
2182 * Returns the number of lttng_session entries in sessions;
2183 * on error, returns a negative value.
57167058 2184 */
b178f53e 2185int lttng_list_sessions(struct lttng_session **out_sessions)
57167058 2186{
ca95a216 2187 int ret;
cd80958d 2188 struct lttcomm_session_msg lsm;
28ab034a
JG
2189 const size_t session_size =
2190 sizeof(struct lttng_session) + sizeof(struct lttng_session_extended);
b178f53e
JG
2191 size_t session_count, i;
2192 struct lttng_session_extended *sessions_extended_begin;
cd9adb8b 2193 struct lttng_session *sessions = nullptr;
57167058 2194
53efb85a 2195 memset(&lsm, 0, sizeof(lsm));
37a5ef39 2196 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_SESSIONS;
985aea18
MD
2197 /*
2198 * Initialize out_sessions to NULL so it is initialized when
2199 * lttng_list_sessions returns 0, thus allowing *out_sessions to
2200 * be subsequently freed.
2201 */
cd9adb8b 2202 *out_sessions = nullptr;
28ab034a 2203 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &sessions);
b178f53e 2204 if (ret <= 0) {
b178f53e
JG
2205 goto end;
2206 }
2207 if (!sessions) {
2208 ret = -LTTNG_ERR_FATAL;
2209 goto end;
2210 }
2211
2212 if (ret % session_size) {
2213 ret = -LTTNG_ERR_UNK;
2214 free(sessions);
b178f53e 2215 goto end;
57167058 2216 }
b178f53e 2217 session_count = (size_t) ret / session_size;
28ab034a 2218 sessions_extended_begin = (struct lttng_session_extended *) (&sessions[session_count]);
57167058 2219
b178f53e
JG
2220 /* Set extended session info pointers. */
2221 for (i = 0; i < session_count; i++) {
2222 struct lttng_session *session = &sessions[i];
28ab034a 2223 struct lttng_session_extended *extended = &(sessions_extended_begin[i]);
b178f53e
JG
2224
2225 session->extended.ptr = extended;
2226 }
2227
2228 ret = (int) session_count;
2229 *out_sessions = sessions;
2230end:
2231 return ret;
2232}
2233
28ab034a
JG
2234enum lttng_error_code lttng_session_get_creation_time(const struct lttng_session *session,
2235 uint64_t *creation_time)
b178f53e
JG
2236{
2237 enum lttng_error_code ret = LTTNG_OK;
2238 struct lttng_session_extended *extended;
2239
2240 if (!session || !creation_time || !session->extended.ptr) {
2241 ret = LTTNG_ERR_INVALID;
2242 goto end;
2243 }
2244
4bd69c5f 2245 extended = (lttng_session_extended *) session->extended.ptr;
b178f53e
JG
2246 if (!extended->creation_time.is_set) {
2247 /* Not created on the session daemon yet. */
2248 ret = LTTNG_ERR_SESSION_NOT_EXIST;
2249 goto end;
2250 }
2251 *creation_time = extended->creation_time.value;
2252end:
2253 return ret;
57167058
DG
2254}
2255
28ab034a 2256int lttng_set_session_shm_path(const char *session_name, const char *shm_path)
d7ba1388 2257{
e1b624d0 2258 int ret;
d7ba1388
MD
2259 struct lttcomm_session_msg lsm;
2260
cd9adb8b 2261 if (session_name == nullptr) {
d7ba1388
MD
2262 return -LTTNG_ERR_INVALID;
2263 }
2264
2265 memset(&lsm, 0, sizeof(lsm));
37a5ef39 2266 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_SET_SESSION_SHM_PATH;
d7ba1388 2267
28ab034a 2268 ret = lttng_strncpy(lsm.session.name, session_name, sizeof(lsm.session.name));
e1b624d0
JG
2269 if (ret) {
2270 ret = -LTTNG_ERR_INVALID;
2271 goto end;
2272 }
2273
28ab034a
JG
2274 ret = lttng_strncpy(
2275 lsm.u.set_shm_path.shm_path, shm_path ?: "", sizeof(lsm.u.set_shm_path.shm_path));
e1b624d0
JG
2276 if (ret) {
2277 ret = -LTTNG_ERR_INVALID;
2278 goto end;
2279 }
d7ba1388 2280
cd9adb8b 2281 ret = lttng_ctl_ask_sessiond(&lsm, nullptr);
e1b624d0
JG
2282end:
2283 return ret;
d7ba1388
MD
2284}
2285
9f19cc17 2286/*
9ae110e2
JG
2287 * Ask the session daemon for all available domains of a session.
2288 * Sets the contents of the domains array.
2289 * Returns the number of lttng_domain entries in domains;
2290 * on error, returns a negative value.
9f19cc17 2291 */
28ab034a 2292int lttng_list_domains(const char *session_name, struct lttng_domain **domains)
9f19cc17
DG
2293{
2294 int ret;
cd80958d
DG
2295 struct lttcomm_session_msg lsm;
2296
cd9adb8b 2297 if (session_name == nullptr) {
e1b624d0
JG
2298 ret = -LTTNG_ERR_INVALID;
2299 goto error;
cd80958d 2300 }
9f19cc17 2301
53efb85a 2302 memset(&lsm, 0, sizeof(lsm));
37a5ef39 2303 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_DOMAINS;
cd80958d 2304
28ab034a 2305 ret = lttng_strncpy(lsm.session.name, session_name, sizeof(lsm.session.name));
e1b624d0
JG
2306 if (ret) {
2307 ret = -LTTNG_ERR_INVALID;
2308 goto error;
2309 }
cd80958d 2310
28ab034a 2311 ret = lttng_ctl_ask_sessiond(&lsm, (void **) domains);
9f19cc17 2312 if (ret < 0) {
e1b624d0 2313 goto error;
9f19cc17
DG
2314 }
2315
2316 return ret / sizeof(struct lttng_domain);
e1b624d0
JG
2317error:
2318 return ret;
9f19cc17
DG
2319}
2320
2321/*
9ae110e2
JG
2322 * Ask the session daemon for all available channels of a session.
2323 * Sets the contents of the channels array.
2324 * Returns the number of lttng_channel entries in channels;
2325 * on error, returns a negative value.
9f19cc17 2326 */
28ab034a 2327int lttng_list_channels(struct lttng_handle *handle, struct lttng_channel **channels)
9f19cc17 2328{
999af9c1 2329 int ret, total_payload_received;
cd80958d 2330 struct lttcomm_session_msg lsm;
cd9adb8b 2331 char *reception_buffer = nullptr;
999af9c1 2332 size_t cmd_header_len = 0;
cd9adb8b 2333 struct lttcomm_list_command_header *cmd_header = nullptr;
999af9c1
JR
2334 struct lttng_dynamic_buffer tmp_buffer;
2335
2336 lttng_dynamic_buffer_init(&tmp_buffer);
cd80958d 2337
cd9adb8b 2338 if (handle == nullptr) {
53e367f9
JG
2339 ret = -LTTNG_ERR_INVALID;
2340 goto end;
cd80958d
DG
2341 }
2342
53efb85a 2343 memset(&lsm, 0, sizeof(lsm));
37a5ef39 2344 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_CHANNELS;
28ab034a 2345 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
e1b624d0
JG
2346 if (ret) {
2347 ret = -LTTNG_ERR_INVALID;
2348 goto end;
2349 }
9f19cc17 2350
60160d2a 2351 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
9f19cc17 2352
28ab034a 2353 ret = lttng_ctl_ask_sessiond_fds_varlen(&lsm,
cd9adb8b 2354 nullptr,
28ab034a 2355 0,
cd9adb8b 2356 nullptr,
28ab034a
JG
2357 0,
2358 (void **) &reception_buffer,
2359 (void **) &cmd_header,
2360 &cmd_header_len);
9f19cc17 2361 if (ret < 0) {
53e367f9
JG
2362 goto end;
2363 }
2364
999af9c1
JR
2365 total_payload_received = ret;
2366
2367 if (cmd_header_len != sizeof(*cmd_header)) {
2368 ret = -LTTNG_ERR_FATAL;
53e367f9 2369 goto end;
9f19cc17
DG
2370 }
2371
999af9c1
JR
2372 if (!cmd_header) {
2373 ret = LTTNG_ERR_UNK;
2374 goto end;
2375 }
2376
2377 if (cmd_header->count > INT_MAX) {
2378 ret = -LTTNG_ERR_OVERFLOW;
2379 goto end;
2380 }
53e367f9 2381
999af9c1
JR
2382 {
2383 enum lttng_error_code ret_code;
2384 const struct lttng_buffer_view events_view =
28ab034a 2385 lttng_buffer_view_init(reception_buffer, 0, total_payload_received);
999af9c1
JR
2386
2387 ret_code = lttng_channels_create_and_flatten_from_buffer(
28ab034a 2388 &events_view, cmd_header->count, channels);
999af9c1
JR
2389 if (ret_code != LTTNG_OK) {
2390 ret = -ret_code;
2391 goto end;
2392 }
53e367f9
JG
2393 }
2394
999af9c1 2395 ret = (int) cmd_header->count;
53e367f9 2396end:
999af9c1
JR
2397 free(cmd_header);
2398 free(reception_buffer);
53e367f9 2399 return ret;
9f19cc17
DG
2400}
2401
2402/*
9ae110e2
JG
2403 * Ask the session daemon for all available events of a session channel.
2404 * Sets the contents of the events array.
2405 * Returns the number of lttng_event entries in events;
2406 * on error, returns a negative value.
9f19cc17 2407 */
cd80958d 2408int lttng_list_events(struct lttng_handle *handle,
28ab034a
JG
2409 const char *channel_name,
2410 struct lttng_event **events)
9f19cc17
DG
2411{
2412 int ret;
e368fb43 2413 struct lttcomm_session_msg lsm = {};
8ddd72ef 2414 struct lttng_payload reply;
e368fb43 2415 struct lttng_payload_view lsm_view =
28ab034a 2416 lttng_payload_view_init_from_buffer((const char *) &lsm, 0, sizeof(lsm));
8ddd72ef 2417 unsigned int nb_events = 0;
9f19cc17 2418
821a8b53
JR
2419 lttng_payload_init(&reply);
2420
8ddd72ef 2421 /* Safety check. An handle and channel name are mandatory. */
cd9adb8b 2422 if (handle == nullptr || channel_name == nullptr) {
e368fb43
JG
2423 ret = -LTTNG_ERR_INVALID;
2424 goto end;
cd80958d
DG
2425 }
2426
8ddd72ef 2427 /* Initialize command parameters. */
37a5ef39 2428 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_EVENTS;
28ab034a 2429 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
e1b624d0
JG
2430 if (ret) {
2431 ret = -LTTNG_ERR_INVALID;
2432 goto end;
2433 }
2434
28ab034a 2435 ret = lttng_strncpy(lsm.u.list.channel_name, channel_name, sizeof(lsm.u.list.channel_name));
e1b624d0
JG
2436 if (ret) {
2437 ret = -LTTNG_ERR_INVALID;
2438 goto end;
2439 }
2440
60160d2a 2441 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
9f19cc17 2442
8ddd72ef
JR
2443 /* Execute command against the session daemon. */
2444 ret = lttng_ctl_ask_sessiond_payload(&lsm_view, &reply);
9f19cc17 2445 if (ret < 0) {
de453daa 2446 goto end;
9f19cc17
DG
2447 }
2448
e368fb43 2449 {
cd9adb8b 2450 const struct lttcomm_list_command_header *cmd_reply_header = nullptr;
8ddd72ef 2451 const lttng_payload_view cmd_reply_header_view =
28ab034a 2452 lttng_payload_view_from_payload(&reply, 0, sizeof(*cmd_reply_header));
8ddd72ef
JR
2453
2454 if (!lttng_payload_view_is_valid(&cmd_reply_header_view)) {
2455 ret = -LTTNG_ERR_INVALID_PROTOCOL;
2456 goto end;
56f0bc67 2457 }
b4e3ceb9 2458
8ddd72ef 2459 cmd_reply_header = (const struct lttcomm_list_command_header *)
28ab034a 2460 cmd_reply_header_view.buffer.data;
8ddd72ef
JR
2461 if (cmd_reply_header->count > INT_MAX) {
2462 ret = -LTTNG_ERR_OVERFLOW;
2463 goto end;
2464 }
56f0bc67 2465
8ddd72ef 2466 nb_events = (unsigned int) cmd_reply_header->count;
56f0bc67 2467 }
de453daa 2468
e368fb43 2469 {
8ddd72ef
JR
2470 enum lttng_error_code ret_code;
2471 lttng_payload_view cmd_reply_payload = lttng_payload_view_from_payload(
28ab034a 2472 &reply, sizeof(struct lttcomm_list_command_header), -1);
56f0bc67 2473
8ddd72ef 2474 ret_code = lttng_events_create_and_flatten_from_payload(
28ab034a 2475 &cmd_reply_payload, nb_events, events);
8ddd72ef
JR
2476 if (ret_code != LTTNG_OK) {
2477 ret = -((int) ret_code);
2478 goto end;
56f0bc67 2479 }
de453daa
JG
2480 }
2481
de453daa
JG
2482 ret = (int) nb_events;
2483end:
8ddd72ef 2484 lttng_payload_reset(&reply);
b4e3ceb9 2485 return ret;
9f19cc17
DG
2486}
2487
fac6795d 2488/*
1c8d13c8
TD
2489 * Sets the tracing_group variable with name.
2490 * This function allocates memory pointed to by tracing_group.
2491 * On success, returns 0, on error, returns -1 (null name) or -ENOMEM.
fac6795d
DG
2492 */
2493int lttng_set_tracing_group(const char *name)
2494{
e32a3d0f 2495 int ret = 0;
76da29b6 2496 char *new_group;
e32a3d0f 2497
cd9adb8b 2498 if (name == nullptr) {
e32a3d0f
JG
2499 ret = -LTTNG_ERR_INVALID;
2500 goto end;
9d697d3d
DG
2501 }
2502
e32a3d0f
JG
2503 new_group = strdup(name);
2504 if (!new_group) {
2505 ret = -LTTNG_ERR_FATAL;
2506 goto end;
fac6795d
DG
2507 }
2508
76da29b6
JR
2509 free(tracing_group);
2510 tracing_group = new_group;
cd9adb8b 2511 new_group = nullptr;
76da29b6 2512
e32a3d0f
JG
2513end:
2514 return ret;
fac6795d
DG
2515}
2516
f46376a1 2517int lttng_calibrate(struct lttng_handle *handle __attribute__((unused)),
28ab034a 2518 struct lttng_calibrate *calibrate __attribute__((unused)))
d0254c7c 2519{
b812e5ca
PP
2520 /*
2521 * This command was removed in LTTng 2.9.
2522 */
2523 return -LTTNG_ERR_UND;
d0254c7c
MD
2524}
2525
5edd7e09
DG
2526/*
2527 * Set default channel attributes.
441c16a7 2528 * If either or both of the arguments are null, attr content is zeroe'd.
5edd7e09 2529 */
28ab034a 2530void lttng_channel_set_default_attr(struct lttng_domain *domain, struct lttng_channel_attr *attr)
5edd7e09 2531{
294851b0 2532 struct lttng_channel_extended *extended;
cf0bcb51 2533
5edd7e09 2534 /* Safety check */
cd9adb8b 2535 if (attr == nullptr || domain == nullptr) {
5edd7e09
DG
2536 return;
2537 }
2538
999af9c1 2539 /* Save the pointer for later use */
294851b0 2540 extended = (struct lttng_channel_extended *) attr->extended.ptr;
eacaa7a6
DS
2541 memset(attr, 0, sizeof(struct lttng_channel_attr));
2542
0a9c6494
DG
2543 /* Same for all domains. */
2544 attr->overwrite = DEFAULT_CHANNEL_OVERWRITE;
2545 attr->tracefile_size = DEFAULT_CHANNEL_TRACEFILE_SIZE;
2546 attr->tracefile_count = DEFAULT_CHANNEL_TRACEFILE_COUNT;
2547
5edd7e09
DG
2548 switch (domain->type) {
2549 case LTTNG_DOMAIN_KERNEL:
28ab034a 2550 attr->switch_timer_interval = DEFAULT_KERNEL_CHANNEL_SWITCH_TIMER;
d92ff3ef 2551 attr->read_timer_interval = DEFAULT_KERNEL_CHANNEL_READ_TIMER;
3e230f92 2552 attr->subbuf_size = default_get_kernel_channel_subbuf_size();
5edd7e09
DG
2553 attr->num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM;
2554 attr->output = DEFAULT_KERNEL_CHANNEL_OUTPUT;
2555 break;
2556 case LTTNG_DOMAIN_UST:
0a9c6494
DG
2557 switch (domain->buf_type) {
2558 case LTTNG_BUFFER_PER_UID:
2559 attr->subbuf_size = default_get_ust_uid_channel_subbuf_size();
2560 attr->num_subbuf = DEFAULT_UST_UID_CHANNEL_SUBBUF_NUM;
2561 attr->output = DEFAULT_UST_UID_CHANNEL_OUTPUT;
28ab034a
JG
2562 attr->switch_timer_interval = DEFAULT_UST_UID_CHANNEL_SWITCH_TIMER;
2563 attr->read_timer_interval = DEFAULT_UST_UID_CHANNEL_READ_TIMER;
0a9c6494
DG
2564 break;
2565 case LTTNG_BUFFER_PER_PID:
2566 default:
2567 attr->subbuf_size = default_get_ust_pid_channel_subbuf_size();
2568 attr->num_subbuf = DEFAULT_UST_PID_CHANNEL_SUBBUF_NUM;
2569 attr->output = DEFAULT_UST_PID_CHANNEL_OUTPUT;
28ab034a
JG
2570 attr->switch_timer_interval = DEFAULT_UST_PID_CHANNEL_SWITCH_TIMER;
2571 attr->read_timer_interval = DEFAULT_UST_PID_CHANNEL_READ_TIMER;
0a9c6494
DG
2572 break;
2573 }
5edd7e09 2574 default:
441c16a7 2575 /* Default behavior: leave set to 0. */
5edd7e09
DG
2576 break;
2577 }
cf0bcb51 2578
999af9c1
JR
2579 if (extended) {
2580 lttng_channel_set_default_extended_attr(domain, extended);
2581 }
2582
2583 /* Reassign the extended pointer. */
cf0bcb51 2584 attr->extended.ptr = extended;
5edd7e09
DG
2585}
2586
5ba3702f 2587int lttng_channel_get_discarded_event_count(struct lttng_channel *channel,
28ab034a 2588 uint64_t *discarded_events)
5ba3702f
JG
2589{
2590 int ret = 0;
cf0bcb51 2591 struct lttng_channel_extended *chan_ext;
5ba3702f
JG
2592
2593 if (!channel || !discarded_events) {
2594 ret = -LTTNG_ERR_INVALID;
2595 goto end;
2596 }
2597
4bd69c5f 2598 chan_ext = (lttng_channel_extended *) channel->attr.extended.ptr;
5ba3702f
JG
2599 if (!chan_ext) {
2600 /*
2601 * This can happen since the lttng_channel structure is
2602 * used for other tasks where this pointer is never set.
2603 */
2604 *discarded_events = 0;
2605 goto end;
2606 }
2607
2608 *discarded_events = chan_ext->discarded_events;
2609end:
2610 return ret;
2611}
2612
28ab034a 2613int lttng_channel_get_lost_packet_count(struct lttng_channel *channel, uint64_t *lost_packets)
5ba3702f
JG
2614{
2615 int ret = 0;
cf0bcb51 2616 struct lttng_channel_extended *chan_ext;
5ba3702f
JG
2617
2618 if (!channel || !lost_packets) {
2619 ret = -LTTNG_ERR_INVALID;
2620 goto end;
2621 }
2622
4bd69c5f 2623 chan_ext = (lttng_channel_extended *) channel->attr.extended.ptr;
5ba3702f
JG
2624 if (!chan_ext) {
2625 /*
2626 * This can happen since the lttng_channel structure is
2627 * used for other tasks where this pointer is never set.
2628 */
2629 *lost_packets = 0;
2630 goto end;
2631 }
2632
2633 *lost_packets = chan_ext->lost_packets;
2634end:
2635 return ret;
2636}
2637
cf0bcb51 2638int lttng_channel_get_monitor_timer_interval(struct lttng_channel *chan,
28ab034a 2639 uint64_t *monitor_timer_interval)
cf0bcb51
JG
2640{
2641 int ret = 0;
2642
2643 if (!chan || !monitor_timer_interval) {
2644 ret = -LTTNG_ERR_INVALID;
2645 goto end;
2646 }
2647
2648 if (!chan->attr.extended.ptr) {
2649 ret = -LTTNG_ERR_INVALID;
2650 goto end;
2651 }
2652
28ab034a
JG
2653 *monitor_timer_interval =
2654 ((struct lttng_channel_extended *) chan->attr.extended.ptr)->monitor_timer_interval;
cf0bcb51
JG
2655end:
2656 return ret;
2657}
2658
2659int lttng_channel_set_monitor_timer_interval(struct lttng_channel *chan,
28ab034a 2660 uint64_t monitor_timer_interval)
cf0bcb51
JG
2661{
2662 int ret = 0;
2663
2664 if (!chan || !chan->attr.extended.ptr) {
2665 ret = -LTTNG_ERR_INVALID;
2666 goto end;
2667 }
2668
28ab034a
JG
2669 ((struct lttng_channel_extended *) chan->attr.extended.ptr)->monitor_timer_interval =
2670 monitor_timer_interval;
cf0bcb51
JG
2671end:
2672 return ret;
2673}
2674
28ab034a 2675int lttng_channel_get_blocking_timeout(struct lttng_channel *chan, int64_t *blocking_timeout)
491d1539
MD
2676{
2677 int ret = 0;
2678
2679 if (!chan || !blocking_timeout) {
2680 ret = -LTTNG_ERR_INVALID;
2681 goto end;
2682 }
2683
2684 if (!chan->attr.extended.ptr) {
2685 ret = -LTTNG_ERR_INVALID;
2686 goto end;
2687 }
2688
28ab034a
JG
2689 *blocking_timeout =
2690 ((struct lttng_channel_extended *) chan->attr.extended.ptr)->blocking_timeout;
491d1539
MD
2691end:
2692 return ret;
2693}
2694
28ab034a 2695int lttng_channel_set_blocking_timeout(struct lttng_channel *chan, int64_t blocking_timeout)
491d1539
MD
2696{
2697 int ret = 0;
2698 int64_t msec_timeout;
2699
2700 if (!chan || !chan->attr.extended.ptr) {
2701 ret = -LTTNG_ERR_INVALID;
2702 goto end;
2703 }
2704
2705 if (blocking_timeout < 0 && blocking_timeout != -1) {
2706 ret = -LTTNG_ERR_INVALID;
2707 goto end;
2708 }
2709
2710 /*
2711 * LTTng-ust's use of poll() to implement this timeout mechanism forces
2712 * us to accept a narrower range of values (msecs expressed as a signed
2713 * 32-bit integer).
2714 */
2715 msec_timeout = blocking_timeout / 1000;
2716 if (msec_timeout != (int32_t) msec_timeout) {
2717 ret = -LTTNG_ERR_INVALID;
2718 goto end;
2719 }
2720
28ab034a
JG
2721 ((struct lttng_channel_extended *) chan->attr.extended.ptr)->blocking_timeout =
2722 blocking_timeout;
491d1539
MD
2723end:
2724 return ret;
2725}
2726
fac6795d 2727/*
2269e89e 2728 * Check if session daemon is alive.
fac6795d 2729 *
2269e89e 2730 * Return 1 if alive or 0 if not.
1c8d13c8 2731 * On error returns a negative value.
fac6795d 2732 */
947308c4 2733int lttng_session_daemon_alive(void)
fac6795d
DG
2734{
2735 int ret;
2736
2737 ret = set_session_daemon_path();
2738 if (ret < 0) {
9ae110e2 2739 /* Error. */
fac6795d
DG
2740 return ret;
2741 }
2742
9d035200 2743 if (*sessiond_sock_path == '\0') {
2f70b271 2744 /*
9ae110e2
JG
2745 * No socket path set. Weird error which means the constructor
2746 * was not called.
2f70b271 2747 */
a0377dfe 2748 abort();
fac6795d
DG
2749 }
2750
2269e89e 2751 ret = try_connect_sessiond(sessiond_sock_path);
7d8234d9 2752 if (ret < 0) {
9ae110e2 2753 /* Not alive. */
7d8234d9
MD
2754 return 0;
2755 }
7d8234d9 2756
9ae110e2 2757 /* Is alive. */
947308c4 2758 return 1;
fac6795d
DG
2759}
2760
00e2e675 2761/*
a4b92340 2762 * Set URL for a consumer for a session and domain.
00e2e675
DG
2763 *
2764 * Return 0 on success, else a negative value.
2765 */
a4b92340 2766int lttng_set_consumer_url(struct lttng_handle *handle,
28ab034a
JG
2767 const char *control_url,
2768 const char *data_url)
00e2e675 2769{
3dd05a85 2770 int ret;
a4b92340 2771 ssize_t size;
00e2e675 2772 struct lttcomm_session_msg lsm;
cd9adb8b 2773 struct lttng_uri *uris = nullptr;
00e2e675 2774
cd9adb8b 2775 if (handle == nullptr || (control_url == nullptr && data_url == nullptr)) {
e1b624d0
JG
2776 ret = -LTTNG_ERR_INVALID;
2777 goto error;
00e2e675
DG
2778 }
2779
a4b92340
DG
2780 memset(&lsm, 0, sizeof(lsm));
2781
37a5ef39 2782 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_SET_CONSUMER_URI;
00e2e675 2783
28ab034a 2784 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
e1b624d0
JG
2785 if (ret) {
2786 ret = -LTTNG_ERR_INVALID;
2787 goto error;
2788 }
2789
60160d2a 2790 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
00e2e675 2791
bc894455 2792 size = uri_parse_str_urls(control_url, data_url, &uris);
a4b92340 2793 if (size < 0) {
e1b624d0
JG
2794 ret = -LTTNG_ERR_INVALID;
2795 goto error;
a4b92340
DG
2796 }
2797
2798 lsm.u.uri.size = size;
00e2e675 2799
28ab034a 2800 ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(
cd9adb8b 2801 &lsm, uris, sizeof(struct lttng_uri) * size, nullptr);
3dd05a85
DG
2802
2803 free(uris);
e1b624d0 2804error:
3dd05a85 2805 return ret;
00e2e675
DG
2806}
2807
2808/*
9c6bda17 2809 * [OBSOLETE]
00e2e675 2810 */
28ab034a 2811extern "C" LTTNG_EXPORT int lttng_enable_consumer(struct lttng_handle *handle);
f46376a1 2812int lttng_enable_consumer(struct lttng_handle *handle __attribute__((unused)))
00e2e675 2813{
785d2d0d 2814 return -ENOSYS;
00e2e675
DG
2815}
2816
2817/*
9c6bda17 2818 * [OBSOLETE]
00e2e675 2819 */
28ab034a 2820extern "C" LTTNG_EXPORT int lttng_disable_consumer(struct lttng_handle *handle);
f46376a1 2821int lttng_disable_consumer(struct lttng_handle *handle __attribute__((unused)))
00e2e675 2822{
785d2d0d 2823 return -ENOSYS;
00e2e675
DG
2824}
2825
07424f16 2826/*
b178f53e 2827 * [OBSOLETE]
07424f16 2828 */
28ab034a
JG
2829extern "C" LTTNG_EXPORT int
2830_lttng_create_session_ext(const char *name, const char *url, const char *datetime);
f46376a1 2831int _lttng_create_session_ext(const char *name __attribute__((unused)),
28ab034a
JG
2832 const char *url __attribute__((unused)),
2833 const char *datetime __attribute__((unused)))
07424f16 2834{
b178f53e 2835 return -ENOSYS;
07424f16
DG
2836}
2837
806e2684
DG
2838/*
2839 * For a given session name, this call checks if the data is ready to be read
2840 * or is still being extracted by the consumer(s) hence not ready to be used by
2841 * any readers.
2842 */
6d805429 2843int lttng_data_pending(const char *session_name)
806e2684
DG
2844{
2845 int ret;
2846 struct lttcomm_session_msg lsm;
cd9adb8b 2847 uint8_t *pending = nullptr;
806e2684 2848
cd9adb8b 2849 if (session_name == nullptr) {
806e2684
DG
2850 return -LTTNG_ERR_INVALID;
2851 }
2852
53efb85a 2853 memset(&lsm, 0, sizeof(lsm));
37a5ef39 2854 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_DATA_PENDING;
806e2684 2855
28ab034a 2856 ret = lttng_strncpy(lsm.session.name, session_name, sizeof(lsm.session.name));
e1b624d0
JG
2857 if (ret) {
2858 ret = -LTTNG_ERR_INVALID;
2859 goto end;
2860 }
806e2684 2861
f6151c55
JG
2862 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &pending);
2863 if (ret < 0) {
2864 goto end;
2865 } else if (ret != 1) {
2866 /* Unexpected payload size */
2867 ret = -LTTNG_ERR_INVALID;
2868 goto end;
e848d36d
JG
2869 } else if (!pending) {
2870 /* Internal error. */
2871 ret = -LTTNG_ERR_UNK;
2872 goto end;
806e2684
DG
2873 }
2874
f6151c55
JG
2875 ret = (int) *pending;
2876end:
2877 free(pending);
806e2684
DG
2878 return ret;
2879}
2880
49cddecd
KS
2881/*
2882 * Get the status of the kernel tracer
2883 *
2884 * Sets the value of the argument
2885 */
d93bbc2a 2886enum lttng_error_code lttng_get_kernel_tracer_status(enum lttng_kernel_tracer_status *out_status)
49cddecd 2887{
d93bbc2a 2888 if (out_status == nullptr) {
49cddecd
KS
2889 return LTTNG_ERR_INVALID;
2890 }
2891
2892 struct lttcomm_session_msg lsm = {};
2893 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_KERNEL_TRACER_STATUS;
2894
d93bbc2a
JG
2895 uint32_t *raw_tracer_status = nullptr;
2896 const auto ask_ret = lttng_ctl_ask_sessiond(&lsm, (void **) &raw_tracer_status);
2897
2898 const auto tracer_status =
303ac4ed 2899 lttng::make_unique_wrapper<uint32_t, lttng::memory::free>(raw_tracer_status);
d93bbc2a 2900
49cddecd 2901 if (ask_ret != 4) {
d93bbc2a 2902 return LTTNG_ERR_INVALID;
49cddecd
KS
2903 }
2904
d93bbc2a
JG
2905 *out_status = (enum lttng_kernel_tracer_status) * tracer_status;
2906 return LTTNG_OK;
49cddecd
KS
2907}
2908
93ec662e
JD
2909/*
2910 * Regenerate the metadata for a session.
2911 * Return 0 on success, a negative error code on error.
2912 */
eded6438 2913int lttng_regenerate_metadata(const char *session_name)
93ec662e
JD
2914{
2915 int ret;
2916 struct lttcomm_session_msg lsm;
2917
2918 if (!session_name) {
2919 ret = -LTTNG_ERR_INVALID;
2920 goto end;
2921 }
2922
2923 memset(&lsm, 0, sizeof(lsm));
37a5ef39 2924 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_REGENERATE_METADATA;
93ec662e 2925
28ab034a 2926 ret = lttng_strncpy(lsm.session.name, session_name, sizeof(lsm.session.name));
e1b624d0
JG
2927 if (ret) {
2928 ret = -LTTNG_ERR_INVALID;
2929 goto end;
2930 }
93ec662e 2931
cd9adb8b 2932 ret = lttng_ctl_ask_sessiond(&lsm, nullptr);
93ec662e
JD
2933 if (ret < 0) {
2934 goto end;
2935 }
2936
2937 ret = 0;
2938end:
2939 return ret;
2940}
2941
eded6438
JD
2942/*
2943 * Deprecated, replaced by lttng_regenerate_metadata.
2944 */
2945int lttng_metadata_regenerate(const char *session_name)
2946{
2947 return lttng_regenerate_metadata(session_name);
2948}
2949
c2561365
JD
2950/*
2951 * Regenerate the statedump of a session.
2952 * Return 0 on success, a negative error code on error.
2953 */
2954int lttng_regenerate_statedump(const char *session_name)
2955{
2956 int ret;
2957 struct lttcomm_session_msg lsm;
2958
2959 if (!session_name) {
2960 ret = -LTTNG_ERR_INVALID;
2961 goto end;
2962 }
2963
2964 memset(&lsm, 0, sizeof(lsm));
37a5ef39 2965 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_REGENERATE_STATEDUMP;
c2561365 2966
28ab034a 2967 ret = lttng_strncpy(lsm.session.name, session_name, sizeof(lsm.session.name));
e1b624d0
JG
2968 if (ret) {
2969 ret = -LTTNG_ERR_INVALID;
2970 goto end;
2971 }
c2561365 2972
cd9adb8b 2973 ret = lttng_ctl_ask_sessiond(&lsm, nullptr);
c2561365
JD
2974 if (ret < 0) {
2975 goto end;
2976 }
2977
2978 ret = 0;
2979end:
2980 return ret;
2981}
2982
28ab034a
JG
2983static int
2984_lttng_register_trigger(struct lttng_trigger *trigger, const char *name, bool generate_name)
a58c490f
JG
2985{
2986 int ret;
99608320 2987 struct lttcomm_session_msg lsm = {
37a5ef39 2988 .cmd_type = LTTCOMM_SESSIOND_COMMAND_REGISTER_TRIGGER,
1c9a0b0e
MJ
2989 .session = {},
2990 .domain = {},
2991 .u = {},
2992 .fd_count = 0,
99608320 2993 };
4bd69c5f 2994 lsm.u.trigger.is_trigger_anonymous = !name && !generate_name;
99608320
JR
2995 struct lttcomm_session_msg *message_lsm;
2996 struct lttng_payload message;
2997 struct lttng_payload reply;
cd9adb8b 2998 struct lttng_trigger *reply_trigger = nullptr;
9124c630 2999 enum lttng_domain_type domain_type;
64eafdf6
JR
3000 const struct lttng_credentials user_creds = {
3001 .uid = LTTNG_OPTIONAL_INIT_VALUE(geteuid()),
3002 .gid = LTTNG_OPTIONAL_INIT_UNSET,
3003 };
cd9adb8b 3004 const char *unused_trigger_name = nullptr;
a5c2d2a7 3005 enum lttng_trigger_status trigger_status;
99608320
JR
3006
3007 lttng_payload_init(&message);
3008 lttng_payload_init(&reply);
a58c490f
JG
3009
3010 if (!trigger) {
3011 ret = -LTTNG_ERR_INVALID;
3012 goto end;
3013 }
3014
a5c2d2a7
JG
3015 trigger_status = lttng_trigger_get_name(trigger, &unused_trigger_name);
3016 if (trigger_status != LTTNG_TRIGGER_STATUS_UNSET) {
3017 /* Re-using already registered trigger. */
3018 ret = -LTTNG_ERR_INVALID;
3019 goto end;
3020 }
3021
3022 if (name) {
3023 trigger_status = lttng_trigger_set_name(trigger, name);
3024 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
3025 ret = -LTTNG_ERR_NOMEM;
3026 goto end;
3027 }
3028 }
3029
64eafdf6
JR
3030 if (!trigger->creds.uid.is_set) {
3031 /* Use the client's credentials as the trigger credentials. */
3032 lttng_trigger_set_credentials(trigger, &user_creds);
3033 } else {
3034 /*
3035 * Validate that either the current trigger credentials and the
3036 * client credentials are identical or that the current user is
3037 * root. The root user can register, unregister triggers for
3038 * himself and other users.
3039 *
3040 * This check is also present on the sessiond side, using the
3041 * credentials passed on the socket. These check are all
3042 * "safety" checks.
3043 */
3044 const struct lttng_credentials *trigger_creds =
28ab034a 3045 lttng_trigger_get_credentials(trigger);
64eafdf6
JR
3046
3047 if (!lttng_credentials_is_equal_uid(trigger_creds, &user_creds)) {
3048 if (lttng_credentials_get_uid(&user_creds) != 0) {
3049 ret = -LTTNG_ERR_EPERM;
a5c2d2a7 3050 goto end_unset_name;
64eafdf6
JR
3051 }
3052 }
3053 }
3054
a58c490f 3055 if (!lttng_trigger_validate(trigger)) {
eac4828d 3056 ret = -LTTNG_ERR_INVALID_TRIGGER;
a5c2d2a7 3057 goto end_unset_name;
a58c490f
JG
3058 }
3059
28ab034a 3060 domain_type = lttng_trigger_get_underlying_domain_type_restriction(trigger);
9124c630
JR
3061
3062 lsm.domain.type = domain_type;
3063
97285430
JG
3064 ret = lttng_dynamic_buffer_append(&message.buffer, &lsm, sizeof(lsm));
3065 if (ret) {
3066 ret = -LTTNG_ERR_NOMEM;
a5c2d2a7 3067 goto end_unset_name;
97285430 3068 }
99608320 3069
99608320 3070 ret = lttng_trigger_serialize(trigger, &message);
3647288f 3071 if (ret < 0) {
a58c490f 3072 ret = -LTTNG_ERR_UNK;
a5c2d2a7 3073 goto end_unset_name;
a58c490f
JG
3074 }
3075
b22f4f54
JG
3076 /*
3077 * This is needed to populate the trigger object size for the command
3078 * header.
3079 */
3080 message_lsm = (struct lttcomm_session_msg *) message.buffer.data;
3081
99608320
JR
3082 message_lsm->u.trigger.length = (uint32_t) message.buffer.size - sizeof(lsm);
3083
3084 {
3085 struct lttng_payload_view message_view =
28ab034a 3086 lttng_payload_view_from_payload(&message, 0, -1);
99608320 3087
28ab034a 3088 message_lsm->fd_count = lttng_payload_view_get_fd_handle_count(&message_view);
99608320
JR
3089 ret = lttng_ctl_ask_sessiond_payload(&message_view, &reply);
3090 if (ret < 0) {
a5c2d2a7 3091 goto end_unset_name;
99608320
JR
3092 }
3093 }
3094
242388e4
JR
3095 {
3096 struct lttng_payload_view reply_view =
28ab034a 3097 lttng_payload_view_from_payload(&reply, 0, reply.buffer.size);
242388e4 3098
28ab034a 3099 ret = lttng_trigger_create_from_payload(&reply_view, &reply_trigger);
242388e4 3100 if (ret < 0) {
a5c2d2a7
JG
3101 ret = -LTTNG_ERR_INVALID_PROTOCOL;
3102 goto end_unset_name;
242388e4
JR
3103 }
3104 }
3105
a5c2d2a7
JG
3106 if (name || generate_name) {
3107 ret = lttng_trigger_assign_name(trigger, reply_trigger);
3108 if (ret < 0) {
3109 ret = -LTTNG_ERR_NOMEM;
3110 goto end;
3111 }
242388e4
JR
3112 }
3113
99608320 3114 ret = 0;
a5c2d2a7
JG
3115 goto end;
3116
3117end_unset_name:
cd9adb8b 3118 trigger_status = lttng_trigger_set_name(trigger, nullptr);
a5c2d2a7
JG
3119 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
3120 ret = -LTTNG_ERR_UNK;
3121 }
a58c490f 3122end:
99608320
JR
3123 lttng_payload_reset(&message);
3124 lttng_payload_reset(&reply);
242388e4 3125 lttng_trigger_destroy(reply_trigger);
a58c490f
JG
3126 return ret;
3127}
3128
a5c2d2a7
JG
3129int lttng_register_trigger(struct lttng_trigger *trigger)
3130{
3131 /* Register an anonymous trigger. */
cd9adb8b 3132 return _lttng_register_trigger(trigger, nullptr, false);
a5c2d2a7
JG
3133}
3134
28ab034a
JG
3135enum lttng_error_code lttng_register_trigger_with_name(struct lttng_trigger *trigger,
3136 const char *name)
a5c2d2a7
JG
3137{
3138 const int ret = _lttng_register_trigger(trigger, name, false);
3139
28ab034a 3140 return ret == 0 ? LTTNG_OK : (enum lttng_error_code) - ret;
a5c2d2a7
JG
3141}
3142
28ab034a 3143enum lttng_error_code lttng_register_trigger_with_automatic_name(struct lttng_trigger *trigger)
a5c2d2a7 3144{
28ab034a 3145 const int ret = _lttng_register_trigger(trigger, nullptr, true);
a5c2d2a7 3146
28ab034a 3147 return ret == 0 ? LTTNG_OK : (enum lttng_error_code) - ret;
a5c2d2a7
JG
3148}
3149
28ab034a
JG
3150enum lttng_error_code lttng_error_query_execute(const struct lttng_error_query *query,
3151 const struct lttng_endpoint *endpoint,
3152 struct lttng_error_query_results **results)
b99a0cb3
JG
3153{
3154 int ret;
3155 enum lttng_error_code ret_code;
3156 struct lttcomm_session_msg lsm = {
37a5ef39 3157 .cmd_type = LTTCOMM_SESSIOND_COMMAND_EXECUTE_ERROR_QUERY,
1c9a0b0e
MJ
3158 .session = {},
3159 .domain = {},
3160 .u = {},
3161 .fd_count = 0,
b99a0cb3
JG
3162 };
3163 struct lttng_payload message;
3164 struct lttng_payload reply;
3165 struct lttcomm_session_msg *message_lsm;
3166
3167 lttng_payload_init(&message);
3168 lttng_payload_init(&reply);
3169
3170 if (!query || !results) {
3171 ret_code = LTTNG_ERR_INVALID;
3172 goto end;
3173 }
3174
3175 if (endpoint != lttng_session_daemon_command_endpoint) {
3176 ret_code = LTTNG_ERR_INVALID_ERROR_QUERY_TARGET;
3177 goto end;
3178 }
3179
3180 ret = lttng_dynamic_buffer_append(&message.buffer, &lsm, sizeof(lsm));
3181 if (ret) {
3182 ret_code = LTTNG_ERR_NOMEM;
3183 goto end;
3184 }
3185
3186 ret = lttng_error_query_serialize(query, &message);
3187 if (ret) {
3188 ret_code = LTTNG_ERR_UNK;
3189 goto end;
3190 }
3191
3192 message_lsm = (struct lttcomm_session_msg *) message.buffer.data;
28ab034a 3193 message_lsm->u.error_query.length = (uint32_t) message.buffer.size - sizeof(lsm);
b99a0cb3
JG
3194
3195 {
3196 struct lttng_payload_view message_view =
28ab034a 3197 lttng_payload_view_from_payload(&message, 0, -1);
b99a0cb3 3198
28ab034a 3199 message_lsm->fd_count = lttng_payload_view_get_fd_handle_count(&message_view);
b99a0cb3
JG
3200 ret = lttng_ctl_ask_sessiond_payload(&message_view, &reply);
3201 if (ret < 0) {
28ab034a 3202 ret_code = (lttng_error_code) -ret;
b99a0cb3
JG
3203 goto end;
3204 }
3205 }
3206
3207 {
3208 ssize_t reply_create_ret;
3209 struct lttng_payload_view reply_view =
28ab034a 3210 lttng_payload_view_from_payload(&reply, 0, reply.buffer.size);
b99a0cb3 3211
28ab034a
JG
3212 reply_create_ret =
3213 lttng_error_query_results_create_from_payload(&reply_view, results);
b99a0cb3
JG
3214 if (reply_create_ret < 0) {
3215 ret_code = LTTNG_ERR_INVALID_PROTOCOL;
3216 goto end;
3217 }
3218 }
3219
3220 ret_code = LTTNG_OK;
3221end:
3222 lttng_payload_reset(&message);
3223 lttng_payload_reset(&reply);
3224 return ret_code;
3225}
3226
b61776fb 3227int lttng_unregister_trigger(const struct lttng_trigger *trigger)
a58c490f
JG
3228{
3229 int ret;
3230 struct lttcomm_session_msg lsm;
99608320
JR
3231 struct lttcomm_session_msg *message_lsm;
3232 struct lttng_payload message;
3233 struct lttng_payload reply;
cd9adb8b 3234 struct lttng_trigger *copy = nullptr;
64eafdf6
JR
3235 const struct lttng_credentials user_creds = {
3236 .uid = LTTNG_OPTIONAL_INIT_VALUE(geteuid()),
3237 .gid = LTTNG_OPTIONAL_INIT_UNSET,
3238 };
99608320
JR
3239
3240 lttng_payload_init(&message);
3241 lttng_payload_init(&reply);
a58c490f
JG
3242
3243 if (!trigger) {
3244 ret = -LTTNG_ERR_INVALID;
3245 goto end;
3246 }
3247
b61776fb
SM
3248 copy = lttng_trigger_copy(trigger);
3249 if (!copy) {
3250 ret = -LTTNG_ERR_UNK;
3251 goto end;
3252 }
3253
3254 if (!copy->creds.uid.is_set) {
3255 /* Use the client credentials as the trigger credentials */
3256 lttng_trigger_set_credentials(copy, &user_creds);
64eafdf6
JR
3257 } else {
3258 /*
3259 * Validate that either the current trigger credentials and the
3260 * client credentials are identical or that the current user is
3261 * root. The root user can register, unregister triggers for
3262 * himself and other users.
3263 *
3264 * This check is also present on the sessiond side, using the
3265 * credentials passed on the socket. These check are all
3266 * "safety" checks.
3267 */
28ab034a 3268 const struct lttng_credentials *trigger_creds = lttng_trigger_get_credentials(copy);
64eafdf6
JR
3269 if (!lttng_credentials_is_equal_uid(trigger_creds, &user_creds)) {
3270 if (lttng_credentials_get_uid(&user_creds) != 0) {
3271 ret = -LTTNG_ERR_EPERM;
3272 goto end;
3273 }
3274 }
3275 }
3276
b61776fb 3277 if (!lttng_trigger_validate(copy)) {
3647288f 3278 ret = -LTTNG_ERR_INVALID_TRIGGER;
a58c490f
JG
3279 goto end;
3280 }
3281
99608320 3282 memset(&lsm, 0, sizeof(lsm));
37a5ef39 3283 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_UNREGISTER_TRIGGER;
99608320 3284
97285430
JG
3285 ret = lttng_dynamic_buffer_append(&message.buffer, &lsm, sizeof(lsm));
3286 if (ret) {
3287 ret = -LTTNG_ERR_NOMEM;
3288 goto end;
3289 }
99608320 3290
b61776fb 3291 ret = lttng_trigger_serialize(copy, &message);
3647288f 3292 if (ret < 0) {
a58c490f
JG
3293 ret = -LTTNG_ERR_UNK;
3294 goto end;
3295 }
3296
b0a79813
FD
3297 /*
3298 * This is needed to populate the trigger object size for the command
3299 * header and number of fds sent.
28ab034a 3300 */
b0a79813
FD
3301 message_lsm = (struct lttcomm_session_msg *) message.buffer.data;
3302
99608320
JR
3303 message_lsm->u.trigger.length = (uint32_t) message.buffer.size - sizeof(lsm);
3304
3305 {
3306 struct lttng_payload_view message_view =
28ab034a 3307 lttng_payload_view_from_payload(&message, 0, -1);
99608320
JR
3308
3309 /*
3310 * Update the message header with the number of fd that will be
3311 * sent.
3312 */
28ab034a 3313 message_lsm->fd_count = lttng_payload_view_get_fd_handle_count(&message_view);
99608320
JR
3314
3315 ret = lttng_ctl_ask_sessiond_payload(&message_view, &reply);
3316 if (ret < 0) {
3317 goto end;
3318 }
3319 }
3320
3321 ret = 0;
a58c490f 3322end:
b61776fb 3323 lttng_trigger_destroy(copy);
99608320
JR
3324 lttng_payload_reset(&message);
3325 lttng_payload_reset(&reply);
a58c490f
JG
3326 return ret;
3327}
3328
fbc9f37d
JR
3329/*
3330 * Ask the session daemon for all registered triggers for the current user.
3331 *
3332 * Allocates and return an lttng_triggers set.
3333 * On error, returns a suitable lttng_error_code.
3334 */
3335enum lttng_error_code lttng_list_triggers(struct lttng_triggers **triggers)
3336{
3337 int ret;
3338 enum lttng_error_code ret_code = LTTNG_OK;
1c9a0b0e 3339 struct lttcomm_session_msg lsm = {
37a5ef39 3340 .cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_TRIGGERS,
1c9a0b0e
MJ
3341 .session = {},
3342 .domain = {},
3343 .u = {},
3344 .fd_count = 0,
3345 };
cd9adb8b 3346 struct lttng_triggers *local_triggers = nullptr;
fbc9f37d
JR
3347 struct lttng_payload reply;
3348 struct lttng_payload_view lsm_view =
28ab034a 3349 lttng_payload_view_init_from_buffer((const char *) &lsm, 0, sizeof(lsm));
fbc9f37d
JR
3350
3351 lttng_payload_init(&reply);
3352
3353 ret = lttng_ctl_ask_sessiond_payload(&lsm_view, &reply);
3354 if (ret < 0) {
28ab034a 3355 ret_code = (enum lttng_error_code) - ret;
fbc9f37d
JR
3356 goto end;
3357 }
3358
3359 {
3360 struct lttng_payload_view reply_view =
28ab034a 3361 lttng_payload_view_from_payload(&reply, 0, reply.buffer.size);
fbc9f37d 3362
28ab034a 3363 ret = lttng_triggers_create_from_payload(&reply_view, &local_triggers);
fbc9f37d
JR
3364 if (ret < 0) {
3365 ret_code = LTTNG_ERR_FATAL;
3366 goto end;
3367 }
3368 }
3369
3370 *triggers = local_triggers;
cd9adb8b 3371 local_triggers = nullptr;
fbc9f37d
JR
3372end:
3373 lttng_payload_reset(&reply);
3374 lttng_triggers_destroy(local_triggers);
3375 return ret_code;
3376}
3377
fac6795d 3378/*
9ae110e2 3379 * lib constructor.
fac6795d 3380 */
cd9adb8b 3381static void __attribute__((constructor)) init()
fac6795d
DG
3382{
3383 /* Set default session group */
bbccc3d2 3384 lttng_set_tracing_group(DEFAULT_TRACING_GROUP);
fac6795d 3385}
49cca668
DG
3386
3387/*
9ae110e2 3388 * lib destructor.
49cca668 3389 */
cd9adb8b 3390static void __attribute__((destructor)) lttng_ctl_exit()
49cca668
DG
3391{
3392 free(tracing_group);
3393}
This page took 0.293875 seconds and 5 git commands to generate.