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