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