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