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