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