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