Run clang-format on the whole tree
[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 */
6c71277b 247int lttng_check_tracing_group(void)
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 */
261 grp_list_size = getgroups(0, NULL);
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
DG
392 */
393static int set_session_daemon_path(void)
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 */
ca806b0b 454int connect_sessiond(void)
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
3e3665b8
JG
475static void reset_global_sessiond_connection_state(void)
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
DG
485 */
486static int disconnect_sessiond(void)
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;
64803277 501 char *buf = NULL;
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;
527 buf = NULL;
528 *user_len = len;
529 } else {
530 /* No command header. */
531 if (user_len) {
532 *user_len = 0;
533 }
534
535 if (user_buf) {
536 *user_buf = NULL;
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;
2f70b271
DG
727 struct lttng_handle *handle = NULL;
728
64803277 729 handle = zmalloc<lttng_handle>();
cd80958d 730 if (handle == NULL) {
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);
750 return NULL;
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
2f70b271 771 if (handle == NULL || socket_path == NULL) {
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
e1b624d0
JG
792 ret = lttng_ctl_ask_sessiond(&lsm, NULL);
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
6a4f824d 807 if (session_name == NULL) {
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
e1b624d0
JG
821 ret = lttng_ctl_ask_sessiond(&lsm, NULL);
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
6a4f824d 834 if (session_name == NULL) {
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
cac3069d 848 ret = lttng_ctl_ask_sessiond(&lsm, NULL);
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. */
9d697d3d 922 if (handle == NULL || ctx == NULL) {
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{
28ab034a 989 return lttng_enable_event_with_exclusions(handle, ev, channel_name, NULL, 0, NULL);
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
JG
1003 return lttng_enable_event_with_exclusions(
1004 handle, event, channel_name, filter_expression, 0, NULL);
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;
0e115563 1016 char *agent_filter = NULL;
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);
6a556f7b 1068 return NULL;
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;
93deb080 1096 struct filter_parser_ctx *ctx = NULL;
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
JI
1111
1112 if (handle == NULL || ev == NULL) {
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. */
28ab034a
JG
1134 if (filter_expression != NULL || handle->domain.type == LTTNG_DOMAIN_JUL ||
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,
1186 (ctx && bytecode_len) ? &ctx->bytecode->b : NULL,
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,
28ab034a
JG
1238 fd_count ? &fd_to_send : NULL,
1239 fd_count,
1240 view.buffer.size ? view.buffer.data : NULL,
1241 view.buffer.size,
1242 NULL,
1243 NULL,
1244 0);
e368fb43 1245 }
93deb080 1246
8ddd72ef 1247error:
7ca1dc6f 1248 if (filter_expression && ctx) {
93deb080
JI
1249 filter_bytecode_free(ctx);
1250 filter_ir_free(ctx);
1251 filter_parser_ctx_free(ctx);
7ca1dc6f 1252 }
7ca1dc6f
DG
1253 if (free_filter_expression) {
1254 /*
9ae110e2
JG
1255 * The filter expression has been replaced and must be freed as
1256 * it is not the original filter expression received as a
1257 * parameter.
7ca1dc6f
DG
1258 */
1259 free(filter_expression);
93deb080 1260 }
137b9942 1261 /*
9ae110e2
JG
1262 * Return directly to the caller and don't ask the sessiond since
1263 * something went wrong in the parsing of data above.
137b9942 1264 */
e368fb43 1265 lttng_payload_reset(&payload);
93deb080
JI
1266 return ret;
1267}
1268
6e911cad 1269int lttng_disable_event_ext(struct lttng_handle *handle,
28ab034a
JG
1270 struct lttng_event *ev,
1271 const char *channel_name,
1272 const char *original_filter_expression)
1df4dedd 1273{
1c9a0b0e 1274 struct lttcomm_session_msg lsm = {
37a5ef39 1275 .cmd_type = LTTCOMM_SESSIOND_COMMAND_DISABLE_EVENT,
1c9a0b0e
MJ
1276 .session = {},
1277 .domain = {},
1278 .u = {},
1279 .fd_count = 0,
1280 };
8ddd72ef 1281 struct lttng_payload payload;
6e911cad
MD
1282 int ret = 0;
1283 unsigned int free_filter_expression = 0;
1284 struct filter_parser_ctx *ctx = NULL;
8ddd72ef
JR
1285 size_t bytecode_len = 0;
1286
1287 /*
1288 * We have either a filter or some exclusions, so we need to set up
1289 * a variable-length payload from where to send the data.
1290 */
1291 lttng_payload_init(&payload);
1292
6e911cad
MD
1293 /*
1294 * Cast as non-const since we may replace the filter expression
1295 * by a dynamically allocated string. Otherwise, the original
1296 * string is not modified.
1297 */
1298 char *filter_expression = (char *) original_filter_expression;
1df4dedd 1299
6e911cad
MD
1300 if (handle == NULL || ev == NULL) {
1301 ret = -LTTNG_ERR_INVALID;
1302 goto error;
1303 }
1304
9ae110e2
JG
1305 /*
1306 * Empty filter string will always be rejected by the parser
6e911cad
MD
1307 * anyway, so treat this corner-case early to eliminate
1308 * lttng_fmemopen error for 0-byte allocation.
1309 */
1310 if (filter_expression && filter_expression[0] == '\0') {
1311 ret = -LTTNG_ERR_INVALID;
1312 goto error;
cd80958d
DG
1313 }
1314
8ddd72ef 1315 /* Parse filter expression. */
28ab034a
JG
1316 if (filter_expression != NULL || handle->domain.type == LTTNG_DOMAIN_JUL ||
1317 handle->domain.type == LTTNG_DOMAIN_LOG4J ||
1318 handle->domain.type == LTTNG_DOMAIN_PYTHON) {
6e911cad 1319 if (handle->domain.type == LTTNG_DOMAIN_JUL ||
28ab034a
JG
1320 handle->domain.type == LTTNG_DOMAIN_LOG4J ||
1321 handle->domain.type == LTTNG_DOMAIN_PYTHON) {
0e115563 1322 char *agent_filter;
6e911cad 1323
8ddd72ef 1324 /* Setup agent filter if needed. */
0e115563
DG
1325 agent_filter = set_agent_filter(filter_expression, ev);
1326 if (!agent_filter) {
6e911cad 1327 if (!filter_expression) {
9ae110e2
JG
1328 /*
1329 * No JUL and no filter, just skip
1330 * everything below.
1331 */
8ddd72ef 1332 goto serialize;
6e911cad
MD
1333 }
1334 } else {
1335 /*
8ddd72ef 1336 * With an agent filter, the original filter has
9ae110e2
JG
1337 * been added to it thus replace the filter
1338 * expression.
6e911cad 1339 */
0e115563 1340 filter_expression = agent_filter;
6e911cad
MD
1341 free_filter_expression = 1;
1342 }
1343 }
1344
28ab034a 1345 if (strnlen(filter_expression, LTTNG_FILTER_MAX_LEN) == LTTNG_FILTER_MAX_LEN) {
8ddd72ef
JR
1346 ret = -LTTNG_ERR_FILTER_INVAL;
1347 goto error;
1348 }
1349
e4d2f27a 1350 ret = filter_parser_ctx_create_from_filter_expression(filter_expression, &ctx);
6e911cad 1351 if (ret) {
8ddd72ef 1352 goto error;
6e911cad 1353 }
e4d2f27a 1354
28ab034a 1355 bytecode_len = bytecode_get_len(&ctx->bytecode->b) + sizeof(ctx->bytecode->b);
8ddd72ef
JR
1356 if (bytecode_len > LTTNG_FILTER_MAX_LEN) {
1357 ret = -LTTNG_ERR_FILTER_INVAL;
1358 goto error;
1359 }
6e911cad
MD
1360 }
1361
8ddd72ef 1362serialize:
28ab034a
JG
1363 ret = lttng_event_serialize(ev,
1364 0,
1365 NULL,
1366 filter_expression,
1367 bytecode_len,
1368 (ctx && bytecode_len) ? &ctx->bytecode->b : NULL,
1369 &payload);
8ddd72ef
JR
1370 if (ret) {
1371 ret = -LTTNG_ERR_INVALID;
1372 goto error;
6e911cad
MD
1373 }
1374
8ddd72ef 1375 /* If no channel name, send empty string. */
28ab034a
JG
1376 ret = lttng_strncpy(
1377 lsm.u.disable.channel_name, channel_name ?: "", sizeof(lsm.u.disable.channel_name));
8ddd72ef
JR
1378 if (ret) {
1379 ret = -LTTNG_ERR_INVALID;
1380 goto error;
6e911cad 1381 }
8ddd72ef
JR
1382
1383 /* Domain */
1384 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
1385
1386 /* Session name */
28ab034a 1387 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
8ddd72ef
JR
1388 if (ret) {
1389 ret = -LTTNG_ERR_INVALID;
1390 goto error;
6e911cad
MD
1391 }
1392
8ddd72ef
JR
1393 /* Length of the serialized event. */
1394 lsm.u.disable.length = (uint32_t) payload.buffer.size;
1395
1396 {
28ab034a 1397 struct lttng_payload_view view = lttng_payload_view_from_payload(&payload, 0, -1);
8ddd72ef
JR
1398 int fd_count = lttng_payload_view_get_fd_handle_count(&view);
1399 int fd_to_send;
1400
1401 if (fd_count < 0) {
1402 goto error;
1403 }
1404
1405 LTTNG_ASSERT(fd_count == 0 || fd_count == 1);
1406 if (fd_count == 1) {
28ab034a 1407 struct fd_handle *h = lttng_payload_view_pop_fd_handle(&view);
6e911cad 1408
8ddd72ef
JR
1409 if (!h) {
1410 goto error;
1411 }
1412
1413 fd_to_send = fd_handle_get_fd(h);
1414 fd_handle_put(h);
1415 }
1416
1417 ret = lttng_ctl_ask_sessiond_fds_varlen(&lsm,
28ab034a
JG
1418 fd_count ? &fd_to_send : NULL,
1419 fd_count,
1420 view.buffer.size ? view.buffer.data : NULL,
1421 view.buffer.size,
1422 NULL,
1423 NULL,
1424 0);
8ddd72ef
JR
1425 }
1426
1427error:
6e911cad
MD
1428 if (filter_expression && ctx) {
1429 filter_bytecode_free(ctx);
1430 filter_ir_free(ctx);
1431 filter_parser_ctx_free(ctx);
1432 }
6e911cad
MD
1433 if (free_filter_expression) {
1434 /*
9ae110e2
JG
1435 * The filter expression has been replaced and must be freed as
1436 * it is not the original filter expression received as a
1437 * parameter.
6e911cad
MD
1438 */
1439 free(filter_expression);
1440 }
6e911cad 1441 /*
9ae110e2
JG
1442 * Return directly to the caller and don't ask the sessiond since
1443 * something went wrong in the parsing of data above.
6e911cad 1444 */
8ddd72ef 1445 lttng_payload_reset(&payload);
6e911cad
MD
1446 return ret;
1447}
1448
1449/*
9ae110e2
JG
1450 * Disable event(s) of a channel and domain.
1451 * If no event name is specified, all events are disabled.
1452 * If no channel name is specified, the default 'channel0' is used.
1453 * Returns size of returned session payload data or a negative error code.
6e911cad 1454 */
28ab034a 1455int lttng_disable_event(struct lttng_handle *handle, const char *name, const char *channel_name)
6e911cad 1456{
e1b624d0 1457 int ret;
6e911cad
MD
1458 struct lttng_event ev;
1459
1460 memset(&ev, 0, sizeof(ev));
9b7431cf 1461 ev.loglevel = -1;
6e911cad 1462 ev.type = LTTNG_EVENT_ALL;
e1b624d0
JG
1463 ret = lttng_strncpy(ev.name, name ?: "", sizeof(ev.name));
1464 if (ret) {
1465 ret = -LTTNG_ERR_INVALID;
1466 goto end;
1467 }
1468
1469 ret = lttng_disable_event_ext(handle, &ev, channel_name, NULL);
1470end:
1471 return ret;
1df4dedd
DG
1472}
1473
cf0bcb51
JG
1474struct lttng_channel *lttng_channel_create(struct lttng_domain *domain)
1475{
1476 struct lttng_channel *channel = NULL;
cf0bcb51
JG
1477
1478 if (!domain) {
999af9c1 1479 goto end;
cf0bcb51
JG
1480 }
1481
1482 /* Validate domain. */
1483 switch (domain->type) {
1484 case LTTNG_DOMAIN_UST:
1485 switch (domain->buf_type) {
1486 case LTTNG_BUFFER_PER_UID:
1487 case LTTNG_BUFFER_PER_PID:
1488 break;
1489 default:
999af9c1 1490 goto end;
cf0bcb51
JG
1491 }
1492 break;
1493 case LTTNG_DOMAIN_KERNEL:
1494 if (domain->buf_type != LTTNG_BUFFER_GLOBAL) {
999af9c1 1495 goto end;
cf0bcb51
JG
1496 }
1497 break;
1498 default:
999af9c1 1499 goto end;
cf0bcb51
JG
1500 }
1501
999af9c1 1502 channel = lttng_channel_create_internal();
cf0bcb51 1503 if (!channel) {
999af9c1 1504 goto end;
cf0bcb51
JG
1505 }
1506
cf0bcb51 1507 lttng_channel_set_default_attr(domain, &channel->attr);
999af9c1 1508end:
cf0bcb51 1509 return channel;
cf0bcb51
JG
1510}
1511
1512void lttng_channel_destroy(struct lttng_channel *channel)
1513{
1514 if (!channel) {
1515 return;
1516 }
1517
1518 if (channel->attr.extended.ptr) {
1519 free(channel->attr.extended.ptr);
1520 }
1521 free(channel);
1522}
1523
1df4dedd 1524/*
9ae110e2
JG
1525 * Enable channel per domain
1526 * Returns size of returned session payload data or a negative error code.
a5c5a2bd 1527 */
28ab034a 1528int lttng_enable_channel(struct lttng_handle *handle, struct lttng_channel *in_chan)
a5c5a2bd 1529{
13dd7782 1530 enum lttng_error_code ret_code;
e1b624d0 1531 int ret;
999af9c1 1532 struct lttng_dynamic_buffer buffer;
cd80958d 1533 struct lttcomm_session_msg lsm;
13dd7782 1534 uint64_t total_buffer_size_needed_per_cpu = 0;
999af9c1
JR
1535 struct lttng_channel *channel = NULL;
1536
1537 lttng_dynamic_buffer_init(&buffer);
cd80958d 1538
9ae110e2 1539 /* NULL arguments are forbidden. No default values. */
cf0bcb51 1540 if (handle == NULL || in_chan == NULL) {
999af9c1
JR
1541 ret = -LTTNG_ERR_INVALID;
1542 goto end;
cf0bcb51 1543 }
cd80958d 1544
09b72f7a
FD
1545 /*
1546 * Verify that the amount of memory required to create the requested
1547 * buffer is available on the system at the moment.
1548 */
28ab034a 1549 if (in_chan->attr.num_subbuf > UINT64_MAX / in_chan->attr.subbuf_size) {
13dd7782
JR
1550 /* Overflow */
1551 ret = -LTTNG_ERR_OVERFLOW;
1552 goto end;
1553 }
1554
28ab034a
JG
1555 total_buffer_size_needed_per_cpu = in_chan->attr.num_subbuf * in_chan->attr.subbuf_size;
1556 ret_code = check_enough_available_memory(total_buffer_size_needed_per_cpu);
13dd7782
JR
1557 if (ret_code != LTTNG_OK) {
1558 ret = -ret_code;
1559 goto end;
09b72f7a
FD
1560 }
1561
999af9c1
JR
1562 /* Copy the channel for easier manipulation. */
1563 channel = lttng_channel_copy(in_chan);
1564 if (!channel) {
1565 ret = -LTTNG_ERR_NOMEM;
1566 goto end;
1567 }
1568
1569 /* Populate the channel extended attribute if necessary. */
1570 if (!channel->attr.extended.ptr) {
28ab034a 1571 struct lttng_channel_extended *extended = zmalloc<lttng_channel_extended>();
999af9c1
JR
1572
1573 if (!extended) {
1574 ret = -LTTNG_ERR_NOMEM;
1575 goto end;
1576 }
64803277 1577
28ab034a 1578 lttng_channel_set_default_extended_attr(&handle->domain, extended);
999af9c1
JR
1579 channel->attr.extended.ptr = extended;
1580 }
1581
1582 /* Prepare the payload */
1583 memset(&lsm, 0, sizeof(lsm));
1584
37a5ef39 1585 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_ENABLE_CHANNEL;
60160d2a 1586 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
7d29a247 1587
28ab034a 1588 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
e1b624d0
JG
1589 if (ret) {
1590 ret = -LTTNG_ERR_INVALID;
1591 goto end;
1592 }
cd80958d 1593
999af9c1
JR
1594 ret = lttng_channel_serialize(channel, &buffer);
1595 if (ret) {
1596 ret = -LTTNG_ERR_FATAL;
1597 goto end;
1598 }
1599
1600 lsm.u.channel.length = buffer.size;
1601
28ab034a 1602 ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(&lsm, buffer.data, buffer.size, NULL);
e1b624d0 1603end:
999af9c1
JR
1604 lttng_channel_destroy(channel);
1605 lttng_dynamic_buffer_reset(&buffer);
e1b624d0 1606 return ret;
8c0faa1d 1607}
1df4dedd 1608
2ef84c95 1609/*
9ae110e2
JG
1610 * All tracing will be stopped for registered events of the channel.
1611 * Returns size of returned session payload data or a negative error code.
2ef84c95 1612 */
cd80958d 1613int lttng_disable_channel(struct lttng_handle *handle, const char *name)
2ef84c95 1614{
e1b624d0 1615 int ret;
cd80958d
DG
1616 struct lttcomm_session_msg lsm;
1617
9ae110e2 1618 /* Safety check. Both are mandatory. */
9d697d3d 1619 if (handle == NULL || name == NULL) {
2f70b271 1620 return -LTTNG_ERR_INVALID;
cd80958d
DG
1621 }
1622
441c16a7
MD
1623 memset(&lsm, 0, sizeof(lsm));
1624
37a5ef39 1625 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_DISABLE_CHANNEL;
1df4dedd 1626
28ab034a 1627 ret = lttng_strncpy(lsm.u.disable.channel_name, name, sizeof(lsm.u.disable.channel_name));
e1b624d0
JG
1628 if (ret) {
1629 ret = -LTTNG_ERR_INVALID;
1630 goto end;
1631 }
9d697d3d 1632
60160d2a 1633 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
cd80958d 1634
28ab034a 1635 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
e1b624d0
JG
1636 if (ret) {
1637 ret = -LTTNG_ERR_INVALID;
1638 goto end;
1639 }
cd80958d 1640
e1b624d0
JG
1641 ret = lttng_ctl_ask_sessiond(&lsm, NULL);
1642end:
1643 return ret;
ca95a216
DG
1644}
1645
fac6795d 1646/*
9ae110e2
JG
1647 * Lists all available tracepoints of domain.
1648 * Sets the contents of the events array.
1649 * Returns the number of lttng_event entries in events;
1650 * on error, returns a negative value.
fac6795d 1651 */
28ab034a 1652int lttng_list_tracepoints(struct lttng_handle *handle, struct lttng_event **events)
fac6795d 1653{
28ab034a
JG
1654 enum lttng_error_code ret_code;
1655 int ret, total_payload_received;
1656 char *reception_buffer = NULL;
1657 struct lttcomm_session_msg lsm = {
37a5ef39 1658 .cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_TRACEPOINTS,
1c9a0b0e
MJ
1659 .session = {},
1660 .domain = {},
1661 .u = {},
1662 .fd_count = 0,
1663 };
28ab034a
JG
1664 struct lttcomm_list_command_header *cmd_header = NULL;
1665 size_t cmd_header_len;
1666 unsigned int nb_events = 0;
8ddd72ef 1667
28ab034a
JG
1668 if (handle == NULL) {
1669 ret = -LTTNG_ERR_INVALID;
1670 goto end;
1671 }
8ddd72ef 1672
28ab034a 1673 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
8ddd72ef 1674
28ab034a
JG
1675 ret = lttng_ctl_ask_sessiond_fds_varlen(&lsm,
1676 NULL,
1677 0,
1678 NULL,
1679 0,
1680 (void **) &reception_buffer,
1681 (void **) &cmd_header,
1682 &cmd_header_len);
1683 if (ret < 0) {
1684 goto end;
1685 }
8ddd72ef 1686
28ab034a 1687 total_payload_received = ret;
8ddd72ef 1688
28ab034a
JG
1689 if (!cmd_header) {
1690 ret = -LTTNG_ERR_UNK;
1691 goto end;
1692 }
8ddd72ef 1693
28ab034a
JG
1694 if (cmd_header->count > INT_MAX) {
1695 ret = -LTTNG_ERR_OVERFLOW;
1696 goto end;
1697 }
8ddd72ef 1698
28ab034a 1699 nb_events = (unsigned int) cmd_header->count;
fac6795d 1700
8ddd72ef
JR
1701 {
1702 struct lttng_buffer_view events_view =
28ab034a 1703 lttng_buffer_view_init(reception_buffer, 0, total_payload_received);
8ddd72ef 1704 struct lttng_payload_view events_payload_view =
28ab034a 1705 lttng_payload_view_from_buffer_view(&events_view, 0, -1);
2a71efd5 1706
8ddd72ef 1707 ret_code = lttng_events_create_and_flatten_from_payload(
28ab034a 1708 &events_payload_view, nb_events, events);
8ddd72ef
JR
1709 if (ret_code != LTTNG_OK) {
1710 ret = -ret_code;
1711 goto end;
1712 }
eb354453 1713 }
fac6795d 1714
8ddd72ef
JR
1715 ret = (int) nb_events;
1716
1717end:
28ab034a
JG
1718 free(cmd_header);
1719 free(reception_buffer);
1720 return ret;
fac6795d
DG
1721}
1722
f37d259d 1723/*
9ae110e2
JG
1724 * Lists all available tracepoint fields of domain.
1725 * Sets the contents of the event field array.
1726 * Returns the number of lttng_event_field entries in events;
1727 * on error, returns a negative value.
f37d259d 1728 */
28ab034a 1729int lttng_list_tracepoint_fields(struct lttng_handle *handle, struct lttng_event_field **fields)
f37d259d 1730{
b2d68839 1731 enum lttng_error_code ret_code;
f37d259d
MD
1732 int ret;
1733 struct lttcomm_session_msg lsm;
b2d68839
JR
1734 const struct lttcomm_list_command_header *cmd_header = NULL;
1735 unsigned int nb_event_fields = 0;
1736 struct lttng_payload reply;
f37d259d 1737
5c5c6942
JG
1738 lttng_payload_init(&reply);
1739
f37d259d 1740 if (handle == NULL) {
b2d68839
JR
1741 ret = -LTTNG_ERR_INVALID;
1742 goto end;
f37d259d
MD
1743 }
1744
53efb85a 1745 memset(&lsm, 0, sizeof(lsm));
37a5ef39 1746 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_TRACEPOINT_FIELDS;
60160d2a 1747 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
f37d259d 1748
b2d68839
JR
1749 {
1750 lttng_payload_view message_view =
28ab034a 1751 lttng_payload_view_init_from_buffer((const char *) &lsm, 0, sizeof(lsm));
b2d68839
JR
1752
1753 ret = lttng_ctl_ask_sessiond_payload(&message_view, &reply);
1754 if (ret < 0) {
1755 goto end;
1756 }
1757 }
1758
1759 {
28ab034a
JG
1760 const lttng_buffer_view cmd_header_view = lttng_buffer_view_from_dynamic_buffer(
1761 &reply.buffer, 0, sizeof(*cmd_header));
b2d68839
JR
1762
1763 if (!lttng_buffer_view_is_valid(&cmd_header_view)) {
1764 ret = -LTTNG_ERR_INVALID_PROTOCOL;
1765 goto end;
1766 }
1767
28ab034a 1768 cmd_header = (struct lttcomm_list_command_header *) cmd_header_view.data;
b2d68839
JR
1769 }
1770
1771 if (cmd_header->count > INT_MAX) {
1772 ret = -LTTNG_ERR_OVERFLOW;
1773 goto end;
f37d259d
MD
1774 }
1775
b2d68839
JR
1776 nb_event_fields = cmd_header->count;
1777
1778 {
1779 lttng_payload_view reply_view =
28ab034a 1780 lttng_payload_view_from_payload(&reply, sizeof(*cmd_header), -1);
b2d68839
JR
1781
1782 ret_code = lttng_event_fields_create_and_flatten_from_payload(
28ab034a 1783 &reply_view, nb_event_fields, fields);
b2d68839
JR
1784 if (ret_code != LTTNG_OK) {
1785 ret = -ret_code;
1786 goto end;
1787 }
1788 }
1789
1790 ret = nb_event_fields;
1791
1792end:
5c5c6942 1793 lttng_payload_reset(&reply);
b2d68839 1794 return ret;
f37d259d
MD
1795}
1796
834978fd 1797/*
9ae110e2
JG
1798 * Lists all available kernel system calls. Allocates and sets the contents of
1799 * the events array.
834978fd 1800 *
9ae110e2
JG
1801 * Returns the number of lttng_event entries in events; on error, returns a
1802 * negative value.
834978fd
DG
1803 */
1804int lttng_list_syscalls(struct lttng_event **events)
1805{
28ab034a
JG
1806 enum lttng_error_code ret_code;
1807 int ret, total_payload_received;
1808 char *reception_buffer = NULL;
1809 struct lttcomm_session_msg lsm = {};
1810 struct lttcomm_list_command_header *cmd_header = NULL;
1811 size_t cmd_header_len;
1812 uint32_t nb_events = 0;
1813
1814 if (!events) {
1815 ret = -LTTNG_ERR_INVALID;
1816 goto end;
1817 }
1818
1819 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_SYSCALLS;
1820 /* Force kernel domain for system calls. */
1821 lsm.domain.type = LTTNG_DOMAIN_KERNEL;
1822
1823 ret = lttng_ctl_ask_sessiond_fds_varlen(&lsm,
1824 NULL,
1825 0,
1826 NULL,
1827 0,
1828 (void **) &reception_buffer,
1829 (void **) &cmd_header,
1830 &cmd_header_len);
1831 if (ret < 0) {
1832 goto end;
1833 }
1834 total_payload_received = ret;
1835
1836 if (!cmd_header) {
1837 ret = -LTTNG_ERR_UNK;
1838 goto end;
1839 }
1840
1841 if (cmd_header->count > INT_MAX) {
1842 ret = -LTTNG_ERR_OVERFLOW;
1843 goto end;
1844 }
1845
1846 nb_events = (unsigned int) cmd_header->count;
1847
1848 {
1849 const struct lttng_buffer_view events_view =
1850 lttng_buffer_view_init(reception_buffer, 0, total_payload_received);
8ddd72ef 1851 struct lttng_payload_view events_payload_view =
28ab034a 1852 lttng_payload_view_from_buffer_view(&events_view, 0, -1);
8ddd72ef 1853
28ab034a
JG
1854 ret_code = lttng_events_create_and_flatten_from_payload(
1855 &events_payload_view, nb_events, events);
1856 if (ret_code != LTTNG_OK) {
1857 ret = -ret_code;
1858 goto end;
1859 }
1860 }
8ddd72ef 1861
28ab034a 1862 ret = (int) nb_events;
834978fd 1863
8ddd72ef 1864end:
28ab034a
JG
1865 free(reception_buffer);
1866 free(cmd_header);
1867 return ret;
834978fd
DG
1868}
1869
1657e9bb 1870/*
9ae110e2 1871 * Returns a human readable string describing
8346beb6 1872 * the error code (positive or negative value).
1657e9bb 1873 */
9a745bc7 1874const char *lttng_strerror(int code)
1657e9bb 1875{
8346beb6
PP
1876 if (code > 0) {
1877 code = -code;
1878 }
1879
f73fabfd 1880 return error_get_str(code);
1657e9bb
DG
1881}
1882
28ab034a 1883enum lttng_error_code lttng_create_session_ext(struct lttng_session_descriptor *session_descriptor)
b178f53e
JG
1884{
1885 enum lttng_error_code ret_code;
1886 struct lttcomm_session_msg lsm = {
37a5ef39 1887 .cmd_type = LTTCOMM_SESSIOND_COMMAND_CREATE_SESSION_EXT,
1c9a0b0e
MJ
1888 .session = {},
1889 .domain = {},
1890 .u = {},
1891 .fd_count = 0,
b178f53e
JG
1892 };
1893 void *reply = NULL;
1894 struct lttng_buffer_view reply_view;
1895 int reply_ret;
1896 bool sessiond_must_generate_ouput;
1897 struct lttng_dynamic_buffer payload;
1898 int ret;
1899 size_t descriptor_size;
1900 struct lttng_session_descriptor *descriptor_reply = NULL;
1901
1902 lttng_dynamic_buffer_init(&payload);
1903 if (!session_descriptor) {
1904 ret_code = LTTNG_ERR_INVALID;
1905 goto end;
1906 }
1907
1908 sessiond_must_generate_ouput =
28ab034a 1909 !lttng_session_descriptor_is_output_destination_initialized(session_descriptor);
b178f53e
JG
1910 if (sessiond_must_generate_ouput) {
1911 const char *home_dir = utils_get_home_dir();
1912 size_t home_dir_len = home_dir ? strlen(home_dir) + 1 : 0;
1913
1914 if (!home_dir || home_dir_len > LTTNG_PATH_MAX) {
1915 ret_code = LTTNG_ERR_FATAL;
1916 goto end;
1917 }
1918
1919 lsm.u.create_session.home_dir_size = (uint16_t) home_dir_len;
28ab034a 1920 ret = lttng_dynamic_buffer_append(&payload, home_dir, home_dir_len);
b178f53e
JG
1921 if (ret) {
1922 ret_code = LTTNG_ERR_NOMEM;
1923 goto end;
1924 }
1925 }
1926
1927 descriptor_size = payload.size;
28ab034a 1928 ret = lttng_session_descriptor_serialize(session_descriptor, &payload);
b178f53e
JG
1929 if (ret) {
1930 ret_code = LTTNG_ERR_INVALID;
1931 goto end;
1932 }
1933 descriptor_size = payload.size - descriptor_size;
1934 lsm.u.create_session.session_descriptor_size = descriptor_size;
1935
1936 /* Command returns a session descriptor on success. */
28ab034a
JG
1937 reply_ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(
1938 &lsm, payload.data, payload.size, &reply);
b178f53e 1939 if (reply_ret < 0) {
4bd69c5f 1940 ret_code = (lttng_error_code) -reply_ret;
b178f53e
JG
1941 goto end;
1942 } else if (reply_ret == 0) {
1943 /* Socket unexpectedly closed by the session daemon. */
1944 ret_code = LTTNG_ERR_FATAL;
1945 goto end;
1946 }
1947
4bd69c5f 1948 reply_view = lttng_buffer_view_init((const char *) reply, 0, reply_ret);
28ab034a 1949 ret = lttng_session_descriptor_create_from_buffer(&reply_view, &descriptor_reply);
b178f53e
JG
1950 if (ret < 0) {
1951 ret_code = LTTNG_ERR_FATAL;
1952 goto end;
1953 }
1954 ret_code = LTTNG_OK;
1955 lttng_session_descriptor_assign(session_descriptor, descriptor_reply);
1956end:
1957 free(reply);
1958 lttng_dynamic_buffer_reset(&payload);
1959 lttng_session_descriptor_destroy(descriptor_reply);
1960 return ret_code;
1961}
1962
aaf97519 1963/*
b178f53e 1964 * Create a new session using name and url for destination.
a4b92340 1965 *
780d4bb8 1966 * Return 0 on success else a negative LTTng error code.
00e2e675 1967 */
a4b92340 1968int lttng_create_session(const char *name, const char *url)
00e2e675 1969{
3dd05a85 1970 int ret;
a4b92340 1971 ssize_t size;
a4b92340 1972 struct lttng_uri *uris = NULL;
b178f53e
JG
1973 struct lttng_session_descriptor *descriptor = NULL;
1974 enum lttng_error_code ret_code;
00e2e675 1975
b178f53e
JG
1976 if (!name) {
1977 ret = -LTTNG_ERR_INVALID;
1978 goto end;
00e2e675
DG
1979 }
1980
bc894455 1981 size = uri_parse_str_urls(url, NULL, &uris);
a4b92340 1982 if (size < 0) {
b178f53e
JG
1983 ret = -LTTNG_ERR_INVALID;
1984 goto end;
1985 }
1986 switch (size) {
1987 case 0:
1988 descriptor = lttng_session_descriptor_create(name);
1989 break;
1990 case 1:
1991 if (uris[0].dtype != LTTNG_DST_PATH) {
1992 ret = -LTTNG_ERR_INVALID;
1993 goto end;
1994 }
28ab034a 1995 descriptor = lttng_session_descriptor_local_create(name, uris[0].dst.path);
b178f53e
JG
1996 break;
1997 case 2:
28ab034a 1998 descriptor = lttng_session_descriptor_network_create(name, url, NULL);
b178f53e
JG
1999 break;
2000 default:
2001 ret = -LTTNG_ERR_INVALID;
2002 goto end;
2003 }
2004 if (!descriptor) {
2005 ret = -LTTNG_ERR_INVALID;
2006 goto end;
00e2e675 2007 }
b178f53e
JG
2008 ret_code = lttng_create_session_ext(descriptor);
2009 ret = ret_code == LTTNG_OK ? 0 : -ret_code;
2010end:
2011 lttng_session_descriptor_destroy(descriptor);
2012 free(uris);
2013 return ret;
2014}
00e2e675 2015
b178f53e
JG
2016/*
2017 * Create a session exclusively used for snapshot.
2018 *
780d4bb8 2019 * Return 0 on success else a negative LTTng error code.
b178f53e
JG
2020 */
2021int lttng_create_session_snapshot(const char *name, const char *snapshot_url)
2022{
2023 int ret;
2024 enum lttng_error_code ret_code;
2025 ssize_t size;
2026 struct lttng_uri *uris = NULL;
2027 struct lttng_session_descriptor *descriptor = NULL;
a4b92340 2028
b178f53e
JG
2029 if (!name) {
2030 ret = -LTTNG_ERR_INVALID;
2031 goto end;
2032 }
2033
2034 size = uri_parse_str_urls(snapshot_url, NULL, &uris);
2035 if (size < 0) {
2036 ret = -LTTNG_ERR_INVALID;
2037 goto end;
2038 }
2039 /*
2040 * If the user does not specify a custom subdir, use the session name.
2041 */
28ab034a
JG
2042 if (size > 0 && uris[0].dtype != LTTNG_DST_PATH && strlen(uris[0].subdir) == 0) {
2043 ret = snprintf(uris[0].subdir, sizeof(uris[0].subdir), "%s", name);
b178f53e
JG
2044 if (ret < 0) {
2045 PERROR("Failed to set session name as network destination sub-directory");
2046 ret = -LTTNG_ERR_FATAL;
2047 goto end;
2048 } else if (ret >= sizeof(uris[0].subdir)) {
2049 /* Truncated output. */
2050 ret = -LTTNG_ERR_INVALID;
2051 goto end;
2052 }
2053 }
3dd05a85 2054
b178f53e
JG
2055 switch (size) {
2056 case 0:
2057 descriptor = lttng_session_descriptor_snapshot_create(name);
2058 break;
2059 case 1:
2060 if (uris[0].dtype != LTTNG_DST_PATH) {
2061 ret = -LTTNG_ERR_INVALID;
2062 goto end;
2063 }
28ab034a 2064 descriptor = lttng_session_descriptor_snapshot_local_create(name, uris[0].dst.path);
b178f53e
JG
2065 break;
2066 case 2:
28ab034a
JG
2067 descriptor =
2068 lttng_session_descriptor_snapshot_network_create(name, snapshot_url, NULL);
b178f53e
JG
2069 break;
2070 default:
2071 ret = -LTTNG_ERR_INVALID;
2072 goto end;
2073 }
2074 if (!descriptor) {
2075 ret = -LTTNG_ERR_INVALID;
2076 goto end;
2077 }
2078 ret_code = lttng_create_session_ext(descriptor);
2079 ret = ret_code == LTTNG_OK ? 0 : -ret_code;
2080end:
2081 lttng_session_descriptor_destroy(descriptor);
3dd05a85
DG
2082 free(uris);
2083 return ret;
00e2e675
DG
2084}
2085
b178f53e
JG
2086/*
2087 * Create a session exclusively used for live.
2088 *
780d4bb8 2089 * Return 0 on success else a negative LTTng error code.
b178f53e 2090 */
28ab034a 2091int lttng_create_session_live(const char *name, const char *url, unsigned int timer_interval)
b178f53e
JG
2092{
2093 int ret;
2094 enum lttng_error_code ret_code;
2095 struct lttng_session_descriptor *descriptor = NULL;
2096
2097 if (!name) {
2098 ret = -LTTNG_ERR_INVALID;
2099 goto end;
2100 }
2101
2102 if (url) {
2103 descriptor = lttng_session_descriptor_live_network_create(
28ab034a 2104 name, url, NULL, timer_interval);
b178f53e 2105 } else {
28ab034a 2106 descriptor = lttng_session_descriptor_live_create(name, timer_interval);
b178f53e
JG
2107 }
2108 if (!descriptor) {
2109 ret = -LTTNG_ERR_INVALID;
2110 goto end;
2111 }
2112 ret_code = lttng_create_session_ext(descriptor);
2113 ret = ret_code == LTTNG_OK ? 0 : -ret_code;
2114end:
2115 lttng_session_descriptor_destroy(descriptor);
2116 return ret;
2117}
2118
e20ee7c2
JD
2119/*
2120 * Stop the session and wait for the data before destroying it
780d4bb8
MD
2121 *
2122 * Return 0 on success else a negative LTTng error code.
e20ee7c2
JD
2123 */
2124int lttng_destroy_session(const char *session_name)
2125{
2126 int ret;
3e3665b8
JG
2127 enum lttng_error_code ret_code;
2128 enum lttng_destruction_handle_status status;
2129 struct lttng_destruction_handle *handle = NULL;
e20ee7c2
JD
2130
2131 /*
3e3665b8
JG
2132 * Stop the tracing and wait for the data to be
2133 * consumed.
e20ee7c2
JD
2134 */
2135 ret = _lttng_stop_tracing(session_name, 1);
2136 if (ret && ret != -LTTNG_ERR_TRACE_ALREADY_STOPPED) {
2137 goto end;
2138 }
2139
3e3665b8
JG
2140 ret_code = lttng_destroy_session_ext(session_name, &handle);
2141 if (ret_code != LTTNG_OK) {
2142 ret = (int) -ret_code;
2143 goto end;
2144 }
a0377dfe 2145 LTTNG_ASSERT(handle);
3e3665b8
JG
2146
2147 /* Block until the completion of the destruction of the session. */
2148 status = lttng_destruction_handle_wait_for_completion(handle, -1);
2149 if (status != LTTNG_DESTRUCTION_HANDLE_STATUS_COMPLETED) {
2150 ret = -LTTNG_ERR_UNK;
2151 goto end;
2152 }
2153
2154 status = lttng_destruction_handle_get_result(handle, &ret_code);
2155 if (status != LTTNG_DESTRUCTION_HANDLE_STATUS_OK) {
2156 ret = -LTTNG_ERR_UNK;
2157 goto end;
2158 }
780d4bb8 2159 ret = ret_code == LTTNG_OK ? 0 : -ret_code;
e20ee7c2 2160end:
3e3665b8 2161 lttng_destruction_handle_destroy(handle);
e20ee7c2
JD
2162 return ret;
2163}
2164
2165/*
2166 * Destroy the session without waiting for the data.
2167 */
2168int lttng_destroy_session_no_wait(const char *session_name)
2169{
3e3665b8 2170 enum lttng_error_code ret_code;
e20ee7c2 2171
3e3665b8 2172 ret_code = lttng_destroy_session_ext(session_name, NULL);
3204017e 2173 return ret_code == LTTNG_OK ? 0 : -ret_code;
e20ee7c2
JD
2174}
2175
57167058 2176/*
9ae110e2
JG
2177 * Ask the session daemon for all available sessions.
2178 * Sets the contents of the sessions array.
2179 * Returns the number of lttng_session entries in sessions;
2180 * on error, returns a negative value.
57167058 2181 */
b178f53e 2182int lttng_list_sessions(struct lttng_session **out_sessions)
57167058 2183{
ca95a216 2184 int ret;
cd80958d 2185 struct lttcomm_session_msg lsm;
28ab034a
JG
2186 const size_t session_size =
2187 sizeof(struct lttng_session) + sizeof(struct lttng_session_extended);
b178f53e
JG
2188 size_t session_count, i;
2189 struct lttng_session_extended *sessions_extended_begin;
2190 struct lttng_session *sessions = NULL;
57167058 2191
53efb85a 2192 memset(&lsm, 0, sizeof(lsm));
37a5ef39 2193 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_SESSIONS;
985aea18
MD
2194 /*
2195 * Initialize out_sessions to NULL so it is initialized when
2196 * lttng_list_sessions returns 0, thus allowing *out_sessions to
2197 * be subsequently freed.
2198 */
2199 *out_sessions = NULL;
28ab034a 2200 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &sessions);
b178f53e 2201 if (ret <= 0) {
b178f53e
JG
2202 goto end;
2203 }
2204 if (!sessions) {
2205 ret = -LTTNG_ERR_FATAL;
2206 goto end;
2207 }
2208
2209 if (ret % session_size) {
2210 ret = -LTTNG_ERR_UNK;
2211 free(sessions);
b178f53e 2212 goto end;
57167058 2213 }
b178f53e 2214 session_count = (size_t) ret / session_size;
28ab034a 2215 sessions_extended_begin = (struct lttng_session_extended *) (&sessions[session_count]);
57167058 2216
b178f53e
JG
2217 /* Set extended session info pointers. */
2218 for (i = 0; i < session_count; i++) {
2219 struct lttng_session *session = &sessions[i];
28ab034a 2220 struct lttng_session_extended *extended = &(sessions_extended_begin[i]);
b178f53e
JG
2221
2222 session->extended.ptr = extended;
2223 }
2224
2225 ret = (int) session_count;
2226 *out_sessions = sessions;
2227end:
2228 return ret;
2229}
2230
28ab034a
JG
2231enum lttng_error_code lttng_session_get_creation_time(const struct lttng_session *session,
2232 uint64_t *creation_time)
b178f53e
JG
2233{
2234 enum lttng_error_code ret = LTTNG_OK;
2235 struct lttng_session_extended *extended;
2236
2237 if (!session || !creation_time || !session->extended.ptr) {
2238 ret = LTTNG_ERR_INVALID;
2239 goto end;
2240 }
2241
4bd69c5f 2242 extended = (lttng_session_extended *) session->extended.ptr;
b178f53e
JG
2243 if (!extended->creation_time.is_set) {
2244 /* Not created on the session daemon yet. */
2245 ret = LTTNG_ERR_SESSION_NOT_EXIST;
2246 goto end;
2247 }
2248 *creation_time = extended->creation_time.value;
2249end:
2250 return ret;
57167058
DG
2251}
2252
28ab034a 2253int lttng_set_session_shm_path(const char *session_name, const char *shm_path)
d7ba1388 2254{
e1b624d0 2255 int ret;
d7ba1388
MD
2256 struct lttcomm_session_msg lsm;
2257
2258 if (session_name == NULL) {
2259 return -LTTNG_ERR_INVALID;
2260 }
2261
2262 memset(&lsm, 0, sizeof(lsm));
37a5ef39 2263 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_SET_SESSION_SHM_PATH;
d7ba1388 2264
28ab034a 2265 ret = lttng_strncpy(lsm.session.name, session_name, sizeof(lsm.session.name));
e1b624d0
JG
2266 if (ret) {
2267 ret = -LTTNG_ERR_INVALID;
2268 goto end;
2269 }
2270
28ab034a
JG
2271 ret = lttng_strncpy(
2272 lsm.u.set_shm_path.shm_path, shm_path ?: "", sizeof(lsm.u.set_shm_path.shm_path));
e1b624d0
JG
2273 if (ret) {
2274 ret = -LTTNG_ERR_INVALID;
2275 goto end;
2276 }
d7ba1388 2277
e1b624d0
JG
2278 ret = lttng_ctl_ask_sessiond(&lsm, NULL);
2279end:
2280 return ret;
d7ba1388
MD
2281}
2282
9f19cc17 2283/*
9ae110e2
JG
2284 * Ask the session daemon for all available domains of a session.
2285 * Sets the contents of the domains array.
2286 * Returns the number of lttng_domain entries in domains;
2287 * on error, returns a negative value.
9f19cc17 2288 */
28ab034a 2289int lttng_list_domains(const char *session_name, struct lttng_domain **domains)
9f19cc17
DG
2290{
2291 int ret;
cd80958d
DG
2292 struct lttcomm_session_msg lsm;
2293
330be774 2294 if (session_name == NULL) {
e1b624d0
JG
2295 ret = -LTTNG_ERR_INVALID;
2296 goto error;
cd80958d 2297 }
9f19cc17 2298
53efb85a 2299 memset(&lsm, 0, sizeof(lsm));
37a5ef39 2300 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_DOMAINS;
cd80958d 2301
28ab034a 2302 ret = lttng_strncpy(lsm.session.name, session_name, sizeof(lsm.session.name));
e1b624d0
JG
2303 if (ret) {
2304 ret = -LTTNG_ERR_INVALID;
2305 goto error;
2306 }
cd80958d 2307
28ab034a 2308 ret = lttng_ctl_ask_sessiond(&lsm, (void **) domains);
9f19cc17 2309 if (ret < 0) {
e1b624d0 2310 goto error;
9f19cc17
DG
2311 }
2312
2313 return ret / sizeof(struct lttng_domain);
e1b624d0
JG
2314error:
2315 return ret;
9f19cc17
DG
2316}
2317
2318/*
9ae110e2
JG
2319 * Ask the session daemon for all available channels of a session.
2320 * Sets the contents of the channels array.
2321 * Returns the number of lttng_channel entries in channels;
2322 * on error, returns a negative value.
9f19cc17 2323 */
28ab034a 2324int lttng_list_channels(struct lttng_handle *handle, struct lttng_channel **channels)
9f19cc17 2325{
999af9c1 2326 int ret, total_payload_received;
cd80958d 2327 struct lttcomm_session_msg lsm;
999af9c1
JR
2328 char *reception_buffer = NULL;
2329 size_t cmd_header_len = 0;
2330 struct lttcomm_list_command_header *cmd_header = NULL;
2331 struct lttng_dynamic_buffer tmp_buffer;
2332
2333 lttng_dynamic_buffer_init(&tmp_buffer);
cd80958d 2334
9d697d3d 2335 if (handle == NULL) {
53e367f9
JG
2336 ret = -LTTNG_ERR_INVALID;
2337 goto end;
cd80958d
DG
2338 }
2339
53efb85a 2340 memset(&lsm, 0, sizeof(lsm));
37a5ef39 2341 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_CHANNELS;
28ab034a 2342 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
e1b624d0
JG
2343 if (ret) {
2344 ret = -LTTNG_ERR_INVALID;
2345 goto end;
2346 }
9f19cc17 2347
60160d2a 2348 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
9f19cc17 2349
28ab034a
JG
2350 ret = lttng_ctl_ask_sessiond_fds_varlen(&lsm,
2351 NULL,
2352 0,
2353 NULL,
2354 0,
2355 (void **) &reception_buffer,
2356 (void **) &cmd_header,
2357 &cmd_header_len);
9f19cc17 2358 if (ret < 0) {
53e367f9
JG
2359 goto end;
2360 }
2361
999af9c1
JR
2362 total_payload_received = ret;
2363
2364 if (cmd_header_len != sizeof(*cmd_header)) {
2365 ret = -LTTNG_ERR_FATAL;
53e367f9 2366 goto end;
9f19cc17
DG
2367 }
2368
999af9c1
JR
2369 if (!cmd_header) {
2370 ret = LTTNG_ERR_UNK;
2371 goto end;
2372 }
2373
2374 if (cmd_header->count > INT_MAX) {
2375 ret = -LTTNG_ERR_OVERFLOW;
2376 goto end;
2377 }
53e367f9 2378
999af9c1
JR
2379 {
2380 enum lttng_error_code ret_code;
2381 const struct lttng_buffer_view events_view =
28ab034a 2382 lttng_buffer_view_init(reception_buffer, 0, total_payload_received);
999af9c1
JR
2383
2384 ret_code = lttng_channels_create_and_flatten_from_buffer(
28ab034a 2385 &events_view, cmd_header->count, channels);
999af9c1
JR
2386 if (ret_code != LTTNG_OK) {
2387 ret = -ret_code;
2388 goto end;
2389 }
53e367f9
JG
2390 }
2391
999af9c1 2392 ret = (int) cmd_header->count;
53e367f9 2393end:
999af9c1
JR
2394 free(cmd_header);
2395 free(reception_buffer);
53e367f9 2396 return ret;
9f19cc17
DG
2397}
2398
2399/*
9ae110e2
JG
2400 * Ask the session daemon for all available events of a session channel.
2401 * Sets the contents of the events array.
2402 * Returns the number of lttng_event entries in events;
2403 * on error, returns a negative value.
9f19cc17 2404 */
cd80958d 2405int lttng_list_events(struct lttng_handle *handle,
28ab034a
JG
2406 const char *channel_name,
2407 struct lttng_event **events)
9f19cc17
DG
2408{
2409 int ret;
e368fb43 2410 struct lttcomm_session_msg lsm = {};
8ddd72ef 2411 struct lttng_payload reply;
e368fb43 2412 struct lttng_payload_view lsm_view =
28ab034a 2413 lttng_payload_view_init_from_buffer((const char *) &lsm, 0, sizeof(lsm));
8ddd72ef 2414 unsigned int nb_events = 0;
9f19cc17 2415
821a8b53
JR
2416 lttng_payload_init(&reply);
2417
8ddd72ef 2418 /* Safety check. An handle and channel name are mandatory. */
9d697d3d 2419 if (handle == NULL || channel_name == NULL) {
e368fb43
JG
2420 ret = -LTTNG_ERR_INVALID;
2421 goto end;
cd80958d
DG
2422 }
2423
8ddd72ef 2424 /* Initialize command parameters. */
37a5ef39 2425 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_EVENTS;
28ab034a 2426 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
e1b624d0
JG
2427 if (ret) {
2428 ret = -LTTNG_ERR_INVALID;
2429 goto end;
2430 }
2431
28ab034a 2432 ret = lttng_strncpy(lsm.u.list.channel_name, channel_name, sizeof(lsm.u.list.channel_name));
e1b624d0
JG
2433 if (ret) {
2434 ret = -LTTNG_ERR_INVALID;
2435 goto end;
2436 }
2437
60160d2a 2438 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
9f19cc17 2439
8ddd72ef
JR
2440 /* Execute command against the session daemon. */
2441 ret = lttng_ctl_ask_sessiond_payload(&lsm_view, &reply);
9f19cc17 2442 if (ret < 0) {
de453daa 2443 goto end;
9f19cc17
DG
2444 }
2445
e368fb43 2446 {
28ab034a 2447 const struct lttcomm_list_command_header *cmd_reply_header = NULL;
8ddd72ef 2448 const lttng_payload_view cmd_reply_header_view =
28ab034a 2449 lttng_payload_view_from_payload(&reply, 0, sizeof(*cmd_reply_header));
8ddd72ef
JR
2450
2451 if (!lttng_payload_view_is_valid(&cmd_reply_header_view)) {
2452 ret = -LTTNG_ERR_INVALID_PROTOCOL;
2453 goto end;
56f0bc67 2454 }
b4e3ceb9 2455
8ddd72ef 2456 cmd_reply_header = (const struct lttcomm_list_command_header *)
28ab034a 2457 cmd_reply_header_view.buffer.data;
8ddd72ef
JR
2458 if (cmd_reply_header->count > INT_MAX) {
2459 ret = -LTTNG_ERR_OVERFLOW;
2460 goto end;
2461 }
56f0bc67 2462
8ddd72ef 2463 nb_events = (unsigned int) cmd_reply_header->count;
56f0bc67 2464 }
de453daa 2465
e368fb43 2466 {
8ddd72ef
JR
2467 enum lttng_error_code ret_code;
2468 lttng_payload_view cmd_reply_payload = lttng_payload_view_from_payload(
28ab034a 2469 &reply, sizeof(struct lttcomm_list_command_header), -1);
56f0bc67 2470
8ddd72ef 2471 ret_code = lttng_events_create_and_flatten_from_payload(
28ab034a 2472 &cmd_reply_payload, nb_events, events);
8ddd72ef
JR
2473 if (ret_code != LTTNG_OK) {
2474 ret = -((int) ret_code);
2475 goto end;
56f0bc67 2476 }
de453daa
JG
2477 }
2478
de453daa
JG
2479 ret = (int) nb_events;
2480end:
8ddd72ef 2481 lttng_payload_reset(&reply);
b4e3ceb9 2482 return ret;
9f19cc17
DG
2483}
2484
fac6795d 2485/*
1c8d13c8
TD
2486 * Sets the tracing_group variable with name.
2487 * This function allocates memory pointed to by tracing_group.
2488 * On success, returns 0, on error, returns -1 (null name) or -ENOMEM.
fac6795d
DG
2489 */
2490int lttng_set_tracing_group(const char *name)
2491{
e32a3d0f 2492 int ret = 0;
76da29b6 2493 char *new_group;
e32a3d0f 2494
9d697d3d 2495 if (name == NULL) {
e32a3d0f
JG
2496 ret = -LTTNG_ERR_INVALID;
2497 goto end;
9d697d3d
DG
2498 }
2499
e32a3d0f
JG
2500 new_group = strdup(name);
2501 if (!new_group) {
2502 ret = -LTTNG_ERR_FATAL;
2503 goto end;
fac6795d
DG
2504 }
2505
76da29b6
JR
2506 free(tracing_group);
2507 tracing_group = new_group;
2508 new_group = NULL;
2509
e32a3d0f
JG
2510end:
2511 return ret;
fac6795d
DG
2512}
2513
f46376a1 2514int lttng_calibrate(struct lttng_handle *handle __attribute__((unused)),
28ab034a 2515 struct lttng_calibrate *calibrate __attribute__((unused)))
d0254c7c 2516{
b812e5ca
PP
2517 /*
2518 * This command was removed in LTTng 2.9.
2519 */
2520 return -LTTNG_ERR_UND;
d0254c7c
MD
2521}
2522
5edd7e09
DG
2523/*
2524 * Set default channel attributes.
441c16a7 2525 * If either or both of the arguments are null, attr content is zeroe'd.
5edd7e09 2526 */
28ab034a 2527void lttng_channel_set_default_attr(struct lttng_domain *domain, struct lttng_channel_attr *attr)
5edd7e09 2528{
294851b0 2529 struct lttng_channel_extended *extended;
cf0bcb51 2530
5edd7e09
DG
2531 /* Safety check */
2532 if (attr == NULL || domain == NULL) {
2533 return;
2534 }
2535
999af9c1 2536 /* Save the pointer for later use */
294851b0 2537 extended = (struct lttng_channel_extended *) attr->extended.ptr;
eacaa7a6
DS
2538 memset(attr, 0, sizeof(struct lttng_channel_attr));
2539
0a9c6494
DG
2540 /* Same for all domains. */
2541 attr->overwrite = DEFAULT_CHANNEL_OVERWRITE;
2542 attr->tracefile_size = DEFAULT_CHANNEL_TRACEFILE_SIZE;
2543 attr->tracefile_count = DEFAULT_CHANNEL_TRACEFILE_COUNT;
2544
5edd7e09
DG
2545 switch (domain->type) {
2546 case LTTNG_DOMAIN_KERNEL:
28ab034a 2547 attr->switch_timer_interval = DEFAULT_KERNEL_CHANNEL_SWITCH_TIMER;
d92ff3ef 2548 attr->read_timer_interval = DEFAULT_KERNEL_CHANNEL_READ_TIMER;
3e230f92 2549 attr->subbuf_size = default_get_kernel_channel_subbuf_size();
5edd7e09
DG
2550 attr->num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM;
2551 attr->output = DEFAULT_KERNEL_CHANNEL_OUTPUT;
2552 break;
2553 case LTTNG_DOMAIN_UST:
0a9c6494
DG
2554 switch (domain->buf_type) {
2555 case LTTNG_BUFFER_PER_UID:
2556 attr->subbuf_size = default_get_ust_uid_channel_subbuf_size();
2557 attr->num_subbuf = DEFAULT_UST_UID_CHANNEL_SUBBUF_NUM;
2558 attr->output = DEFAULT_UST_UID_CHANNEL_OUTPUT;
28ab034a
JG
2559 attr->switch_timer_interval = DEFAULT_UST_UID_CHANNEL_SWITCH_TIMER;
2560 attr->read_timer_interval = DEFAULT_UST_UID_CHANNEL_READ_TIMER;
0a9c6494
DG
2561 break;
2562 case LTTNG_BUFFER_PER_PID:
2563 default:
2564 attr->subbuf_size = default_get_ust_pid_channel_subbuf_size();
2565 attr->num_subbuf = DEFAULT_UST_PID_CHANNEL_SUBBUF_NUM;
2566 attr->output = DEFAULT_UST_PID_CHANNEL_OUTPUT;
28ab034a
JG
2567 attr->switch_timer_interval = DEFAULT_UST_PID_CHANNEL_SWITCH_TIMER;
2568 attr->read_timer_interval = DEFAULT_UST_PID_CHANNEL_READ_TIMER;
0a9c6494
DG
2569 break;
2570 }
5edd7e09 2571 default:
441c16a7 2572 /* Default behavior: leave set to 0. */
5edd7e09
DG
2573 break;
2574 }
cf0bcb51 2575
999af9c1
JR
2576 if (extended) {
2577 lttng_channel_set_default_extended_attr(domain, extended);
2578 }
2579
2580 /* Reassign the extended pointer. */
cf0bcb51 2581 attr->extended.ptr = extended;
5edd7e09
DG
2582}
2583
5ba3702f 2584int lttng_channel_get_discarded_event_count(struct lttng_channel *channel,
28ab034a 2585 uint64_t *discarded_events)
5ba3702f
JG
2586{
2587 int ret = 0;
cf0bcb51 2588 struct lttng_channel_extended *chan_ext;
5ba3702f
JG
2589
2590 if (!channel || !discarded_events) {
2591 ret = -LTTNG_ERR_INVALID;
2592 goto end;
2593 }
2594
4bd69c5f 2595 chan_ext = (lttng_channel_extended *) channel->attr.extended.ptr;
5ba3702f
JG
2596 if (!chan_ext) {
2597 /*
2598 * This can happen since the lttng_channel structure is
2599 * used for other tasks where this pointer is never set.
2600 */
2601 *discarded_events = 0;
2602 goto end;
2603 }
2604
2605 *discarded_events = chan_ext->discarded_events;
2606end:
2607 return ret;
2608}
2609
28ab034a 2610int lttng_channel_get_lost_packet_count(struct lttng_channel *channel, uint64_t *lost_packets)
5ba3702f
JG
2611{
2612 int ret = 0;
cf0bcb51 2613 struct lttng_channel_extended *chan_ext;
5ba3702f
JG
2614
2615 if (!channel || !lost_packets) {
2616 ret = -LTTNG_ERR_INVALID;
2617 goto end;
2618 }
2619
4bd69c5f 2620 chan_ext = (lttng_channel_extended *) channel->attr.extended.ptr;
5ba3702f
JG
2621 if (!chan_ext) {
2622 /*
2623 * This can happen since the lttng_channel structure is
2624 * used for other tasks where this pointer is never set.
2625 */
2626 *lost_packets = 0;
2627 goto end;
2628 }
2629
2630 *lost_packets = chan_ext->lost_packets;
2631end:
2632 return ret;
2633}
2634
cf0bcb51 2635int lttng_channel_get_monitor_timer_interval(struct lttng_channel *chan,
28ab034a 2636 uint64_t *monitor_timer_interval)
cf0bcb51
JG
2637{
2638 int ret = 0;
2639
2640 if (!chan || !monitor_timer_interval) {
2641 ret = -LTTNG_ERR_INVALID;
2642 goto end;
2643 }
2644
2645 if (!chan->attr.extended.ptr) {
2646 ret = -LTTNG_ERR_INVALID;
2647 goto end;
2648 }
2649
28ab034a
JG
2650 *monitor_timer_interval =
2651 ((struct lttng_channel_extended *) chan->attr.extended.ptr)->monitor_timer_interval;
cf0bcb51
JG
2652end:
2653 return ret;
2654}
2655
2656int lttng_channel_set_monitor_timer_interval(struct lttng_channel *chan,
28ab034a 2657 uint64_t monitor_timer_interval)
cf0bcb51
JG
2658{
2659 int ret = 0;
2660
2661 if (!chan || !chan->attr.extended.ptr) {
2662 ret = -LTTNG_ERR_INVALID;
2663 goto end;
2664 }
2665
28ab034a
JG
2666 ((struct lttng_channel_extended *) chan->attr.extended.ptr)->monitor_timer_interval =
2667 monitor_timer_interval;
cf0bcb51
JG
2668end:
2669 return ret;
2670}
2671
28ab034a 2672int lttng_channel_get_blocking_timeout(struct lttng_channel *chan, int64_t *blocking_timeout)
491d1539
MD
2673{
2674 int ret = 0;
2675
2676 if (!chan || !blocking_timeout) {
2677 ret = -LTTNG_ERR_INVALID;
2678 goto end;
2679 }
2680
2681 if (!chan->attr.extended.ptr) {
2682 ret = -LTTNG_ERR_INVALID;
2683 goto end;
2684 }
2685
28ab034a
JG
2686 *blocking_timeout =
2687 ((struct lttng_channel_extended *) chan->attr.extended.ptr)->blocking_timeout;
491d1539
MD
2688end:
2689 return ret;
2690}
2691
28ab034a 2692int lttng_channel_set_blocking_timeout(struct lttng_channel *chan, int64_t blocking_timeout)
491d1539
MD
2693{
2694 int ret = 0;
2695 int64_t msec_timeout;
2696
2697 if (!chan || !chan->attr.extended.ptr) {
2698 ret = -LTTNG_ERR_INVALID;
2699 goto end;
2700 }
2701
2702 if (blocking_timeout < 0 && blocking_timeout != -1) {
2703 ret = -LTTNG_ERR_INVALID;
2704 goto end;
2705 }
2706
2707 /*
2708 * LTTng-ust's use of poll() to implement this timeout mechanism forces
2709 * us to accept a narrower range of values (msecs expressed as a signed
2710 * 32-bit integer).
2711 */
2712 msec_timeout = blocking_timeout / 1000;
2713 if (msec_timeout != (int32_t) msec_timeout) {
2714 ret = -LTTNG_ERR_INVALID;
2715 goto end;
2716 }
2717
28ab034a
JG
2718 ((struct lttng_channel_extended *) chan->attr.extended.ptr)->blocking_timeout =
2719 blocking_timeout;
491d1539
MD
2720end:
2721 return ret;
2722}
2723
fac6795d 2724/*
2269e89e 2725 * Check if session daemon is alive.
fac6795d 2726 *
2269e89e 2727 * Return 1 if alive or 0 if not.
1c8d13c8 2728 * On error returns a negative value.
fac6795d 2729 */
947308c4 2730int lttng_session_daemon_alive(void)
fac6795d
DG
2731{
2732 int ret;
2733
2734 ret = set_session_daemon_path();
2735 if (ret < 0) {
9ae110e2 2736 /* Error. */
fac6795d
DG
2737 return ret;
2738 }
2739
9d035200 2740 if (*sessiond_sock_path == '\0') {
2f70b271 2741 /*
9ae110e2
JG
2742 * No socket path set. Weird error which means the constructor
2743 * was not called.
2f70b271 2744 */
a0377dfe 2745 abort();
fac6795d
DG
2746 }
2747
2269e89e 2748 ret = try_connect_sessiond(sessiond_sock_path);
7d8234d9 2749 if (ret < 0) {
9ae110e2 2750 /* Not alive. */
7d8234d9
MD
2751 return 0;
2752 }
7d8234d9 2753
9ae110e2 2754 /* Is alive. */
947308c4 2755 return 1;
fac6795d
DG
2756}
2757
00e2e675 2758/*
a4b92340 2759 * Set URL for a consumer for a session and domain.
00e2e675
DG
2760 *
2761 * Return 0 on success, else a negative value.
2762 */
a4b92340 2763int lttng_set_consumer_url(struct lttng_handle *handle,
28ab034a
JG
2764 const char *control_url,
2765 const char *data_url)
00e2e675 2766{
3dd05a85 2767 int ret;
a4b92340 2768 ssize_t size;
00e2e675 2769 struct lttcomm_session_msg lsm;
a4b92340 2770 struct lttng_uri *uris = NULL;
00e2e675 2771
a4b92340 2772 if (handle == NULL || (control_url == NULL && data_url == NULL)) {
e1b624d0
JG
2773 ret = -LTTNG_ERR_INVALID;
2774 goto error;
00e2e675
DG
2775 }
2776
a4b92340
DG
2777 memset(&lsm, 0, sizeof(lsm));
2778
37a5ef39 2779 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_SET_CONSUMER_URI;
00e2e675 2780
28ab034a 2781 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
e1b624d0
JG
2782 if (ret) {
2783 ret = -LTTNG_ERR_INVALID;
2784 goto error;
2785 }
2786
60160d2a 2787 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
00e2e675 2788
bc894455 2789 size = uri_parse_str_urls(control_url, data_url, &uris);
a4b92340 2790 if (size < 0) {
e1b624d0
JG
2791 ret = -LTTNG_ERR_INVALID;
2792 goto error;
a4b92340
DG
2793 }
2794
2795 lsm.u.uri.size = size;
00e2e675 2796
28ab034a
JG
2797 ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(
2798 &lsm, uris, sizeof(struct lttng_uri) * size, NULL);
3dd05a85
DG
2799
2800 free(uris);
e1b624d0 2801error:
3dd05a85 2802 return ret;
00e2e675
DG
2803}
2804
2805/*
9c6bda17 2806 * [OBSOLETE]
00e2e675 2807 */
28ab034a 2808extern "C" LTTNG_EXPORT int lttng_enable_consumer(struct lttng_handle *handle);
f46376a1 2809int lttng_enable_consumer(struct lttng_handle *handle __attribute__((unused)))
00e2e675 2810{
785d2d0d 2811 return -ENOSYS;
00e2e675
DG
2812}
2813
2814/*
9c6bda17 2815 * [OBSOLETE]
00e2e675 2816 */
28ab034a 2817extern "C" LTTNG_EXPORT int lttng_disable_consumer(struct lttng_handle *handle);
f46376a1 2818int lttng_disable_consumer(struct lttng_handle *handle __attribute__((unused)))
00e2e675 2819{
785d2d0d 2820 return -ENOSYS;
00e2e675
DG
2821}
2822
07424f16 2823/*
b178f53e 2824 * [OBSOLETE]
07424f16 2825 */
28ab034a
JG
2826extern "C" LTTNG_EXPORT int
2827_lttng_create_session_ext(const char *name, const char *url, const char *datetime);
f46376a1 2828int _lttng_create_session_ext(const char *name __attribute__((unused)),
28ab034a
JG
2829 const char *url __attribute__((unused)),
2830 const char *datetime __attribute__((unused)))
07424f16 2831{
b178f53e 2832 return -ENOSYS;
07424f16
DG
2833}
2834
806e2684
DG
2835/*
2836 * For a given session name, this call checks if the data is ready to be read
2837 * or is still being extracted by the consumer(s) hence not ready to be used by
2838 * any readers.
2839 */
6d805429 2840int lttng_data_pending(const char *session_name)
806e2684
DG
2841{
2842 int ret;
2843 struct lttcomm_session_msg lsm;
f6151c55 2844 uint8_t *pending = NULL;
806e2684
DG
2845
2846 if (session_name == NULL) {
2847 return -LTTNG_ERR_INVALID;
2848 }
2849
53efb85a 2850 memset(&lsm, 0, sizeof(lsm));
37a5ef39 2851 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_DATA_PENDING;
806e2684 2852
28ab034a 2853 ret = lttng_strncpy(lsm.session.name, session_name, sizeof(lsm.session.name));
e1b624d0
JG
2854 if (ret) {
2855 ret = -LTTNG_ERR_INVALID;
2856 goto end;
2857 }
806e2684 2858
f6151c55
JG
2859 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &pending);
2860 if (ret < 0) {
2861 goto end;
2862 } else if (ret != 1) {
2863 /* Unexpected payload size */
2864 ret = -LTTNG_ERR_INVALID;
2865 goto end;
e848d36d
JG
2866 } else if (!pending) {
2867 /* Internal error. */
2868 ret = -LTTNG_ERR_UNK;
2869 goto end;
806e2684
DG
2870 }
2871
f6151c55
JG
2872 ret = (int) *pending;
2873end:
2874 free(pending);
806e2684
DG
2875 return ret;
2876}
2877
93ec662e
JD
2878/*
2879 * Regenerate the metadata for a session.
2880 * Return 0 on success, a negative error code on error.
2881 */
eded6438 2882int lttng_regenerate_metadata(const char *session_name)
93ec662e
JD
2883{
2884 int ret;
2885 struct lttcomm_session_msg lsm;
2886
2887 if (!session_name) {
2888 ret = -LTTNG_ERR_INVALID;
2889 goto end;
2890 }
2891
2892 memset(&lsm, 0, sizeof(lsm));
37a5ef39 2893 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_REGENERATE_METADATA;
93ec662e 2894
28ab034a 2895 ret = lttng_strncpy(lsm.session.name, session_name, sizeof(lsm.session.name));
e1b624d0
JG
2896 if (ret) {
2897 ret = -LTTNG_ERR_INVALID;
2898 goto end;
2899 }
93ec662e
JD
2900
2901 ret = lttng_ctl_ask_sessiond(&lsm, NULL);
2902 if (ret < 0) {
2903 goto end;
2904 }
2905
2906 ret = 0;
2907end:
2908 return ret;
2909}
2910
eded6438
JD
2911/*
2912 * Deprecated, replaced by lttng_regenerate_metadata.
2913 */
2914int lttng_metadata_regenerate(const char *session_name)
2915{
2916 return lttng_regenerate_metadata(session_name);
2917}
2918
c2561365
JD
2919/*
2920 * Regenerate the statedump of a session.
2921 * Return 0 on success, a negative error code on error.
2922 */
2923int lttng_regenerate_statedump(const char *session_name)
2924{
2925 int ret;
2926 struct lttcomm_session_msg lsm;
2927
2928 if (!session_name) {
2929 ret = -LTTNG_ERR_INVALID;
2930 goto end;
2931 }
2932
2933 memset(&lsm, 0, sizeof(lsm));
37a5ef39 2934 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_REGENERATE_STATEDUMP;
c2561365 2935
28ab034a 2936 ret = lttng_strncpy(lsm.session.name, session_name, sizeof(lsm.session.name));
e1b624d0
JG
2937 if (ret) {
2938 ret = -LTTNG_ERR_INVALID;
2939 goto end;
2940 }
c2561365
JD
2941
2942 ret = lttng_ctl_ask_sessiond(&lsm, NULL);
2943 if (ret < 0) {
2944 goto end;
2945 }
2946
2947 ret = 0;
2948end:
2949 return ret;
2950}
2951
28ab034a
JG
2952static int
2953_lttng_register_trigger(struct lttng_trigger *trigger, const char *name, bool generate_name)
a58c490f
JG
2954{
2955 int ret;
99608320 2956 struct lttcomm_session_msg lsm = {
37a5ef39 2957 .cmd_type = LTTCOMM_SESSIOND_COMMAND_REGISTER_TRIGGER,
1c9a0b0e
MJ
2958 .session = {},
2959 .domain = {},
2960 .u = {},
2961 .fd_count = 0,
99608320 2962 };
4bd69c5f 2963 lsm.u.trigger.is_trigger_anonymous = !name && !generate_name;
99608320
JR
2964 struct lttcomm_session_msg *message_lsm;
2965 struct lttng_payload message;
2966 struct lttng_payload reply;
242388e4 2967 struct lttng_trigger *reply_trigger = NULL;
9124c630 2968 enum lttng_domain_type domain_type;
64eafdf6
JR
2969 const struct lttng_credentials user_creds = {
2970 .uid = LTTNG_OPTIONAL_INIT_VALUE(geteuid()),
2971 .gid = LTTNG_OPTIONAL_INIT_UNSET,
2972 };
a5c2d2a7
JG
2973 const char *unused_trigger_name = NULL;
2974 enum lttng_trigger_status trigger_status;
99608320
JR
2975
2976 lttng_payload_init(&message);
2977 lttng_payload_init(&reply);
a58c490f
JG
2978
2979 if (!trigger) {
2980 ret = -LTTNG_ERR_INVALID;
2981 goto end;
2982 }
2983
a5c2d2a7
JG
2984 trigger_status = lttng_trigger_get_name(trigger, &unused_trigger_name);
2985 if (trigger_status != LTTNG_TRIGGER_STATUS_UNSET) {
2986 /* Re-using already registered trigger. */
2987 ret = -LTTNG_ERR_INVALID;
2988 goto end;
2989 }
2990
2991 if (name) {
2992 trigger_status = lttng_trigger_set_name(trigger, name);
2993 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
2994 ret = -LTTNG_ERR_NOMEM;
2995 goto end;
2996 }
2997 }
2998
64eafdf6
JR
2999 if (!trigger->creds.uid.is_set) {
3000 /* Use the client's credentials as the trigger credentials. */
3001 lttng_trigger_set_credentials(trigger, &user_creds);
3002 } else {
3003 /*
3004 * Validate that either the current trigger credentials and the
3005 * client credentials are identical or that the current user is
3006 * root. The root user can register, unregister triggers for
3007 * himself and other users.
3008 *
3009 * This check is also present on the sessiond side, using the
3010 * credentials passed on the socket. These check are all
3011 * "safety" checks.
3012 */
3013 const struct lttng_credentials *trigger_creds =
28ab034a 3014 lttng_trigger_get_credentials(trigger);
64eafdf6
JR
3015
3016 if (!lttng_credentials_is_equal_uid(trigger_creds, &user_creds)) {
3017 if (lttng_credentials_get_uid(&user_creds) != 0) {
3018 ret = -LTTNG_ERR_EPERM;
a5c2d2a7 3019 goto end_unset_name;
64eafdf6
JR
3020 }
3021 }
3022 }
3023
a58c490f 3024 if (!lttng_trigger_validate(trigger)) {
eac4828d 3025 ret = -LTTNG_ERR_INVALID_TRIGGER;
a5c2d2a7 3026 goto end_unset_name;
a58c490f
JG
3027 }
3028
28ab034a 3029 domain_type = lttng_trigger_get_underlying_domain_type_restriction(trigger);
9124c630
JR
3030
3031 lsm.domain.type = domain_type;
3032
97285430
JG
3033 ret = lttng_dynamic_buffer_append(&message.buffer, &lsm, sizeof(lsm));
3034 if (ret) {
3035 ret = -LTTNG_ERR_NOMEM;
a5c2d2a7 3036 goto end_unset_name;
97285430 3037 }
99608320 3038
99608320 3039 ret = lttng_trigger_serialize(trigger, &message);
3647288f 3040 if (ret < 0) {
a58c490f 3041 ret = -LTTNG_ERR_UNK;
a5c2d2a7 3042 goto end_unset_name;
a58c490f
JG
3043 }
3044
b22f4f54
JG
3045 /*
3046 * This is needed to populate the trigger object size for the command
3047 * header.
3048 */
3049 message_lsm = (struct lttcomm_session_msg *) message.buffer.data;
3050
99608320
JR
3051 message_lsm->u.trigger.length = (uint32_t) message.buffer.size - sizeof(lsm);
3052
3053 {
3054 struct lttng_payload_view message_view =
28ab034a 3055 lttng_payload_view_from_payload(&message, 0, -1);
99608320 3056
28ab034a 3057 message_lsm->fd_count = lttng_payload_view_get_fd_handle_count(&message_view);
99608320
JR
3058 ret = lttng_ctl_ask_sessiond_payload(&message_view, &reply);
3059 if (ret < 0) {
a5c2d2a7 3060 goto end_unset_name;
99608320
JR
3061 }
3062 }
3063
242388e4
JR
3064 {
3065 struct lttng_payload_view reply_view =
28ab034a 3066 lttng_payload_view_from_payload(&reply, 0, reply.buffer.size);
242388e4 3067
28ab034a 3068 ret = lttng_trigger_create_from_payload(&reply_view, &reply_trigger);
242388e4 3069 if (ret < 0) {
a5c2d2a7
JG
3070 ret = -LTTNG_ERR_INVALID_PROTOCOL;
3071 goto end_unset_name;
242388e4
JR
3072 }
3073 }
3074
a5c2d2a7
JG
3075 if (name || generate_name) {
3076 ret = lttng_trigger_assign_name(trigger, reply_trigger);
3077 if (ret < 0) {
3078 ret = -LTTNG_ERR_NOMEM;
3079 goto end;
3080 }
242388e4
JR
3081 }
3082
99608320 3083 ret = 0;
a5c2d2a7
JG
3084 goto end;
3085
3086end_unset_name:
3087 trigger_status = lttng_trigger_set_name(trigger, NULL);
3088 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
3089 ret = -LTTNG_ERR_UNK;
3090 }
a58c490f 3091end:
99608320
JR
3092 lttng_payload_reset(&message);
3093 lttng_payload_reset(&reply);
242388e4 3094 lttng_trigger_destroy(reply_trigger);
a58c490f
JG
3095 return ret;
3096}
3097
a5c2d2a7
JG
3098int lttng_register_trigger(struct lttng_trigger *trigger)
3099{
3100 /* Register an anonymous trigger. */
3101 return _lttng_register_trigger(trigger, NULL, false);
3102}
3103
28ab034a
JG
3104enum lttng_error_code lttng_register_trigger_with_name(struct lttng_trigger *trigger,
3105 const char *name)
a5c2d2a7
JG
3106{
3107 const int ret = _lttng_register_trigger(trigger, name, false);
3108
28ab034a 3109 return ret == 0 ? LTTNG_OK : (enum lttng_error_code) - ret;
a5c2d2a7
JG
3110}
3111
28ab034a 3112enum lttng_error_code lttng_register_trigger_with_automatic_name(struct lttng_trigger *trigger)
a5c2d2a7 3113{
28ab034a 3114 const int ret = _lttng_register_trigger(trigger, nullptr, true);
a5c2d2a7 3115
28ab034a 3116 return ret == 0 ? LTTNG_OK : (enum lttng_error_code) - ret;
a5c2d2a7
JG
3117}
3118
28ab034a
JG
3119enum lttng_error_code lttng_error_query_execute(const struct lttng_error_query *query,
3120 const struct lttng_endpoint *endpoint,
3121 struct lttng_error_query_results **results)
b99a0cb3
JG
3122{
3123 int ret;
3124 enum lttng_error_code ret_code;
3125 struct lttcomm_session_msg lsm = {
37a5ef39 3126 .cmd_type = LTTCOMM_SESSIOND_COMMAND_EXECUTE_ERROR_QUERY,
1c9a0b0e
MJ
3127 .session = {},
3128 .domain = {},
3129 .u = {},
3130 .fd_count = 0,
b99a0cb3
JG
3131 };
3132 struct lttng_payload message;
3133 struct lttng_payload reply;
3134 struct lttcomm_session_msg *message_lsm;
3135
3136 lttng_payload_init(&message);
3137 lttng_payload_init(&reply);
3138
3139 if (!query || !results) {
3140 ret_code = LTTNG_ERR_INVALID;
3141 goto end;
3142 }
3143
3144 if (endpoint != lttng_session_daemon_command_endpoint) {
3145 ret_code = LTTNG_ERR_INVALID_ERROR_QUERY_TARGET;
3146 goto end;
3147 }
3148
3149 ret = lttng_dynamic_buffer_append(&message.buffer, &lsm, sizeof(lsm));
3150 if (ret) {
3151 ret_code = LTTNG_ERR_NOMEM;
3152 goto end;
3153 }
3154
3155 ret = lttng_error_query_serialize(query, &message);
3156 if (ret) {
3157 ret_code = LTTNG_ERR_UNK;
3158 goto end;
3159 }
3160
3161 message_lsm = (struct lttcomm_session_msg *) message.buffer.data;
28ab034a 3162 message_lsm->u.error_query.length = (uint32_t) message.buffer.size - sizeof(lsm);
b99a0cb3
JG
3163
3164 {
3165 struct lttng_payload_view message_view =
28ab034a 3166 lttng_payload_view_from_payload(&message, 0, -1);
b99a0cb3 3167
28ab034a 3168 message_lsm->fd_count = lttng_payload_view_get_fd_handle_count(&message_view);
b99a0cb3
JG
3169 ret = lttng_ctl_ask_sessiond_payload(&message_view, &reply);
3170 if (ret < 0) {
28ab034a 3171 ret_code = (lttng_error_code) -ret;
b99a0cb3
JG
3172 goto end;
3173 }
3174 }
3175
3176 {
3177 ssize_t reply_create_ret;
3178 struct lttng_payload_view reply_view =
28ab034a 3179 lttng_payload_view_from_payload(&reply, 0, reply.buffer.size);
b99a0cb3 3180
28ab034a
JG
3181 reply_create_ret =
3182 lttng_error_query_results_create_from_payload(&reply_view, results);
b99a0cb3
JG
3183 if (reply_create_ret < 0) {
3184 ret_code = LTTNG_ERR_INVALID_PROTOCOL;
3185 goto end;
3186 }
3187 }
3188
3189 ret_code = LTTNG_OK;
3190end:
3191 lttng_payload_reset(&message);
3192 lttng_payload_reset(&reply);
3193 return ret_code;
3194}
3195
b61776fb 3196int lttng_unregister_trigger(const struct lttng_trigger *trigger)
a58c490f
JG
3197{
3198 int ret;
3199 struct lttcomm_session_msg lsm;
99608320
JR
3200 struct lttcomm_session_msg *message_lsm;
3201 struct lttng_payload message;
3202 struct lttng_payload reply;
b61776fb 3203 struct lttng_trigger *copy = NULL;
64eafdf6
JR
3204 const struct lttng_credentials user_creds = {
3205 .uid = LTTNG_OPTIONAL_INIT_VALUE(geteuid()),
3206 .gid = LTTNG_OPTIONAL_INIT_UNSET,
3207 };
99608320
JR
3208
3209 lttng_payload_init(&message);
3210 lttng_payload_init(&reply);
a58c490f
JG
3211
3212 if (!trigger) {
3213 ret = -LTTNG_ERR_INVALID;
3214 goto end;
3215 }
3216
b61776fb
SM
3217 copy = lttng_trigger_copy(trigger);
3218 if (!copy) {
3219 ret = -LTTNG_ERR_UNK;
3220 goto end;
3221 }
3222
3223 if (!copy->creds.uid.is_set) {
3224 /* Use the client credentials as the trigger credentials */
3225 lttng_trigger_set_credentials(copy, &user_creds);
64eafdf6
JR
3226 } else {
3227 /*
3228 * Validate that either the current trigger credentials and the
3229 * client credentials are identical or that the current user is
3230 * root. The root user can register, unregister triggers for
3231 * himself and other users.
3232 *
3233 * This check is also present on the sessiond side, using the
3234 * credentials passed on the socket. These check are all
3235 * "safety" checks.
3236 */
28ab034a 3237 const struct lttng_credentials *trigger_creds = lttng_trigger_get_credentials(copy);
64eafdf6
JR
3238 if (!lttng_credentials_is_equal_uid(trigger_creds, &user_creds)) {
3239 if (lttng_credentials_get_uid(&user_creds) != 0) {
3240 ret = -LTTNG_ERR_EPERM;
3241 goto end;
3242 }
3243 }
3244 }
3245
b61776fb 3246 if (!lttng_trigger_validate(copy)) {
3647288f 3247 ret = -LTTNG_ERR_INVALID_TRIGGER;
a58c490f
JG
3248 goto end;
3249 }
3250
99608320 3251 memset(&lsm, 0, sizeof(lsm));
37a5ef39 3252 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_UNREGISTER_TRIGGER;
99608320 3253
97285430
JG
3254 ret = lttng_dynamic_buffer_append(&message.buffer, &lsm, sizeof(lsm));
3255 if (ret) {
3256 ret = -LTTNG_ERR_NOMEM;
3257 goto end;
3258 }
99608320 3259
b61776fb 3260 ret = lttng_trigger_serialize(copy, &message);
3647288f 3261 if (ret < 0) {
a58c490f
JG
3262 ret = -LTTNG_ERR_UNK;
3263 goto end;
3264 }
3265
b0a79813
FD
3266 /*
3267 * This is needed to populate the trigger object size for the command
3268 * header and number of fds sent.
28ab034a 3269 */
b0a79813
FD
3270 message_lsm = (struct lttcomm_session_msg *) message.buffer.data;
3271
99608320
JR
3272 message_lsm->u.trigger.length = (uint32_t) message.buffer.size - sizeof(lsm);
3273
3274 {
3275 struct lttng_payload_view message_view =
28ab034a 3276 lttng_payload_view_from_payload(&message, 0, -1);
99608320
JR
3277
3278 /*
3279 * Update the message header with the number of fd that will be
3280 * sent.
3281 */
28ab034a 3282 message_lsm->fd_count = lttng_payload_view_get_fd_handle_count(&message_view);
99608320
JR
3283
3284 ret = lttng_ctl_ask_sessiond_payload(&message_view, &reply);
3285 if (ret < 0) {
3286 goto end;
3287 }
3288 }
3289
3290 ret = 0;
a58c490f 3291end:
b61776fb 3292 lttng_trigger_destroy(copy);
99608320
JR
3293 lttng_payload_reset(&message);
3294 lttng_payload_reset(&reply);
a58c490f
JG
3295 return ret;
3296}
3297
fbc9f37d
JR
3298/*
3299 * Ask the session daemon for all registered triggers for the current user.
3300 *
3301 * Allocates and return an lttng_triggers set.
3302 * On error, returns a suitable lttng_error_code.
3303 */
3304enum lttng_error_code lttng_list_triggers(struct lttng_triggers **triggers)
3305{
3306 int ret;
3307 enum lttng_error_code ret_code = LTTNG_OK;
1c9a0b0e 3308 struct lttcomm_session_msg lsm = {
37a5ef39 3309 .cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_TRIGGERS,
1c9a0b0e
MJ
3310 .session = {},
3311 .domain = {},
3312 .u = {},
3313 .fd_count = 0,
3314 };
fbc9f37d
JR
3315 struct lttng_triggers *local_triggers = NULL;
3316 struct lttng_payload reply;
3317 struct lttng_payload_view lsm_view =
28ab034a 3318 lttng_payload_view_init_from_buffer((const char *) &lsm, 0, sizeof(lsm));
fbc9f37d
JR
3319
3320 lttng_payload_init(&reply);
3321
3322 ret = lttng_ctl_ask_sessiond_payload(&lsm_view, &reply);
3323 if (ret < 0) {
28ab034a 3324 ret_code = (enum lttng_error_code) - ret;
fbc9f37d
JR
3325 goto end;
3326 }
3327
3328 {
3329 struct lttng_payload_view reply_view =
28ab034a 3330 lttng_payload_view_from_payload(&reply, 0, reply.buffer.size);
fbc9f37d 3331
28ab034a 3332 ret = lttng_triggers_create_from_payload(&reply_view, &local_triggers);
fbc9f37d
JR
3333 if (ret < 0) {
3334 ret_code = LTTNG_ERR_FATAL;
3335 goto end;
3336 }
3337 }
3338
3339 *triggers = local_triggers;
3340 local_triggers = NULL;
3341end:
3342 lttng_payload_reset(&reply);
3343 lttng_triggers_destroy(local_triggers);
3344 return ret_code;
3345}
3346
fac6795d 3347/*
9ae110e2 3348 * lib constructor.
fac6795d 3349 */
b2b89e8a 3350static void __attribute__((constructor)) init(void)
fac6795d
DG
3351{
3352 /* Set default session group */
bbccc3d2 3353 lttng_set_tracing_group(DEFAULT_TRACING_GROUP);
fac6795d 3354}
49cca668
DG
3355
3356/*
9ae110e2 3357 * lib destructor.
49cca668 3358 */
b2b89e8a 3359static void __attribute__((destructor)) lttng_ctl_exit(void)
49cca668
DG
3360{
3361 free(tracing_group);
3362}
This page took 0.277905 seconds and 4 git commands to generate.