SoW-2019-0007-2: Dynamic Snapshot: Triggers send partial event payload with notifications
[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 ssize_t ustcomm_recv_trigger_notif_fd_from_sessiond(int sock,
673 int *_trigger_notif_fd)
674 {
675 ssize_t nr_fd;
676 int trigger_notif_fd, ret;
677
678 /* Receive trigger notification fd */
679 lttng_ust_lock_fd_tracker();
680 nr_fd = ustcomm_recv_fds_unix_sock(sock, &trigger_notif_fd, 1);
681 if (nr_fd <= 0) {
682 lttng_ust_unlock_fd_tracker();
683 if (nr_fd < 0) {
684 ret = nr_fd;
685 goto error;
686 } else {
687 ret = -EIO;
688 goto error;
689 }
690 }
691
692 ret = lttng_ust_add_fd_to_tracker(trigger_notif_fd);
693 if (ret < 0) {
694 ret = close(trigger_notif_fd);
695 if (ret) {
696 PERROR("close on trigger notif fd");
697 }
698 ret = -EIO;
699 lttng_ust_unlock_fd_tracker();
700 goto error;
701 }
702
703 *_trigger_notif_fd = ret;
704 lttng_ust_unlock_fd_tracker();
705
706 ret = nr_fd;
707
708 error:
709 return ret;
710 }
711
712 int ustcomm_recv_stream_from_sessiond(int sock,
713 uint64_t *memory_map_size,
714 int *shm_fd, int *wakeup_fd)
715 {
716 ssize_t len;
717 int ret;
718 int fds[2];
719
720 /* recv shm fd and wakeup fd */
721 lttng_ust_lock_fd_tracker();
722 len = ustcomm_recv_fds_unix_sock(sock, fds, 2);
723 if (len <= 0) {
724 lttng_ust_unlock_fd_tracker();
725 if (len < 0) {
726 ret = len;
727 goto error;
728 } else {
729 ret = -EIO;
730 goto error;
731 }
732 }
733
734 ret = lttng_ust_add_fd_to_tracker(fds[0]);
735 if (ret < 0) {
736 ret = close(fds[0]);
737 if (ret) {
738 PERROR("close on received shm_fd");
739 }
740 ret = -EIO;
741 lttng_ust_unlock_fd_tracker();
742 goto error;
743 }
744 *shm_fd = ret;
745
746 ret = lttng_ust_add_fd_to_tracker(fds[1]);
747 if (ret < 0) {
748 ret = close(*shm_fd);
749 if (ret) {
750 PERROR("close on shm_fd");
751 }
752 *shm_fd = -1;
753 ret = close(fds[1]);
754 if (ret) {
755 PERROR("close on received wakeup_fd");
756 }
757 ret = -EIO;
758 lttng_ust_unlock_fd_tracker();
759 goto error;
760 }
761 *wakeup_fd = ret;
762 lttng_ust_unlock_fd_tracker();
763 return 0;
764
765 error:
766 return ret;
767 }
768
769 /*
770 * Returns 0 on success, negative error value on error.
771 */
772 int ustcomm_send_reg_msg(int sock,
773 enum ustctl_socket_type type,
774 uint32_t bits_per_long,
775 uint32_t uint8_t_alignment,
776 uint32_t uint16_t_alignment,
777 uint32_t uint32_t_alignment,
778 uint32_t uint64_t_alignment,
779 uint32_t long_alignment)
780 {
781 ssize_t len;
782 struct ustctl_reg_msg reg_msg;
783
784 reg_msg.magic = LTTNG_UST_COMM_MAGIC;
785 reg_msg.major = LTTNG_UST_ABI_MAJOR_VERSION;
786 reg_msg.minor = LTTNG_UST_ABI_MINOR_VERSION;
787 reg_msg.pid = getpid();
788 reg_msg.ppid = getppid();
789 reg_msg.uid = getuid();
790 reg_msg.gid = getgid();
791 reg_msg.bits_per_long = bits_per_long;
792 reg_msg.uint8_t_alignment = uint8_t_alignment;
793 reg_msg.uint16_t_alignment = uint16_t_alignment;
794 reg_msg.uint32_t_alignment = uint32_t_alignment;
795 reg_msg.uint64_t_alignment = uint64_t_alignment;
796 reg_msg.long_alignment = long_alignment;
797 reg_msg.socket_type = type;
798 lttng_ust_getprocname(reg_msg.name);
799 memset(reg_msg.padding, 0, sizeof(reg_msg.padding));
800
801 len = ustcomm_send_unix_sock(sock, &reg_msg, sizeof(reg_msg));
802 if (len > 0 && len != sizeof(reg_msg))
803 return -EIO;
804 if (len < 0)
805 return len;
806 return 0;
807 }
808
809 static
810 ssize_t count_one_type(const struct lttng_type *lt)
811 {
812 switch (lt->atype) {
813 case atype_integer:
814 case atype_float:
815 case atype_string:
816 case atype_enum:
817 case atype_array:
818 case atype_sequence:
819 return 1;
820 case atype_struct:
821 return count_fields_recursive(lt->u.legacy._struct.nr_fields,
822 lt->u.legacy._struct.fields) + 1;
823 case atype_enum_nestable:
824 return count_one_type(lt->u.enum_nestable.container_type) + 1;
825 case atype_array_nestable:
826 return count_one_type(lt->u.array_nestable.elem_type) + 1;
827 case atype_sequence_nestable:
828 return count_one_type(lt->u.sequence_nestable.elem_type) + 1;
829 case atype_struct_nestable:
830 return count_fields_recursive(lt->u.struct_nestable.nr_fields,
831 lt->u.struct_nestable.fields) + 1;
832
833 case atype_dynamic:
834 {
835 const struct lttng_event_field *choices;
836 size_t nr_choices;
837 int ret;
838
839 ret = lttng_ust_dynamic_type_choices(&nr_choices,
840 &choices);
841 if (ret)
842 return ret;
843 /*
844 * Two fields for enum, one field for variant, and
845 * one field per choice.
846 */
847 return count_fields_recursive(nr_choices, choices) + 3;
848 }
849
850 default:
851 return -EINVAL;
852 }
853 return 0;
854 }
855
856 static
857 ssize_t count_fields_recursive(size_t nr_fields,
858 const struct lttng_event_field *lttng_fields)
859 {
860 int i;
861 ssize_t ret, count = 0;
862
863 for (i = 0; i < nr_fields; i++) {
864 const struct lttng_event_field *lf;
865
866 lf = &lttng_fields[i];
867 /* skip 'nowrite' fields */
868 if (lf->nowrite)
869 continue;
870 ret = count_one_type(&lf->type);
871 if (ret < 0)
872 return ret; /* error */
873 count += ret;
874 }
875 return count;
876 }
877
878 static
879 ssize_t count_ctx_fields_recursive(size_t nr_fields,
880 const struct lttng_ctx_field *lttng_fields)
881 {
882 int i;
883 ssize_t ret, count = 0;
884
885 for (i = 0; i < nr_fields; i++) {
886 const struct lttng_event_field *lf;
887
888 lf = &lttng_fields[i].event_field;
889 /* skip 'nowrite' fields */
890 if (lf->nowrite)
891 continue;
892 ret = count_one_type(&lf->type);
893 if (ret < 0)
894 return ret; /* error */
895 count += ret;
896 }
897 return count;
898 }
899
900 static
901 int serialize_string_encoding(int32_t *ue,
902 enum lttng_string_encodings le)
903 {
904 switch (le) {
905 case lttng_encode_none:
906 *ue = ustctl_encode_none;
907 break;
908 case lttng_encode_UTF8:
909 *ue = ustctl_encode_UTF8;
910 break;
911 case lttng_encode_ASCII:
912 *ue = ustctl_encode_ASCII;
913 break;
914 default:
915 return -EINVAL;
916 }
917 return 0;
918 }
919
920 static
921 int serialize_integer_type(struct ustctl_integer_type *uit,
922 const struct lttng_integer_type *lit)
923 {
924 int32_t encoding;
925
926 uit->size = lit->size;
927 uit->signedness = lit->signedness;
928 uit->reverse_byte_order = lit->reverse_byte_order;
929 uit->base = lit->base;
930 if (serialize_string_encoding(&encoding, lit->encoding))
931 return -EINVAL;
932 uit->encoding = encoding;
933 uit->alignment = lit->alignment;
934 return 0;
935 }
936
937 static
938 int serialize_basic_type(struct lttng_session *session,
939 enum ustctl_abstract_types *uatype,
940 enum lttng_abstract_types atype,
941 union _ustctl_basic_type *ubt,
942 const union _lttng_basic_type *lbt)
943 {
944 switch (atype) {
945 case atype_integer:
946 {
947 if (serialize_integer_type(&ubt->integer, &lbt->integer))
948 return -EINVAL;
949 *uatype = ustctl_atype_integer;
950 break;
951 }
952 case atype_string:
953 {
954 int32_t encoding;
955
956 if (serialize_string_encoding(&encoding, lbt->string.encoding))
957 return -EINVAL;
958 ubt->string.encoding = encoding;
959 *uatype = ustctl_atype_string;
960 break;
961 }
962 case atype_float:
963 {
964 struct ustctl_float_type *uft;
965 const struct lttng_float_type *lft;
966
967 uft = &ubt->_float;
968 lft = &lbt->_float;
969 uft->exp_dig = lft->exp_dig;
970 uft->mant_dig = lft->mant_dig;
971 uft->alignment = lft->alignment;
972 uft->reverse_byte_order = lft->reverse_byte_order;
973 *uatype = ustctl_atype_float;
974 break;
975 }
976 case atype_enum:
977 {
978 strncpy(ubt->enumeration.name, lbt->enumeration.desc->name,
979 LTTNG_UST_SYM_NAME_LEN);
980 ubt->enumeration.name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
981 if (serialize_integer_type(&ubt->enumeration.container_type,
982 &lbt->enumeration.container_type))
983 return -EINVAL;
984 if (session) {
985 const struct lttng_enum *_enum;
986
987 _enum = lttng_ust_enum_get_from_desc(session, lbt->enumeration.desc);
988 if (!_enum)
989 return -EINVAL;
990 ubt->enumeration.id = _enum->id;
991 } else {
992 ubt->enumeration.id = -1ULL;
993 }
994 *uatype = ustctl_atype_enum;
995 break;
996 }
997 case atype_array:
998 case atype_array_nestable:
999 case atype_sequence:
1000 case atype_sequence_nestable:
1001 case atype_enum_nestable:
1002 default:
1003 return -EINVAL;
1004 }
1005 return 0;
1006 }
1007
1008 static
1009 int serialize_dynamic_type(struct lttng_session *session,
1010 struct ustctl_field *fields, size_t *iter_output,
1011 const char *field_name)
1012 {
1013 const struct lttng_event_field *choices;
1014 char tag_field_name[LTTNG_UST_SYM_NAME_LEN];
1015 const struct lttng_type *tag_type;
1016 const struct lttng_event_field *tag_field_generic;
1017 struct lttng_event_field tag_field = {
1018 .name = tag_field_name,
1019 .nowrite = 0,
1020 };
1021 struct ustctl_field *uf;
1022 size_t nr_choices, i;
1023 int ret;
1024
1025 tag_field_generic = lttng_ust_dynamic_type_tag_field();
1026 tag_type = &tag_field_generic->type;
1027
1028 /* Serialize enum field. */
1029 strncpy(tag_field_name, field_name, LTTNG_UST_SYM_NAME_LEN);
1030 tag_field_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1031 strncat(tag_field_name,
1032 "_tag",
1033 LTTNG_UST_SYM_NAME_LEN - strlen(tag_field_name) - 1);
1034 tag_field.type = *tag_type;
1035 ret = serialize_one_field(session, fields, iter_output,
1036 &tag_field);
1037 if (ret)
1038 return ret;
1039
1040 /* Serialize variant field. */
1041 uf = &fields[*iter_output];
1042 ret = lttng_ust_dynamic_type_choices(&nr_choices, &choices);
1043 if (ret)
1044 return ret;
1045
1046 strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
1047 uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1048 uf->type.atype = ustctl_atype_variant;
1049 uf->type.u.variant_nestable.nr_choices = nr_choices;
1050 strncpy(uf->type.u.variant_nestable.tag_name,
1051 tag_field_name,
1052 LTTNG_UST_SYM_NAME_LEN);
1053 uf->type.u.variant_nestable.tag_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1054 uf->type.u.variant_nestable.alignment = 0;
1055 (*iter_output)++;
1056
1057 /* Serialize choice fields after variant. */
1058 for (i = 0; i < nr_choices; i++) {
1059 ret = serialize_one_field(session, fields,
1060 iter_output, &choices[i]);
1061 if (ret)
1062 return ret;
1063 }
1064 return 0;
1065 }
1066
1067 static
1068 int serialize_one_type(struct lttng_session *session,
1069 struct ustctl_field *fields, size_t *iter_output,
1070 const char *field_name, const struct lttng_type *lt)
1071 {
1072 int ret;
1073
1074 /*
1075 * Serializing a type (rather than a field) generates a ustctl_field
1076 * entry with 0-length name.
1077 */
1078
1079 switch (lt->atype) {
1080 case atype_integer:
1081 case atype_float:
1082 case atype_string:
1083 case atype_enum:
1084 {
1085 struct ustctl_field *uf = &fields[*iter_output];
1086 struct ustctl_type *ut = &uf->type;
1087 enum ustctl_abstract_types atype;
1088
1089 if (field_name) {
1090 strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
1091 uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1092 } else {
1093 uf->name[0] = '\0';
1094 }
1095 ret = serialize_basic_type(session, &atype, lt->atype,
1096 &ut->u.legacy.basic, &lt->u.legacy.basic);
1097 if (ret)
1098 return ret;
1099 ut->atype = atype;
1100 (*iter_output)++;
1101 break;
1102 }
1103 case atype_array:
1104 {
1105 struct ustctl_field *uf = &fields[*iter_output];
1106 struct ustctl_type *ut = &uf->type;
1107 struct ustctl_basic_type *ubt;
1108 const struct lttng_basic_type *lbt;
1109 enum ustctl_abstract_types atype;
1110
1111 if (field_name) {
1112 strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
1113 uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1114 } else {
1115 uf->name[0] = '\0';
1116 }
1117 ut->atype = ustctl_atype_array;
1118 ubt = &ut->u.legacy.array.elem_type;
1119 lbt = &lt->u.legacy.array.elem_type;
1120 ut->u.legacy.array.length = lt->u.legacy.array.length;
1121 ret = serialize_basic_type(session, &atype, lbt->atype,
1122 &ubt->u.basic, &lbt->u.basic);
1123 if (ret)
1124 return -EINVAL;
1125 ubt->atype = atype;
1126 (*iter_output)++;
1127 break;
1128 }
1129 case atype_array_nestable:
1130 {
1131 struct ustctl_field *uf = &fields[*iter_output];
1132 struct ustctl_type *ut = &uf->type;
1133
1134 if (field_name) {
1135 strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
1136 uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1137 } else {
1138 uf->name[0] = '\0';
1139 }
1140 ut->atype = ustctl_atype_array_nestable;
1141 ut->u.array_nestable.length = lt->u.array_nestable.length;
1142 ut->u.array_nestable.alignment = lt->u.array_nestable.alignment;
1143 (*iter_output)++;
1144
1145 ret = serialize_one_type(session, fields, iter_output, NULL,
1146 lt->u.array_nestable.elem_type);
1147 if (ret)
1148 return -EINVAL;
1149 break;
1150 }
1151 case atype_sequence:
1152 {
1153 struct ustctl_field *uf = &fields[*iter_output];
1154 struct ustctl_type *ut = &uf->type;
1155 struct ustctl_basic_type *ubt;
1156 const struct lttng_basic_type *lbt;
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 uf->type.atype = ustctl_atype_sequence;
1166 ubt = &ut->u.legacy.sequence.length_type;
1167 lbt = &lt->u.legacy.sequence.length_type;
1168 ret = serialize_basic_type(session, &atype, lbt->atype,
1169 &ubt->u.basic, &lbt->u.basic);
1170 if (ret)
1171 return -EINVAL;
1172 ubt->atype = atype;
1173 ubt = &ut->u.legacy.sequence.elem_type;
1174 lbt = &lt->u.legacy.sequence.elem_type;
1175 ret = serialize_basic_type(session, &atype, lbt->atype,
1176 &ubt->u.basic, &lbt->u.basic);
1177 if (ret)
1178 return -EINVAL;
1179 ubt->atype = atype;
1180 (*iter_output)++;
1181 break;
1182 }
1183 case atype_sequence_nestable:
1184 {
1185 struct ustctl_field *uf = &fields[*iter_output];
1186 struct ustctl_type *ut = &uf->type;
1187
1188 if (field_name) {
1189 strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
1190 uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1191 } else {
1192 uf->name[0] = '\0';
1193 }
1194 ut->atype = ustctl_atype_sequence_nestable;
1195 strncpy(ut->u.sequence_nestable.length_name,
1196 lt->u.sequence_nestable.length_name,
1197 LTTNG_UST_SYM_NAME_LEN);
1198 ut->u.sequence_nestable.length_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1199 ut->u.sequence_nestable.alignment = lt->u.sequence_nestable.alignment;
1200 (*iter_output)++;
1201
1202 ret = serialize_one_type(session, fields, iter_output, NULL,
1203 lt->u.sequence_nestable.elem_type);
1204 if (ret)
1205 return -EINVAL;
1206 break;
1207 }
1208 case atype_dynamic:
1209 {
1210 ret = serialize_dynamic_type(session, fields, iter_output,
1211 field_name);
1212 if (ret)
1213 return -EINVAL;
1214 break;
1215 }
1216 case atype_struct:
1217 {
1218 struct ustctl_field *uf = &fields[*iter_output];
1219
1220 if (field_name) {
1221 strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
1222 uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1223 } else {
1224 uf->name[0] = '\0';
1225 }
1226 uf->type.atype = ustctl_atype_struct;
1227 uf->type.u.legacy._struct.nr_fields = lt->u.legacy._struct.nr_fields;
1228 (*iter_output)++;
1229
1230 ret = serialize_fields(session, fields, iter_output,
1231 lt->u.legacy._struct.nr_fields,
1232 lt->u.legacy._struct.fields);
1233 if (ret)
1234 return -EINVAL;
1235 break;
1236 }
1237 case atype_struct_nestable:
1238 {
1239 struct ustctl_field *uf = &fields[*iter_output];
1240
1241 if (field_name) {
1242 strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
1243 uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1244 } else {
1245 uf->name[0] = '\0';
1246 }
1247 uf->type.atype = ustctl_atype_struct_nestable;
1248 uf->type.u.struct_nestable.nr_fields = lt->u.struct_nestable.nr_fields;
1249 uf->type.u.struct_nestable.alignment = lt->u.struct_nestable.alignment;
1250 (*iter_output)++;
1251
1252 ret = serialize_fields(session, fields, iter_output,
1253 lt->u.struct_nestable.nr_fields,
1254 lt->u.struct_nestable.fields);
1255 if (ret)
1256 return -EINVAL;
1257 break;
1258 }
1259 case atype_enum_nestable:
1260 {
1261 struct ustctl_field *uf = &fields[*iter_output];
1262 struct ustctl_type *ut = &uf->type;
1263
1264 if (field_name) {
1265 strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
1266 uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1267 } else {
1268 uf->name[0] = '\0';
1269 }
1270 strncpy(ut->u.enum_nestable.name, lt->u.enum_nestable.desc->name,
1271 LTTNG_UST_SYM_NAME_LEN);
1272 ut->u.enum_nestable.name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1273 ut->atype = ustctl_atype_enum_nestable;
1274 (*iter_output)++;
1275
1276 ret = serialize_one_type(session, fields, iter_output, NULL,
1277 lt->u.enum_nestable.container_type);
1278 if (ret)
1279 return -EINVAL;
1280 if (session) {
1281 const struct lttng_enum *_enum;
1282
1283 _enum = lttng_ust_enum_get_from_desc(session, lt->u.enum_nestable.desc);
1284 if (!_enum)
1285 return -EINVAL;
1286 ut->u.enum_nestable.id = _enum->id;
1287 } else {
1288 ut->u.enum_nestable.id = -1ULL;
1289 }
1290 break;
1291 }
1292 default:
1293 return -EINVAL;
1294 }
1295 return 0;
1296 }
1297
1298 static
1299 int serialize_one_field(struct lttng_session *session,
1300 struct ustctl_field *fields, size_t *iter_output,
1301 const struct lttng_event_field *lf)
1302 {
1303 /* skip 'nowrite' fields */
1304 if (lf->nowrite)
1305 return 0;
1306
1307 return serialize_one_type(session, fields, iter_output, lf->name, &lf->type);
1308 }
1309
1310 static
1311 int serialize_fields(struct lttng_session *session,
1312 struct ustctl_field *ustctl_fields,
1313 size_t *iter_output, size_t nr_lttng_fields,
1314 const struct lttng_event_field *lttng_fields)
1315 {
1316 int ret;
1317 size_t i;
1318
1319 for (i = 0; i < nr_lttng_fields; i++) {
1320 ret = serialize_one_field(session, ustctl_fields,
1321 iter_output, &lttng_fields[i]);
1322 if (ret)
1323 return ret;
1324 }
1325 return 0;
1326 }
1327
1328 static
1329 int alloc_serialize_fields(struct lttng_session *session,
1330 size_t *_nr_write_fields,
1331 struct ustctl_field **ustctl_fields,
1332 size_t nr_fields,
1333 const struct lttng_event_field *lttng_fields)
1334 {
1335 struct ustctl_field *fields;
1336 int ret;
1337 size_t iter_output = 0;
1338 ssize_t nr_write_fields;
1339
1340 nr_write_fields = count_fields_recursive(nr_fields, lttng_fields);
1341 if (nr_write_fields < 0) {
1342 return (int) nr_write_fields;
1343 }
1344
1345 fields = zmalloc(nr_write_fields * sizeof(*fields));
1346 if (!fields)
1347 return -ENOMEM;
1348
1349 ret = serialize_fields(session, fields, &iter_output, nr_fields,
1350 lttng_fields);
1351 if (ret)
1352 goto error_type;
1353
1354 *_nr_write_fields = nr_write_fields;
1355 *ustctl_fields = fields;
1356 return 0;
1357
1358 error_type:
1359 free(fields);
1360 return ret;
1361 }
1362
1363 static
1364 int serialize_entries(struct ustctl_enum_entry **_entries,
1365 size_t nr_entries,
1366 const struct lttng_enum_entry *lttng_entries)
1367 {
1368 struct ustctl_enum_entry *entries;
1369 int i;
1370
1371 /* Serialize the entries */
1372 entries = zmalloc(nr_entries * sizeof(*entries));
1373 if (!entries)
1374 return -ENOMEM;
1375 for (i = 0; i < nr_entries; i++) {
1376 struct ustctl_enum_entry *uentry;
1377 const struct lttng_enum_entry *lentry;
1378
1379 uentry = &entries[i];
1380 lentry = &lttng_entries[i];
1381
1382 uentry->start.value = lentry->start.value;
1383 uentry->start.signedness = lentry->start.signedness;
1384 uentry->end.value = lentry->end.value;
1385 uentry->end.signedness = lentry->end.signedness;
1386 strncpy(uentry->string, lentry->string, LTTNG_UST_SYM_NAME_LEN);
1387 uentry->string[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1388
1389 if (lentry->u.extra.options & LTTNG_ENUM_ENTRY_OPTION_IS_AUTO) {
1390 uentry->u.extra.options |=
1391 USTCTL_UST_ENUM_ENTRY_OPTION_IS_AUTO;
1392 }
1393 }
1394 *_entries = entries;
1395 return 0;
1396 }
1397
1398 static
1399 int serialize_ctx_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_ctx_field *lttng_fields)
1404 {
1405 struct ustctl_field *fields;
1406 int ret;
1407 size_t i, iter_output = 0;
1408 ssize_t nr_write_fields;
1409
1410 nr_write_fields = count_ctx_fields_recursive(nr_fields,
1411 lttng_fields);
1412 if (nr_write_fields < 0) {
1413 return (int) nr_write_fields;
1414 }
1415
1416 fields = zmalloc(nr_write_fields * sizeof(*fields));
1417 if (!fields)
1418 return -ENOMEM;
1419
1420 for (i = 0; i < nr_fields; i++) {
1421 ret = serialize_one_field(session, fields, &iter_output,
1422 &lttng_fields[i].event_field);
1423 if (ret)
1424 goto error_type;
1425 }
1426
1427 *_nr_write_fields = nr_write_fields;
1428 *ustctl_fields = fields;
1429 return 0;
1430
1431 error_type:
1432 free(fields);
1433 return ret;
1434 }
1435
1436 /*
1437 * Returns 0 on success, negative error value on error.
1438 */
1439 int ustcomm_register_event(int sock,
1440 struct lttng_session *session,
1441 int session_objd, /* session descriptor */
1442 int channel_objd, /* channel descriptor */
1443 const char *event_name, /* event name (input) */
1444 int loglevel,
1445 const char *signature, /* event signature (input) */
1446 size_t nr_fields, /* fields */
1447 const struct lttng_event_field *lttng_fields,
1448 const char *model_emf_uri,
1449 uint32_t *id) /* event id (output) */
1450 {
1451 ssize_t len;
1452 struct {
1453 struct ustcomm_notify_hdr header;
1454 struct ustcomm_notify_event_msg m;
1455 } msg;
1456 struct {
1457 struct ustcomm_notify_hdr header;
1458 struct ustcomm_notify_event_reply r;
1459 } reply;
1460 size_t signature_len, fields_len, model_emf_uri_len;
1461 struct ustctl_field *fields = NULL;
1462 size_t nr_write_fields = 0;
1463 int ret;
1464
1465 memset(&msg, 0, sizeof(msg));
1466 msg.header.notify_cmd = USTCTL_NOTIFY_CMD_EVENT;
1467 msg.m.session_objd = session_objd;
1468 msg.m.channel_objd = channel_objd;
1469 strncpy(msg.m.event_name, event_name, LTTNG_UST_SYM_NAME_LEN);
1470 msg.m.event_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1471 msg.m.loglevel = loglevel;
1472 signature_len = strlen(signature) + 1;
1473 msg.m.signature_len = signature_len;
1474
1475 /* Calculate fields len, serialize fields. */
1476 if (nr_fields > 0) {
1477 ret = alloc_serialize_fields(session, &nr_write_fields, &fields,
1478 nr_fields, lttng_fields);
1479 if (ret)
1480 return ret;
1481 }
1482
1483 fields_len = sizeof(*fields) * nr_write_fields;
1484 msg.m.fields_len = fields_len;
1485 if (model_emf_uri) {
1486 model_emf_uri_len = strlen(model_emf_uri) + 1;
1487 } else {
1488 model_emf_uri_len = 0;
1489 }
1490 msg.m.model_emf_uri_len = model_emf_uri_len;
1491
1492 len = ustcomm_send_unix_sock(sock, &msg, sizeof(msg));
1493 if (len > 0 && len != sizeof(msg)) {
1494 ret = -EIO;
1495 goto error_fields;
1496 }
1497 if (len < 0) {
1498 ret = len;
1499 goto error_fields;
1500 }
1501
1502 /* send signature */
1503 len = ustcomm_send_unix_sock(sock, signature, signature_len);
1504 if (len > 0 && len != signature_len) {
1505 ret = -EIO;
1506 goto error_fields;
1507 }
1508 if (len < 0) {
1509 ret = len;
1510 goto error_fields;
1511 }
1512
1513 /* send fields */
1514 if (fields_len > 0) {
1515 len = ustcomm_send_unix_sock(sock, fields, fields_len);
1516 if (len > 0 && len != fields_len) {
1517 ret = -EIO;
1518 goto error_fields;
1519 }
1520 if (len < 0) {
1521 ret = len;
1522 goto error_fields;
1523 }
1524 }
1525 free(fields);
1526
1527 if (model_emf_uri_len) {
1528 /* send model_emf_uri */
1529 len = ustcomm_send_unix_sock(sock, model_emf_uri,
1530 model_emf_uri_len);
1531 if (len > 0 && len != model_emf_uri_len) {
1532 return -EIO;
1533 }
1534 if (len < 0) {
1535 return len;
1536 }
1537 }
1538
1539 /* receive reply */
1540 len = ustcomm_recv_unix_sock(sock, &reply, sizeof(reply));
1541 switch (len) {
1542 case 0: /* orderly shutdown */
1543 return -EPIPE;
1544 case sizeof(reply):
1545 if (reply.header.notify_cmd != msg.header.notify_cmd) {
1546 ERR("Unexpected result message command "
1547 "expected: %u vs received: %u\n",
1548 msg.header.notify_cmd, reply.header.notify_cmd);
1549 return -EINVAL;
1550 }
1551 if (reply.r.ret_code > 0)
1552 return -EINVAL;
1553 if (reply.r.ret_code < 0)
1554 return reply.r.ret_code;
1555 *id = reply.r.event_id;
1556 DBG("Sent register event notification for name \"%s\": ret_code %d, event_id %u\n",
1557 event_name, reply.r.ret_code, reply.r.event_id);
1558 return 0;
1559 default:
1560 if (len < 0) {
1561 /* Transport level error */
1562 if (errno == EPIPE || errno == ECONNRESET)
1563 len = -errno;
1564 return len;
1565 } else {
1566 ERR("incorrect message size: %zd\n", len);
1567 return len;
1568 }
1569 }
1570 /* Unreached. */
1571
1572 /* Error path only. */
1573 error_fields:
1574 free(fields);
1575 return ret;
1576 }
1577
1578 /*
1579 * Returns 0 on success, negative error value on error.
1580 * Returns -EPIPE or -ECONNRESET if other end has hung up.
1581 */
1582 int ustcomm_register_enum(int sock,
1583 int session_objd, /* session descriptor */
1584 const char *enum_name, /* enum name (input) */
1585 size_t nr_entries, /* entries */
1586 const struct lttng_enum_entry *lttng_entries,
1587 uint64_t *id)
1588 {
1589 ssize_t len;
1590 struct {
1591 struct ustcomm_notify_hdr header;
1592 struct ustcomm_notify_enum_msg m;
1593 } msg;
1594 struct {
1595 struct ustcomm_notify_hdr header;
1596 struct ustcomm_notify_enum_reply r;
1597 } reply;
1598 size_t entries_len;
1599 struct ustctl_enum_entry *entries = NULL;
1600 int ret;
1601
1602 memset(&msg, 0, sizeof(msg));
1603 msg.header.notify_cmd = USTCTL_NOTIFY_CMD_ENUM;
1604 msg.m.session_objd = session_objd;
1605 strncpy(msg.m.enum_name, enum_name, LTTNG_UST_SYM_NAME_LEN);
1606 msg.m.enum_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1607
1608 /* Calculate entries len, serialize entries. */
1609 if (nr_entries > 0) {
1610 ret = serialize_entries(&entries,
1611 nr_entries, lttng_entries);
1612 if (ret)
1613 return ret;
1614 }
1615
1616 entries_len = sizeof(*entries) * nr_entries;
1617 msg.m.entries_len = entries_len;
1618
1619 len = ustcomm_send_unix_sock(sock, &msg, sizeof(msg));
1620 if (len > 0 && len != sizeof(msg)) {
1621 ret = -EIO;
1622 goto error_entries;
1623 }
1624 if (len < 0) {
1625 ret = len;
1626 goto error_entries;
1627 }
1628
1629 /* send entries */
1630 if (entries_len > 0) {
1631 len = ustcomm_send_unix_sock(sock, entries, entries_len);
1632 if (len > 0 && len != entries_len) {
1633 ret = -EIO;
1634 goto error_entries;
1635 }
1636 if (len < 0) {
1637 ret = len;
1638 goto error_entries;
1639 }
1640 }
1641 free(entries);
1642 entries = NULL;
1643
1644 /* receive reply */
1645 len = ustcomm_recv_unix_sock(sock, &reply, sizeof(reply));
1646 switch (len) {
1647 case 0: /* orderly shutdown */
1648 return -EPIPE;
1649 case sizeof(reply):
1650 if (reply.header.notify_cmd != msg.header.notify_cmd) {
1651 ERR("Unexpected result message command "
1652 "expected: %u vs received: %u\n",
1653 msg.header.notify_cmd, reply.header.notify_cmd);
1654 return -EINVAL;
1655 }
1656 if (reply.r.ret_code > 0)
1657 return -EINVAL;
1658 if (reply.r.ret_code < 0)
1659 return reply.r.ret_code;
1660 *id = reply.r.enum_id;
1661 DBG("Sent register enum notification for name \"%s\": ret_code %d\n",
1662 enum_name, reply.r.ret_code);
1663 return 0;
1664 default:
1665 if (len < 0) {
1666 /* Transport level error */
1667 if (errno == EPIPE || errno == ECONNRESET)
1668 len = -errno;
1669 return len;
1670 } else {
1671 ERR("incorrect message size: %zd\n", len);
1672 return len;
1673 }
1674 }
1675 return ret;
1676
1677 error_entries:
1678 free(entries);
1679 return ret;
1680 }
1681
1682 /*
1683 * Returns 0 on success, negative error value on error.
1684 * Returns -EPIPE or -ECONNRESET if other end has hung up.
1685 */
1686 int ustcomm_register_channel(int sock,
1687 struct lttng_session *session,
1688 int session_objd, /* session descriptor */
1689 int channel_objd, /* channel descriptor */
1690 size_t nr_ctx_fields,
1691 const struct lttng_ctx_field *ctx_fields,
1692 uint32_t *chan_id, /* channel id (output) */
1693 int *header_type) /* header type (output) */
1694 {
1695 ssize_t len;
1696 struct {
1697 struct ustcomm_notify_hdr header;
1698 struct ustcomm_notify_channel_msg m;
1699 } msg;
1700 struct {
1701 struct ustcomm_notify_hdr header;
1702 struct ustcomm_notify_channel_reply r;
1703 } reply;
1704 size_t fields_len;
1705 struct ustctl_field *fields = NULL;
1706 int ret;
1707 size_t nr_write_fields = 0;
1708
1709 memset(&msg, 0, sizeof(msg));
1710 msg.header.notify_cmd = USTCTL_NOTIFY_CMD_CHANNEL;
1711 msg.m.session_objd = session_objd;
1712 msg.m.channel_objd = channel_objd;
1713
1714 /* Calculate fields len, serialize fields. */
1715 if (nr_ctx_fields > 0) {
1716 ret = serialize_ctx_fields(session, &nr_write_fields, &fields,
1717 nr_ctx_fields, ctx_fields);
1718 if (ret)
1719 return ret;
1720 }
1721
1722 fields_len = sizeof(*fields) * nr_write_fields;
1723 msg.m.ctx_fields_len = fields_len;
1724 len = ustcomm_send_unix_sock(sock, &msg, sizeof(msg));
1725 if (len > 0 && len != sizeof(msg)) {
1726 free(fields);
1727 return -EIO;
1728 }
1729 if (len < 0) {
1730 free(fields);
1731 return len;
1732 }
1733
1734 /* send fields */
1735 if (fields_len > 0) {
1736 len = ustcomm_send_unix_sock(sock, fields, fields_len);
1737 free(fields);
1738 if (len > 0 && len != fields_len) {
1739 return -EIO;
1740 }
1741 if (len < 0) {
1742 return len;
1743 }
1744 } else {
1745 free(fields);
1746 }
1747
1748 len = ustcomm_recv_unix_sock(sock, &reply, sizeof(reply));
1749 switch (len) {
1750 case 0: /* orderly shutdown */
1751 return -EPIPE;
1752 case sizeof(reply):
1753 if (reply.header.notify_cmd != msg.header.notify_cmd) {
1754 ERR("Unexpected result message command "
1755 "expected: %u vs received: %u\n",
1756 msg.header.notify_cmd, reply.header.notify_cmd);
1757 return -EINVAL;
1758 }
1759 if (reply.r.ret_code > 0)
1760 return -EINVAL;
1761 if (reply.r.ret_code < 0)
1762 return reply.r.ret_code;
1763 *chan_id = reply.r.chan_id;
1764 switch (reply.r.header_type) {
1765 case 1:
1766 case 2:
1767 *header_type = reply.r.header_type;
1768 break;
1769 default:
1770 ERR("Unexpected channel header type %u\n",
1771 reply.r.header_type);
1772 return -EINVAL;
1773 }
1774 DBG("Sent register channel notification: chan_id %d, header_type %d\n",
1775 reply.r.chan_id, reply.r.header_type);
1776 return 0;
1777 default:
1778 if (len < 0) {
1779 /* Transport level error */
1780 if (errno == EPIPE || errno == ECONNRESET)
1781 len = -errno;
1782 return len;
1783 } else {
1784 ERR("incorrect message size: %zd\n", len);
1785 return len;
1786 }
1787 }
1788 }
1789
1790 /*
1791 * Set socket reciving timeout.
1792 */
1793 int ustcomm_setsockopt_rcv_timeout(int sock, unsigned int msec)
1794 {
1795 int ret;
1796 struct timeval tv;
1797
1798 tv.tv_sec = msec / 1000;
1799 tv.tv_usec = (msec * 1000 % 1000000);
1800
1801 ret = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
1802 if (ret < 0) {
1803 PERROR("setsockopt SO_RCVTIMEO");
1804 ret = -errno;
1805 }
1806
1807 return ret;
1808 }
1809
1810 /*
1811 * Set socket sending timeout.
1812 */
1813 int ustcomm_setsockopt_snd_timeout(int sock, unsigned int msec)
1814 {
1815 int ret;
1816 struct timeval tv;
1817
1818 tv.tv_sec = msec / 1000;
1819 tv.tv_usec = (msec * 1000) % 1000000;
1820
1821 ret = setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
1822 if (ret < 0) {
1823 PERROR("setsockopt SO_SNDTIMEO");
1824 ret = -errno;
1825 }
1826
1827 return ret;
1828 }
This page took 0.09306 seconds and 5 git commands to generate.