Move LTTng-UST buffer ownership from application to consumer
[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 <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 <ust-comm.h>
35 #include <helper.h>
36 #include <lttng/ust-error.h>
37
38 #define USTCOMM_CODE_OFFSET(code) \
39 (code == LTTNG_UST_OK ? 0 : (code - LTTNG_UST_ERR + 1))
40
41 #define USTCOMM_MAX_SEND_FDS 4
42
43 /*
44 * Human readable error message.
45 */
46 static const char *ustcomm_readable_code[] = {
47 [ USTCOMM_CODE_OFFSET(LTTNG_UST_OK) ] = "Success",
48 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR) ] = "Unknown error",
49 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_NOENT) ] = "No entry",
50 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_EXIST) ] = "Object already exists",
51 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_INVAL) ] = "Invalid argument",
52 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_PERM) ] = "Permission denied",
53 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_NOSYS) ] = "Not implemented",
54 [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_EXITING) ] = "Process is exiting",
55 };
56
57 /*
58 * lttng_ust_strerror
59 *
60 * Receives positive error value.
61 * Return ptr to string representing a human readable
62 * error code from the ustcomm_return_code enum.
63 */
64 const char *lttng_ust_strerror(int code)
65 {
66 if (code == LTTNG_UST_OK)
67 return ustcomm_readable_code[USTCOMM_CODE_OFFSET(code)];
68 if (code < LTTNG_UST_ERR)
69 return strerror(code);
70 if (code >= LTTNG_UST_ERR_NR)
71 code = LTTNG_UST_ERR;
72 return ustcomm_readable_code[USTCOMM_CODE_OFFSET(code)];
73
74 }
75
76 /*
77 * ustcomm_connect_unix_sock
78 *
79 * Connect to unix socket using the path name.
80 */
81 int ustcomm_connect_unix_sock(const char *pathname)
82 {
83 struct sockaddr_un sun;
84 int fd, ret;
85
86 /*
87 * libust threads require the close-on-exec flag for all
88 * resources so it does not leak file descriptors upon exec.
89 */
90 fd = socket(PF_UNIX, SOCK_STREAM, 0);
91 if (fd < 0) {
92 perror("socket");
93 ret = -errno;
94 goto error;
95 }
96 ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
97 if (ret < 0) {
98 perror("fcntl");
99 ret = -errno;
100 goto error_fcntl;
101 }
102
103 memset(&sun, 0, sizeof(sun));
104 sun.sun_family = AF_UNIX;
105 strncpy(sun.sun_path, pathname, sizeof(sun.sun_path));
106 sun.sun_path[sizeof(sun.sun_path) - 1] = '\0';
107
108 ret = connect(fd, (struct sockaddr *) &sun, sizeof(sun));
109 if (ret < 0) {
110 /*
111 * Don't print message on connect error, because connect
112 * is used in normal execution to detect if sessiond is
113 * alive.
114 */
115 ret = -errno;
116 goto error_connect;
117 }
118
119 return fd;
120
121 error_connect:
122 error_fcntl:
123 {
124 int closeret;
125
126 closeret = close(fd);
127 if (closeret)
128 perror("close");
129 }
130 error:
131 return ret;
132 }
133
134 /*
135 * ustcomm_accept_unix_sock
136 *
137 * Do an accept(2) on the sock and return the
138 * new file descriptor. The socket MUST be bind(2) before.
139 */
140 int ustcomm_accept_unix_sock(int sock)
141 {
142 int new_fd;
143 struct sockaddr_un sun;
144 socklen_t len = 0;
145
146 /* Blocking call */
147 new_fd = accept(sock, (struct sockaddr *) &sun, &len);
148 if (new_fd < 0) {
149 perror("accept");
150 return -errno;
151 }
152 return new_fd;
153 }
154
155 /*
156 * ustcomm_create_unix_sock
157 *
158 * Creates a AF_UNIX local socket using pathname
159 * bind the socket upon creation and return the fd.
160 */
161 int ustcomm_create_unix_sock(const char *pathname)
162 {
163 struct sockaddr_un sun;
164 int fd, ret;
165
166 /* Create server socket */
167 if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
168 perror("socket");
169 ret = -errno;
170 goto error;
171 }
172
173 memset(&sun, 0, sizeof(sun));
174 sun.sun_family = AF_UNIX;
175 strncpy(sun.sun_path, pathname, sizeof(sun.sun_path));
176 sun.sun_path[sizeof(sun.sun_path) - 1] = '\0';
177
178 /* Unlink the old file if present */
179 (void) unlink(pathname);
180 ret = bind(fd, (struct sockaddr *) &sun, sizeof(sun));
181 if (ret < 0) {
182 perror("bind");
183 ret = -errno;
184 goto error_close;
185 }
186
187 return fd;
188
189 error_close:
190 {
191 int closeret;
192
193 closeret = close(fd);
194 if (closeret) {
195 perror("close");
196 }
197 }
198 error:
199 return ret;
200 }
201
202 /*
203 * ustcomm_listen_unix_sock
204 *
205 * Make the socket listen using LTTNG_UST_COMM_MAX_LISTEN.
206 */
207 int ustcomm_listen_unix_sock(int sock)
208 {
209 int ret;
210
211 ret = listen(sock, LTTNG_UST_COMM_MAX_LISTEN);
212 if (ret < 0) {
213 ret = -errno;
214 perror("listen");
215 }
216
217 return ret;
218 }
219
220 /*
221 * ustcomm_close_unix_sock
222 *
223 * Shutdown cleanly a unix socket.
224 */
225 int ustcomm_close_unix_sock(int sock)
226 {
227 int ret;
228
229 ret = close(sock);
230 if (ret < 0) {
231 perror("close");
232 ret = -errno;
233 }
234
235 return ret;
236 }
237
238 /*
239 * ustcomm_recv_unix_sock
240 *
241 * Receive data of size len in put that data into
242 * the buf param. Using recvmsg API.
243 * Return the size of received data.
244 * Return 0 on orderly shutdown.
245 */
246 ssize_t ustcomm_recv_unix_sock(int sock, void *buf, size_t len)
247 {
248 struct msghdr msg;
249 struct iovec iov[1];
250 ssize_t ret;
251
252 memset(&msg, 0, sizeof(msg));
253
254 iov[0].iov_base = buf;
255 iov[0].iov_len = len;
256 msg.msg_iov = iov;
257 msg.msg_iovlen = 1;
258
259 do {
260 ret = recvmsg(sock, &msg, 0);
261 } while (ret < 0 && errno == EINTR);
262
263 if (ret < 0) {
264 int shutret;
265
266 if (errno != EPIPE && errno != ECONNRESET)
267 perror("recvmsg");
268 ret = -errno;
269
270 shutret = shutdown(sock, SHUT_RDWR);
271 if (shutret)
272 fprintf(stderr, "Socket shutdown error");
273 }
274
275 return ret;
276 }
277
278 /*
279 * ustcomm_send_unix_sock
280 *
281 * Send buf data of size len. Using sendmsg API.
282 * Return the size of sent data.
283 */
284 ssize_t ustcomm_send_unix_sock(int sock, void *buf, size_t len)
285 {
286 struct msghdr msg;
287 struct iovec iov[1];
288 ssize_t ret;
289
290 memset(&msg, 0, sizeof(msg));
291
292 iov[0].iov_base = buf;
293 iov[0].iov_len = len;
294 msg.msg_iov = iov;
295 msg.msg_iovlen = 1;
296
297 /*
298 * Using the MSG_NOSIGNAL when sending data from sessiond to
299 * libust, so libust does not receive an unhandled SIGPIPE or
300 * SIGURG. The sessiond receiver side can be made more resilient
301 * by ignoring SIGPIPE, but we don't have this luxury on the
302 * libust side.
303 */
304 do {
305 ret = sendmsg(sock, &msg, MSG_NOSIGNAL);
306 } while (ret < 0 && errno == EINTR);
307
308 if (ret < 0) {
309 int shutret;
310
311 if (errno != EPIPE && errno != ECONNRESET)
312 perror("sendmsg");
313 ret = -errno;
314
315 shutret = shutdown(sock, SHUT_RDWR);
316 if (shutret)
317 fprintf(stderr, "Socket shutdown error");
318 }
319
320 return ret;
321 }
322
323 /*
324 * Send a message accompanied by fd(s) over a unix socket.
325 *
326 * Returns the size of data sent, or negative error value.
327 */
328 ssize_t ustcomm_send_fds_unix_sock(int sock, int *fds, size_t nb_fd)
329 {
330 struct msghdr msg;
331 struct cmsghdr *cmptr;
332 struct iovec iov[1];
333 ssize_t ret = -1;
334 unsigned int sizeof_fds = nb_fd * sizeof(int);
335 char tmp[CMSG_SPACE(sizeof_fds)];
336 char dummy = 0;
337
338 memset(&msg, 0, sizeof(msg));
339 memset(tmp, 0, CMSG_SPACE(sizeof_fds) * sizeof(char));
340
341 if (nb_fd > USTCOMM_MAX_SEND_FDS)
342 return -EINVAL;
343
344 msg.msg_control = (caddr_t)tmp;
345 msg.msg_controllen = CMSG_LEN(sizeof_fds);
346
347 cmptr = CMSG_FIRSTHDR(&msg);
348 cmptr->cmsg_level = SOL_SOCKET;
349 cmptr->cmsg_type = SCM_RIGHTS;
350 cmptr->cmsg_len = CMSG_LEN(sizeof_fds);
351 memcpy(CMSG_DATA(cmptr), fds, sizeof_fds);
352 /* Sum of the length of all control messages in the buffer: */
353 msg.msg_controllen = cmptr->cmsg_len;
354
355 iov[0].iov_base = &dummy;
356 iov[0].iov_len = 1;
357 msg.msg_iov = iov;
358 msg.msg_iovlen = 1;
359
360 do {
361 ret = sendmsg(sock, &msg, 0);
362 } while (ret < 0 && errno == EINTR);
363 if (ret < 0) {
364 /*
365 * We consider EPIPE and ECONNRESET as expected.
366 */
367 if (errno != EPIPE && errno != ECONNRESET) {
368 perror("sendmsg");
369 }
370 }
371 return ret;
372 }
373
374 /*
375 * Recv a message accompanied by fd(s) from a unix socket.
376 *
377 * Returns the size of received data, or negative error value.
378 *
379 * Expect at most "nb_fd" file descriptors. Returns the number of fd
380 * actually received in nb_fd.
381 * Returns -EPIPE on orderly shutdown.
382 */
383 ssize_t ustcomm_recv_fds_unix_sock(int sock, int *fds, size_t nb_fd)
384 {
385 struct iovec iov[1];
386 ssize_t ret = 0;
387 struct cmsghdr *cmsg;
388 size_t sizeof_fds = nb_fd * sizeof(int);
389 char recv_fd[CMSG_SPACE(sizeof_fds)];
390 struct msghdr msg;
391 char dummy;
392
393 memset(&msg, 0, sizeof(msg));
394
395 /* Prepare to receive the structures */
396 iov[0].iov_base = &dummy;
397 iov[0].iov_len = 1;
398 msg.msg_iov = iov;
399 msg.msg_iovlen = 1;
400 msg.msg_control = recv_fd;
401 msg.msg_controllen = sizeof(recv_fd);
402
403 do {
404 ret = recvmsg(sock, &msg, 0);
405 } while (ret < 0 && errno == EINTR);
406 if (ret < 0) {
407 if (errno != EPIPE && errno != ECONNRESET) {
408 perror("recvmsg fds");
409 }
410 if (errno == EPIPE || errno == ECONNRESET)
411 ret = -errno;
412 goto end;
413 }
414 if (ret == 0) {
415 /* orderly shutdown */
416 ret = -EPIPE;
417 goto end;
418 }
419 if (ret != 1) {
420 fprintf(stderr, "Error: Received %zd bytes, expected %d\n",
421 ret, 1);
422 goto end;
423 }
424 if (msg.msg_flags & MSG_CTRUNC) {
425 fprintf(stderr, "Error: Control message truncated.\n");
426 ret = -1;
427 goto end;
428 }
429 cmsg = CMSG_FIRSTHDR(&msg);
430 if (!cmsg) {
431 fprintf(stderr, "Error: Invalid control message header\n");
432 ret = -1;
433 goto end;
434 }
435 if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
436 fprintf(stderr, "Didn't received any fd\n");
437 ret = -1;
438 goto end;
439 }
440 if (cmsg->cmsg_len != CMSG_LEN(sizeof_fds)) {
441 fprintf(stderr, "Error: Received %zu bytes of ancillary data, expected %zu\n",
442 (size_t) cmsg->cmsg_len, (size_t) CMSG_LEN(sizeof_fds));
443 ret = -1;
444 goto end;
445 }
446 memcpy(fds, CMSG_DATA(cmsg), sizeof_fds);
447 ret = sizeof_fds;
448 end:
449 return ret;
450 }
451
452 int ustcomm_send_app_msg(int sock, struct ustcomm_ust_msg *lum)
453 {
454 ssize_t len;
455
456 len = ustcomm_send_unix_sock(sock, lum, sizeof(*lum));
457 switch (len) {
458 case sizeof(*lum):
459 break;
460 default:
461 if (len < 0) {
462 return len;
463 } else {
464 fprintf(stderr, "incorrect message size: %zd\n", len);
465 return -EINVAL;
466 }
467 }
468 return 0;
469 }
470
471 int ustcomm_recv_app_reply(int sock, struct ustcomm_ust_reply *lur,
472 uint32_t expected_handle, uint32_t expected_cmd)
473 {
474 ssize_t len;
475
476 memset(lur, 0, sizeof(*lur));
477 len = ustcomm_recv_unix_sock(sock, lur, sizeof(*lur));
478 switch (len) {
479 case 0: /* orderly shutdown */
480 return -EPIPE;
481 case sizeof(*lur):
482 if (lur->handle != expected_handle) {
483 fprintf(stderr, "Unexpected result message handle: "
484 "expected: %u vs received: %u\n",
485 expected_handle, lur->handle);
486 return -EINVAL;
487 }
488 if (lur->cmd != expected_cmd) {
489 fprintf(stderr, "Unexpected result message command "
490 "expected: %u vs received: %u\n",
491 expected_cmd, lur->cmd);
492 return -EINVAL;
493 }
494 return lur->ret_code;
495 default:
496 if (len < 0) {
497 /* Transport level error */
498 if (errno == EPIPE || errno == ECONNRESET)
499 len = -errno;
500 return len;
501 } else {
502 fprintf(stderr, "incorrect message size: %zd\n", len);
503 return len;
504 }
505 }
506 }
507
508 int ustcomm_send_app_cmd(int sock,
509 struct ustcomm_ust_msg *lum,
510 struct ustcomm_ust_reply *lur)
511 {
512 int ret;
513
514 ret = ustcomm_send_app_msg(sock, lum);
515 if (ret)
516 return ret;
517 ret = ustcomm_recv_app_reply(sock, lur, lum->handle, lum->cmd);
518 if (ret > 0)
519 return -EIO;
520 return ret;
521 }
522
523 /*
524 * chan_data is allocated internally if this function returns the
525 * expected var_len.
526 */
527 ssize_t ustcomm_recv_channel_from_sessiond(int sock,
528 void **_chan_data, uint64_t var_len)
529 {
530 void *chan_data;
531 ssize_t len;
532
533 if (var_len > LTTNG_UST_CHANNEL_DATA_MAX_LEN) {
534 len = -EINVAL;
535 goto error_check;
536 }
537 /* Receive variable length data */
538 chan_data = zmalloc(var_len);
539 if (!chan_data) {
540 len = -ENOMEM;
541 goto error_alloc;
542 }
543 len = ustcomm_recv_unix_sock(sock, chan_data, var_len);
544 if (len != var_len) {
545 goto error_recv;
546 }
547 *_chan_data = chan_data;
548 return len;
549
550 error_recv:
551 free(chan_data);
552 error_alloc:
553 error_check:
554 return len;
555 }
556
557 int ustcomm_recv_stream_from_sessiond(int sock,
558 uint64_t *memory_map_size,
559 int *shm_fd, int *wakeup_fd)
560 {
561 ssize_t len;
562 int ret;
563 int fds[2];
564
565 /* recv shm fd and wakeup fd */
566 len = ustcomm_recv_fds_unix_sock(sock, fds, 2);
567 if (len <= 0) {
568 if (len < 0) {
569 ret = len;
570 goto error;
571 } else {
572 ret = -EIO;
573 goto error;
574 }
575 }
576 *shm_fd = fds[0];
577 *wakeup_fd = fds[1];
578 return 0;
579
580 error:
581 return ret;
582 }
This page took 0.040644 seconds and 5 git commands to generate.