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