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