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