Merge branch 'master' of git://git.lttng.org/lttng-tools
[lttng-tools.git] / src / common / sessiond-comm / sessiond-comm.c
index 3b7a2a2ad827c11428f542c94d3334d96109b758..96615f4389adad78ac3804a9cd9c1b1dba7a763a 100644 (file)
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <sys/un.h>
 #include <unistd.h>
 #include <errno.h>
 
 #include <common/defaults.h>
+#include <common/error.h>
 
 #include "sessiond-comm.h"
 
@@ -47,7 +47,7 @@ static const char *lttcomm_readable_code[] = {
        [ LTTCOMM_ERR_INDEX(LTTCOMM_SESS_NOT_FOUND) ] = "Session name not found",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_NO_TRACE) ] = "No trace found",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_FATAL) ] = "Fatal error of the session daemon",
-       [ LTTCOMM_ERR_INDEX(LTTCOMM_CREATE_FAIL) ] = "Create trace failed",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_CREATE_DIR_FAIL) ] = "Create directory failed",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_START_FAIL) ] = "Start trace failed",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_STOP_FAIL) ] = "Stop trace failed",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_NO_TRACEABLE) ] = "App is not traceable",
@@ -100,6 +100,7 @@ static const char *lttcomm_readable_code[] = {
        [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_EVENT_EXIST) ] = "UST event already exist",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_EVENT_NOT_FOUND)] = "UST event not found",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_CONTEXT_EXIST)] = "UST context already exist",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_CONTEXT_INVAL)] = "UST invalid context",
        [ LTTCOMM_ERR_INDEX(CONSUMERD_COMMAND_SOCK_READY) ] = "consumerd command socket ready",
        [ LTTCOMM_ERR_INDEX(CONSUMERD_SUCCESS_RECV_FD) ] = "consumerd success on receiving fds",
        [ LTTCOMM_ERR_INDEX(CONSUMERD_ERROR_RECV_FD) ] = "consumerd error on receiving fds",
@@ -115,6 +116,7 @@ static const char *lttcomm_readable_code[] = {
        [ LTTCOMM_ERR_INDEX(CONSUMERD_SPLICE_ENOMEM) ] = "consumerd splice ENOMEM",
        [ LTTCOMM_ERR_INDEX(CONSUMERD_SPLICE_ESPIPE) ] = "consumerd splice ESPIPE",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_NO_EVENT) ] = "Event not found",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_NEED_ROOT_SESSIOND) ] = "A root lttng-sessiond needs to be running, and client user part of the \"tracing\" group, to interact with kernel tracing",
 };
 
 /*
@@ -140,12 +142,11 @@ const char *lttcomm_get_readable_code(enum lttcomm_return_code code)
 int lttcomm_connect_unix_sock(const char *pathname)
 {
        struct sockaddr_un sun;
-       int fd;
-       int ret;
+       int fd, ret, closeret;
 
        fd = socket(PF_UNIX, SOCK_STREAM, 0);
        if (fd < 0) {
-               perror("socket");
+               PERROR("socket");
                ret = fd;
                goto error;
        }
@@ -167,7 +168,10 @@ int lttcomm_connect_unix_sock(const char *pathname)
        return fd;
 
 error_connect:
-       close(fd);
+       closeret = close(fd);
+       if (closeret) {
+               PERROR("close");
+       }
 error:
        return ret;
 }
@@ -185,7 +189,7 @@ int lttcomm_accept_unix_sock(int sock)
        /* Blocking call */
        new_fd = accept(sock, (struct sockaddr *) &sun, &len);
        if (new_fd < 0) {
-               perror("accept");
+               PERROR("accept");
        }
 
        return new_fd;
@@ -203,7 +207,7 @@ int lttcomm_create_unix_sock(const char *pathname)
 
        /* Create server socket */
        if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
-               perror("socket");
+               PERROR("socket");
                goto error;
        }
 
@@ -216,7 +220,7 @@ int lttcomm_create_unix_sock(const char *pathname)
        (void) unlink(pathname);
        ret = bind(fd, (struct sockaddr *) &sun, sizeof(sun));
        if (ret < 0) {
-               perror("bind");
+               PERROR("bind");
                goto error;
        }
 
@@ -235,7 +239,7 @@ int lttcomm_listen_unix_sock(int sock)
 
        ret = listen(sock, LTTNG_SESSIOND_COMM_MAX_LISTEN);
        if (ret < 0) {
-               perror("listen");
+               PERROR("listen");
        }
 
        return ret;
@@ -249,18 +253,20 @@ int lttcomm_listen_unix_sock(int sock)
  */
 ssize_t lttcomm_recv_unix_sock(int sock, void *buf, size_t len)
 {
-       struct msghdr msg = { 0 };
+       struct msghdr msg;
        struct iovec iov[1];
        ssize_t ret = -1;
 
+       memset(&msg, 0, sizeof(msg));
+
        iov[0].iov_base = buf;
        iov[0].iov_len = len;
        msg.msg_iov = iov;
        msg.msg_iovlen = 1;
 
-       ret = recvmsg(sock, &msg, 0);
+       ret = recvmsg(sock, &msg, MSG_WAITALL);
        if (ret < 0) {
-               perror("recvmsg");
+               PERROR("recvmsg");
        }
 
        return ret;
@@ -273,10 +279,12 @@ ssize_t lttcomm_recv_unix_sock(int sock, void *buf, size_t len)
  */
 ssize_t lttcomm_send_unix_sock(int sock, void *buf, size_t len)
 {
-       struct msghdr msg = { 0 };
+       struct msghdr msg;
        struct iovec iov[1];
        ssize_t ret = -1;
 
+       memset(&msg, 0, sizeof(msg));
+
        iov[0].iov_base = buf;
        iov[0].iov_len = len;
        msg.msg_iov = iov;
@@ -284,7 +292,13 @@ ssize_t lttcomm_send_unix_sock(int sock, void *buf, size_t len)
 
        ret = sendmsg(sock, &msg, 0);
        if (ret < 0) {
-               perror("sendmsg");
+               /*
+                * Only warn about EPIPE when quiet mode is deactivated.
+                * We consider EPIPE as expected.
+                */
+               if (errno != EPIPE || !opt_quiet) {
+                       PERROR("sendmsg");
+               }
        }
 
        return ret;
@@ -295,12 +309,17 @@ ssize_t lttcomm_send_unix_sock(int sock, void *buf, size_t len)
  */
 int lttcomm_close_unix_sock(int sock)
 {
-       int ret;
+       int ret, closeret;
 
        /* Shutdown receptions and transmissions */
        ret = shutdown(sock, SHUT_RDWR);
        if (ret < 0) {
-               perror("shutdown");
+               PERROR("shutdown");
+       }
+
+       closeret = close(sock);
+       if (closeret) {
+               PERROR("close");
        }
 
        return ret;
@@ -313,7 +332,7 @@ int lttcomm_close_unix_sock(int sock)
  */
 ssize_t lttcomm_send_fds_unix_sock(int sock, int *fds, size_t nb_fd)
 {
-       struct msghdr msg = { 0 };
+       struct msghdr msg;
        struct cmsghdr *cmptr;
        struct iovec iov[1];
        ssize_t ret = -1;
@@ -321,6 +340,8 @@ ssize_t lttcomm_send_fds_unix_sock(int sock, int *fds, size_t nb_fd)
        char tmp[CMSG_SPACE(sizeof_fds)];
        char dummy = 0;
 
+       memset(&msg, 0, sizeof(msg));
+
        if (nb_fd > LTTCOMM_MAX_SEND_FDS)
                return -EINVAL;
 
@@ -342,7 +363,13 @@ ssize_t lttcomm_send_fds_unix_sock(int sock, int *fds, size_t nb_fd)
 
        ret = sendmsg(sock, &msg, 0);
        if (ret < 0) {
-               perror("sendmsg");
+               /*
+                * Only warn about EPIPE when quiet mode is deactivated.
+                * We consider EPIPE as expected.
+                */
+               if (errno != EPIPE || !opt_quiet) {
+                       PERROR("sendmsg");
+               }
        }
        return ret;
 }
@@ -362,9 +389,11 @@ ssize_t lttcomm_recv_fds_unix_sock(int sock, int *fds, size_t nb_fd)
        struct cmsghdr *cmsg;
        size_t sizeof_fds = nb_fd * sizeof(int);
        char recv_fd[CMSG_SPACE(sizeof_fds)];
-       struct msghdr msg = { 0 };
+       struct msghdr msg;
        char dummy;
 
+       memset(&msg, 0, sizeof(msg));
+
        /* Prepare to receive the structures */
        iov[0].iov_base = &dummy;
        iov[0].iov_len = 1;
@@ -375,7 +404,7 @@ ssize_t lttcomm_recv_fds_unix_sock(int sock, int *fds, size_t nb_fd)
 
        ret = recvmsg(sock, &msg, 0);
        if (ret < 0) {
-               perror("recvmsg fds");
+               PERROR("recvmsg fds");
                goto end;
        }
        if (ret != 1) {
@@ -401,7 +430,7 @@ ssize_t lttcomm_recv_fds_unix_sock(int sock, int *fds, size_t nb_fd)
        }
        if (cmsg->cmsg_len != CMSG_LEN(sizeof_fds)) {
                fprintf(stderr, "Error: Received %zu bytes of ancillary data, expected %zu\n",
-                               cmsg->cmsg_len, CMSG_LEN(sizeof_fds));
+                               (size_t) cmsg->cmsg_len, (size_t) CMSG_LEN(sizeof_fds));
                ret = -1;
                goto end;
        }
@@ -418,38 +447,49 @@ end:
  */
 ssize_t lttcomm_send_creds_unix_sock(int sock, void *buf, size_t len)
 {
-       struct msghdr msg = { 0 };
-       struct cmsghdr *cmptr;
+       struct msghdr msg;
        struct iovec iov[1];
        ssize_t ret = -1;
-       struct ucred *creds;
-       size_t sizeof_cred = sizeof(struct ucred);
+#ifdef __linux__
+       struct cmsghdr *cmptr;
+       size_t sizeof_cred = sizeof(lttng_sock_cred);
        char anc_buf[CMSG_SPACE(sizeof_cred)];
+       lttng_sock_cred *creds;
+#endif /* __linux__ */
+
+       memset(&msg, 0, sizeof(msg));
 
        iov[0].iov_base = buf;
        iov[0].iov_len = len;
        msg.msg_iov = iov;
        msg.msg_iovlen = 1;
 
+#ifdef __linux__
        msg.msg_control = (caddr_t) anc_buf;
        msg.msg_controllen = CMSG_LEN(sizeof_cred);
 
        cmptr = CMSG_FIRSTHDR(&msg);
        cmptr->cmsg_level = SOL_SOCKET;
-       cmptr->cmsg_type = SCM_CREDENTIALS;
+       cmptr->cmsg_type = LTTNG_SOCK_CREDS;
        cmptr->cmsg_len = CMSG_LEN(sizeof_cred);
 
-       creds = (struct ucred *) CMSG_DATA(cmptr);
+       creds = (lttng_sock_cred*) CMSG_DATA(cmptr);
 
-       creds->uid = geteuid();
-       creds->gid = getegid();
-       creds->pid = getpid();
+       LTTNG_SOCK_SET_UID_CRED(creds, geteuid());
+       LTTNG_SOCK_SET_GID_CRED(creds, getegid());
+       LTTNG_SOCK_SET_PID_CRED(creds, getpid());
+#endif /* __linux__ */
 
        ret = sendmsg(sock, &msg, 0);
        if (ret < 0) {
-               perror("sendmsg");
+               /*
+                * Only warn about EPIPE when quiet mode is deactivated.
+                * We consider EPIPE as expected.
+                */
+               if (errno != EPIPE || !opt_quiet) {
+                       PERROR("sendmsg");
+               }
        }
-
        return ret;
 }
 
@@ -459,14 +499,18 @@ ssize_t lttcomm_send_creds_unix_sock(int sock, void *buf, size_t len)
  * Returns the size of received data, or negative error value.
  */
 ssize_t lttcomm_recv_creds_unix_sock(int sock, void *buf, size_t len,
-               struct ucred *creds)
+               lttng_sock_cred *creds)
 {
-       struct msghdr msg = { 0 };
-       struct cmsghdr *cmptr;
+       struct msghdr msg;
        struct iovec iov[1];
        ssize_t ret;
-       size_t sizeof_cred = sizeof(struct ucred);
+#ifdef __linux__
+       struct cmsghdr *cmptr;
+       size_t sizeof_cred = sizeof(lttng_sock_cred);
        char anc_buf[CMSG_SPACE(sizeof_cred)];
+#endif /* __linux__ */
+
+       memset(&msg, 0, sizeof(msg));
 
        /* Not allowed */
        if (creds == NULL) {
@@ -480,15 +524,18 @@ ssize_t lttcomm_recv_creds_unix_sock(int sock, void *buf, size_t len,
        msg.msg_iov = iov;
        msg.msg_iovlen = 1;
 
+#ifdef __linux__
        msg.msg_control = anc_buf;
        msg.msg_controllen = sizeof(anc_buf);
+#endif /* __linux__ */
 
        ret = recvmsg(sock, &msg, 0);
        if (ret < 0) {
-               perror("recvmsg fds");
+               PERROR("recvmsg fds");
                goto end;
        }
 
+#ifdef __linux__
        if (msg.msg_flags & MSG_CTRUNC) {
                fprintf(stderr, "Error: Control message truncated.\n");
                ret = -1;
@@ -503,7 +550,7 @@ ssize_t lttcomm_recv_creds_unix_sock(int sock, void *buf, size_t len,
        }
 
        if (cmptr->cmsg_level != SOL_SOCKET ||
-                       cmptr->cmsg_type != SCM_CREDENTIALS) {
+                       cmptr->cmsg_type != LTTNG_SOCK_CREDS) {
                fprintf(stderr, "Didn't received any credentials\n");
                ret = -1;
                goto end;
@@ -511,12 +558,24 @@ ssize_t lttcomm_recv_creds_unix_sock(int sock, void *buf, size_t len,
 
        if (cmptr->cmsg_len != CMSG_LEN(sizeof_cred)) {
                fprintf(stderr, "Error: Received %zu bytes of ancillary data, expected %zu\n",
-                               cmptr->cmsg_len, CMSG_LEN(sizeof_cred));
+                               (size_t) cmptr->cmsg_len, (size_t) CMSG_LEN(sizeof_cred));
                ret = -1;
                goto end;
        }
 
        memcpy(creds, CMSG_DATA(cmptr), sizeof_cred);
+#elif defined(__FreeBSD__)
+       {
+               int peer_ret;
+
+               peer_ret = getpeereid(sock, &creds->uid, &creds->gid);
+               if (peer_ret != 0) {
+                       return peer_ret;
+               }
+       }
+#else
+#error "Please implement credential support for your OS."
+#endif /* __linux__ */
 
 end:
        return ret;
@@ -525,6 +584,7 @@ end:
 /*
  * Set socket option to use credentials passing.
  */
+#ifdef __linux__
 int lttcomm_setsockopt_creds_unix_sock(int sock)
 {
        int ret, on = 1;
@@ -532,8 +592,15 @@ int lttcomm_setsockopt_creds_unix_sock(int sock)
        /* Set socket for credentials retrieval */
        ret = setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
        if (ret < 0) {
-               perror("setsockopt creds unix sock");
+               PERROR("setsockopt creds unix sock");
        }
-
        return ret;
 }
+#elif defined(__FreeBSD__)
+int lttcomm_setsockopt_creds_unix_sock(int sock)
+{
+       return 0;
+}
+#else
+#error "Please implement credential support for your OS."
+#endif /* __linux__ */
This page took 0.029853 seconds and 5 git commands to generate.