Introduce LTTNG_UST_MAP_POPULATE_POLICY environment variable
[lttng-ust.git] / liblttng-ust-comm / lttng-ust-comm.c
1 /*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 * Copyright (C) 2011-2013 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; only
8 * version 2.1 of the License.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #define _GNU_SOURCE
21 #include <limits.h>
22 #include <stdint.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/socket.h>
27 #include <sys/stat.h>
28 #include <sys/types.h>
29 #include <sys/un.h>
30 #include <unistd.h>
31 #include <assert.h>
32 #include <errno.h>
33 #include <fcntl.h>
34
35 #include <lttng/ust-ctl.h>
36 #include <ust-comm.h>
37 #include <ust-fd.h>
38 #include <helper.h>
39 #include <lttng/ust-error.h>
40 #include <lttng/ust-events.h>
41 #include <lttng/ust-dynamic-type.h>
42 #include <usterr-signal-safe.h>
43
44 #include "../liblttng-ust/compat.h"
45
46 #define USTCOMM_CODE_OFFSET(code) \
47 (code == LTTNG_UST_OK ? 0 : (code - LTTNG_UST_ERR + 1))
48
49 #define USTCOMM_MAX_SEND_FDS 4
50
51 static
52 ssize_t count_fields_recursive(size_t nr_fields,
53 const struct lttng_event_field *lttng_fields);
54 static
55 int serialize_one_field(struct lttng_session *session,
56 struct ustctl_field *fields, size_t *iter_output,
57 const struct lttng_event_field *lf);
58 static
59 int serialize_fields(struct lttng_session *session,
60 struct ustctl_field *ustctl_fields,
61 size_t *iter_output, size_t nr_lttng_fields,
62 const struct lttng_event_field *lttng_fields);
63
64 /*
65 * Human readable error message.
66 */
67 static const char *ustcomm_readable_code[] = {
68 [ USTCOMM_CODE_OFFSET(LTTNG_UST_OK) ] = "Success",
69 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR) ] = "Unknown error",
70 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_NOENT) ] = "No entry",
71 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_EXIST) ] = "Object already exists",
72 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_INVAL) ] = "Invalid argument",
73 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_PERM) ] = "Permission denied",
74 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_NOSYS) ] = "Not implemented",
75 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_EXITING) ] = "Process is exiting",
76
77 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_INVAL_MAGIC) ] = "Invalid magic number",
78 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_INVAL_SOCKET_TYPE) ] = "Invalid socket type",
79 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_UNSUP_MAJOR) ] = "Unsupported major version",
80 };
81
82 /*
83 * lttng_ust_strerror
84 *
85 * Receives positive error value.
86 * Return ptr to string representing a human readable
87 * error code from the ustcomm_return_code enum.
88 */
89 const char *lttng_ust_strerror(int code)
90 {
91 if (code == LTTNG_UST_OK)
92 return ustcomm_readable_code[USTCOMM_CODE_OFFSET(code)];
93 if (code < LTTNG_UST_ERR)
94 return strerror(code);
95 if (code >= LTTNG_UST_ERR_NR)
96 code = LTTNG_UST_ERR;
97 return ustcomm_readable_code[USTCOMM_CODE_OFFSET(code)];
98 }
99
100 /*
101 * ustcomm_connect_unix_sock
102 *
103 * Connect to unix socket using the path name.
104 *
105 * Caller handles FD tracker.
106 */
107 int ustcomm_connect_unix_sock(const char *pathname, long timeout)
108 {
109 struct sockaddr_un sun;
110 int fd, ret;
111
112 /*
113 * libust threads require the close-on-exec flag for all
114 * resources so it does not leak file descriptors upon exec.
115 * SOCK_CLOEXEC is not used since it is linux specific.
116 */
117 fd = socket(PF_UNIX, SOCK_STREAM, 0);
118 if (fd < 0) {
119 PERROR("socket");
120 ret = -errno;
121 goto error;
122 }
123 if (timeout >= 0) {
124 /* Give at least 10ms. */
125 if (timeout < 10)
126 timeout = 10;
127 ret = ustcomm_setsockopt_snd_timeout(fd, timeout);
128 if (ret < 0) {
129 WARN("Error setting connect socket send timeout");
130 }
131 }
132 ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
133 if (ret < 0) {
134 PERROR("fcntl");
135 ret = -errno;
136 goto error_fcntl;
137 }
138
139 memset(&sun, 0, sizeof(sun));
140 sun.sun_family = AF_UNIX;
141 strncpy(sun.sun_path, pathname, sizeof(sun.sun_path));
142 sun.sun_path[sizeof(sun.sun_path) - 1] = '\0';
143
144 ret = connect(fd, (struct sockaddr *) &sun, sizeof(sun));
145 if (ret < 0) {
146 /*
147 * Don't print message on connect ENOENT error, because
148 * connect is used in normal execution to detect if
149 * sessiond is alive. ENOENT is when the unix socket
150 * file does not exist, and ECONNREFUSED is when the
151 * file exists but no sessiond is listening.
152 */
153 if (errno != ECONNREFUSED && errno != ECONNRESET
154 && errno != ENOENT && errno != EACCES)
155 PERROR("connect");
156 ret = -errno;
157 if (ret == -ECONNREFUSED || ret == -ECONNRESET)
158 ret = -EPIPE;
159 goto error_connect;
160 }
161
162 return fd;
163
164 error_connect:
165 error_fcntl:
166 {
167 int closeret;
168
169 closeret = close(fd);
170 if (closeret)
171 PERROR("close");
172 }
173 error:
174 return ret;
175 }
176
177 /*
178 * ustcomm_accept_unix_sock
179 *
180 * Do an accept(2) on the sock and return the
181 * new file descriptor. The socket MUST be bind(2) before.
182 */
183 int ustcomm_accept_unix_sock(int sock)
184 {
185 int new_fd;
186 struct sockaddr_un sun;
187 socklen_t len = 0;
188
189 /* Blocking call */
190 new_fd = accept(sock, (struct sockaddr *) &sun, &len);
191 if (new_fd < 0) {
192 if (errno != ECONNABORTED)
193 PERROR("accept");
194 new_fd = -errno;
195 if (new_fd == -ECONNABORTED)
196 new_fd = -EPIPE;
197 }
198 return new_fd;
199 }
200
201 /*
202 * ustcomm_create_unix_sock
203 *
204 * Creates a AF_UNIX local socket using pathname
205 * bind the socket upon creation and return the fd.
206 */
207 int ustcomm_create_unix_sock(const char *pathname)
208 {
209 struct sockaddr_un sun;
210 int fd, ret;
211
212 /* Create server socket */
213 if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
214 PERROR("socket");
215 ret = -errno;
216 goto error;
217 }
218
219 memset(&sun, 0, sizeof(sun));
220 sun.sun_family = AF_UNIX;
221 strncpy(sun.sun_path, pathname, sizeof(sun.sun_path));
222 sun.sun_path[sizeof(sun.sun_path) - 1] = '\0';
223
224 /* Unlink the old file if present */
225 (void) unlink(pathname);
226 ret = bind(fd, (struct sockaddr *) &sun, sizeof(sun));
227 if (ret < 0) {
228 PERROR("bind");
229 ret = -errno;
230 goto error_close;
231 }
232
233 return fd;
234
235 error_close:
236 {
237 int closeret;
238
239 closeret = close(fd);
240 if (closeret) {
241 PERROR("close");
242 }
243 }
244 error:
245 return ret;
246 }
247
248 /*
249 * ustcomm_listen_unix_sock
250 *
251 * Make the socket listen using LTTNG_UST_COMM_MAX_LISTEN.
252 */
253 int ustcomm_listen_unix_sock(int sock)
254 {
255 int ret;
256
257 ret = listen(sock, LTTNG_UST_COMM_MAX_LISTEN);
258 if (ret < 0) {
259 ret = -errno;
260 PERROR("listen");
261 }
262
263 return ret;
264 }
265
266 /*
267 * ustcomm_close_unix_sock
268 *
269 * Shutdown cleanly a unix socket.
270 *
271 * Handles fd tracker internally.
272 */
273 int ustcomm_close_unix_sock(int sock)
274 {
275 int ret;
276
277 lttng_ust_lock_fd_tracker();
278 ret = close(sock);
279 if (!ret) {
280 lttng_ust_delete_fd_from_tracker(sock);
281 } else {
282 PERROR("close");
283 ret = -errno;
284 }
285 lttng_ust_unlock_fd_tracker();
286
287 return ret;
288 }
289
290 /*
291 * ustcomm_recv_unix_sock
292 *
293 * Receive data of size len in put that data into
294 * the buf param. Using recvmsg API.
295 * Return the size of received data.
296 * Return 0 on orderly shutdown.
297 */
298 ssize_t ustcomm_recv_unix_sock(int sock, void *buf, size_t len)
299 {
300 struct msghdr msg;
301 struct iovec iov[1];
302 ssize_t ret = -1;
303 size_t len_last;
304
305 memset(&msg, 0, sizeof(msg));
306
307 iov[0].iov_base = buf;
308 iov[0].iov_len = len;
309 msg.msg_iov = iov;
310 msg.msg_iovlen = 1;
311
312 do {
313 len_last = iov[0].iov_len;
314 ret = recvmsg(sock, &msg, 0);
315 if (ret > 0) {
316 iov[0].iov_base += ret;
317 iov[0].iov_len -= ret;
318 assert(ret <= len_last);
319 }
320 } while ((ret > 0 && ret < len_last) || (ret < 0 && errno == EINTR));
321
322 if (ret < 0) {
323 int shutret;
324
325 if (errno != EPIPE && errno != ECONNRESET && errno != ECONNREFUSED)
326 PERROR("recvmsg");
327 ret = -errno;
328 if (ret == -ECONNRESET || ret == -ECONNREFUSED)
329 ret = -EPIPE;
330
331 shutret = shutdown(sock, SHUT_RDWR);
332 if (shutret)
333 ERR("Socket shutdown error");
334 } else if (ret > 0) {
335 ret = len;
336 }
337 /* ret = 0 means an orderly shutdown. */
338
339 return ret;
340 }
341
342 /*
343 * ustcomm_send_unix_sock
344 *
345 * Send buf data of size len. Using sendmsg API.
346 * Return the size of sent data.
347 */
348 ssize_t ustcomm_send_unix_sock(int sock, const void *buf, size_t len)
349 {
350 struct msghdr msg;
351 struct iovec iov[1];
352 ssize_t ret;
353
354 memset(&msg, 0, sizeof(msg));
355
356 iov[0].iov_base = (void *) buf;
357 iov[0].iov_len = len;
358 msg.msg_iov = iov;
359 msg.msg_iovlen = 1;
360
361 /*
362 * Using the MSG_NOSIGNAL when sending data from sessiond to
363 * libust, so libust does not receive an unhandled SIGPIPE or
364 * SIGURG. The sessiond receiver side can be made more resilient
365 * by ignoring SIGPIPE, but we don't have this luxury on the
366 * libust side.
367 */
368 do {
369 ret = sendmsg(sock, &msg, MSG_NOSIGNAL);
370 } while (ret < 0 && errno == EINTR);
371
372 if (ret < 0) {
373 int shutret;
374
375 if (errno != EPIPE && errno != ECONNRESET)
376 PERROR("sendmsg");
377 ret = -errno;
378 if (ret == -ECONNRESET)
379 ret = -EPIPE;
380
381 shutret = shutdown(sock, SHUT_RDWR);
382 if (shutret)
383 ERR("Socket shutdown error");
384 }
385
386 return ret;
387 }
388
389 /*
390 * Send a message accompanied by fd(s) over a unix socket.
391 *
392 * Returns the size of data sent, or negative error value.
393 */
394 ssize_t ustcomm_send_fds_unix_sock(int sock, int *fds, size_t nb_fd)
395 {
396 struct msghdr msg;
397 struct cmsghdr *cmptr;
398 struct iovec iov[1];
399 ssize_t ret = -1;
400 unsigned int sizeof_fds = nb_fd * sizeof(int);
401 char tmp[CMSG_SPACE(sizeof_fds)];
402 char dummy = 0;
403
404 memset(&msg, 0, sizeof(msg));
405 memset(tmp, 0, CMSG_SPACE(sizeof_fds) * sizeof(char));
406
407 if (nb_fd > USTCOMM_MAX_SEND_FDS)
408 return -EINVAL;
409
410 msg.msg_control = (caddr_t)tmp;
411 msg.msg_controllen = CMSG_LEN(sizeof_fds);
412
413 cmptr = CMSG_FIRSTHDR(&msg);
414 if (!cmptr)
415 return -EINVAL;
416 cmptr->cmsg_level = SOL_SOCKET;
417 cmptr->cmsg_type = SCM_RIGHTS;
418 cmptr->cmsg_len = CMSG_LEN(sizeof_fds);
419 memcpy(CMSG_DATA(cmptr), fds, sizeof_fds);
420 /* Sum of the length of all control messages in the buffer: */
421 msg.msg_controllen = cmptr->cmsg_len;
422
423 iov[0].iov_base = &dummy;
424 iov[0].iov_len = 1;
425 msg.msg_iov = iov;
426 msg.msg_iovlen = 1;
427
428 do {
429 ret = sendmsg(sock, &msg, MSG_NOSIGNAL);
430 } while (ret < 0 && errno == EINTR);
431 if (ret < 0) {
432 /*
433 * We consider EPIPE and ECONNRESET as expected.
434 */
435 if (errno != EPIPE && errno != ECONNRESET) {
436 PERROR("sendmsg");
437 }
438 ret = -errno;
439 if (ret == -ECONNRESET)
440 ret = -EPIPE;
441 }
442 return ret;
443 }
444
445 /*
446 * Recv a message accompanied by fd(s) from a unix socket.
447 *
448 * Expect at most "nb_fd" file descriptors. Returns the number of fd
449 * actually received in nb_fd.
450 * Returns -EPIPE on orderly shutdown.
451 */
452 ssize_t ustcomm_recv_fds_unix_sock(int sock, int *fds, size_t nb_fd)
453 {
454 struct iovec iov[1];
455 ssize_t ret = 0;
456 struct cmsghdr *cmsg;
457 size_t sizeof_fds = nb_fd * sizeof(int);
458 char recv_fd[CMSG_SPACE(sizeof_fds)];
459 struct msghdr msg;
460 char dummy;
461 int i;
462
463 memset(&msg, 0, sizeof(msg));
464
465 /* Prepare to receive the structures */
466 iov[0].iov_base = &dummy;
467 iov[0].iov_len = 1;
468 msg.msg_iov = iov;
469 msg.msg_iovlen = 1;
470 msg.msg_control = recv_fd;
471 msg.msg_controllen = sizeof(recv_fd);
472
473 do {
474 ret = recvmsg(sock, &msg, 0);
475 } while (ret < 0 && errno == EINTR);
476 if (ret < 0) {
477 if (errno != EPIPE && errno != ECONNRESET) {
478 PERROR("recvmsg fds");
479 }
480 ret = -errno;
481 if (ret == -ECONNRESET)
482 ret = -EPIPE;
483 goto end;
484 }
485 if (ret == 0) {
486 /* orderly shutdown */
487 ret = -EPIPE;
488 goto end;
489 }
490 if (ret != 1) {
491 ERR("Error: Received %zd bytes, expected %d\n",
492 ret, 1);
493 goto end;
494 }
495 if (msg.msg_flags & MSG_CTRUNC) {
496 ERR("Error: Control message truncated.\n");
497 ret = -1;
498 goto end;
499 }
500 cmsg = CMSG_FIRSTHDR(&msg);
501 if (!cmsg) {
502 ERR("Error: Invalid control message header\n");
503 ret = -1;
504 goto end;
505 }
506 if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
507 ERR("Didn't received any fd\n");
508 ret = -1;
509 goto end;
510 }
511 if (cmsg->cmsg_len != CMSG_LEN(sizeof_fds)) {
512 ERR("Error: Received %zu bytes of ancillary data, expected %zu\n",
513 (size_t) cmsg->cmsg_len, (size_t) CMSG_LEN(sizeof_fds));
514 ret = -1;
515 goto end;
516 }
517
518 memcpy(fds, CMSG_DATA(cmsg), sizeof_fds);
519
520 /* Set FD_CLOEXEC */
521 for (i = 0; i < nb_fd; i++) {
522 ret = fcntl(fds[i], F_SETFD, FD_CLOEXEC);
523 if (ret < 0) {
524 PERROR("fcntl failed to set FD_CLOEXEC on fd %d",
525 fds[i]);
526 }
527 }
528
529 ret = nb_fd;
530 end:
531 return ret;
532 }
533
534 int ustcomm_send_app_msg(int sock, struct ustcomm_ust_msg *lum)
535 {
536 ssize_t len;
537
538 len = ustcomm_send_unix_sock(sock, lum, sizeof(*lum));
539 switch (len) {
540 case sizeof(*lum):
541 break;
542 default:
543 if (len < 0) {
544 return len;
545 } else {
546 ERR("incorrect message size: %zd\n", len);
547 return -EINVAL;
548 }
549 }
550 return 0;
551 }
552
553 int ustcomm_recv_app_reply(int sock, struct ustcomm_ust_reply *lur,
554 uint32_t expected_handle, uint32_t expected_cmd)
555 {
556 ssize_t len;
557
558 memset(lur, 0, sizeof(*lur));
559 len = ustcomm_recv_unix_sock(sock, lur, sizeof(*lur));
560 switch (len) {
561 case 0: /* orderly shutdown */
562 return -EPIPE;
563 case sizeof(*lur):
564 {
565 int err = 0;
566
567 if (lur->handle != expected_handle) {
568 ERR("Unexpected result message handle: "
569 "expected: %u vs received: %u\n",
570 expected_handle, lur->handle);
571 err = 1;
572 }
573 if (lur->cmd != expected_cmd) {
574 ERR("Unexpected result message command "
575 "expected: %u vs received: %u\n",
576 expected_cmd, lur->cmd);
577 err = 1;
578 }
579 if (err) {
580 return -EINVAL;
581 } else {
582 return lur->ret_code;
583 }
584 }
585 default:
586 if (len >= 0) {
587 ERR("incorrect message size: %zd\n", len);
588 }
589 return len;
590 }
591 }
592
593 int ustcomm_send_app_cmd(int sock,
594 struct ustcomm_ust_msg *lum,
595 struct ustcomm_ust_reply *lur)
596 {
597 int ret;
598
599 ret = ustcomm_send_app_msg(sock, lum);
600 if (ret)
601 return ret;
602 ret = ustcomm_recv_app_reply(sock, lur, lum->handle, lum->cmd);
603 if (ret > 0)
604 return -EIO;
605 return ret;
606 }
607
608 /*
609 * chan_data is allocated internally if this function returns the
610 * expected var_len.
611 */
612 ssize_t ustcomm_recv_channel_from_sessiond(int sock,
613 void **_chan_data, uint64_t var_len,
614 int *_wakeup_fd)
615 {
616 void *chan_data;
617 ssize_t len, nr_fd;
618 int wakeup_fd, ret;
619
620 if (var_len > LTTNG_UST_CHANNEL_DATA_MAX_LEN) {
621 len = -EINVAL;
622 goto error_check;
623 }
624 /* Receive variable length data */
625 chan_data = zmalloc(var_len);
626 if (!chan_data) {
627 len = -ENOMEM;
628 goto error_alloc;
629 }
630 len = ustcomm_recv_unix_sock(sock, chan_data, var_len);
631 if (len != var_len) {
632 goto error_recv;
633 }
634 /* recv wakeup fd */
635 lttng_ust_lock_fd_tracker();
636 nr_fd = ustcomm_recv_fds_unix_sock(sock, &wakeup_fd, 1);
637 if (nr_fd <= 0) {
638 lttng_ust_unlock_fd_tracker();
639 if (nr_fd < 0) {
640 len = nr_fd;
641 goto error_recv;
642 } else {
643 len = -EIO;
644 goto error_recv;
645 }
646 }
647
648 ret = lttng_ust_add_fd_to_tracker(wakeup_fd);
649 if (ret < 0) {
650 ret = close(wakeup_fd);
651 if (ret) {
652 PERROR("close on wakeup_fd");
653 }
654 len = -EIO;
655 lttng_ust_unlock_fd_tracker();
656 goto error_recv;
657 }
658
659 *_wakeup_fd = ret;
660 lttng_ust_unlock_fd_tracker();
661
662 *_chan_data = chan_data;
663 return len;
664
665 error_recv:
666 free(chan_data);
667 error_alloc:
668 error_check:
669 return len;
670 }
671
672 int ustcomm_recv_stream_from_sessiond(int sock,
673 uint64_t *memory_map_size,
674 int *shm_fd, int *wakeup_fd)
675 {
676 ssize_t len;
677 int ret;
678 int fds[2];
679
680 /* recv shm fd and wakeup fd */
681 lttng_ust_lock_fd_tracker();
682 len = ustcomm_recv_fds_unix_sock(sock, fds, 2);
683 if (len <= 0) {
684 lttng_ust_unlock_fd_tracker();
685 if (len < 0) {
686 ret = len;
687 goto error;
688 } else {
689 ret = -EIO;
690 goto error;
691 }
692 }
693
694 ret = lttng_ust_add_fd_to_tracker(fds[0]);
695 if (ret < 0) {
696 ret = close(fds[0]);
697 if (ret) {
698 PERROR("close on received shm_fd");
699 }
700 ret = -EIO;
701 lttng_ust_unlock_fd_tracker();
702 goto error;
703 }
704 *shm_fd = ret;
705
706 ret = lttng_ust_add_fd_to_tracker(fds[1]);
707 if (ret < 0) {
708 ret = close(*shm_fd);
709 if (ret) {
710 PERROR("close on shm_fd");
711 }
712 *shm_fd = -1;
713 ret = close(fds[1]);
714 if (ret) {
715 PERROR("close on received wakeup_fd");
716 }
717 ret = -EIO;
718 lttng_ust_unlock_fd_tracker();
719 goto error;
720 }
721 *wakeup_fd = ret;
722 lttng_ust_unlock_fd_tracker();
723 return 0;
724
725 error:
726 return ret;
727 }
728
729 /*
730 * Returns 0 on success, negative error value on error.
731 */
732 int ustcomm_send_reg_msg(int sock,
733 enum ustctl_socket_type type,
734 uint32_t bits_per_long,
735 uint32_t uint8_t_alignment,
736 uint32_t uint16_t_alignment,
737 uint32_t uint32_t_alignment,
738 uint32_t uint64_t_alignment,
739 uint32_t long_alignment)
740 {
741 ssize_t len;
742 struct ustctl_reg_msg reg_msg;
743
744 reg_msg.magic = LTTNG_UST_COMM_MAGIC;
745 reg_msg.major = LTTNG_UST_ABI_MAJOR_VERSION;
746 reg_msg.minor = LTTNG_UST_ABI_MINOR_VERSION;
747 reg_msg.pid = getpid();
748 reg_msg.ppid = getppid();
749 reg_msg.uid = getuid();
750 reg_msg.gid = getgid();
751 reg_msg.bits_per_long = bits_per_long;
752 reg_msg.uint8_t_alignment = uint8_t_alignment;
753 reg_msg.uint16_t_alignment = uint16_t_alignment;
754 reg_msg.uint32_t_alignment = uint32_t_alignment;
755 reg_msg.uint64_t_alignment = uint64_t_alignment;
756 reg_msg.long_alignment = long_alignment;
757 reg_msg.socket_type = type;
758 lttng_ust_getprocname(reg_msg.name);
759 memset(reg_msg.padding, 0, sizeof(reg_msg.padding));
760
761 len = ustcomm_send_unix_sock(sock, &reg_msg, sizeof(reg_msg));
762 if (len > 0 && len != sizeof(reg_msg))
763 return -EIO;
764 if (len < 0)
765 return len;
766 return 0;
767 }
768
769 static
770 ssize_t count_one_type(const struct lttng_type *lt)
771 {
772 switch (lt->atype) {
773 case atype_integer:
774 case atype_float:
775 case atype_string:
776 case atype_enum:
777 case atype_array:
778 case atype_sequence:
779 return 1;
780 case atype_struct:
781 return count_fields_recursive(lt->u.legacy._struct.nr_fields,
782 lt->u.legacy._struct.fields) + 1;
783 case atype_enum_nestable:
784 return count_one_type(lt->u.enum_nestable.container_type) + 1;
785 case atype_array_nestable:
786 return count_one_type(lt->u.array_nestable.elem_type) + 1;
787 case atype_sequence_nestable:
788 return count_one_type(lt->u.sequence_nestable.elem_type) + 1;
789 case atype_struct_nestable:
790 return count_fields_recursive(lt->u.struct_nestable.nr_fields,
791 lt->u.struct_nestable.fields) + 1;
792
793 case atype_dynamic:
794 {
795 const struct lttng_event_field *choices;
796 size_t nr_choices;
797 int ret;
798
799 ret = lttng_ust_dynamic_type_choices(&nr_choices,
800 &choices);
801 if (ret)
802 return ret;
803 /*
804 * Two fields for enum, one field for variant, and
805 * one field per choice.
806 */
807 return count_fields_recursive(nr_choices, choices) + 3;
808 }
809
810 default:
811 return -EINVAL;
812 }
813 return 0;
814 }
815
816 static
817 ssize_t count_fields_recursive(size_t nr_fields,
818 const struct lttng_event_field *lttng_fields)
819 {
820 int i;
821 ssize_t ret, count = 0;
822
823 for (i = 0; i < nr_fields; i++) {
824 const struct lttng_event_field *lf;
825
826 lf = &lttng_fields[i];
827 /* skip 'nowrite' fields */
828 if (lf->nowrite)
829 continue;
830 ret = count_one_type(&lf->type);
831 if (ret < 0)
832 return ret; /* error */
833 count += ret;
834 }
835 return count;
836 }
837
838 static
839 ssize_t count_ctx_fields_recursive(size_t nr_fields,
840 const struct lttng_ctx_field *lttng_fields)
841 {
842 int i;
843 ssize_t ret, count = 0;
844
845 for (i = 0; i < nr_fields; i++) {
846 const struct lttng_event_field *lf;
847
848 lf = &lttng_fields[i].event_field;
849 /* skip 'nowrite' fields */
850 if (lf->nowrite)
851 continue;
852 ret = count_one_type(&lf->type);
853 if (ret < 0)
854 return ret; /* error */
855 count += ret;
856 }
857 return count;
858 }
859
860 static
861 int serialize_string_encoding(int32_t *ue,
862 enum lttng_string_encodings le)
863 {
864 switch (le) {
865 case lttng_encode_none:
866 *ue = ustctl_encode_none;
867 break;
868 case lttng_encode_UTF8:
869 *ue = ustctl_encode_UTF8;
870 break;
871 case lttng_encode_ASCII:
872 *ue = ustctl_encode_ASCII;
873 break;
874 default:
875 return -EINVAL;
876 }
877 return 0;
878 }
879
880 static
881 int serialize_integer_type(struct ustctl_integer_type *uit,
882 const struct lttng_integer_type *lit)
883 {
884 int32_t encoding;
885
886 uit->size = lit->size;
887 uit->signedness = lit->signedness;
888 uit->reverse_byte_order = lit->reverse_byte_order;
889 uit->base = lit->base;
890 if (serialize_string_encoding(&encoding, lit->encoding))
891 return -EINVAL;
892 uit->encoding = encoding;
893 uit->alignment = lit->alignment;
894 return 0;
895 }
896
897 static
898 int serialize_basic_type(struct lttng_session *session,
899 enum ustctl_abstract_types *uatype,
900 enum lttng_abstract_types atype,
901 union _ustctl_basic_type *ubt,
902 const union _lttng_basic_type *lbt)
903 {
904 switch (atype) {
905 case atype_integer:
906 {
907 if (serialize_integer_type(&ubt->integer, &lbt->integer))
908 return -EINVAL;
909 *uatype = ustctl_atype_integer;
910 break;
911 }
912 case atype_string:
913 {
914 int32_t encoding;
915
916 if (serialize_string_encoding(&encoding, lbt->string.encoding))
917 return -EINVAL;
918 ubt->string.encoding = encoding;
919 *uatype = ustctl_atype_string;
920 break;
921 }
922 case atype_float:
923 {
924 struct ustctl_float_type *uft;
925 const struct lttng_float_type *lft;
926
927 uft = &ubt->_float;
928 lft = &lbt->_float;
929 uft->exp_dig = lft->exp_dig;
930 uft->mant_dig = lft->mant_dig;
931 uft->alignment = lft->alignment;
932 uft->reverse_byte_order = lft->reverse_byte_order;
933 *uatype = ustctl_atype_float;
934 break;
935 }
936 case atype_enum:
937 {
938 strncpy(ubt->enumeration.name, lbt->enumeration.desc->name,
939 LTTNG_UST_SYM_NAME_LEN);
940 ubt->enumeration.name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
941 if (serialize_integer_type(&ubt->enumeration.container_type,
942 &lbt->enumeration.container_type))
943 return -EINVAL;
944 if (session) {
945 const struct lttng_enum *_enum;
946
947 _enum = lttng_ust_enum_get_from_desc(session, lbt->enumeration.desc);
948 if (!_enum)
949 return -EINVAL;
950 ubt->enumeration.id = _enum->id;
951 } else {
952 ubt->enumeration.id = -1ULL;
953 }
954 *uatype = ustctl_atype_enum;
955 break;
956 }
957 case atype_array:
958 case atype_array_nestable:
959 case atype_sequence:
960 case atype_sequence_nestable:
961 case atype_enum_nestable:
962 default:
963 return -EINVAL;
964 }
965 return 0;
966 }
967
968 static
969 int serialize_dynamic_type(struct lttng_session *session,
970 struct ustctl_field *fields, size_t *iter_output,
971 const char *field_name)
972 {
973 const struct lttng_event_field *choices;
974 char tag_field_name[LTTNG_UST_SYM_NAME_LEN];
975 const struct lttng_type *tag_type;
976 const struct lttng_event_field *tag_field_generic;
977 struct lttng_event_field tag_field = {
978 .name = tag_field_name,
979 .nowrite = 0,
980 };
981 struct ustctl_field *uf;
982 size_t nr_choices, i;
983 int ret;
984
985 tag_field_generic = lttng_ust_dynamic_type_tag_field();
986 tag_type = &tag_field_generic->type;
987
988 /* Serialize enum field. */
989 strncpy(tag_field_name, field_name, LTTNG_UST_SYM_NAME_LEN);
990 tag_field_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
991 strncat(tag_field_name,
992 "_tag",
993 LTTNG_UST_SYM_NAME_LEN - strlen(tag_field_name) - 1);
994 tag_field.type = *tag_type;
995 ret = serialize_one_field(session, fields, iter_output,
996 &tag_field);
997 if (ret)
998 return ret;
999
1000 /* Serialize variant field. */
1001 uf = &fields[*iter_output];
1002 ret = lttng_ust_dynamic_type_choices(&nr_choices, &choices);
1003 if (ret)
1004 return ret;
1005
1006 strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
1007 uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1008 uf->type.atype = ustctl_atype_variant;
1009 uf->type.u.variant_nestable.nr_choices = nr_choices;
1010 strncpy(uf->type.u.variant_nestable.tag_name,
1011 tag_field_name,
1012 LTTNG_UST_SYM_NAME_LEN);
1013 uf->type.u.variant_nestable.tag_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1014 uf->type.u.variant_nestable.alignment = 0;
1015 (*iter_output)++;
1016
1017 /* Serialize choice fields after variant. */
1018 for (i = 0; i < nr_choices; i++) {
1019 ret = serialize_one_field(session, fields,
1020 iter_output, &choices[i]);
1021 if (ret)
1022 return ret;
1023 }
1024 return 0;
1025 }
1026
1027 static
1028 int serialize_one_type(struct lttng_session *session,
1029 struct ustctl_field *fields, size_t *iter_output,
1030 const char *field_name, const struct lttng_type *lt)
1031 {
1032 int ret;
1033
1034 /*
1035 * Serializing a type (rather than a field) generates a ustctl_field
1036 * entry with 0-length name.
1037 */
1038
1039 switch (lt->atype) {
1040 case atype_integer:
1041 case atype_float:
1042 case atype_string:
1043 case atype_enum:
1044 {
1045 struct ustctl_field *uf = &fields[*iter_output];
1046 struct ustctl_type *ut = &uf->type;
1047 enum ustctl_abstract_types atype;
1048
1049 if (field_name) {
1050 strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
1051 uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1052 } else {
1053 uf->name[0] = '\0';
1054 }
1055 ret = serialize_basic_type(session, &atype, lt->atype,
1056 &ut->u.legacy.basic, &lt->u.legacy.basic);
1057 if (ret)
1058 return ret;
1059 ut->atype = atype;
1060 (*iter_output)++;
1061 break;
1062 }
1063 case atype_array:
1064 {
1065 struct ustctl_field *uf = &fields[*iter_output];
1066 struct ustctl_type *ut = &uf->type;
1067 struct ustctl_basic_type *ubt;
1068 const struct lttng_basic_type *lbt;
1069 enum ustctl_abstract_types atype;
1070
1071 if (field_name) {
1072 strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
1073 uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1074 } else {
1075 uf->name[0] = '\0';
1076 }
1077 ut->atype = ustctl_atype_array;
1078 ubt = &ut->u.legacy.array.elem_type;
1079 lbt = &lt->u.legacy.array.elem_type;
1080 ut->u.legacy.array.length = lt->u.legacy.array.length;
1081 ret = serialize_basic_type(session, &atype, lbt->atype,
1082 &ubt->u.basic, &lbt->u.basic);
1083 if (ret)
1084 return -EINVAL;
1085 ubt->atype = atype;
1086 (*iter_output)++;
1087 break;
1088 }
1089 case atype_array_nestable:
1090 {
1091 struct ustctl_field *uf = &fields[*iter_output];
1092 struct ustctl_type *ut = &uf->type;
1093
1094 if (field_name) {
1095 strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
1096 uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1097 } else {
1098 uf->name[0] = '\0';
1099 }
1100 ut->atype = ustctl_atype_array_nestable;
1101 ut->u.array_nestable.length = lt->u.array_nestable.length;
1102 ut->u.array_nestable.alignment = lt->u.array_nestable.alignment;
1103 (*iter_output)++;
1104
1105 ret = serialize_one_type(session, fields, iter_output, NULL,
1106 lt->u.array_nestable.elem_type);
1107 if (ret)
1108 return -EINVAL;
1109 break;
1110 }
1111 case atype_sequence:
1112 {
1113 struct ustctl_field *uf = &fields[*iter_output];
1114 struct ustctl_type *ut = &uf->type;
1115 struct ustctl_basic_type *ubt;
1116 const struct lttng_basic_type *lbt;
1117 enum ustctl_abstract_types atype;
1118
1119 if (field_name) {
1120 strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
1121 uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1122 } else {
1123 uf->name[0] = '\0';
1124 }
1125 uf->type.atype = ustctl_atype_sequence;
1126 ubt = &ut->u.legacy.sequence.length_type;
1127 lbt = &lt->u.legacy.sequence.length_type;
1128 ret = serialize_basic_type(session, &atype, lbt->atype,
1129 &ubt->u.basic, &lbt->u.basic);
1130 if (ret)
1131 return -EINVAL;
1132 ubt->atype = atype;
1133 ubt = &ut->u.legacy.sequence.elem_type;
1134 lbt = &lt->u.legacy.sequence.elem_type;
1135 ret = serialize_basic_type(session, &atype, lbt->atype,
1136 &ubt->u.basic, &lbt->u.basic);
1137 if (ret)
1138 return -EINVAL;
1139 ubt->atype = atype;
1140 (*iter_output)++;
1141 break;
1142 }
1143 case atype_sequence_nestable:
1144 {
1145 struct ustctl_field *uf = &fields[*iter_output];
1146 struct ustctl_type *ut = &uf->type;
1147
1148 if (field_name) {
1149 strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
1150 uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1151 } else {
1152 uf->name[0] = '\0';
1153 }
1154 ut->atype = ustctl_atype_sequence_nestable;
1155 strncpy(ut->u.sequence_nestable.length_name,
1156 lt->u.sequence_nestable.length_name,
1157 LTTNG_UST_SYM_NAME_LEN);
1158 ut->u.sequence_nestable.length_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1159 ut->u.sequence_nestable.alignment = lt->u.sequence_nestable.alignment;
1160 (*iter_output)++;
1161
1162 ret = serialize_one_type(session, fields, iter_output, NULL,
1163 lt->u.sequence_nestable.elem_type);
1164 if (ret)
1165 return -EINVAL;
1166 break;
1167 }
1168 case atype_dynamic:
1169 {
1170 ret = serialize_dynamic_type(session, fields, iter_output,
1171 field_name);
1172 if (ret)
1173 return -EINVAL;
1174 break;
1175 }
1176 case atype_struct:
1177 {
1178 struct ustctl_field *uf = &fields[*iter_output];
1179
1180 if (field_name) {
1181 strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
1182 uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1183 } else {
1184 uf->name[0] = '\0';
1185 }
1186 uf->type.atype = ustctl_atype_struct;
1187 uf->type.u.legacy._struct.nr_fields = lt->u.legacy._struct.nr_fields;
1188 (*iter_output)++;
1189
1190 ret = serialize_fields(session, fields, iter_output,
1191 lt->u.legacy._struct.nr_fields,
1192 lt->u.legacy._struct.fields);
1193 if (ret)
1194 return -EINVAL;
1195 break;
1196 }
1197 case atype_struct_nestable:
1198 {
1199 struct ustctl_field *uf = &fields[*iter_output];
1200
1201 if (field_name) {
1202 strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
1203 uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1204 } else {
1205 uf->name[0] = '\0';
1206 }
1207 uf->type.atype = ustctl_atype_struct_nestable;
1208 uf->type.u.struct_nestable.nr_fields = lt->u.struct_nestable.nr_fields;
1209 uf->type.u.struct_nestable.alignment = lt->u.struct_nestable.alignment;
1210 (*iter_output)++;
1211
1212 ret = serialize_fields(session, fields, iter_output,
1213 lt->u.struct_nestable.nr_fields,
1214 lt->u.struct_nestable.fields);
1215 if (ret)
1216 return -EINVAL;
1217 break;
1218 }
1219 case atype_enum_nestable:
1220 {
1221 struct ustctl_field *uf = &fields[*iter_output];
1222 struct ustctl_type *ut = &uf->type;
1223
1224 if (field_name) {
1225 strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
1226 uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1227 } else {
1228 uf->name[0] = '\0';
1229 }
1230 strncpy(ut->u.enum_nestable.name, lt->u.enum_nestable.desc->name,
1231 LTTNG_UST_SYM_NAME_LEN);
1232 ut->u.enum_nestable.name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1233 ut->atype = ustctl_atype_enum_nestable;
1234 (*iter_output)++;
1235
1236 ret = serialize_one_type(session, fields, iter_output, NULL,
1237 lt->u.enum_nestable.container_type);
1238 if (ret)
1239 return -EINVAL;
1240 if (session) {
1241 const struct lttng_enum *_enum;
1242
1243 _enum = lttng_ust_enum_get_from_desc(session, lt->u.enum_nestable.desc);
1244 if (!_enum)
1245 return -EINVAL;
1246 ut->u.enum_nestable.id = _enum->id;
1247 } else {
1248 ut->u.enum_nestable.id = -1ULL;
1249 }
1250 break;
1251 }
1252 default:
1253 return -EINVAL;
1254 }
1255 return 0;
1256 }
1257
1258 static
1259 int serialize_one_field(struct lttng_session *session,
1260 struct ustctl_field *fields, size_t *iter_output,
1261 const struct lttng_event_field *lf)
1262 {
1263 /* skip 'nowrite' fields */
1264 if (lf->nowrite)
1265 return 0;
1266
1267 return serialize_one_type(session, fields, iter_output, lf->name, &lf->type);
1268 }
1269
1270 static
1271 int serialize_fields(struct lttng_session *session,
1272 struct ustctl_field *ustctl_fields,
1273 size_t *iter_output, size_t nr_lttng_fields,
1274 const struct lttng_event_field *lttng_fields)
1275 {
1276 int ret;
1277 size_t i;
1278
1279 for (i = 0; i < nr_lttng_fields; i++) {
1280 ret = serialize_one_field(session, ustctl_fields,
1281 iter_output, &lttng_fields[i]);
1282 if (ret)
1283 return ret;
1284 }
1285 return 0;
1286 }
1287
1288 static
1289 int alloc_serialize_fields(struct lttng_session *session,
1290 size_t *_nr_write_fields,
1291 struct ustctl_field **ustctl_fields,
1292 size_t nr_fields,
1293 const struct lttng_event_field *lttng_fields)
1294 {
1295 struct ustctl_field *fields;
1296 int ret;
1297 size_t iter_output = 0;
1298 ssize_t nr_write_fields;
1299
1300 nr_write_fields = count_fields_recursive(nr_fields, lttng_fields);
1301 if (nr_write_fields < 0) {
1302 return (int) nr_write_fields;
1303 }
1304
1305 fields = zmalloc(nr_write_fields * sizeof(*fields));
1306 if (!fields)
1307 return -ENOMEM;
1308
1309 ret = serialize_fields(session, fields, &iter_output, nr_fields,
1310 lttng_fields);
1311 if (ret)
1312 goto error_type;
1313
1314 *_nr_write_fields = nr_write_fields;
1315 *ustctl_fields = fields;
1316 return 0;
1317
1318 error_type:
1319 free(fields);
1320 return ret;
1321 }
1322
1323 static
1324 int serialize_entries(struct ustctl_enum_entry **_entries,
1325 size_t nr_entries,
1326 const struct lttng_enum_entry *lttng_entries)
1327 {
1328 struct ustctl_enum_entry *entries;
1329 int i;
1330
1331 /* Serialize the entries */
1332 entries = zmalloc(nr_entries * sizeof(*entries));
1333 if (!entries)
1334 return -ENOMEM;
1335 for (i = 0; i < nr_entries; i++) {
1336 struct ustctl_enum_entry *uentry;
1337 const struct lttng_enum_entry *lentry;
1338
1339 uentry = &entries[i];
1340 lentry = &lttng_entries[i];
1341
1342 uentry->start.value = lentry->start.value;
1343 uentry->start.signedness = lentry->start.signedness;
1344 uentry->end.value = lentry->end.value;
1345 uentry->end.signedness = lentry->end.signedness;
1346 strncpy(uentry->string, lentry->string, LTTNG_UST_SYM_NAME_LEN);
1347 uentry->string[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1348
1349 if (lentry->u.extra.options & LTTNG_ENUM_ENTRY_OPTION_IS_AUTO) {
1350 uentry->u.extra.options |=
1351 USTCTL_UST_ENUM_ENTRY_OPTION_IS_AUTO;
1352 }
1353 }
1354 *_entries = entries;
1355 return 0;
1356 }
1357
1358 static
1359 int serialize_ctx_fields(struct lttng_session *session,
1360 size_t *_nr_write_fields,
1361 struct ustctl_field **ustctl_fields,
1362 size_t nr_fields,
1363 const struct lttng_ctx_field *lttng_fields)
1364 {
1365 struct ustctl_field *fields;
1366 int ret;
1367 size_t i, iter_output = 0;
1368 ssize_t nr_write_fields;
1369
1370 nr_write_fields = count_ctx_fields_recursive(nr_fields,
1371 lttng_fields);
1372 if (nr_write_fields < 0) {
1373 return (int) nr_write_fields;
1374 }
1375
1376 fields = zmalloc(nr_write_fields * sizeof(*fields));
1377 if (!fields)
1378 return -ENOMEM;
1379
1380 for (i = 0; i < nr_fields; i++) {
1381 ret = serialize_one_field(session, fields, &iter_output,
1382 &lttng_fields[i].event_field);
1383 if (ret)
1384 goto error_type;
1385 }
1386
1387 *_nr_write_fields = nr_write_fields;
1388 *ustctl_fields = fields;
1389 return 0;
1390
1391 error_type:
1392 free(fields);
1393 return ret;
1394 }
1395
1396 /*
1397 * Returns 0 on success, negative error value on error.
1398 */
1399 int ustcomm_register_event(int sock,
1400 struct lttng_session *session,
1401 int session_objd, /* session descriptor */
1402 int channel_objd, /* channel descriptor */
1403 const char *event_name, /* event name (input) */
1404 int loglevel,
1405 const char *signature, /* event signature (input) */
1406 size_t nr_fields, /* fields */
1407 const struct lttng_event_field *lttng_fields,
1408 const char *model_emf_uri,
1409 uint32_t *id) /* event id (output) */
1410 {
1411 ssize_t len;
1412 struct {
1413 struct ustcomm_notify_hdr header;
1414 struct ustcomm_notify_event_msg m;
1415 } msg;
1416 struct {
1417 struct ustcomm_notify_hdr header;
1418 struct ustcomm_notify_event_reply r;
1419 } reply;
1420 size_t signature_len, fields_len, model_emf_uri_len;
1421 struct ustctl_field *fields = NULL;
1422 size_t nr_write_fields = 0;
1423 int ret;
1424
1425 memset(&msg, 0, sizeof(msg));
1426 msg.header.notify_cmd = USTCTL_NOTIFY_CMD_EVENT;
1427 msg.m.session_objd = session_objd;
1428 msg.m.channel_objd = channel_objd;
1429 strncpy(msg.m.event_name, event_name, LTTNG_UST_SYM_NAME_LEN);
1430 msg.m.event_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1431 msg.m.loglevel = loglevel;
1432 signature_len = strlen(signature) + 1;
1433 msg.m.signature_len = signature_len;
1434
1435 /* Calculate fields len, serialize fields. */
1436 if (nr_fields > 0) {
1437 ret = alloc_serialize_fields(session, &nr_write_fields, &fields,
1438 nr_fields, lttng_fields);
1439 if (ret)
1440 return ret;
1441 }
1442
1443 fields_len = sizeof(*fields) * nr_write_fields;
1444 msg.m.fields_len = fields_len;
1445 if (model_emf_uri) {
1446 model_emf_uri_len = strlen(model_emf_uri) + 1;
1447 } else {
1448 model_emf_uri_len = 0;
1449 }
1450 msg.m.model_emf_uri_len = model_emf_uri_len;
1451
1452 len = ustcomm_send_unix_sock(sock, &msg, sizeof(msg));
1453 if (len > 0 && len != sizeof(msg)) {
1454 ret = -EIO;
1455 goto error_fields;
1456 }
1457 if (len < 0) {
1458 ret = len;
1459 goto error_fields;
1460 }
1461
1462 /* send signature */
1463 len = ustcomm_send_unix_sock(sock, signature, signature_len);
1464 if (len > 0 && len != signature_len) {
1465 ret = -EIO;
1466 goto error_fields;
1467 }
1468 if (len < 0) {
1469 ret = len;
1470 goto error_fields;
1471 }
1472
1473 /* send fields */
1474 if (fields_len > 0) {
1475 len = ustcomm_send_unix_sock(sock, fields, fields_len);
1476 if (len > 0 && len != fields_len) {
1477 ret = -EIO;
1478 goto error_fields;
1479 }
1480 if (len < 0) {
1481 ret = len;
1482 goto error_fields;
1483 }
1484 }
1485 free(fields);
1486
1487 if (model_emf_uri_len) {
1488 /* send model_emf_uri */
1489 len = ustcomm_send_unix_sock(sock, model_emf_uri,
1490 model_emf_uri_len);
1491 if (len > 0 && len != model_emf_uri_len) {
1492 return -EIO;
1493 }
1494 if (len < 0) {
1495 return len;
1496 }
1497 }
1498
1499 /* receive reply */
1500 len = ustcomm_recv_unix_sock(sock, &reply, sizeof(reply));
1501 switch (len) {
1502 case 0: /* orderly shutdown */
1503 return -EPIPE;
1504 case sizeof(reply):
1505 if (reply.header.notify_cmd != msg.header.notify_cmd) {
1506 ERR("Unexpected result message command "
1507 "expected: %u vs received: %u\n",
1508 msg.header.notify_cmd, reply.header.notify_cmd);
1509 return -EINVAL;
1510 }
1511 if (reply.r.ret_code > 0)
1512 return -EINVAL;
1513 if (reply.r.ret_code < 0)
1514 return reply.r.ret_code;
1515 *id = reply.r.event_id;
1516 DBG("Sent register event notification for name \"%s\": ret_code %d, event_id %u\n",
1517 event_name, reply.r.ret_code, reply.r.event_id);
1518 return 0;
1519 default:
1520 if (len < 0) {
1521 /* Transport level error */
1522 if (errno == EPIPE || errno == ECONNRESET)
1523 len = -errno;
1524 return len;
1525 } else {
1526 ERR("incorrect message size: %zd\n", len);
1527 return len;
1528 }
1529 }
1530 /* Unreached. */
1531
1532 /* Error path only. */
1533 error_fields:
1534 free(fields);
1535 return ret;
1536 }
1537
1538 /*
1539 * Returns 0 on success, negative error value on error.
1540 * Returns -EPIPE or -ECONNRESET if other end has hung up.
1541 */
1542 int ustcomm_register_enum(int sock,
1543 int session_objd, /* session descriptor */
1544 const char *enum_name, /* enum name (input) */
1545 size_t nr_entries, /* entries */
1546 const struct lttng_enum_entry *lttng_entries,
1547 uint64_t *id)
1548 {
1549 ssize_t len;
1550 struct {
1551 struct ustcomm_notify_hdr header;
1552 struct ustcomm_notify_enum_msg m;
1553 } msg;
1554 struct {
1555 struct ustcomm_notify_hdr header;
1556 struct ustcomm_notify_enum_reply r;
1557 } reply;
1558 size_t entries_len;
1559 struct ustctl_enum_entry *entries = NULL;
1560 int ret;
1561
1562 memset(&msg, 0, sizeof(msg));
1563 msg.header.notify_cmd = USTCTL_NOTIFY_CMD_ENUM;
1564 msg.m.session_objd = session_objd;
1565 strncpy(msg.m.enum_name, enum_name, LTTNG_UST_SYM_NAME_LEN);
1566 msg.m.enum_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1567
1568 /* Calculate entries len, serialize entries. */
1569 if (nr_entries > 0) {
1570 ret = serialize_entries(&entries,
1571 nr_entries, lttng_entries);
1572 if (ret)
1573 return ret;
1574 }
1575
1576 entries_len = sizeof(*entries) * nr_entries;
1577 msg.m.entries_len = entries_len;
1578
1579 len = ustcomm_send_unix_sock(sock, &msg, sizeof(msg));
1580 if (len > 0 && len != sizeof(msg)) {
1581 ret = -EIO;
1582 goto error_entries;
1583 }
1584 if (len < 0) {
1585 ret = len;
1586 goto error_entries;
1587 }
1588
1589 /* send entries */
1590 if (entries_len > 0) {
1591 len = ustcomm_send_unix_sock(sock, entries, entries_len);
1592 if (len > 0 && len != entries_len) {
1593 ret = -EIO;
1594 goto error_entries;
1595 }
1596 if (len < 0) {
1597 ret = len;
1598 goto error_entries;
1599 }
1600 }
1601 free(entries);
1602 entries = NULL;
1603
1604 /* receive reply */
1605 len = ustcomm_recv_unix_sock(sock, &reply, sizeof(reply));
1606 switch (len) {
1607 case 0: /* orderly shutdown */
1608 return -EPIPE;
1609 case sizeof(reply):
1610 if (reply.header.notify_cmd != msg.header.notify_cmd) {
1611 ERR("Unexpected result message command "
1612 "expected: %u vs received: %u\n",
1613 msg.header.notify_cmd, reply.header.notify_cmd);
1614 return -EINVAL;
1615 }
1616 if (reply.r.ret_code > 0)
1617 return -EINVAL;
1618 if (reply.r.ret_code < 0)
1619 return reply.r.ret_code;
1620 *id = reply.r.enum_id;
1621 DBG("Sent register enum notification for name \"%s\": ret_code %d\n",
1622 enum_name, reply.r.ret_code);
1623 return 0;
1624 default:
1625 if (len < 0) {
1626 /* Transport level error */
1627 if (errno == EPIPE || errno == ECONNRESET)
1628 len = -errno;
1629 return len;
1630 } else {
1631 ERR("incorrect message size: %zd\n", len);
1632 return len;
1633 }
1634 }
1635 return ret;
1636
1637 error_entries:
1638 free(entries);
1639 return ret;
1640 }
1641
1642 /*
1643 * Returns 0 on success, negative error value on error.
1644 * Returns -EPIPE or -ECONNRESET if other end has hung up.
1645 */
1646 int ustcomm_register_channel(int sock,
1647 struct lttng_session *session,
1648 int session_objd, /* session descriptor */
1649 int channel_objd, /* channel descriptor */
1650 size_t nr_ctx_fields,
1651 const struct lttng_ctx_field *ctx_fields,
1652 uint32_t *chan_id, /* channel id (output) */
1653 int *header_type) /* header type (output) */
1654 {
1655 ssize_t len;
1656 struct {
1657 struct ustcomm_notify_hdr header;
1658 struct ustcomm_notify_channel_msg m;
1659 } msg;
1660 struct {
1661 struct ustcomm_notify_hdr header;
1662 struct ustcomm_notify_channel_reply r;
1663 } reply;
1664 size_t fields_len;
1665 struct ustctl_field *fields = NULL;
1666 int ret;
1667 size_t nr_write_fields = 0;
1668
1669 memset(&msg, 0, sizeof(msg));
1670 msg.header.notify_cmd = USTCTL_NOTIFY_CMD_CHANNEL;
1671 msg.m.session_objd = session_objd;
1672 msg.m.channel_objd = channel_objd;
1673
1674 /* Calculate fields len, serialize fields. */
1675 if (nr_ctx_fields > 0) {
1676 ret = serialize_ctx_fields(session, &nr_write_fields, &fields,
1677 nr_ctx_fields, ctx_fields);
1678 if (ret)
1679 return ret;
1680 }
1681
1682 fields_len = sizeof(*fields) * nr_write_fields;
1683 msg.m.ctx_fields_len = fields_len;
1684 len = ustcomm_send_unix_sock(sock, &msg, sizeof(msg));
1685 if (len > 0 && len != sizeof(msg)) {
1686 free(fields);
1687 return -EIO;
1688 }
1689 if (len < 0) {
1690 free(fields);
1691 return len;
1692 }
1693
1694 /* send fields */
1695 if (fields_len > 0) {
1696 len = ustcomm_send_unix_sock(sock, fields, fields_len);
1697 free(fields);
1698 if (len > 0 && len != fields_len) {
1699 return -EIO;
1700 }
1701 if (len < 0) {
1702 return len;
1703 }
1704 } else {
1705 free(fields);
1706 }
1707
1708 len = ustcomm_recv_unix_sock(sock, &reply, sizeof(reply));
1709 switch (len) {
1710 case 0: /* orderly shutdown */
1711 return -EPIPE;
1712 case sizeof(reply):
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);
1717 return -EINVAL;
1718 }
1719 if (reply.r.ret_code > 0)
1720 return -EINVAL;
1721 if (reply.r.ret_code < 0)
1722 return reply.r.ret_code;
1723 *chan_id = reply.r.chan_id;
1724 switch (reply.r.header_type) {
1725 case 1:
1726 case 2:
1727 *header_type = reply.r.header_type;
1728 break;
1729 default:
1730 ERR("Unexpected channel header type %u\n",
1731 reply.r.header_type);
1732 return -EINVAL;
1733 }
1734 DBG("Sent register channel notification: chan_id %d, header_type %d\n",
1735 reply.r.chan_id, reply.r.header_type);
1736 return 0;
1737 default:
1738 if (len < 0) {
1739 /* Transport level error */
1740 if (errno == EPIPE || errno == ECONNRESET)
1741 len = -errno;
1742 return len;
1743 } else {
1744 ERR("incorrect message size: %zd\n", len);
1745 return len;
1746 }
1747 }
1748 }
1749
1750 /*
1751 * Set socket reciving timeout.
1752 */
1753 int ustcomm_setsockopt_rcv_timeout(int sock, unsigned int msec)
1754 {
1755 int ret;
1756 struct timeval tv;
1757
1758 tv.tv_sec = msec / 1000;
1759 tv.tv_usec = (msec * 1000 % 1000000);
1760
1761 ret = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
1762 if (ret < 0) {
1763 PERROR("setsockopt SO_RCVTIMEO");
1764 ret = -errno;
1765 }
1766
1767 return ret;
1768 }
1769
1770 /*
1771 * Set socket sending timeout.
1772 */
1773 int ustcomm_setsockopt_snd_timeout(int sock, unsigned int msec)
1774 {
1775 int ret;
1776 struct timeval tv;
1777
1778 tv.tv_sec = msec / 1000;
1779 tv.tv_usec = (msec * 1000) % 1000000;
1780
1781 ret = setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
1782 if (ret < 0) {
1783 PERROR("setsockopt SO_SNDTIMEO");
1784 ret = -errno;
1785 }
1786
1787 return ret;
1788 }
This page took 0.122832 seconds and 4 git commands to generate.