82f10bec03228f16a5267e899e8c9efe23f11872
[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(void)
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, NULL);
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(void)
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(void)
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(void)
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(void)
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 = NULL;
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 = NULL;
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 = NULL;
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 = NULL;
728
729 handle = zmalloc<lttng_handle>();
730 if (handle == NULL) {
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 NULL;
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 == NULL || socket_path == NULL) {
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, NULL);
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 == NULL) {
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, NULL);
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 == NULL) {
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, NULL);
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 == NULL || ctx == NULL) {
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, NULL, 0, NULL);
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, NULL);
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 = NULL;
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 NULL;
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 = NULL;
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 == NULL || ev == NULL) {
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 != NULL || 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 : NULL,
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 : NULL,
1239 fd_count,
1240 view.buffer.size ? view.buffer.data : NULL,
1241 view.buffer.size,
1242 NULL,
1243 NULL,
1244 0);
1245 }
1246
1247 error:
1248 if (filter_expression && ctx) {
1249 filter_bytecode_free(ctx);
1250 filter_ir_free(ctx);
1251 filter_parser_ctx_free(ctx);
1252 }
1253 if (free_filter_expression) {
1254 /*
1255 * The filter expression has been replaced and must be freed as
1256 * it is not the original filter expression received as a
1257 * parameter.
1258 */
1259 free(filter_expression);
1260 }
1261 /*
1262 * Return directly to the caller and don't ask the sessiond since
1263 * something went wrong in the parsing of data above.
1264 */
1265 lttng_payload_reset(&payload);
1266 return ret;
1267 }
1268
1269 int lttng_disable_event_ext(struct lttng_handle *handle,
1270 struct lttng_event *ev,
1271 const char *channel_name,
1272 const char *original_filter_expression)
1273 {
1274 struct lttcomm_session_msg lsm = {
1275 .cmd_type = LTTCOMM_SESSIOND_COMMAND_DISABLE_EVENT,
1276 .session = {},
1277 .domain = {},
1278 .u = {},
1279 .fd_count = 0,
1280 };
1281 struct lttng_payload payload;
1282 int ret = 0;
1283 unsigned int free_filter_expression = 0;
1284 struct filter_parser_ctx *ctx = NULL;
1285 size_t bytecode_len = 0;
1286
1287 /*
1288 * We have either a filter or some exclusions, so we need to set up
1289 * a variable-length payload from where to send the data.
1290 */
1291 lttng_payload_init(&payload);
1292
1293 /*
1294 * Cast as non-const since we may replace the filter expression
1295 * by a dynamically allocated string. Otherwise, the original
1296 * string is not modified.
1297 */
1298 char *filter_expression = (char *) original_filter_expression;
1299
1300 if (handle == NULL || ev == NULL) {
1301 ret = -LTTNG_ERR_INVALID;
1302 goto error;
1303 }
1304
1305 /*
1306 * Empty filter string will always be rejected by the parser
1307 * anyway, so treat this corner-case early to eliminate
1308 * lttng_fmemopen error for 0-byte allocation.
1309 */
1310 if (filter_expression && filter_expression[0] == '\0') {
1311 ret = -LTTNG_ERR_INVALID;
1312 goto error;
1313 }
1314
1315 /* Parse filter expression. */
1316 if (filter_expression != NULL || handle->domain.type == LTTNG_DOMAIN_JUL ||
1317 handle->domain.type == LTTNG_DOMAIN_LOG4J ||
1318 handle->domain.type == LTTNG_DOMAIN_PYTHON) {
1319 if (handle->domain.type == LTTNG_DOMAIN_JUL ||
1320 handle->domain.type == LTTNG_DOMAIN_LOG4J ||
1321 handle->domain.type == LTTNG_DOMAIN_PYTHON) {
1322 char *agent_filter;
1323
1324 /* Setup agent filter if needed. */
1325 agent_filter = set_agent_filter(filter_expression, ev);
1326 if (!agent_filter) {
1327 if (!filter_expression) {
1328 /*
1329 * No JUL and no filter, just skip
1330 * everything below.
1331 */
1332 goto serialize;
1333 }
1334 } else {
1335 /*
1336 * With an agent filter, the original filter has
1337 * been added to it thus replace the filter
1338 * expression.
1339 */
1340 filter_expression = agent_filter;
1341 free_filter_expression = 1;
1342 }
1343 }
1344
1345 if (strnlen(filter_expression, LTTNG_FILTER_MAX_LEN) == LTTNG_FILTER_MAX_LEN) {
1346 ret = -LTTNG_ERR_FILTER_INVAL;
1347 goto error;
1348 }
1349
1350 ret = filter_parser_ctx_create_from_filter_expression(filter_expression, &ctx);
1351 if (ret) {
1352 goto error;
1353 }
1354
1355 bytecode_len = bytecode_get_len(&ctx->bytecode->b) + sizeof(ctx->bytecode->b);
1356 if (bytecode_len > LTTNG_FILTER_MAX_LEN) {
1357 ret = -LTTNG_ERR_FILTER_INVAL;
1358 goto error;
1359 }
1360 }
1361
1362 serialize:
1363 ret = lttng_event_serialize(ev,
1364 0,
1365 NULL,
1366 filter_expression,
1367 bytecode_len,
1368 (ctx && bytecode_len) ? &ctx->bytecode->b : NULL,
1369 &payload);
1370 if (ret) {
1371 ret = -LTTNG_ERR_INVALID;
1372 goto error;
1373 }
1374
1375 /* If no channel name, send empty string. */
1376 ret = lttng_strncpy(
1377 lsm.u.disable.channel_name, channel_name ?: "", sizeof(lsm.u.disable.channel_name));
1378 if (ret) {
1379 ret = -LTTNG_ERR_INVALID;
1380 goto error;
1381 }
1382
1383 /* Domain */
1384 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
1385
1386 /* Session name */
1387 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
1388 if (ret) {
1389 ret = -LTTNG_ERR_INVALID;
1390 goto error;
1391 }
1392
1393 /* Length of the serialized event. */
1394 lsm.u.disable.length = (uint32_t) payload.buffer.size;
1395
1396 {
1397 struct lttng_payload_view view = lttng_payload_view_from_payload(&payload, 0, -1);
1398 int fd_count = lttng_payload_view_get_fd_handle_count(&view);
1399 int fd_to_send;
1400
1401 if (fd_count < 0) {
1402 goto error;
1403 }
1404
1405 LTTNG_ASSERT(fd_count == 0 || fd_count == 1);
1406 if (fd_count == 1) {
1407 struct fd_handle *h = lttng_payload_view_pop_fd_handle(&view);
1408
1409 if (!h) {
1410 goto error;
1411 }
1412
1413 fd_to_send = fd_handle_get_fd(h);
1414 fd_handle_put(h);
1415 }
1416
1417 ret = lttng_ctl_ask_sessiond_fds_varlen(&lsm,
1418 fd_count ? &fd_to_send : NULL,
1419 fd_count,
1420 view.buffer.size ? view.buffer.data : NULL,
1421 view.buffer.size,
1422 NULL,
1423 NULL,
1424 0);
1425 }
1426
1427 error:
1428 if (filter_expression && ctx) {
1429 filter_bytecode_free(ctx);
1430 filter_ir_free(ctx);
1431 filter_parser_ctx_free(ctx);
1432 }
1433 if (free_filter_expression) {
1434 /*
1435 * The filter expression has been replaced and must be freed as
1436 * it is not the original filter expression received as a
1437 * parameter.
1438 */
1439 free(filter_expression);
1440 }
1441 /*
1442 * Return directly to the caller and don't ask the sessiond since
1443 * something went wrong in the parsing of data above.
1444 */
1445 lttng_payload_reset(&payload);
1446 return ret;
1447 }
1448
1449 /*
1450 * Disable event(s) of a channel and domain.
1451 * If no event name is specified, all events are disabled.
1452 * If no channel name is specified, the default 'channel0' is used.
1453 * Returns size of returned session payload data or a negative error code.
1454 */
1455 int lttng_disable_event(struct lttng_handle *handle, const char *name, const char *channel_name)
1456 {
1457 int ret;
1458 struct lttng_event ev;
1459
1460 memset(&ev, 0, sizeof(ev));
1461 ev.loglevel = -1;
1462 ev.type = LTTNG_EVENT_ALL;
1463 ret = lttng_strncpy(ev.name, name ?: "", sizeof(ev.name));
1464 if (ret) {
1465 ret = -LTTNG_ERR_INVALID;
1466 goto end;
1467 }
1468
1469 ret = lttng_disable_event_ext(handle, &ev, channel_name, NULL);
1470 end:
1471 return ret;
1472 }
1473
1474 struct lttng_channel *lttng_channel_create(struct lttng_domain *domain)
1475 {
1476 struct lttng_channel *channel = NULL;
1477
1478 if (!domain) {
1479 goto end;
1480 }
1481
1482 /* Validate domain. */
1483 switch (domain->type) {
1484 case LTTNG_DOMAIN_UST:
1485 switch (domain->buf_type) {
1486 case LTTNG_BUFFER_PER_UID:
1487 case LTTNG_BUFFER_PER_PID:
1488 break;
1489 default:
1490 goto end;
1491 }
1492 break;
1493 case LTTNG_DOMAIN_KERNEL:
1494 if (domain->buf_type != LTTNG_BUFFER_GLOBAL) {
1495 goto end;
1496 }
1497 break;
1498 default:
1499 goto end;
1500 }
1501
1502 channel = lttng_channel_create_internal();
1503 if (!channel) {
1504 goto end;
1505 }
1506
1507 lttng_channel_set_default_attr(domain, &channel->attr);
1508 end:
1509 return channel;
1510 }
1511
1512 void lttng_channel_destroy(struct lttng_channel *channel)
1513 {
1514 if (!channel) {
1515 return;
1516 }
1517
1518 if (channel->attr.extended.ptr) {
1519 free(channel->attr.extended.ptr);
1520 }
1521 free(channel);
1522 }
1523
1524 /*
1525 * Enable channel per domain
1526 * Returns size of returned session payload data or a negative error code.
1527 */
1528 int lttng_enable_channel(struct lttng_handle *handle, struct lttng_channel *in_chan)
1529 {
1530 enum lttng_error_code ret_code;
1531 int ret;
1532 struct lttng_dynamic_buffer buffer;
1533 struct lttcomm_session_msg lsm;
1534 uint64_t total_buffer_size_needed_per_cpu = 0;
1535 struct lttng_channel *channel = NULL;
1536
1537 lttng_dynamic_buffer_init(&buffer);
1538
1539 /* NULL arguments are forbidden. No default values. */
1540 if (handle == NULL || in_chan == NULL) {
1541 ret = -LTTNG_ERR_INVALID;
1542 goto end;
1543 }
1544
1545 /*
1546 * Verify that the amount of memory required to create the requested
1547 * buffer is available on the system at the moment.
1548 */
1549 if (in_chan->attr.num_subbuf > UINT64_MAX / in_chan->attr.subbuf_size) {
1550 /* Overflow */
1551 ret = -LTTNG_ERR_OVERFLOW;
1552 goto end;
1553 }
1554
1555 total_buffer_size_needed_per_cpu = in_chan->attr.num_subbuf * in_chan->attr.subbuf_size;
1556 ret_code = check_enough_available_memory(total_buffer_size_needed_per_cpu);
1557 if (ret_code != LTTNG_OK) {
1558 ret = -ret_code;
1559 goto end;
1560 }
1561
1562 /* Copy the channel for easier manipulation. */
1563 channel = lttng_channel_copy(in_chan);
1564 if (!channel) {
1565 ret = -LTTNG_ERR_NOMEM;
1566 goto end;
1567 }
1568
1569 /* Populate the channel extended attribute if necessary. */
1570 if (!channel->attr.extended.ptr) {
1571 struct lttng_channel_extended *extended = zmalloc<lttng_channel_extended>();
1572
1573 if (!extended) {
1574 ret = -LTTNG_ERR_NOMEM;
1575 goto end;
1576 }
1577
1578 lttng_channel_set_default_extended_attr(&handle->domain, extended);
1579 channel->attr.extended.ptr = extended;
1580 }
1581
1582 /* Prepare the payload */
1583 memset(&lsm, 0, sizeof(lsm));
1584
1585 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_ENABLE_CHANNEL;
1586 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
1587
1588 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
1589 if (ret) {
1590 ret = -LTTNG_ERR_INVALID;
1591 goto end;
1592 }
1593
1594 ret = lttng_channel_serialize(channel, &buffer);
1595 if (ret) {
1596 ret = -LTTNG_ERR_FATAL;
1597 goto end;
1598 }
1599
1600 lsm.u.channel.length = buffer.size;
1601
1602 ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(&lsm, buffer.data, buffer.size, NULL);
1603 end:
1604 lttng_channel_destroy(channel);
1605 lttng_dynamic_buffer_reset(&buffer);
1606 return ret;
1607 }
1608
1609 /*
1610 * All tracing will be stopped for registered events of the channel.
1611 * Returns size of returned session payload data or a negative error code.
1612 */
1613 int lttng_disable_channel(struct lttng_handle *handle, const char *name)
1614 {
1615 int ret;
1616 struct lttcomm_session_msg lsm;
1617
1618 /* Safety check. Both are mandatory. */
1619 if (handle == NULL || name == NULL) {
1620 return -LTTNG_ERR_INVALID;
1621 }
1622
1623 memset(&lsm, 0, sizeof(lsm));
1624
1625 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_DISABLE_CHANNEL;
1626
1627 ret = lttng_strncpy(lsm.u.disable.channel_name, name, sizeof(lsm.u.disable.channel_name));
1628 if (ret) {
1629 ret = -LTTNG_ERR_INVALID;
1630 goto end;
1631 }
1632
1633 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
1634
1635 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
1636 if (ret) {
1637 ret = -LTTNG_ERR_INVALID;
1638 goto end;
1639 }
1640
1641 ret = lttng_ctl_ask_sessiond(&lsm, NULL);
1642 end:
1643 return ret;
1644 }
1645
1646 /*
1647 * Lists all available tracepoints of domain.
1648 * Sets the contents of the events array.
1649 * Returns the number of lttng_event entries in events;
1650 * on error, returns a negative value.
1651 */
1652 int lttng_list_tracepoints(struct lttng_handle *handle, struct lttng_event **events)
1653 {
1654 enum lttng_error_code ret_code;
1655 int ret, total_payload_received;
1656 char *reception_buffer = NULL;
1657 struct lttcomm_session_msg lsm = {
1658 .cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_TRACEPOINTS,
1659 .session = {},
1660 .domain = {},
1661 .u = {},
1662 .fd_count = 0,
1663 };
1664 struct lttcomm_list_command_header *cmd_header = NULL;
1665 size_t cmd_header_len;
1666 unsigned int nb_events = 0;
1667
1668 if (handle == NULL) {
1669 ret = -LTTNG_ERR_INVALID;
1670 goto end;
1671 }
1672
1673 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
1674
1675 ret = lttng_ctl_ask_sessiond_fds_varlen(&lsm,
1676 NULL,
1677 0,
1678 NULL,
1679 0,
1680 (void **) &reception_buffer,
1681 (void **) &cmd_header,
1682 &cmd_header_len);
1683 if (ret < 0) {
1684 goto end;
1685 }
1686
1687 total_payload_received = ret;
1688
1689 if (!cmd_header) {
1690 ret = -LTTNG_ERR_UNK;
1691 goto end;
1692 }
1693
1694 if (cmd_header->count > INT_MAX) {
1695 ret = -LTTNG_ERR_OVERFLOW;
1696 goto end;
1697 }
1698
1699 nb_events = (unsigned int) cmd_header->count;
1700
1701 {
1702 struct lttng_buffer_view events_view =
1703 lttng_buffer_view_init(reception_buffer, 0, total_payload_received);
1704 struct lttng_payload_view events_payload_view =
1705 lttng_payload_view_from_buffer_view(&events_view, 0, -1);
1706
1707 ret_code = lttng_events_create_and_flatten_from_payload(
1708 &events_payload_view, nb_events, events);
1709 if (ret_code != LTTNG_OK) {
1710 ret = -ret_code;
1711 goto end;
1712 }
1713 }
1714
1715 ret = (int) nb_events;
1716
1717 end:
1718 free(cmd_header);
1719 free(reception_buffer);
1720 return ret;
1721 }
1722
1723 /*
1724 * Lists all available tracepoint fields of domain.
1725 * Sets the contents of the event field array.
1726 * Returns the number of lttng_event_field entries in events;
1727 * on error, returns a negative value.
1728 */
1729 int lttng_list_tracepoint_fields(struct lttng_handle *handle, struct lttng_event_field **fields)
1730 {
1731 enum lttng_error_code ret_code;
1732 int ret;
1733 struct lttcomm_session_msg lsm;
1734 const struct lttcomm_list_command_header *cmd_header = NULL;
1735 unsigned int nb_event_fields = 0;
1736 struct lttng_payload reply;
1737
1738 lttng_payload_init(&reply);
1739
1740 if (handle == NULL) {
1741 ret = -LTTNG_ERR_INVALID;
1742 goto end;
1743 }
1744
1745 memset(&lsm, 0, sizeof(lsm));
1746 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_TRACEPOINT_FIELDS;
1747 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
1748
1749 {
1750 lttng_payload_view message_view =
1751 lttng_payload_view_init_from_buffer((const char *) &lsm, 0, sizeof(lsm));
1752
1753 ret = lttng_ctl_ask_sessiond_payload(&message_view, &reply);
1754 if (ret < 0) {
1755 goto end;
1756 }
1757 }
1758
1759 {
1760 const lttng_buffer_view cmd_header_view = lttng_buffer_view_from_dynamic_buffer(
1761 &reply.buffer, 0, sizeof(*cmd_header));
1762
1763 if (!lttng_buffer_view_is_valid(&cmd_header_view)) {
1764 ret = -LTTNG_ERR_INVALID_PROTOCOL;
1765 goto end;
1766 }
1767
1768 cmd_header = (struct lttcomm_list_command_header *) cmd_header_view.data;
1769 }
1770
1771 if (cmd_header->count > INT_MAX) {
1772 ret = -LTTNG_ERR_OVERFLOW;
1773 goto end;
1774 }
1775
1776 nb_event_fields = cmd_header->count;
1777
1778 {
1779 lttng_payload_view reply_view =
1780 lttng_payload_view_from_payload(&reply, sizeof(*cmd_header), -1);
1781
1782 ret_code = lttng_event_fields_create_and_flatten_from_payload(
1783 &reply_view, nb_event_fields, fields);
1784 if (ret_code != LTTNG_OK) {
1785 ret = -ret_code;
1786 goto end;
1787 }
1788 }
1789
1790 ret = nb_event_fields;
1791
1792 end:
1793 lttng_payload_reset(&reply);
1794 return ret;
1795 }
1796
1797 /*
1798 * Lists all available kernel system calls. Allocates and sets the contents of
1799 * the events array.
1800 *
1801 * Returns the number of lttng_event entries in events; on error, returns a
1802 * negative value.
1803 */
1804 int lttng_list_syscalls(struct lttng_event **events)
1805 {
1806 enum lttng_error_code ret_code;
1807 int ret, total_payload_received;
1808 char *reception_buffer = NULL;
1809 struct lttcomm_session_msg lsm = {};
1810 struct lttcomm_list_command_header *cmd_header = NULL;
1811 size_t cmd_header_len;
1812 uint32_t nb_events = 0;
1813
1814 if (!events) {
1815 ret = -LTTNG_ERR_INVALID;
1816 goto end;
1817 }
1818
1819 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_SYSCALLS;
1820 /* Force kernel domain for system calls. */
1821 lsm.domain.type = LTTNG_DOMAIN_KERNEL;
1822
1823 ret = lttng_ctl_ask_sessiond_fds_varlen(&lsm,
1824 NULL,
1825 0,
1826 NULL,
1827 0,
1828 (void **) &reception_buffer,
1829 (void **) &cmd_header,
1830 &cmd_header_len);
1831 if (ret < 0) {
1832 goto end;
1833 }
1834 total_payload_received = ret;
1835
1836 if (!cmd_header) {
1837 ret = -LTTNG_ERR_UNK;
1838 goto end;
1839 }
1840
1841 if (cmd_header->count > INT_MAX) {
1842 ret = -LTTNG_ERR_OVERFLOW;
1843 goto end;
1844 }
1845
1846 nb_events = (unsigned int) cmd_header->count;
1847
1848 {
1849 const struct lttng_buffer_view events_view =
1850 lttng_buffer_view_init(reception_buffer, 0, total_payload_received);
1851 struct lttng_payload_view events_payload_view =
1852 lttng_payload_view_from_buffer_view(&events_view, 0, -1);
1853
1854 ret_code = lttng_events_create_and_flatten_from_payload(
1855 &events_payload_view, nb_events, events);
1856 if (ret_code != LTTNG_OK) {
1857 ret = -ret_code;
1858 goto end;
1859 }
1860 }
1861
1862 ret = (int) nb_events;
1863
1864 end:
1865 free(reception_buffer);
1866 free(cmd_header);
1867 return ret;
1868 }
1869
1870 /*
1871 * Returns a human readable string describing
1872 * the error code (positive or negative value).
1873 */
1874 const char *lttng_strerror(int code)
1875 {
1876 if (code > 0) {
1877 code = -code;
1878 }
1879
1880 return error_get_str(code);
1881 }
1882
1883 enum lttng_error_code lttng_create_session_ext(struct lttng_session_descriptor *session_descriptor)
1884 {
1885 enum lttng_error_code ret_code;
1886 struct lttcomm_session_msg lsm = {
1887 .cmd_type = LTTCOMM_SESSIOND_COMMAND_CREATE_SESSION_EXT,
1888 .session = {},
1889 .domain = {},
1890 .u = {},
1891 .fd_count = 0,
1892 };
1893 void *reply = NULL;
1894 struct lttng_buffer_view reply_view;
1895 int reply_ret;
1896 bool sessiond_must_generate_ouput;
1897 struct lttng_dynamic_buffer payload;
1898 int ret;
1899 size_t descriptor_size;
1900 struct lttng_session_descriptor *descriptor_reply = NULL;
1901
1902 lttng_dynamic_buffer_init(&payload);
1903 if (!session_descriptor) {
1904 ret_code = LTTNG_ERR_INVALID;
1905 goto end;
1906 }
1907
1908 sessiond_must_generate_ouput =
1909 !lttng_session_descriptor_is_output_destination_initialized(session_descriptor);
1910 if (sessiond_must_generate_ouput) {
1911 const char *home_dir = utils_get_home_dir();
1912 size_t home_dir_len = home_dir ? strlen(home_dir) + 1 : 0;
1913
1914 if (!home_dir || home_dir_len > LTTNG_PATH_MAX) {
1915 ret_code = LTTNG_ERR_FATAL;
1916 goto end;
1917 }
1918
1919 lsm.u.create_session.home_dir_size = (uint16_t) home_dir_len;
1920 ret = lttng_dynamic_buffer_append(&payload, home_dir, home_dir_len);
1921 if (ret) {
1922 ret_code = LTTNG_ERR_NOMEM;
1923 goto end;
1924 }
1925 }
1926
1927 descriptor_size = payload.size;
1928 ret = lttng_session_descriptor_serialize(session_descriptor, &payload);
1929 if (ret) {
1930 ret_code = LTTNG_ERR_INVALID;
1931 goto end;
1932 }
1933 descriptor_size = payload.size - descriptor_size;
1934 lsm.u.create_session.session_descriptor_size = descriptor_size;
1935
1936 /* Command returns a session descriptor on success. */
1937 reply_ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(
1938 &lsm, payload.data, payload.size, &reply);
1939 if (reply_ret < 0) {
1940 ret_code = (lttng_error_code) -reply_ret;
1941 goto end;
1942 } else if (reply_ret == 0) {
1943 /* Socket unexpectedly closed by the session daemon. */
1944 ret_code = LTTNG_ERR_FATAL;
1945 goto end;
1946 }
1947
1948 reply_view = lttng_buffer_view_init((const char *) reply, 0, reply_ret);
1949 ret = lttng_session_descriptor_create_from_buffer(&reply_view, &descriptor_reply);
1950 if (ret < 0) {
1951 ret_code = LTTNG_ERR_FATAL;
1952 goto end;
1953 }
1954 ret_code = LTTNG_OK;
1955 lttng_session_descriptor_assign(session_descriptor, descriptor_reply);
1956 end:
1957 free(reply);
1958 lttng_dynamic_buffer_reset(&payload);
1959 lttng_session_descriptor_destroy(descriptor_reply);
1960 return ret_code;
1961 }
1962
1963 /*
1964 * Create a new session using name and url for destination.
1965 *
1966 * Return 0 on success else a negative LTTng error code.
1967 */
1968 int lttng_create_session(const char *name, const char *url)
1969 {
1970 int ret;
1971 ssize_t size;
1972 struct lttng_uri *uris = NULL;
1973 struct lttng_session_descriptor *descriptor = NULL;
1974 enum lttng_error_code ret_code;
1975
1976 if (!name) {
1977 ret = -LTTNG_ERR_INVALID;
1978 goto end;
1979 }
1980
1981 size = uri_parse_str_urls(url, NULL, &uris);
1982 if (size < 0) {
1983 ret = -LTTNG_ERR_INVALID;
1984 goto end;
1985 }
1986 switch (size) {
1987 case 0:
1988 descriptor = lttng_session_descriptor_create(name);
1989 break;
1990 case 1:
1991 if (uris[0].dtype != LTTNG_DST_PATH) {
1992 ret = -LTTNG_ERR_INVALID;
1993 goto end;
1994 }
1995 descriptor = lttng_session_descriptor_local_create(name, uris[0].dst.path);
1996 break;
1997 case 2:
1998 descriptor = lttng_session_descriptor_network_create(name, url, NULL);
1999 break;
2000 default:
2001 ret = -LTTNG_ERR_INVALID;
2002 goto end;
2003 }
2004 if (!descriptor) {
2005 ret = -LTTNG_ERR_INVALID;
2006 goto end;
2007 }
2008 ret_code = lttng_create_session_ext(descriptor);
2009 ret = ret_code == LTTNG_OK ? 0 : -ret_code;
2010 end:
2011 lttng_session_descriptor_destroy(descriptor);
2012 free(uris);
2013 return ret;
2014 }
2015
2016 /*
2017 * Create a session exclusively used for snapshot.
2018 *
2019 * Return 0 on success else a negative LTTng error code.
2020 */
2021 int lttng_create_session_snapshot(const char *name, const char *snapshot_url)
2022 {
2023 int ret;
2024 enum lttng_error_code ret_code;
2025 ssize_t size;
2026 struct lttng_uri *uris = NULL;
2027 struct lttng_session_descriptor *descriptor = NULL;
2028
2029 if (!name) {
2030 ret = -LTTNG_ERR_INVALID;
2031 goto end;
2032 }
2033
2034 size = uri_parse_str_urls(snapshot_url, NULL, &uris);
2035 if (size < 0) {
2036 ret = -LTTNG_ERR_INVALID;
2037 goto end;
2038 }
2039 /*
2040 * If the user does not specify a custom subdir, use the session name.
2041 */
2042 if (size > 0 && uris[0].dtype != LTTNG_DST_PATH && strlen(uris[0].subdir) == 0) {
2043 ret = snprintf(uris[0].subdir, sizeof(uris[0].subdir), "%s", name);
2044 if (ret < 0) {
2045 PERROR("Failed to set session name as network destination sub-directory");
2046 ret = -LTTNG_ERR_FATAL;
2047 goto end;
2048 } else if (ret >= sizeof(uris[0].subdir)) {
2049 /* Truncated output. */
2050 ret = -LTTNG_ERR_INVALID;
2051 goto end;
2052 }
2053 }
2054
2055 switch (size) {
2056 case 0:
2057 descriptor = lttng_session_descriptor_snapshot_create(name);
2058 break;
2059 case 1:
2060 if (uris[0].dtype != LTTNG_DST_PATH) {
2061 ret = -LTTNG_ERR_INVALID;
2062 goto end;
2063 }
2064 descriptor = lttng_session_descriptor_snapshot_local_create(name, uris[0].dst.path);
2065 break;
2066 case 2:
2067 descriptor =
2068 lttng_session_descriptor_snapshot_network_create(name, snapshot_url, NULL);
2069 break;
2070 default:
2071 ret = -LTTNG_ERR_INVALID;
2072 goto end;
2073 }
2074 if (!descriptor) {
2075 ret = -LTTNG_ERR_INVALID;
2076 goto end;
2077 }
2078 ret_code = lttng_create_session_ext(descriptor);
2079 ret = ret_code == LTTNG_OK ? 0 : -ret_code;
2080 end:
2081 lttng_session_descriptor_destroy(descriptor);
2082 free(uris);
2083 return ret;
2084 }
2085
2086 /*
2087 * Create a session exclusively used for live.
2088 *
2089 * Return 0 on success else a negative LTTng error code.
2090 */
2091 int lttng_create_session_live(const char *name, const char *url, unsigned int timer_interval)
2092 {
2093 int ret;
2094 enum lttng_error_code ret_code;
2095 struct lttng_session_descriptor *descriptor = NULL;
2096
2097 if (!name) {
2098 ret = -LTTNG_ERR_INVALID;
2099 goto end;
2100 }
2101
2102 if (url) {
2103 descriptor = lttng_session_descriptor_live_network_create(
2104 name, url, NULL, timer_interval);
2105 } else {
2106 descriptor = lttng_session_descriptor_live_create(name, timer_interval);
2107 }
2108 if (!descriptor) {
2109 ret = -LTTNG_ERR_INVALID;
2110 goto end;
2111 }
2112 ret_code = lttng_create_session_ext(descriptor);
2113 ret = ret_code == LTTNG_OK ? 0 : -ret_code;
2114 end:
2115 lttng_session_descriptor_destroy(descriptor);
2116 return ret;
2117 }
2118
2119 /*
2120 * Stop the session and wait for the data before destroying it
2121 *
2122 * Return 0 on success else a negative LTTng error code.
2123 */
2124 int lttng_destroy_session(const char *session_name)
2125 {
2126 int ret;
2127 enum lttng_error_code ret_code;
2128 enum lttng_destruction_handle_status status;
2129 struct lttng_destruction_handle *handle = NULL;
2130
2131 /*
2132 * Stop the tracing and wait for the data to be
2133 * consumed.
2134 */
2135 ret = _lttng_stop_tracing(session_name, 1);
2136 if (ret && ret != -LTTNG_ERR_TRACE_ALREADY_STOPPED) {
2137 goto end;
2138 }
2139
2140 ret_code = lttng_destroy_session_ext(session_name, &handle);
2141 if (ret_code != LTTNG_OK) {
2142 ret = (int) -ret_code;
2143 goto end;
2144 }
2145 LTTNG_ASSERT(handle);
2146
2147 /* Block until the completion of the destruction of the session. */
2148 status = lttng_destruction_handle_wait_for_completion(handle, -1);
2149 if (status != LTTNG_DESTRUCTION_HANDLE_STATUS_COMPLETED) {
2150 ret = -LTTNG_ERR_UNK;
2151 goto end;
2152 }
2153
2154 status = lttng_destruction_handle_get_result(handle, &ret_code);
2155 if (status != LTTNG_DESTRUCTION_HANDLE_STATUS_OK) {
2156 ret = -LTTNG_ERR_UNK;
2157 goto end;
2158 }
2159 ret = ret_code == LTTNG_OK ? 0 : -ret_code;
2160 end:
2161 lttng_destruction_handle_destroy(handle);
2162 return ret;
2163 }
2164
2165 /*
2166 * Destroy the session without waiting for the data.
2167 */
2168 int lttng_destroy_session_no_wait(const char *session_name)
2169 {
2170 enum lttng_error_code ret_code;
2171
2172 ret_code = lttng_destroy_session_ext(session_name, NULL);
2173 return ret_code == LTTNG_OK ? 0 : -ret_code;
2174 }
2175
2176 /*
2177 * Ask the session daemon for all available sessions.
2178 * Sets the contents of the sessions array.
2179 * Returns the number of lttng_session entries in sessions;
2180 * on error, returns a negative value.
2181 */
2182 int lttng_list_sessions(struct lttng_session **out_sessions)
2183 {
2184 int ret;
2185 struct lttcomm_session_msg lsm;
2186 const size_t session_size =
2187 sizeof(struct lttng_session) + sizeof(struct lttng_session_extended);
2188 size_t session_count, i;
2189 struct lttng_session_extended *sessions_extended_begin;
2190 struct lttng_session *sessions = NULL;
2191
2192 memset(&lsm, 0, sizeof(lsm));
2193 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_SESSIONS;
2194 /*
2195 * Initialize out_sessions to NULL so it is initialized when
2196 * lttng_list_sessions returns 0, thus allowing *out_sessions to
2197 * be subsequently freed.
2198 */
2199 *out_sessions = NULL;
2200 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &sessions);
2201 if (ret <= 0) {
2202 goto end;
2203 }
2204 if (!sessions) {
2205 ret = -LTTNG_ERR_FATAL;
2206 goto end;
2207 }
2208
2209 if (ret % session_size) {
2210 ret = -LTTNG_ERR_UNK;
2211 free(sessions);
2212 goto end;
2213 }
2214 session_count = (size_t) ret / session_size;
2215 sessions_extended_begin = (struct lttng_session_extended *) (&sessions[session_count]);
2216
2217 /* Set extended session info pointers. */
2218 for (i = 0; i < session_count; i++) {
2219 struct lttng_session *session = &sessions[i];
2220 struct lttng_session_extended *extended = &(sessions_extended_begin[i]);
2221
2222 session->extended.ptr = extended;
2223 }
2224
2225 ret = (int) session_count;
2226 *out_sessions = sessions;
2227 end:
2228 return ret;
2229 }
2230
2231 enum lttng_error_code lttng_session_get_creation_time(const struct lttng_session *session,
2232 uint64_t *creation_time)
2233 {
2234 enum lttng_error_code ret = LTTNG_OK;
2235 struct lttng_session_extended *extended;
2236
2237 if (!session || !creation_time || !session->extended.ptr) {
2238 ret = LTTNG_ERR_INVALID;
2239 goto end;
2240 }
2241
2242 extended = (lttng_session_extended *) session->extended.ptr;
2243 if (!extended->creation_time.is_set) {
2244 /* Not created on the session daemon yet. */
2245 ret = LTTNG_ERR_SESSION_NOT_EXIST;
2246 goto end;
2247 }
2248 *creation_time = extended->creation_time.value;
2249 end:
2250 return ret;
2251 }
2252
2253 int lttng_set_session_shm_path(const char *session_name, const char *shm_path)
2254 {
2255 int ret;
2256 struct lttcomm_session_msg lsm;
2257
2258 if (session_name == NULL) {
2259 return -LTTNG_ERR_INVALID;
2260 }
2261
2262 memset(&lsm, 0, sizeof(lsm));
2263 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_SET_SESSION_SHM_PATH;
2264
2265 ret = lttng_strncpy(lsm.session.name, session_name, sizeof(lsm.session.name));
2266 if (ret) {
2267 ret = -LTTNG_ERR_INVALID;
2268 goto end;
2269 }
2270
2271 ret = lttng_strncpy(
2272 lsm.u.set_shm_path.shm_path, shm_path ?: "", sizeof(lsm.u.set_shm_path.shm_path));
2273 if (ret) {
2274 ret = -LTTNG_ERR_INVALID;
2275 goto end;
2276 }
2277
2278 ret = lttng_ctl_ask_sessiond(&lsm, NULL);
2279 end:
2280 return ret;
2281 }
2282
2283 /*
2284 * Ask the session daemon for all available domains of a session.
2285 * Sets the contents of the domains array.
2286 * Returns the number of lttng_domain entries in domains;
2287 * on error, returns a negative value.
2288 */
2289 int lttng_list_domains(const char *session_name, struct lttng_domain **domains)
2290 {
2291 int ret;
2292 struct lttcomm_session_msg lsm;
2293
2294 if (session_name == NULL) {
2295 ret = -LTTNG_ERR_INVALID;
2296 goto error;
2297 }
2298
2299 memset(&lsm, 0, sizeof(lsm));
2300 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_DOMAINS;
2301
2302 ret = lttng_strncpy(lsm.session.name, session_name, sizeof(lsm.session.name));
2303 if (ret) {
2304 ret = -LTTNG_ERR_INVALID;
2305 goto error;
2306 }
2307
2308 ret = lttng_ctl_ask_sessiond(&lsm, (void **) domains);
2309 if (ret < 0) {
2310 goto error;
2311 }
2312
2313 return ret / sizeof(struct lttng_domain);
2314 error:
2315 return ret;
2316 }
2317
2318 /*
2319 * Ask the session daemon for all available channels of a session.
2320 * Sets the contents of the channels array.
2321 * Returns the number of lttng_channel entries in channels;
2322 * on error, returns a negative value.
2323 */
2324 int lttng_list_channels(struct lttng_handle *handle, struct lttng_channel **channels)
2325 {
2326 int ret, total_payload_received;
2327 struct lttcomm_session_msg lsm;
2328 char *reception_buffer = NULL;
2329 size_t cmd_header_len = 0;
2330 struct lttcomm_list_command_header *cmd_header = NULL;
2331 struct lttng_dynamic_buffer tmp_buffer;
2332
2333 lttng_dynamic_buffer_init(&tmp_buffer);
2334
2335 if (handle == NULL) {
2336 ret = -LTTNG_ERR_INVALID;
2337 goto end;
2338 }
2339
2340 memset(&lsm, 0, sizeof(lsm));
2341 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_CHANNELS;
2342 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
2343 if (ret) {
2344 ret = -LTTNG_ERR_INVALID;
2345 goto end;
2346 }
2347
2348 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
2349
2350 ret = lttng_ctl_ask_sessiond_fds_varlen(&lsm,
2351 NULL,
2352 0,
2353 NULL,
2354 0,
2355 (void **) &reception_buffer,
2356 (void **) &cmd_header,
2357 &cmd_header_len);
2358 if (ret < 0) {
2359 goto end;
2360 }
2361
2362 total_payload_received = ret;
2363
2364 if (cmd_header_len != sizeof(*cmd_header)) {
2365 ret = -LTTNG_ERR_FATAL;
2366 goto end;
2367 }
2368
2369 if (!cmd_header) {
2370 ret = LTTNG_ERR_UNK;
2371 goto end;
2372 }
2373
2374 if (cmd_header->count > INT_MAX) {
2375 ret = -LTTNG_ERR_OVERFLOW;
2376 goto end;
2377 }
2378
2379 {
2380 enum lttng_error_code ret_code;
2381 const struct lttng_buffer_view events_view =
2382 lttng_buffer_view_init(reception_buffer, 0, total_payload_received);
2383
2384 ret_code = lttng_channels_create_and_flatten_from_buffer(
2385 &events_view, cmd_header->count, channels);
2386 if (ret_code != LTTNG_OK) {
2387 ret = -ret_code;
2388 goto end;
2389 }
2390 }
2391
2392 ret = (int) cmd_header->count;
2393 end:
2394 free(cmd_header);
2395 free(reception_buffer);
2396 return ret;
2397 }
2398
2399 /*
2400 * Ask the session daemon for all available events of a session channel.
2401 * Sets the contents of the events array.
2402 * Returns the number of lttng_event entries in events;
2403 * on error, returns a negative value.
2404 */
2405 int lttng_list_events(struct lttng_handle *handle,
2406 const char *channel_name,
2407 struct lttng_event **events)
2408 {
2409 int ret;
2410 struct lttcomm_session_msg lsm = {};
2411 struct lttng_payload reply;
2412 struct lttng_payload_view lsm_view =
2413 lttng_payload_view_init_from_buffer((const char *) &lsm, 0, sizeof(lsm));
2414 unsigned int nb_events = 0;
2415
2416 lttng_payload_init(&reply);
2417
2418 /* Safety check. An handle and channel name are mandatory. */
2419 if (handle == NULL || channel_name == NULL) {
2420 ret = -LTTNG_ERR_INVALID;
2421 goto end;
2422 }
2423
2424 /* Initialize command parameters. */
2425 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_EVENTS;
2426 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
2427 if (ret) {
2428 ret = -LTTNG_ERR_INVALID;
2429 goto end;
2430 }
2431
2432 ret = lttng_strncpy(lsm.u.list.channel_name, channel_name, sizeof(lsm.u.list.channel_name));
2433 if (ret) {
2434 ret = -LTTNG_ERR_INVALID;
2435 goto end;
2436 }
2437
2438 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
2439
2440 /* Execute command against the session daemon. */
2441 ret = lttng_ctl_ask_sessiond_payload(&lsm_view, &reply);
2442 if (ret < 0) {
2443 goto end;
2444 }
2445
2446 {
2447 const struct lttcomm_list_command_header *cmd_reply_header = NULL;
2448 const lttng_payload_view cmd_reply_header_view =
2449 lttng_payload_view_from_payload(&reply, 0, sizeof(*cmd_reply_header));
2450
2451 if (!lttng_payload_view_is_valid(&cmd_reply_header_view)) {
2452 ret = -LTTNG_ERR_INVALID_PROTOCOL;
2453 goto end;
2454 }
2455
2456 cmd_reply_header = (const struct lttcomm_list_command_header *)
2457 cmd_reply_header_view.buffer.data;
2458 if (cmd_reply_header->count > INT_MAX) {
2459 ret = -LTTNG_ERR_OVERFLOW;
2460 goto end;
2461 }
2462
2463 nb_events = (unsigned int) cmd_reply_header->count;
2464 }
2465
2466 {
2467 enum lttng_error_code ret_code;
2468 lttng_payload_view cmd_reply_payload = lttng_payload_view_from_payload(
2469 &reply, sizeof(struct lttcomm_list_command_header), -1);
2470
2471 ret_code = lttng_events_create_and_flatten_from_payload(
2472 &cmd_reply_payload, nb_events, events);
2473 if (ret_code != LTTNG_OK) {
2474 ret = -((int) ret_code);
2475 goto end;
2476 }
2477 }
2478
2479 ret = (int) nb_events;
2480 end:
2481 lttng_payload_reset(&reply);
2482 return ret;
2483 }
2484
2485 /*
2486 * Sets the tracing_group variable with name.
2487 * This function allocates memory pointed to by tracing_group.
2488 * On success, returns 0, on error, returns -1 (null name) or -ENOMEM.
2489 */
2490 int lttng_set_tracing_group(const char *name)
2491 {
2492 int ret = 0;
2493 char *new_group;
2494
2495 if (name == NULL) {
2496 ret = -LTTNG_ERR_INVALID;
2497 goto end;
2498 }
2499
2500 new_group = strdup(name);
2501 if (!new_group) {
2502 ret = -LTTNG_ERR_FATAL;
2503 goto end;
2504 }
2505
2506 free(tracing_group);
2507 tracing_group = new_group;
2508 new_group = NULL;
2509
2510 end:
2511 return ret;
2512 }
2513
2514 int lttng_calibrate(struct lttng_handle *handle __attribute__((unused)),
2515 struct lttng_calibrate *calibrate __attribute__((unused)))
2516 {
2517 /*
2518 * This command was removed in LTTng 2.9.
2519 */
2520 return -LTTNG_ERR_UND;
2521 }
2522
2523 /*
2524 * Set default channel attributes.
2525 * If either or both of the arguments are null, attr content is zeroe'd.
2526 */
2527 void lttng_channel_set_default_attr(struct lttng_domain *domain, struct lttng_channel_attr *attr)
2528 {
2529 struct lttng_channel_extended *extended;
2530
2531 /* Safety check */
2532 if (attr == NULL || domain == NULL) {
2533 return;
2534 }
2535
2536 /* Save the pointer for later use */
2537 extended = (struct lttng_channel_extended *) attr->extended.ptr;
2538 memset(attr, 0, sizeof(struct lttng_channel_attr));
2539
2540 /* Same for all domains. */
2541 attr->overwrite = DEFAULT_CHANNEL_OVERWRITE;
2542 attr->tracefile_size = DEFAULT_CHANNEL_TRACEFILE_SIZE;
2543 attr->tracefile_count = DEFAULT_CHANNEL_TRACEFILE_COUNT;
2544
2545 switch (domain->type) {
2546 case LTTNG_DOMAIN_KERNEL:
2547 attr->switch_timer_interval = DEFAULT_KERNEL_CHANNEL_SWITCH_TIMER;
2548 attr->read_timer_interval = DEFAULT_KERNEL_CHANNEL_READ_TIMER;
2549 attr->subbuf_size = default_get_kernel_channel_subbuf_size();
2550 attr->num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM;
2551 attr->output = DEFAULT_KERNEL_CHANNEL_OUTPUT;
2552 break;
2553 case LTTNG_DOMAIN_UST:
2554 switch (domain->buf_type) {
2555 case LTTNG_BUFFER_PER_UID:
2556 attr->subbuf_size = default_get_ust_uid_channel_subbuf_size();
2557 attr->num_subbuf = DEFAULT_UST_UID_CHANNEL_SUBBUF_NUM;
2558 attr->output = DEFAULT_UST_UID_CHANNEL_OUTPUT;
2559 attr->switch_timer_interval = DEFAULT_UST_UID_CHANNEL_SWITCH_TIMER;
2560 attr->read_timer_interval = DEFAULT_UST_UID_CHANNEL_READ_TIMER;
2561 break;
2562 case LTTNG_BUFFER_PER_PID:
2563 default:
2564 attr->subbuf_size = default_get_ust_pid_channel_subbuf_size();
2565 attr->num_subbuf = DEFAULT_UST_PID_CHANNEL_SUBBUF_NUM;
2566 attr->output = DEFAULT_UST_PID_CHANNEL_OUTPUT;
2567 attr->switch_timer_interval = DEFAULT_UST_PID_CHANNEL_SWITCH_TIMER;
2568 attr->read_timer_interval = DEFAULT_UST_PID_CHANNEL_READ_TIMER;
2569 break;
2570 }
2571 default:
2572 /* Default behavior: leave set to 0. */
2573 break;
2574 }
2575
2576 if (extended) {
2577 lttng_channel_set_default_extended_attr(domain, extended);
2578 }
2579
2580 /* Reassign the extended pointer. */
2581 attr->extended.ptr = extended;
2582 }
2583
2584 int lttng_channel_get_discarded_event_count(struct lttng_channel *channel,
2585 uint64_t *discarded_events)
2586 {
2587 int ret = 0;
2588 struct lttng_channel_extended *chan_ext;
2589
2590 if (!channel || !discarded_events) {
2591 ret = -LTTNG_ERR_INVALID;
2592 goto end;
2593 }
2594
2595 chan_ext = (lttng_channel_extended *) channel->attr.extended.ptr;
2596 if (!chan_ext) {
2597 /*
2598 * This can happen since the lttng_channel structure is
2599 * used for other tasks where this pointer is never set.
2600 */
2601 *discarded_events = 0;
2602 goto end;
2603 }
2604
2605 *discarded_events = chan_ext->discarded_events;
2606 end:
2607 return ret;
2608 }
2609
2610 int lttng_channel_get_lost_packet_count(struct lttng_channel *channel, uint64_t *lost_packets)
2611 {
2612 int ret = 0;
2613 struct lttng_channel_extended *chan_ext;
2614
2615 if (!channel || !lost_packets) {
2616 ret = -LTTNG_ERR_INVALID;
2617 goto end;
2618 }
2619
2620 chan_ext = (lttng_channel_extended *) channel->attr.extended.ptr;
2621 if (!chan_ext) {
2622 /*
2623 * This can happen since the lttng_channel structure is
2624 * used for other tasks where this pointer is never set.
2625 */
2626 *lost_packets = 0;
2627 goto end;
2628 }
2629
2630 *lost_packets = chan_ext->lost_packets;
2631 end:
2632 return ret;
2633 }
2634
2635 int lttng_channel_get_monitor_timer_interval(struct lttng_channel *chan,
2636 uint64_t *monitor_timer_interval)
2637 {
2638 int ret = 0;
2639
2640 if (!chan || !monitor_timer_interval) {
2641 ret = -LTTNG_ERR_INVALID;
2642 goto end;
2643 }
2644
2645 if (!chan->attr.extended.ptr) {
2646 ret = -LTTNG_ERR_INVALID;
2647 goto end;
2648 }
2649
2650 *monitor_timer_interval =
2651 ((struct lttng_channel_extended *) chan->attr.extended.ptr)->monitor_timer_interval;
2652 end:
2653 return ret;
2654 }
2655
2656 int lttng_channel_set_monitor_timer_interval(struct lttng_channel *chan,
2657 uint64_t monitor_timer_interval)
2658 {
2659 int ret = 0;
2660
2661 if (!chan || !chan->attr.extended.ptr) {
2662 ret = -LTTNG_ERR_INVALID;
2663 goto end;
2664 }
2665
2666 ((struct lttng_channel_extended *) chan->attr.extended.ptr)->monitor_timer_interval =
2667 monitor_timer_interval;
2668 end:
2669 return ret;
2670 }
2671
2672 int lttng_channel_get_blocking_timeout(struct lttng_channel *chan, int64_t *blocking_timeout)
2673 {
2674 int ret = 0;
2675
2676 if (!chan || !blocking_timeout) {
2677 ret = -LTTNG_ERR_INVALID;
2678 goto end;
2679 }
2680
2681 if (!chan->attr.extended.ptr) {
2682 ret = -LTTNG_ERR_INVALID;
2683 goto end;
2684 }
2685
2686 *blocking_timeout =
2687 ((struct lttng_channel_extended *) chan->attr.extended.ptr)->blocking_timeout;
2688 end:
2689 return ret;
2690 }
2691
2692 int lttng_channel_set_blocking_timeout(struct lttng_channel *chan, int64_t blocking_timeout)
2693 {
2694 int ret = 0;
2695 int64_t msec_timeout;
2696
2697 if (!chan || !chan->attr.extended.ptr) {
2698 ret = -LTTNG_ERR_INVALID;
2699 goto end;
2700 }
2701
2702 if (blocking_timeout < 0 && blocking_timeout != -1) {
2703 ret = -LTTNG_ERR_INVALID;
2704 goto end;
2705 }
2706
2707 /*
2708 * LTTng-ust's use of poll() to implement this timeout mechanism forces
2709 * us to accept a narrower range of values (msecs expressed as a signed
2710 * 32-bit integer).
2711 */
2712 msec_timeout = blocking_timeout / 1000;
2713 if (msec_timeout != (int32_t) msec_timeout) {
2714 ret = -LTTNG_ERR_INVALID;
2715 goto end;
2716 }
2717
2718 ((struct lttng_channel_extended *) chan->attr.extended.ptr)->blocking_timeout =
2719 blocking_timeout;
2720 end:
2721 return ret;
2722 }
2723
2724 /*
2725 * Check if session daemon is alive.
2726 *
2727 * Return 1 if alive or 0 if not.
2728 * On error returns a negative value.
2729 */
2730 int lttng_session_daemon_alive(void)
2731 {
2732 int ret;
2733
2734 ret = set_session_daemon_path();
2735 if (ret < 0) {
2736 /* Error. */
2737 return ret;
2738 }
2739
2740 if (*sessiond_sock_path == '\0') {
2741 /*
2742 * No socket path set. Weird error which means the constructor
2743 * was not called.
2744 */
2745 abort();
2746 }
2747
2748 ret = try_connect_sessiond(sessiond_sock_path);
2749 if (ret < 0) {
2750 /* Not alive. */
2751 return 0;
2752 }
2753
2754 /* Is alive. */
2755 return 1;
2756 }
2757
2758 /*
2759 * Set URL for a consumer for a session and domain.
2760 *
2761 * Return 0 on success, else a negative value.
2762 */
2763 int lttng_set_consumer_url(struct lttng_handle *handle,
2764 const char *control_url,
2765 const char *data_url)
2766 {
2767 int ret;
2768 ssize_t size;
2769 struct lttcomm_session_msg lsm;
2770 struct lttng_uri *uris = NULL;
2771
2772 if (handle == NULL || (control_url == NULL && data_url == NULL)) {
2773 ret = -LTTNG_ERR_INVALID;
2774 goto error;
2775 }
2776
2777 memset(&lsm, 0, sizeof(lsm));
2778
2779 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_SET_CONSUMER_URI;
2780
2781 ret = lttng_strncpy(lsm.session.name, handle->session_name, sizeof(lsm.session.name));
2782 if (ret) {
2783 ret = -LTTNG_ERR_INVALID;
2784 goto error;
2785 }
2786
2787 COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
2788
2789 size = uri_parse_str_urls(control_url, data_url, &uris);
2790 if (size < 0) {
2791 ret = -LTTNG_ERR_INVALID;
2792 goto error;
2793 }
2794
2795 lsm.u.uri.size = size;
2796
2797 ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(
2798 &lsm, uris, sizeof(struct lttng_uri) * size, NULL);
2799
2800 free(uris);
2801 error:
2802 return ret;
2803 }
2804
2805 /*
2806 * [OBSOLETE]
2807 */
2808 extern "C" LTTNG_EXPORT int lttng_enable_consumer(struct lttng_handle *handle);
2809 int lttng_enable_consumer(struct lttng_handle *handle __attribute__((unused)))
2810 {
2811 return -ENOSYS;
2812 }
2813
2814 /*
2815 * [OBSOLETE]
2816 */
2817 extern "C" LTTNG_EXPORT int lttng_disable_consumer(struct lttng_handle *handle);
2818 int lttng_disable_consumer(struct lttng_handle *handle __attribute__((unused)))
2819 {
2820 return -ENOSYS;
2821 }
2822
2823 /*
2824 * [OBSOLETE]
2825 */
2826 extern "C" LTTNG_EXPORT int
2827 _lttng_create_session_ext(const char *name, const char *url, const char *datetime);
2828 int _lttng_create_session_ext(const char *name __attribute__((unused)),
2829 const char *url __attribute__((unused)),
2830 const char *datetime __attribute__((unused)))
2831 {
2832 return -ENOSYS;
2833 }
2834
2835 /*
2836 * For a given session name, this call checks if the data is ready to be read
2837 * or is still being extracted by the consumer(s) hence not ready to be used by
2838 * any readers.
2839 */
2840 int lttng_data_pending(const char *session_name)
2841 {
2842 int ret;
2843 struct lttcomm_session_msg lsm;
2844 uint8_t *pending = NULL;
2845
2846 if (session_name == NULL) {
2847 return -LTTNG_ERR_INVALID;
2848 }
2849
2850 memset(&lsm, 0, sizeof(lsm));
2851 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_DATA_PENDING;
2852
2853 ret = lttng_strncpy(lsm.session.name, session_name, sizeof(lsm.session.name));
2854 if (ret) {
2855 ret = -LTTNG_ERR_INVALID;
2856 goto end;
2857 }
2858
2859 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &pending);
2860 if (ret < 0) {
2861 goto end;
2862 } else if (ret != 1) {
2863 /* Unexpected payload size */
2864 ret = -LTTNG_ERR_INVALID;
2865 goto end;
2866 } else if (!pending) {
2867 /* Internal error. */
2868 ret = -LTTNG_ERR_UNK;
2869 goto end;
2870 }
2871
2872 ret = (int) *pending;
2873 end:
2874 free(pending);
2875 return ret;
2876 }
2877
2878 /*
2879 * Regenerate the metadata for a session.
2880 * Return 0 on success, a negative error code on error.
2881 */
2882 int lttng_regenerate_metadata(const char *session_name)
2883 {
2884 int ret;
2885 struct lttcomm_session_msg lsm;
2886
2887 if (!session_name) {
2888 ret = -LTTNG_ERR_INVALID;
2889 goto end;
2890 }
2891
2892 memset(&lsm, 0, sizeof(lsm));
2893 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_REGENERATE_METADATA;
2894
2895 ret = lttng_strncpy(lsm.session.name, session_name, sizeof(lsm.session.name));
2896 if (ret) {
2897 ret = -LTTNG_ERR_INVALID;
2898 goto end;
2899 }
2900
2901 ret = lttng_ctl_ask_sessiond(&lsm, NULL);
2902 if (ret < 0) {
2903 goto end;
2904 }
2905
2906 ret = 0;
2907 end:
2908 return ret;
2909 }
2910
2911 /*
2912 * Deprecated, replaced by lttng_regenerate_metadata.
2913 */
2914 int lttng_metadata_regenerate(const char *session_name)
2915 {
2916 return lttng_regenerate_metadata(session_name);
2917 }
2918
2919 /*
2920 * Regenerate the statedump of a session.
2921 * Return 0 on success, a negative error code on error.
2922 */
2923 int lttng_regenerate_statedump(const char *session_name)
2924 {
2925 int ret;
2926 struct lttcomm_session_msg lsm;
2927
2928 if (!session_name) {
2929 ret = -LTTNG_ERR_INVALID;
2930 goto end;
2931 }
2932
2933 memset(&lsm, 0, sizeof(lsm));
2934 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_REGENERATE_STATEDUMP;
2935
2936 ret = lttng_strncpy(lsm.session.name, session_name, sizeof(lsm.session.name));
2937 if (ret) {
2938 ret = -LTTNG_ERR_INVALID;
2939 goto end;
2940 }
2941
2942 ret = lttng_ctl_ask_sessiond(&lsm, NULL);
2943 if (ret < 0) {
2944 goto end;
2945 }
2946
2947 ret = 0;
2948 end:
2949 return ret;
2950 }
2951
2952 static int
2953 _lttng_register_trigger(struct lttng_trigger *trigger, const char *name, bool generate_name)
2954 {
2955 int ret;
2956 struct lttcomm_session_msg lsm = {
2957 .cmd_type = LTTCOMM_SESSIOND_COMMAND_REGISTER_TRIGGER,
2958 .session = {},
2959 .domain = {},
2960 .u = {},
2961 .fd_count = 0,
2962 };
2963 lsm.u.trigger.is_trigger_anonymous = !name && !generate_name;
2964 struct lttcomm_session_msg *message_lsm;
2965 struct lttng_payload message;
2966 struct lttng_payload reply;
2967 struct lttng_trigger *reply_trigger = NULL;
2968 enum lttng_domain_type domain_type;
2969 const struct lttng_credentials user_creds = {
2970 .uid = LTTNG_OPTIONAL_INIT_VALUE(geteuid()),
2971 .gid = LTTNG_OPTIONAL_INIT_UNSET,
2972 };
2973 const char *unused_trigger_name = NULL;
2974 enum lttng_trigger_status trigger_status;
2975
2976 lttng_payload_init(&message);
2977 lttng_payload_init(&reply);
2978
2979 if (!trigger) {
2980 ret = -LTTNG_ERR_INVALID;
2981 goto end;
2982 }
2983
2984 trigger_status = lttng_trigger_get_name(trigger, &unused_trigger_name);
2985 if (trigger_status != LTTNG_TRIGGER_STATUS_UNSET) {
2986 /* Re-using already registered trigger. */
2987 ret = -LTTNG_ERR_INVALID;
2988 goto end;
2989 }
2990
2991 if (name) {
2992 trigger_status = lttng_trigger_set_name(trigger, name);
2993 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
2994 ret = -LTTNG_ERR_NOMEM;
2995 goto end;
2996 }
2997 }
2998
2999 if (!trigger->creds.uid.is_set) {
3000 /* Use the client's credentials as the trigger credentials. */
3001 lttng_trigger_set_credentials(trigger, &user_creds);
3002 } else {
3003 /*
3004 * Validate that either the current trigger credentials and the
3005 * client credentials are identical or that the current user is
3006 * root. The root user can register, unregister triggers for
3007 * himself and other users.
3008 *
3009 * This check is also present on the sessiond side, using the
3010 * credentials passed on the socket. These check are all
3011 * "safety" checks.
3012 */
3013 const struct lttng_credentials *trigger_creds =
3014 lttng_trigger_get_credentials(trigger);
3015
3016 if (!lttng_credentials_is_equal_uid(trigger_creds, &user_creds)) {
3017 if (lttng_credentials_get_uid(&user_creds) != 0) {
3018 ret = -LTTNG_ERR_EPERM;
3019 goto end_unset_name;
3020 }
3021 }
3022 }
3023
3024 if (!lttng_trigger_validate(trigger)) {
3025 ret = -LTTNG_ERR_INVALID_TRIGGER;
3026 goto end_unset_name;
3027 }
3028
3029 domain_type = lttng_trigger_get_underlying_domain_type_restriction(trigger);
3030
3031 lsm.domain.type = domain_type;
3032
3033 ret = lttng_dynamic_buffer_append(&message.buffer, &lsm, sizeof(lsm));
3034 if (ret) {
3035 ret = -LTTNG_ERR_NOMEM;
3036 goto end_unset_name;
3037 }
3038
3039 ret = lttng_trigger_serialize(trigger, &message);
3040 if (ret < 0) {
3041 ret = -LTTNG_ERR_UNK;
3042 goto end_unset_name;
3043 }
3044
3045 /*
3046 * This is needed to populate the trigger object size for the command
3047 * header.
3048 */
3049 message_lsm = (struct lttcomm_session_msg *) message.buffer.data;
3050
3051 message_lsm->u.trigger.length = (uint32_t) message.buffer.size - sizeof(lsm);
3052
3053 {
3054 struct lttng_payload_view message_view =
3055 lttng_payload_view_from_payload(&message, 0, -1);
3056
3057 message_lsm->fd_count = lttng_payload_view_get_fd_handle_count(&message_view);
3058 ret = lttng_ctl_ask_sessiond_payload(&message_view, &reply);
3059 if (ret < 0) {
3060 goto end_unset_name;
3061 }
3062 }
3063
3064 {
3065 struct lttng_payload_view reply_view =
3066 lttng_payload_view_from_payload(&reply, 0, reply.buffer.size);
3067
3068 ret = lttng_trigger_create_from_payload(&reply_view, &reply_trigger);
3069 if (ret < 0) {
3070 ret = -LTTNG_ERR_INVALID_PROTOCOL;
3071 goto end_unset_name;
3072 }
3073 }
3074
3075 if (name || generate_name) {
3076 ret = lttng_trigger_assign_name(trigger, reply_trigger);
3077 if (ret < 0) {
3078 ret = -LTTNG_ERR_NOMEM;
3079 goto end;
3080 }
3081 }
3082
3083 ret = 0;
3084 goto end;
3085
3086 end_unset_name:
3087 trigger_status = lttng_trigger_set_name(trigger, NULL);
3088 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
3089 ret = -LTTNG_ERR_UNK;
3090 }
3091 end:
3092 lttng_payload_reset(&message);
3093 lttng_payload_reset(&reply);
3094 lttng_trigger_destroy(reply_trigger);
3095 return ret;
3096 }
3097
3098 int lttng_register_trigger(struct lttng_trigger *trigger)
3099 {
3100 /* Register an anonymous trigger. */
3101 return _lttng_register_trigger(trigger, NULL, false);
3102 }
3103
3104 enum lttng_error_code lttng_register_trigger_with_name(struct lttng_trigger *trigger,
3105 const char *name)
3106 {
3107 const int ret = _lttng_register_trigger(trigger, name, false);
3108
3109 return ret == 0 ? LTTNG_OK : (enum lttng_error_code) - ret;
3110 }
3111
3112 enum lttng_error_code lttng_register_trigger_with_automatic_name(struct lttng_trigger *trigger)
3113 {
3114 const int ret = _lttng_register_trigger(trigger, nullptr, true);
3115
3116 return ret == 0 ? LTTNG_OK : (enum lttng_error_code) - ret;
3117 }
3118
3119 enum lttng_error_code lttng_error_query_execute(const struct lttng_error_query *query,
3120 const struct lttng_endpoint *endpoint,
3121 struct lttng_error_query_results **results)
3122 {
3123 int ret;
3124 enum lttng_error_code ret_code;
3125 struct lttcomm_session_msg lsm = {
3126 .cmd_type = LTTCOMM_SESSIOND_COMMAND_EXECUTE_ERROR_QUERY,
3127 .session = {},
3128 .domain = {},
3129 .u = {},
3130 .fd_count = 0,
3131 };
3132 struct lttng_payload message;
3133 struct lttng_payload reply;
3134 struct lttcomm_session_msg *message_lsm;
3135
3136 lttng_payload_init(&message);
3137 lttng_payload_init(&reply);
3138
3139 if (!query || !results) {
3140 ret_code = LTTNG_ERR_INVALID;
3141 goto end;
3142 }
3143
3144 if (endpoint != lttng_session_daemon_command_endpoint) {
3145 ret_code = LTTNG_ERR_INVALID_ERROR_QUERY_TARGET;
3146 goto end;
3147 }
3148
3149 ret = lttng_dynamic_buffer_append(&message.buffer, &lsm, sizeof(lsm));
3150 if (ret) {
3151 ret_code = LTTNG_ERR_NOMEM;
3152 goto end;
3153 }
3154
3155 ret = lttng_error_query_serialize(query, &message);
3156 if (ret) {
3157 ret_code = LTTNG_ERR_UNK;
3158 goto end;
3159 }
3160
3161 message_lsm = (struct lttcomm_session_msg *) message.buffer.data;
3162 message_lsm->u.error_query.length = (uint32_t) message.buffer.size - sizeof(lsm);
3163
3164 {
3165 struct lttng_payload_view message_view =
3166 lttng_payload_view_from_payload(&message, 0, -1);
3167
3168 message_lsm->fd_count = lttng_payload_view_get_fd_handle_count(&message_view);
3169 ret = lttng_ctl_ask_sessiond_payload(&message_view, &reply);
3170 if (ret < 0) {
3171 ret_code = (lttng_error_code) -ret;
3172 goto end;
3173 }
3174 }
3175
3176 {
3177 ssize_t reply_create_ret;
3178 struct lttng_payload_view reply_view =
3179 lttng_payload_view_from_payload(&reply, 0, reply.buffer.size);
3180
3181 reply_create_ret =
3182 lttng_error_query_results_create_from_payload(&reply_view, results);
3183 if (reply_create_ret < 0) {
3184 ret_code = LTTNG_ERR_INVALID_PROTOCOL;
3185 goto end;
3186 }
3187 }
3188
3189 ret_code = LTTNG_OK;
3190 end:
3191 lttng_payload_reset(&message);
3192 lttng_payload_reset(&reply);
3193 return ret_code;
3194 }
3195
3196 int lttng_unregister_trigger(const struct lttng_trigger *trigger)
3197 {
3198 int ret;
3199 struct lttcomm_session_msg lsm;
3200 struct lttcomm_session_msg *message_lsm;
3201 struct lttng_payload message;
3202 struct lttng_payload reply;
3203 struct lttng_trigger *copy = NULL;
3204 const struct lttng_credentials user_creds = {
3205 .uid = LTTNG_OPTIONAL_INIT_VALUE(geteuid()),
3206 .gid = LTTNG_OPTIONAL_INIT_UNSET,
3207 };
3208
3209 lttng_payload_init(&message);
3210 lttng_payload_init(&reply);
3211
3212 if (!trigger) {
3213 ret = -LTTNG_ERR_INVALID;
3214 goto end;
3215 }
3216
3217 copy = lttng_trigger_copy(trigger);
3218 if (!copy) {
3219 ret = -LTTNG_ERR_UNK;
3220 goto end;
3221 }
3222
3223 if (!copy->creds.uid.is_set) {
3224 /* Use the client credentials as the trigger credentials */
3225 lttng_trigger_set_credentials(copy, &user_creds);
3226 } else {
3227 /*
3228 * Validate that either the current trigger credentials and the
3229 * client credentials are identical or that the current user is
3230 * root. The root user can register, unregister triggers for
3231 * himself and other users.
3232 *
3233 * This check is also present on the sessiond side, using the
3234 * credentials passed on the socket. These check are all
3235 * "safety" checks.
3236 */
3237 const struct lttng_credentials *trigger_creds = lttng_trigger_get_credentials(copy);
3238 if (!lttng_credentials_is_equal_uid(trigger_creds, &user_creds)) {
3239 if (lttng_credentials_get_uid(&user_creds) != 0) {
3240 ret = -LTTNG_ERR_EPERM;
3241 goto end;
3242 }
3243 }
3244 }
3245
3246 if (!lttng_trigger_validate(copy)) {
3247 ret = -LTTNG_ERR_INVALID_TRIGGER;
3248 goto end;
3249 }
3250
3251 memset(&lsm, 0, sizeof(lsm));
3252 lsm.cmd_type = LTTCOMM_SESSIOND_COMMAND_UNREGISTER_TRIGGER;
3253
3254 ret = lttng_dynamic_buffer_append(&message.buffer, &lsm, sizeof(lsm));
3255 if (ret) {
3256 ret = -LTTNG_ERR_NOMEM;
3257 goto end;
3258 }
3259
3260 ret = lttng_trigger_serialize(copy, &message);
3261 if (ret < 0) {
3262 ret = -LTTNG_ERR_UNK;
3263 goto end;
3264 }
3265
3266 /*
3267 * This is needed to populate the trigger object size for the command
3268 * header and number of fds sent.
3269 */
3270 message_lsm = (struct lttcomm_session_msg *) message.buffer.data;
3271
3272 message_lsm->u.trigger.length = (uint32_t) message.buffer.size - sizeof(lsm);
3273
3274 {
3275 struct lttng_payload_view message_view =
3276 lttng_payload_view_from_payload(&message, 0, -1);
3277
3278 /*
3279 * Update the message header with the number of fd that will be
3280 * sent.
3281 */
3282 message_lsm->fd_count = lttng_payload_view_get_fd_handle_count(&message_view);
3283
3284 ret = lttng_ctl_ask_sessiond_payload(&message_view, &reply);
3285 if (ret < 0) {
3286 goto end;
3287 }
3288 }
3289
3290 ret = 0;
3291 end:
3292 lttng_trigger_destroy(copy);
3293 lttng_payload_reset(&message);
3294 lttng_payload_reset(&reply);
3295 return ret;
3296 }
3297
3298 /*
3299 * Ask the session daemon for all registered triggers for the current user.
3300 *
3301 * Allocates and return an lttng_triggers set.
3302 * On error, returns a suitable lttng_error_code.
3303 */
3304 enum lttng_error_code lttng_list_triggers(struct lttng_triggers **triggers)
3305 {
3306 int ret;
3307 enum lttng_error_code ret_code = LTTNG_OK;
3308 struct lttcomm_session_msg lsm = {
3309 .cmd_type = LTTCOMM_SESSIOND_COMMAND_LIST_TRIGGERS,
3310 .session = {},
3311 .domain = {},
3312 .u = {},
3313 .fd_count = 0,
3314 };
3315 struct lttng_triggers *local_triggers = NULL;
3316 struct lttng_payload reply;
3317 struct lttng_payload_view lsm_view =
3318 lttng_payload_view_init_from_buffer((const char *) &lsm, 0, sizeof(lsm));
3319
3320 lttng_payload_init(&reply);
3321
3322 ret = lttng_ctl_ask_sessiond_payload(&lsm_view, &reply);
3323 if (ret < 0) {
3324 ret_code = (enum lttng_error_code) - ret;
3325 goto end;
3326 }
3327
3328 {
3329 struct lttng_payload_view reply_view =
3330 lttng_payload_view_from_payload(&reply, 0, reply.buffer.size);
3331
3332 ret = lttng_triggers_create_from_payload(&reply_view, &local_triggers);
3333 if (ret < 0) {
3334 ret_code = LTTNG_ERR_FATAL;
3335 goto end;
3336 }
3337 }
3338
3339 *triggers = local_triggers;
3340 local_triggers = NULL;
3341 end:
3342 lttng_payload_reset(&reply);
3343 lttng_triggers_destroy(local_triggers);
3344 return ret_code;
3345 }
3346
3347 /*
3348 * lib constructor.
3349 */
3350 static void __attribute__((constructor)) init(void)
3351 {
3352 /* Set default session group */
3353 lttng_set_tracing_group(DEFAULT_TRACING_GROUP);
3354 }
3355
3356 /*
3357 * lib destructor.
3358 */
3359 static void __attribute__((destructor)) lttng_ctl_exit(void)
3360 {
3361 free(tracing_group);
3362 }
This page took 0.139453 seconds and 4 git commands to generate.