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