2 * SPDX-License-Identifier: LGPL-2.1-only
4 * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
5 * Copyright (C) 2011-2013 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
13 #include <sys/socket.h>
15 #include <sys/types.h>
23 #include <lttng/ust-ctl.h>
27 #include <lttng/ust-error.h>
28 #include <lttng/ust-events.h>
29 #include <lttng/ust-dynamic-type.h>
30 #include <usterr-signal-safe.h>
32 #include "../liblttng-ust/compat.h"
34 #define USTCOMM_CODE_OFFSET(code) \
35 (code == LTTNG_UST_OK ? 0 : (code - LTTNG_UST_ERR + 1))
37 #define USTCOMM_MAX_SEND_FDS 4
40 ssize_t
count_fields_recursive(size_t nr_fields
,
41 const struct lttng_event_field
*lttng_fields
);
43 int serialize_one_field(struct lttng_session
*session
,
44 struct ustctl_field
*fields
, size_t *iter_output
,
45 const struct lttng_event_field
*lf
);
47 int serialize_fields(struct lttng_session
*session
,
48 struct ustctl_field
*ustctl_fields
,
49 size_t *iter_output
, size_t nr_lttng_fields
,
50 const struct lttng_event_field
*lttng_fields
);
53 * Human readable error message.
55 static const char *ustcomm_readable_code
[] = {
56 [ USTCOMM_CODE_OFFSET(LTTNG_UST_OK
) ] = "Success",
57 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR
) ] = "Unknown error",
58 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_NOENT
) ] = "No entry",
59 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_EXIST
) ] = "Object already exists",
60 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_INVAL
) ] = "Invalid argument",
61 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_PERM
) ] = "Permission denied",
62 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_NOSYS
) ] = "Not implemented",
63 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_EXITING
) ] = "Process is exiting",
65 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_INVAL_MAGIC
) ] = "Invalid magic number",
66 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_INVAL_SOCKET_TYPE
) ] = "Invalid socket type",
67 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_UNSUP_MAJOR
) ] = "Unsupported major version",
68 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_PEERCRED
) ] = "Cannot get unix socket peer credentials",
69 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_PEERCRED_PID
) ] = "Peer credentials PID is invalid. Socket appears to belong to a distinct, non-nested pid namespace.",
75 * Receives positive error value.
76 * Return ptr to string representing a human readable
77 * error code from the ustcomm_return_code enum.
79 const char *lttng_ust_strerror(int code
)
81 if (code
== LTTNG_UST_OK
)
82 return ustcomm_readable_code
[USTCOMM_CODE_OFFSET(code
)];
83 if (code
< LTTNG_UST_ERR
)
84 return strerror(code
);
85 if (code
>= LTTNG_UST_ERR_NR
)
87 return ustcomm_readable_code
[USTCOMM_CODE_OFFSET(code
)];
91 * ustcomm_connect_unix_sock
93 * Connect to unix socket using the path name.
95 * Caller handles FD tracker.
97 int ustcomm_connect_unix_sock(const char *pathname
, long timeout
)
99 struct sockaddr_un sun
;
103 * libust threads require the close-on-exec flag for all
104 * resources so it does not leak file descriptors upon exec.
105 * SOCK_CLOEXEC is not used since it is linux specific.
107 fd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
114 /* Give at least 10ms. */
117 ret
= ustcomm_setsockopt_snd_timeout(fd
, timeout
);
119 WARN("Error setting connect socket send timeout");
122 ret
= fcntl(fd
, F_SETFD
, FD_CLOEXEC
);
129 memset(&sun
, 0, sizeof(sun
));
130 sun
.sun_family
= AF_UNIX
;
131 strncpy(sun
.sun_path
, pathname
, sizeof(sun
.sun_path
));
132 sun
.sun_path
[sizeof(sun
.sun_path
) - 1] = '\0';
134 ret
= connect(fd
, (struct sockaddr
*) &sun
, sizeof(sun
));
137 * Don't print message on connect ENOENT error, because
138 * connect is used in normal execution to detect if
139 * sessiond is alive. ENOENT is when the unix socket
140 * file does not exist, and ECONNREFUSED is when the
141 * file exists but no sessiond is listening.
143 if (errno
!= ECONNREFUSED
&& errno
!= ECONNRESET
144 && errno
!= ENOENT
&& errno
!= EACCES
)
147 if (ret
== -ECONNREFUSED
|| ret
== -ECONNRESET
)
159 closeret
= close(fd
);
168 * ustcomm_accept_unix_sock
170 * Do an accept(2) on the sock and return the
171 * new file descriptor. The socket MUST be bind(2) before.
173 int ustcomm_accept_unix_sock(int sock
)
176 struct sockaddr_un sun
;
180 new_fd
= accept(sock
, (struct sockaddr
*) &sun
, &len
);
182 if (errno
!= ECONNABORTED
)
185 if (new_fd
== -ECONNABORTED
)
192 * ustcomm_create_unix_sock
194 * Creates a AF_UNIX local socket using pathname
195 * bind the socket upon creation and return the fd.
197 int ustcomm_create_unix_sock(const char *pathname
)
199 struct sockaddr_un sun
;
202 /* Create server socket */
203 if ((fd
= socket(PF_UNIX
, SOCK_STREAM
, 0)) < 0) {
209 memset(&sun
, 0, sizeof(sun
));
210 sun
.sun_family
= AF_UNIX
;
211 strncpy(sun
.sun_path
, pathname
, sizeof(sun
.sun_path
));
212 sun
.sun_path
[sizeof(sun
.sun_path
) - 1] = '\0';
214 /* Unlink the old file if present */
215 (void) unlink(pathname
);
216 ret
= bind(fd
, (struct sockaddr
*) &sun
, sizeof(sun
));
229 closeret
= close(fd
);
239 * ustcomm_listen_unix_sock
241 * Make the socket listen using LTTNG_UST_COMM_MAX_LISTEN.
243 int ustcomm_listen_unix_sock(int sock
)
247 ret
= listen(sock
, LTTNG_UST_COMM_MAX_LISTEN
);
257 * ustcomm_close_unix_sock
259 * Shutdown cleanly a unix socket.
261 * Handles fd tracker internally.
263 int ustcomm_close_unix_sock(int sock
)
267 lttng_ust_lock_fd_tracker();
270 lttng_ust_delete_fd_from_tracker(sock
);
275 lttng_ust_unlock_fd_tracker();
281 * ustcomm_recv_unix_sock
283 * Receive data of size len in put that data into
284 * the buf param. Using recvmsg API.
285 * Return the size of received data.
286 * Return 0 on orderly shutdown.
288 ssize_t
ustcomm_recv_unix_sock(int sock
, void *buf
, size_t len
)
295 memset(&msg
, 0, sizeof(msg
));
297 iov
[0].iov_base
= buf
;
298 iov
[0].iov_len
= len
;
303 len_last
= iov
[0].iov_len
;
304 ret
= recvmsg(sock
, &msg
, 0);
306 iov
[0].iov_base
+= ret
;
307 iov
[0].iov_len
-= ret
;
308 assert(ret
<= len_last
);
310 } while ((ret
> 0 && ret
< len_last
) || (ret
< 0 && errno
== EINTR
));
315 if (errno
!= EPIPE
&& errno
!= ECONNRESET
&& errno
!= ECONNREFUSED
)
318 if (ret
== -ECONNRESET
|| ret
== -ECONNREFUSED
)
321 shutret
= shutdown(sock
, SHUT_RDWR
);
323 ERR("Socket shutdown error");
324 } else if (ret
> 0) {
327 /* ret = 0 means an orderly shutdown. */
333 * ustcomm_send_unix_sock
335 * Send buf data of size len. Using sendmsg API.
336 * Return the size of sent data.
338 ssize_t
ustcomm_send_unix_sock(int sock
, const void *buf
, size_t len
)
344 memset(&msg
, 0, sizeof(msg
));
346 iov
[0].iov_base
= (void *) buf
;
347 iov
[0].iov_len
= len
;
352 * Using the MSG_NOSIGNAL when sending data from sessiond to
353 * libust, so libust does not receive an unhandled SIGPIPE or
354 * SIGURG. The sessiond receiver side can be made more resilient
355 * by ignoring SIGPIPE, but we don't have this luxury on the
359 ret
= sendmsg(sock
, &msg
, MSG_NOSIGNAL
);
360 } while (ret
< 0 && errno
== EINTR
);
365 if (errno
!= EPIPE
&& errno
!= ECONNRESET
)
368 if (ret
== -ECONNRESET
)
371 shutret
= shutdown(sock
, SHUT_RDWR
);
373 ERR("Socket shutdown error");
380 * Send a message accompanied by fd(s) over a unix socket.
382 * Returns the size of data sent, or negative error value.
384 ssize_t
ustcomm_send_fds_unix_sock(int sock
, int *fds
, size_t nb_fd
)
387 struct cmsghdr
*cmptr
;
390 unsigned int sizeof_fds
= nb_fd
* sizeof(int);
391 char tmp
[CMSG_SPACE(sizeof_fds
)];
394 memset(&msg
, 0, sizeof(msg
));
395 memset(tmp
, 0, CMSG_SPACE(sizeof_fds
) * sizeof(char));
397 if (nb_fd
> USTCOMM_MAX_SEND_FDS
)
400 msg
.msg_control
= (caddr_t
)tmp
;
401 msg
.msg_controllen
= CMSG_LEN(sizeof_fds
);
403 cmptr
= CMSG_FIRSTHDR(&msg
);
406 cmptr
->cmsg_level
= SOL_SOCKET
;
407 cmptr
->cmsg_type
= SCM_RIGHTS
;
408 cmptr
->cmsg_len
= CMSG_LEN(sizeof_fds
);
409 memcpy(CMSG_DATA(cmptr
), fds
, sizeof_fds
);
410 /* Sum of the length of all control messages in the buffer: */
411 msg
.msg_controllen
= cmptr
->cmsg_len
;
413 iov
[0].iov_base
= &dummy
;
419 ret
= sendmsg(sock
, &msg
, MSG_NOSIGNAL
);
420 } while (ret
< 0 && errno
== EINTR
);
423 * We consider EPIPE and ECONNRESET as expected.
425 if (errno
!= EPIPE
&& errno
!= ECONNRESET
) {
429 if (ret
== -ECONNRESET
)
436 * Recv a message accompanied by fd(s) from a unix socket.
438 * Expect at most "nb_fd" file descriptors. Returns the number of fd
439 * actually received in nb_fd.
440 * Returns -EPIPE on orderly shutdown.
442 ssize_t
ustcomm_recv_fds_unix_sock(int sock
, int *fds
, size_t nb_fd
)
446 struct cmsghdr
*cmsg
;
447 size_t sizeof_fds
= nb_fd
* sizeof(int);
448 char recv_fd
[CMSG_SPACE(sizeof_fds
)];
453 memset(&msg
, 0, sizeof(msg
));
455 /* Prepare to receive the structures */
456 iov
[0].iov_base
= &dummy
;
460 msg
.msg_control
= recv_fd
;
461 msg
.msg_controllen
= sizeof(recv_fd
);
464 ret
= recvmsg(sock
, &msg
, 0);
465 } while (ret
< 0 && errno
== EINTR
);
467 if (errno
!= EPIPE
&& errno
!= ECONNRESET
) {
468 PERROR("recvmsg fds");
471 if (ret
== -ECONNRESET
)
476 /* orderly shutdown */
481 ERR("Error: Received %zd bytes, expected %d\n",
485 if (msg
.msg_flags
& MSG_CTRUNC
) {
486 ERR("Error: Control message truncated.\n");
490 cmsg
= CMSG_FIRSTHDR(&msg
);
492 ERR("Error: Invalid control message header\n");
496 if (cmsg
->cmsg_level
!= SOL_SOCKET
|| cmsg
->cmsg_type
!= SCM_RIGHTS
) {
497 ERR("Didn't received any fd\n");
501 if (cmsg
->cmsg_len
!= CMSG_LEN(sizeof_fds
)) {
502 ERR("Error: Received %zu bytes of ancillary data, expected %zu\n",
503 (size_t) cmsg
->cmsg_len
, (size_t) CMSG_LEN(sizeof_fds
));
508 memcpy(fds
, CMSG_DATA(cmsg
), sizeof_fds
);
511 for (i
= 0; i
< nb_fd
; i
++) {
512 ret
= fcntl(fds
[i
], F_SETFD
, FD_CLOEXEC
);
514 PERROR("fcntl failed to set FD_CLOEXEC on fd %d",
524 int ustcomm_send_app_msg(int sock
, struct ustcomm_ust_msg
*lum
)
528 len
= ustcomm_send_unix_sock(sock
, lum
, sizeof(*lum
));
536 ERR("incorrect message size: %zd\n", len
);
543 int ustcomm_recv_app_reply(int sock
, struct ustcomm_ust_reply
*lur
,
544 uint32_t expected_handle
, uint32_t expected_cmd
)
548 memset(lur
, 0, sizeof(*lur
));
549 len
= ustcomm_recv_unix_sock(sock
, lur
, sizeof(*lur
));
551 case 0: /* orderly shutdown */
557 if (lur
->handle
!= expected_handle
) {
558 ERR("Unexpected result message handle: "
559 "expected: %u vs received: %u\n",
560 expected_handle
, lur
->handle
);
563 if (lur
->cmd
!= expected_cmd
) {
564 ERR("Unexpected result message command "
565 "expected: %u vs received: %u\n",
566 expected_cmd
, lur
->cmd
);
572 return lur
->ret_code
;
577 ERR("incorrect message size: %zd\n", len
);
583 int ustcomm_send_app_cmd(int sock
,
584 struct ustcomm_ust_msg
*lum
,
585 struct ustcomm_ust_reply
*lur
)
589 ret
= ustcomm_send_app_msg(sock
, lum
);
592 ret
= ustcomm_recv_app_reply(sock
, lur
, lum
->handle
, lum
->cmd
);
599 * chan_data is allocated internally if this function returns the
602 ssize_t
ustcomm_recv_channel_from_sessiond(int sock
,
603 void **_chan_data
, uint64_t var_len
,
610 if (var_len
> LTTNG_UST_CHANNEL_DATA_MAX_LEN
) {
614 /* Receive variable length data */
615 chan_data
= zmalloc(var_len
);
620 len
= ustcomm_recv_unix_sock(sock
, chan_data
, var_len
);
621 if (len
!= var_len
) {
625 lttng_ust_lock_fd_tracker();
626 nr_fd
= ustcomm_recv_fds_unix_sock(sock
, &wakeup_fd
, 1);
628 lttng_ust_unlock_fd_tracker();
638 ret
= lttng_ust_add_fd_to_tracker(wakeup_fd
);
640 ret
= close(wakeup_fd
);
642 PERROR("close on wakeup_fd");
645 lttng_ust_unlock_fd_tracker();
650 lttng_ust_unlock_fd_tracker();
652 *_chan_data
= chan_data
;
662 ssize_t
ustcomm_recv_event_notifier_notif_fd_from_sessiond(int sock
,
663 int *_event_notifier_notif_fd
)
666 int event_notifier_notif_fd
, ret
;
668 /* Receive event_notifier notification fd */
669 lttng_ust_lock_fd_tracker();
670 nr_fd
= ustcomm_recv_fds_unix_sock(sock
, &event_notifier_notif_fd
, 1);
672 lttng_ust_unlock_fd_tracker();
682 ret
= lttng_ust_add_fd_to_tracker(event_notifier_notif_fd
);
684 ret
= close(event_notifier_notif_fd
);
686 PERROR("close on event_notifier notif fd");
689 lttng_ust_unlock_fd_tracker();
693 *_event_notifier_notif_fd
= ret
;
694 lttng_ust_unlock_fd_tracker();
702 int ustcomm_recv_stream_from_sessiond(int sock
,
703 uint64_t *memory_map_size
,
704 int *shm_fd
, int *wakeup_fd
)
710 /* recv shm fd and wakeup fd */
711 lttng_ust_lock_fd_tracker();
712 len
= ustcomm_recv_fds_unix_sock(sock
, fds
, 2);
714 lttng_ust_unlock_fd_tracker();
724 ret
= lttng_ust_add_fd_to_tracker(fds
[0]);
728 PERROR("close on received shm_fd");
731 lttng_ust_unlock_fd_tracker();
736 ret
= lttng_ust_add_fd_to_tracker(fds
[1]);
738 ret
= close(*shm_fd
);
740 PERROR("close on shm_fd");
745 PERROR("close on received wakeup_fd");
748 lttng_ust_unlock_fd_tracker();
752 lttng_ust_unlock_fd_tracker();
759 ssize_t
ustcomm_recv_counter_from_sessiond(int sock
,
760 void **_counter_data
, uint64_t var_len
)
765 if (var_len
> LTTNG_UST_COUNTER_DATA_MAX_LEN
) {
769 /* Receive variable length data */
770 counter_data
= zmalloc(var_len
);
775 len
= ustcomm_recv_unix_sock(sock
, counter_data
, var_len
);
776 if (len
!= var_len
) {
779 *_counter_data
= counter_data
;
789 int ustcomm_recv_counter_shm_from_sessiond(int sock
,
797 lttng_ust_lock_fd_tracker();
798 len
= ustcomm_recv_fds_unix_sock(sock
, fds
, 1);
800 lttng_ust_unlock_fd_tracker();
810 ret
= lttng_ust_add_fd_to_tracker(fds
[0]);
814 PERROR("close on received shm_fd");
817 lttng_ust_unlock_fd_tracker();
821 lttng_ust_unlock_fd_tracker();
829 * Returns 0 on success, negative error value on error.
831 int ustcomm_send_reg_msg(int sock
,
832 enum ustctl_socket_type type
,
833 uint32_t bits_per_long
,
834 uint32_t uint8_t_alignment
,
835 uint32_t uint16_t_alignment
,
836 uint32_t uint32_t_alignment
,
837 uint32_t uint64_t_alignment
,
838 uint32_t long_alignment
)
841 struct ustctl_reg_msg reg_msg
;
843 reg_msg
.magic
= LTTNG_UST_COMM_MAGIC
;
844 reg_msg
.major
= LTTNG_UST_ABI_MAJOR_VERSION
;
845 reg_msg
.minor
= LTTNG_UST_ABI_MINOR_VERSION
;
846 reg_msg
.pid
= getpid();
847 reg_msg
.ppid
= getppid();
848 reg_msg
.uid
= getuid();
849 reg_msg
.gid
= getgid();
850 reg_msg
.bits_per_long
= bits_per_long
;
851 reg_msg
.uint8_t_alignment
= uint8_t_alignment
;
852 reg_msg
.uint16_t_alignment
= uint16_t_alignment
;
853 reg_msg
.uint32_t_alignment
= uint32_t_alignment
;
854 reg_msg
.uint64_t_alignment
= uint64_t_alignment
;
855 reg_msg
.long_alignment
= long_alignment
;
856 reg_msg
.socket_type
= type
;
857 lttng_pthread_getname_np(reg_msg
.name
, LTTNG_UST_ABI_PROCNAME_LEN
);
858 memset(reg_msg
.padding
, 0, sizeof(reg_msg
.padding
));
860 len
= ustcomm_send_unix_sock(sock
, ®_msg
, sizeof(reg_msg
));
861 if (len
> 0 && len
!= sizeof(reg_msg
))
869 ssize_t
count_one_type(const struct lttng_type
*lt
)
880 return count_fields_recursive(lt
->u
.legacy
._struct
.nr_fields
,
881 lt
->u
.legacy
._struct
.fields
) + 1;
882 case atype_enum_nestable
:
883 return count_one_type(lt
->u
.enum_nestable
.container_type
) + 1;
884 case atype_array_nestable
:
885 return count_one_type(lt
->u
.array_nestable
.elem_type
) + 1;
886 case atype_sequence_nestable
:
887 return count_one_type(lt
->u
.sequence_nestable
.elem_type
) + 1;
888 case atype_struct_nestable
:
889 return count_fields_recursive(lt
->u
.struct_nestable
.nr_fields
,
890 lt
->u
.struct_nestable
.fields
) + 1;
894 const struct lttng_event_field
*choices
;
898 ret
= lttng_ust_dynamic_type_choices(&nr_choices
,
903 * Two fields for enum, one field for variant, and
904 * one field per choice.
906 return count_fields_recursive(nr_choices
, choices
) + 3;
916 ssize_t
count_fields_recursive(size_t nr_fields
,
917 const struct lttng_event_field
*lttng_fields
)
920 ssize_t ret
, count
= 0;
922 for (i
= 0; i
< nr_fields
; i
++) {
923 const struct lttng_event_field
*lf
;
925 lf
= <tng_fields
[i
];
926 /* skip 'nowrite' fields */
929 ret
= count_one_type(&lf
->type
);
931 return ret
; /* error */
938 ssize_t
count_ctx_fields_recursive(size_t nr_fields
,
939 const struct lttng_ctx_field
*lttng_fields
)
942 ssize_t ret
, count
= 0;
944 for (i
= 0; i
< nr_fields
; i
++) {
945 const struct lttng_event_field
*lf
;
947 lf
= <tng_fields
[i
].event_field
;
948 /* skip 'nowrite' fields */
951 ret
= count_one_type(&lf
->type
);
953 return ret
; /* error */
960 int serialize_string_encoding(int32_t *ue
,
961 enum lttng_string_encodings le
)
964 case lttng_encode_none
:
965 *ue
= ustctl_encode_none
;
967 case lttng_encode_UTF8
:
968 *ue
= ustctl_encode_UTF8
;
970 case lttng_encode_ASCII
:
971 *ue
= ustctl_encode_ASCII
;
980 int serialize_integer_type(struct ustctl_integer_type
*uit
,
981 const struct lttng_integer_type
*lit
)
985 uit
->size
= lit
->size
;
986 uit
->signedness
= lit
->signedness
;
987 uit
->reverse_byte_order
= lit
->reverse_byte_order
;
988 uit
->base
= lit
->base
;
989 if (serialize_string_encoding(&encoding
, lit
->encoding
))
991 uit
->encoding
= encoding
;
992 uit
->alignment
= lit
->alignment
;
997 int serialize_basic_type(struct lttng_session
*session
,
998 enum ustctl_abstract_types
*uatype
,
999 enum lttng_abstract_types atype
,
1000 union _ustctl_basic_type
*ubt
,
1001 const union _lttng_basic_type
*lbt
)
1006 if (serialize_integer_type(&ubt
->integer
, &lbt
->integer
))
1008 *uatype
= ustctl_atype_integer
;
1015 if (serialize_string_encoding(&encoding
, lbt
->string
.encoding
))
1017 ubt
->string
.encoding
= encoding
;
1018 *uatype
= ustctl_atype_string
;
1023 struct ustctl_float_type
*uft
;
1024 const struct lttng_float_type
*lft
;
1028 uft
->exp_dig
= lft
->exp_dig
;
1029 uft
->mant_dig
= lft
->mant_dig
;
1030 uft
->alignment
= lft
->alignment
;
1031 uft
->reverse_byte_order
= lft
->reverse_byte_order
;
1032 *uatype
= ustctl_atype_float
;
1037 strncpy(ubt
->enumeration
.name
, lbt
->enumeration
.desc
->name
,
1038 LTTNG_UST_SYM_NAME_LEN
);
1039 ubt
->enumeration
.name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
1040 if (serialize_integer_type(&ubt
->enumeration
.container_type
,
1041 &lbt
->enumeration
.container_type
))
1044 const struct lttng_enum
*_enum
;
1046 _enum
= lttng_ust_enum_get_from_desc(session
, lbt
->enumeration
.desc
);
1049 ubt
->enumeration
.id
= _enum
->id
;
1051 ubt
->enumeration
.id
= -1ULL;
1053 *uatype
= ustctl_atype_enum
;
1057 case atype_array_nestable
:
1058 case atype_sequence
:
1059 case atype_sequence_nestable
:
1060 case atype_enum_nestable
:
1068 int serialize_dynamic_type(struct lttng_session
*session
,
1069 struct ustctl_field
*fields
, size_t *iter_output
,
1070 const char *field_name
)
1072 const struct lttng_event_field
*choices
;
1073 char tag_field_name
[LTTNG_UST_SYM_NAME_LEN
];
1074 const struct lttng_type
*tag_type
;
1075 const struct lttng_event_field
*tag_field_generic
;
1076 struct lttng_event_field tag_field
= {
1077 .name
= tag_field_name
,
1080 struct ustctl_field
*uf
;
1081 size_t nr_choices
, i
;
1084 tag_field_generic
= lttng_ust_dynamic_type_tag_field();
1085 tag_type
= &tag_field_generic
->type
;
1087 /* Serialize enum field. */
1088 strncpy(tag_field_name
, field_name
, LTTNG_UST_SYM_NAME_LEN
);
1089 tag_field_name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
1090 strncat(tag_field_name
,
1092 LTTNG_UST_SYM_NAME_LEN
- strlen(tag_field_name
) - 1);
1093 tag_field
.type
= *tag_type
;
1094 ret
= serialize_one_field(session
, fields
, iter_output
,
1099 /* Serialize variant field. */
1100 uf
= &fields
[*iter_output
];
1101 ret
= lttng_ust_dynamic_type_choices(&nr_choices
, &choices
);
1105 strncpy(uf
->name
, field_name
, LTTNG_UST_SYM_NAME_LEN
);
1106 uf
->name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
1107 uf
->type
.atype
= ustctl_atype_variant
;
1108 uf
->type
.u
.variant_nestable
.nr_choices
= nr_choices
;
1109 strncpy(uf
->type
.u
.variant_nestable
.tag_name
,
1111 LTTNG_UST_SYM_NAME_LEN
);
1112 uf
->type
.u
.variant_nestable
.tag_name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
1113 uf
->type
.u
.variant_nestable
.alignment
= 0;
1116 /* Serialize choice fields after variant. */
1117 for (i
= 0; i
< nr_choices
; i
++) {
1118 ret
= serialize_one_field(session
, fields
,
1119 iter_output
, &choices
[i
]);
1127 int serialize_one_type(struct lttng_session
*session
,
1128 struct ustctl_field
*fields
, size_t *iter_output
,
1129 const char *field_name
, const struct lttng_type
*lt
)
1134 * Serializing a type (rather than a field) generates a ustctl_field
1135 * entry with 0-length name.
1138 switch (lt
->atype
) {
1144 struct ustctl_field
*uf
= &fields
[*iter_output
];
1145 struct ustctl_type
*ut
= &uf
->type
;
1146 enum ustctl_abstract_types atype
;
1149 strncpy(uf
->name
, field_name
, LTTNG_UST_SYM_NAME_LEN
);
1150 uf
->name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
1154 ret
= serialize_basic_type(session
, &atype
, lt
->atype
,
1155 &ut
->u
.legacy
.basic
, <
->u
.legacy
.basic
);
1164 struct ustctl_field
*uf
= &fields
[*iter_output
];
1165 struct ustctl_type
*ut
= &uf
->type
;
1166 struct ustctl_basic_type
*ubt
;
1167 const struct lttng_basic_type
*lbt
;
1168 enum ustctl_abstract_types atype
;
1171 strncpy(uf
->name
, field_name
, LTTNG_UST_SYM_NAME_LEN
);
1172 uf
->name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
1176 ut
->atype
= ustctl_atype_array
;
1177 ubt
= &ut
->u
.legacy
.array
.elem_type
;
1178 lbt
= <
->u
.legacy
.array
.elem_type
;
1179 ut
->u
.legacy
.array
.length
= lt
->u
.legacy
.array
.length
;
1180 ret
= serialize_basic_type(session
, &atype
, lbt
->atype
,
1181 &ubt
->u
.basic
, &lbt
->u
.basic
);
1188 case atype_array_nestable
:
1190 struct ustctl_field
*uf
= &fields
[*iter_output
];
1191 struct ustctl_type
*ut
= &uf
->type
;
1194 strncpy(uf
->name
, field_name
, LTTNG_UST_SYM_NAME_LEN
);
1195 uf
->name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
1199 ut
->atype
= ustctl_atype_array_nestable
;
1200 ut
->u
.array_nestable
.length
= lt
->u
.array_nestable
.length
;
1201 ut
->u
.array_nestable
.alignment
= lt
->u
.array_nestable
.alignment
;
1204 ret
= serialize_one_type(session
, fields
, iter_output
, NULL
,
1205 lt
->u
.array_nestable
.elem_type
);
1210 case atype_sequence
:
1212 struct ustctl_field
*uf
= &fields
[*iter_output
];
1213 struct ustctl_type
*ut
= &uf
->type
;
1214 struct ustctl_basic_type
*ubt
;
1215 const struct lttng_basic_type
*lbt
;
1216 enum ustctl_abstract_types atype
;
1219 strncpy(uf
->name
, field_name
, LTTNG_UST_SYM_NAME_LEN
);
1220 uf
->name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
1224 uf
->type
.atype
= ustctl_atype_sequence
;
1225 ubt
= &ut
->u
.legacy
.sequence
.length_type
;
1226 lbt
= <
->u
.legacy
.sequence
.length_type
;
1227 ret
= serialize_basic_type(session
, &atype
, lbt
->atype
,
1228 &ubt
->u
.basic
, &lbt
->u
.basic
);
1232 ubt
= &ut
->u
.legacy
.sequence
.elem_type
;
1233 lbt
= <
->u
.legacy
.sequence
.elem_type
;
1234 ret
= serialize_basic_type(session
, &atype
, lbt
->atype
,
1235 &ubt
->u
.basic
, &lbt
->u
.basic
);
1242 case atype_sequence_nestable
:
1244 struct ustctl_field
*uf
= &fields
[*iter_output
];
1245 struct ustctl_type
*ut
= &uf
->type
;
1248 strncpy(uf
->name
, field_name
, LTTNG_UST_SYM_NAME_LEN
);
1249 uf
->name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
1253 ut
->atype
= ustctl_atype_sequence_nestable
;
1254 strncpy(ut
->u
.sequence_nestable
.length_name
,
1255 lt
->u
.sequence_nestable
.length_name
,
1256 LTTNG_UST_SYM_NAME_LEN
);
1257 ut
->u
.sequence_nestable
.length_name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
1258 ut
->u
.sequence_nestable
.alignment
= lt
->u
.sequence_nestable
.alignment
;
1261 ret
= serialize_one_type(session
, fields
, iter_output
, NULL
,
1262 lt
->u
.sequence_nestable
.elem_type
);
1269 ret
= serialize_dynamic_type(session
, fields
, iter_output
,
1277 struct ustctl_field
*uf
= &fields
[*iter_output
];
1280 strncpy(uf
->name
, field_name
, LTTNG_UST_SYM_NAME_LEN
);
1281 uf
->name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
1285 uf
->type
.atype
= ustctl_atype_struct
;
1286 uf
->type
.u
.legacy
._struct
.nr_fields
= lt
->u
.legacy
._struct
.nr_fields
;
1289 ret
= serialize_fields(session
, fields
, iter_output
,
1290 lt
->u
.legacy
._struct
.nr_fields
,
1291 lt
->u
.legacy
._struct
.fields
);
1296 case atype_struct_nestable
:
1298 struct ustctl_field
*uf
= &fields
[*iter_output
];
1301 strncpy(uf
->name
, field_name
, LTTNG_UST_SYM_NAME_LEN
);
1302 uf
->name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
1306 uf
->type
.atype
= ustctl_atype_struct_nestable
;
1307 uf
->type
.u
.struct_nestable
.nr_fields
= lt
->u
.struct_nestable
.nr_fields
;
1308 uf
->type
.u
.struct_nestable
.alignment
= lt
->u
.struct_nestable
.alignment
;
1311 ret
= serialize_fields(session
, fields
, iter_output
,
1312 lt
->u
.struct_nestable
.nr_fields
,
1313 lt
->u
.struct_nestable
.fields
);
1318 case atype_enum_nestable
:
1320 struct ustctl_field
*uf
= &fields
[*iter_output
];
1321 struct ustctl_type
*ut
= &uf
->type
;
1324 strncpy(uf
->name
, field_name
, LTTNG_UST_SYM_NAME_LEN
);
1325 uf
->name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
1329 strncpy(ut
->u
.enum_nestable
.name
, lt
->u
.enum_nestable
.desc
->name
,
1330 LTTNG_UST_SYM_NAME_LEN
);
1331 ut
->u
.enum_nestable
.name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
1332 ut
->atype
= ustctl_atype_enum_nestable
;
1335 ret
= serialize_one_type(session
, fields
, iter_output
, NULL
,
1336 lt
->u
.enum_nestable
.container_type
);
1340 const struct lttng_enum
*_enum
;
1342 _enum
= lttng_ust_enum_get_from_desc(session
, lt
->u
.enum_nestable
.desc
);
1345 ut
->u
.enum_nestable
.id
= _enum
->id
;
1347 ut
->u
.enum_nestable
.id
= -1ULL;
1358 int serialize_one_field(struct lttng_session
*session
,
1359 struct ustctl_field
*fields
, size_t *iter_output
,
1360 const struct lttng_event_field
*lf
)
1362 /* skip 'nowrite' fields */
1366 return serialize_one_type(session
, fields
, iter_output
, lf
->name
, &lf
->type
);
1370 int serialize_fields(struct lttng_session
*session
,
1371 struct ustctl_field
*ustctl_fields
,
1372 size_t *iter_output
, size_t nr_lttng_fields
,
1373 const struct lttng_event_field
*lttng_fields
)
1378 for (i
= 0; i
< nr_lttng_fields
; i
++) {
1379 ret
= serialize_one_field(session
, ustctl_fields
,
1380 iter_output
, <tng_fields
[i
]);
1388 int alloc_serialize_fields(struct lttng_session
*session
,
1389 size_t *_nr_write_fields
,
1390 struct ustctl_field
**ustctl_fields
,
1392 const struct lttng_event_field
*lttng_fields
)
1394 struct ustctl_field
*fields
;
1396 size_t iter_output
= 0;
1397 ssize_t nr_write_fields
;
1399 nr_write_fields
= count_fields_recursive(nr_fields
, lttng_fields
);
1400 if (nr_write_fields
< 0) {
1401 return (int) nr_write_fields
;
1404 fields
= zmalloc(nr_write_fields
* sizeof(*fields
));
1408 ret
= serialize_fields(session
, fields
, &iter_output
, nr_fields
,
1413 *_nr_write_fields
= nr_write_fields
;
1414 *ustctl_fields
= fields
;
1423 int serialize_entries(struct ustctl_enum_entry
**_entries
,
1425 const struct lttng_enum_entry
*lttng_entries
)
1427 struct ustctl_enum_entry
*entries
;
1430 /* Serialize the entries */
1431 entries
= zmalloc(nr_entries
* sizeof(*entries
));
1434 for (i
= 0; i
< nr_entries
; i
++) {
1435 struct ustctl_enum_entry
*uentry
;
1436 const struct lttng_enum_entry
*lentry
;
1438 uentry
= &entries
[i
];
1439 lentry
= <tng_entries
[i
];
1441 uentry
->start
.value
= lentry
->start
.value
;
1442 uentry
->start
.signedness
= lentry
->start
.signedness
;
1443 uentry
->end
.value
= lentry
->end
.value
;
1444 uentry
->end
.signedness
= lentry
->end
.signedness
;
1445 strncpy(uentry
->string
, lentry
->string
, LTTNG_UST_SYM_NAME_LEN
);
1446 uentry
->string
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
1448 if (lentry
->u
.extra
.options
& LTTNG_ENUM_ENTRY_OPTION_IS_AUTO
) {
1449 uentry
->u
.extra
.options
|=
1450 USTCTL_UST_ENUM_ENTRY_OPTION_IS_AUTO
;
1453 *_entries
= entries
;
1458 int serialize_ctx_fields(struct lttng_session
*session
,
1459 size_t *_nr_write_fields
,
1460 struct ustctl_field
**ustctl_fields
,
1462 const struct lttng_ctx_field
*lttng_fields
)
1464 struct ustctl_field
*fields
;
1466 size_t i
, iter_output
= 0;
1467 ssize_t nr_write_fields
;
1469 nr_write_fields
= count_ctx_fields_recursive(nr_fields
,
1471 if (nr_write_fields
< 0) {
1472 return (int) nr_write_fields
;
1475 fields
= zmalloc(nr_write_fields
* sizeof(*fields
));
1479 for (i
= 0; i
< nr_fields
; i
++) {
1480 ret
= serialize_one_field(session
, fields
, &iter_output
,
1481 <tng_fields
[i
].event_field
);
1486 *_nr_write_fields
= nr_write_fields
;
1487 *ustctl_fields
= fields
;
1496 * Returns 0 on success, negative error value on error.
1498 int ustcomm_register_event(int sock
,
1499 struct lttng_session
*session
,
1500 int session_objd
, /* session descriptor */
1501 int channel_objd
, /* channel descriptor */
1502 const char *event_name
, /* event name (input) */
1504 const char *signature
, /* event signature (input) */
1505 size_t nr_fields
, /* fields */
1506 const struct lttng_event_field
*lttng_fields
,
1507 const char *model_emf_uri
,
1508 uint64_t user_token
,
1509 uint32_t *event_id
, /* event id (output) */
1510 uint64_t *counter_index
) /* counter index (output) */
1514 struct ustcomm_notify_hdr header
;
1515 struct ustcomm_notify_event_msg m
;
1518 struct ustcomm_notify_hdr header
;
1519 struct ustcomm_notify_event_reply r
;
1521 size_t signature_len
, fields_len
, model_emf_uri_len
;
1522 struct ustctl_field
*fields
= NULL
;
1523 size_t nr_write_fields
= 0;
1526 memset(&msg
, 0, sizeof(msg
));
1527 msg
.header
.notify_cmd
= USTCTL_NOTIFY_CMD_EVENT
;
1528 msg
.m
.session_objd
= session_objd
;
1529 msg
.m
.channel_objd
= channel_objd
;
1530 strncpy(msg
.m
.event_name
, event_name
, LTTNG_UST_SYM_NAME_LEN
);
1531 msg
.m
.event_name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
1532 msg
.m
.loglevel
= loglevel
;
1533 msg
.m
.user_token
= user_token
;
1534 signature_len
= strlen(signature
) + 1;
1535 msg
.m
.signature_len
= signature_len
;
1537 /* Calculate fields len, serialize fields. */
1538 if (nr_fields
> 0) {
1539 ret
= alloc_serialize_fields(session
, &nr_write_fields
, &fields
,
1540 nr_fields
, lttng_fields
);
1545 fields_len
= sizeof(*fields
) * nr_write_fields
;
1546 msg
.m
.fields_len
= fields_len
;
1547 if (model_emf_uri
) {
1548 model_emf_uri_len
= strlen(model_emf_uri
) + 1;
1550 model_emf_uri_len
= 0;
1552 msg
.m
.model_emf_uri_len
= model_emf_uri_len
;
1554 len
= ustcomm_send_unix_sock(sock
, &msg
, sizeof(msg
));
1555 if (len
> 0 && len
!= sizeof(msg
)) {
1564 /* send signature */
1565 len
= ustcomm_send_unix_sock(sock
, signature
, signature_len
);
1566 if (len
> 0 && len
!= signature_len
) {
1576 if (fields_len
> 0) {
1577 len
= ustcomm_send_unix_sock(sock
, fields
, fields_len
);
1578 if (len
> 0 && len
!= fields_len
) {
1589 if (model_emf_uri_len
) {
1590 /* send model_emf_uri */
1591 len
= ustcomm_send_unix_sock(sock
, model_emf_uri
,
1593 if (len
> 0 && len
!= model_emf_uri_len
) {
1602 len
= ustcomm_recv_unix_sock(sock
, &reply
, sizeof(reply
));
1604 case 0: /* orderly shutdown */
1607 if (reply
.header
.notify_cmd
!= msg
.header
.notify_cmd
) {
1608 ERR("Unexpected result message command "
1609 "expected: %u vs received: %u\n",
1610 msg
.header
.notify_cmd
, reply
.header
.notify_cmd
);
1613 if (reply
.r
.ret_code
> 0)
1615 if (reply
.r
.ret_code
< 0)
1616 return reply
.r
.ret_code
;
1617 *event_id
= reply
.r
.event_id
;
1618 *counter_index
= reply
.r
.counter_index
;
1619 DBG("Sent register event notification for name \"%s\": ret_code %d, event_id %u, counter_index %" PRIu64
"\n",
1620 event_name
, reply
.r
.ret_code
, reply
.r
.event_id
, reply
.r
.counter_index
);
1624 /* Transport level error */
1625 if (errno
== EPIPE
|| errno
== ECONNRESET
)
1629 ERR("incorrect message size: %zd\n", len
);
1635 /* Error path only. */
1642 * Returns 0 on success, negative error value on error.
1643 * Returns -EPIPE or -ECONNRESET if other end has hung up.
1645 int ustcomm_register_enum(int sock
,
1646 int session_objd
, /* session descriptor */
1647 const char *enum_name
, /* enum name (input) */
1648 size_t nr_entries
, /* entries */
1649 const struct lttng_enum_entry
*lttng_entries
,
1654 struct ustcomm_notify_hdr header
;
1655 struct ustcomm_notify_enum_msg m
;
1658 struct ustcomm_notify_hdr header
;
1659 struct ustcomm_notify_enum_reply r
;
1662 struct ustctl_enum_entry
*entries
= NULL
;
1665 memset(&msg
, 0, sizeof(msg
));
1666 msg
.header
.notify_cmd
= USTCTL_NOTIFY_CMD_ENUM
;
1667 msg
.m
.session_objd
= session_objd
;
1668 strncpy(msg
.m
.enum_name
, enum_name
, LTTNG_UST_SYM_NAME_LEN
);
1669 msg
.m
.enum_name
[LTTNG_UST_SYM_NAME_LEN
- 1] = '\0';
1671 /* Calculate entries len, serialize entries. */
1672 if (nr_entries
> 0) {
1673 ret
= serialize_entries(&entries
,
1674 nr_entries
, lttng_entries
);
1679 entries_len
= sizeof(*entries
) * nr_entries
;
1680 msg
.m
.entries_len
= entries_len
;
1682 len
= ustcomm_send_unix_sock(sock
, &msg
, sizeof(msg
));
1683 if (len
> 0 && len
!= sizeof(msg
)) {
1693 if (entries_len
> 0) {
1694 len
= ustcomm_send_unix_sock(sock
, entries
, entries_len
);
1695 if (len
> 0 && len
!= entries_len
) {
1708 len
= ustcomm_recv_unix_sock(sock
, &reply
, sizeof(reply
));
1710 case 0: /* orderly shutdown */
1713 if (reply
.header
.notify_cmd
!= msg
.header
.notify_cmd
) {
1714 ERR("Unexpected result message command "
1715 "expected: %u vs received: %u\n",
1716 msg
.header
.notify_cmd
, reply
.header
.notify_cmd
);
1719 if (reply
.r
.ret_code
> 0)
1721 if (reply
.r
.ret_code
< 0)
1722 return reply
.r
.ret_code
;
1723 *id
= reply
.r
.enum_id
;
1724 DBG("Sent register enum notification for name \"%s\": ret_code %d\n",
1725 enum_name
, reply
.r
.ret_code
);
1729 /* Transport level error */
1730 if (errno
== EPIPE
|| errno
== ECONNRESET
)
1734 ERR("incorrect message size: %zd\n", len
);
1746 * Returns 0 on success, negative error value on error.
1747 * Returns -EPIPE or -ECONNRESET if other end has hung up.
1749 int ustcomm_register_channel(int sock
,
1750 struct lttng_session
*session
,
1751 int session_objd
, /* session descriptor */
1752 int channel_objd
, /* channel descriptor */
1753 size_t nr_ctx_fields
,
1754 const struct lttng_ctx_field
*ctx_fields
,
1755 uint32_t *chan_id
, /* channel id (output) */
1756 int *header_type
) /* header type (output) */
1760 struct ustcomm_notify_hdr header
;
1761 struct ustcomm_notify_channel_msg m
;
1764 struct ustcomm_notify_hdr header
;
1765 struct ustcomm_notify_channel_reply r
;
1768 struct ustctl_field
*fields
= NULL
;
1770 size_t nr_write_fields
= 0;
1772 memset(&msg
, 0, sizeof(msg
));
1773 msg
.header
.notify_cmd
= USTCTL_NOTIFY_CMD_CHANNEL
;
1774 msg
.m
.session_objd
= session_objd
;
1775 msg
.m
.channel_objd
= channel_objd
;
1777 /* Calculate fields len, serialize fields. */
1778 if (nr_ctx_fields
> 0) {
1779 ret
= serialize_ctx_fields(session
, &nr_write_fields
, &fields
,
1780 nr_ctx_fields
, ctx_fields
);
1785 fields_len
= sizeof(*fields
) * nr_write_fields
;
1786 msg
.m
.ctx_fields_len
= fields_len
;
1787 len
= ustcomm_send_unix_sock(sock
, &msg
, sizeof(msg
));
1788 if (len
> 0 && len
!= sizeof(msg
)) {
1798 if (fields_len
> 0) {
1799 len
= ustcomm_send_unix_sock(sock
, fields
, fields_len
);
1801 if (len
> 0 && len
!= fields_len
) {
1811 len
= ustcomm_recv_unix_sock(sock
, &reply
, sizeof(reply
));
1813 case 0: /* orderly shutdown */
1816 if (reply
.header
.notify_cmd
!= msg
.header
.notify_cmd
) {
1817 ERR("Unexpected result message command "
1818 "expected: %u vs received: %u\n",
1819 msg
.header
.notify_cmd
, reply
.header
.notify_cmd
);
1822 if (reply
.r
.ret_code
> 0)
1824 if (reply
.r
.ret_code
< 0)
1825 return reply
.r
.ret_code
;
1826 *chan_id
= reply
.r
.chan_id
;
1827 switch (reply
.r
.header_type
) {
1830 *header_type
= reply
.r
.header_type
;
1833 ERR("Unexpected channel header type %u\n",
1834 reply
.r
.header_type
);
1837 DBG("Sent register channel notification: chan_id %d, header_type %d\n",
1838 reply
.r
.chan_id
, reply
.r
.header_type
);
1842 /* Transport level error */
1843 if (errno
== EPIPE
|| errno
== ECONNRESET
)
1847 ERR("incorrect message size: %zd\n", len
);
1854 * Set socket reciving timeout.
1856 int ustcomm_setsockopt_rcv_timeout(int sock
, unsigned int msec
)
1861 tv
.tv_sec
= msec
/ 1000;
1862 tv
.tv_usec
= (msec
* 1000 % 1000000);
1864 ret
= setsockopt(sock
, SOL_SOCKET
, SO_RCVTIMEO
, &tv
, sizeof(tv
));
1866 PERROR("setsockopt SO_RCVTIMEO");
1874 * Set socket sending timeout.
1876 int ustcomm_setsockopt_snd_timeout(int sock
, unsigned int msec
)
1881 tv
.tv_sec
= msec
/ 1000;
1882 tv
.tv_usec
= (msec
* 1000) % 1000000;
1884 ret
= setsockopt(sock
, SOL_SOCKET
, SO_SNDTIMEO
, &tv
, sizeof(tv
));
1886 PERROR("setsockopt SO_SNDTIMEO");