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