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