Don't report back error on syscalls fail for -a -k
[lttng-tools.git] / src / common / sessiond-comm / sessiond-comm.c
index fdd5856c0c0fe2328e12ceb050f6bcbd9814c72e..11319f333e84f34d30a75132d981444d136f7e24 100644 (file)
@@ -2,18 +2,18 @@
  * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
  *                      Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; only version 2 of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
  * 
  * This program is distributed in the hope that it will be useful, but WITHOUT
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  * more details.
  * 
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #define _GNU_SOURCE
@@ -24,7 +24,6 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <sys/un.h>
 #include <unistd.h>
 #include <errno.h>
 
@@ -61,6 +60,7 @@ static const char *lttcomm_readable_code[] = {
        [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_VERSION) ] = "Kernel tracer version is not compatible",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_EVENT_EXIST) ] = "Kernel event already exists",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_SESS_FAIL) ] = "Kernel create session failed",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_CHAN_EXIST) ] = "Kernel channel already exists",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_CHAN_FAIL) ] = "Kernel create channel failed",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_CHAN_NOT_FOUND) ] = "Kernel channel not found",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_CHAN_DISABLE_FAIL) ] = "Disable kernel channel failed",
@@ -102,6 +102,11 @@ static const char *lttcomm_readable_code[] = {
        [ 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(LTTCOMM_NEED_ROOT_SESSIOND) ] = "Tracing the kernel requires a root lttng-sessiond daemon and \"tracing\" group user membership",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_TRACE_ALREADY_STARTED) ] = "Tracing already started",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_TRACE_ALREADY_STOPPED) ] = "Tracing already stopped",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_EVENT_ENOSYS) ] = "Kernel event type not supported",
+
        [ 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",
@@ -117,7 +122,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",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_INVALID) ] = "Invalid parameter",
 };
 
 /*
@@ -265,7 +270,9 @@ ssize_t lttcomm_recv_unix_sock(int sock, void *buf, size_t len)
        msg.msg_iov = iov;
        msg.msg_iovlen = 1;
 
-       ret = recvmsg(sock, &msg, MSG_WAITALL);
+       do {
+               ret = recvmsg(sock, &msg, MSG_WAITALL);
+       } while (ret < 0 && errno == EINTR);
        if (ret < 0) {
                PERROR("recvmsg");
        }
@@ -297,7 +304,7 @@ ssize_t lttcomm_send_unix_sock(int sock, void *buf, size_t len)
                 * Only warn about EPIPE when quiet mode is deactivated.
                 * We consider EPIPE as expected.
                 */
-               if (errno != EPIPE || !opt_quiet) {
+               if (errno != EPIPE || !lttng_opt_quiet) {
                        PERROR("sendmsg");
                }
        }
@@ -362,13 +369,15 @@ ssize_t lttcomm_send_fds_unix_sock(int sock, int *fds, size_t nb_fd)
        msg.msg_iov = iov;
        msg.msg_iovlen = 1;
 
-       ret = sendmsg(sock, &msg, 0);
+       do {
+               ret = sendmsg(sock, &msg, 0);
+       } while (ret < 0 && errno == EINTR);
        if (ret < 0) {
                /*
                 * Only warn about EPIPE when quiet mode is deactivated.
                 * We consider EPIPE as expected.
                 */
-               if (errno != EPIPE || !opt_quiet) {
+               if (errno != EPIPE || !lttng_opt_quiet) {
                        PERROR("sendmsg");
                }
        }
@@ -403,7 +412,9 @@ ssize_t lttcomm_recv_fds_unix_sock(int sock, int *fds, size_t nb_fd)
        msg.msg_control = recv_fd;
        msg.msg_controllen = sizeof(recv_fd);
 
-       ret = recvmsg(sock, &msg, 0);
+       do {
+               ret = recvmsg(sock, &msg, 0);
+       } while (ret < 0 && errno == EINTR);
        if (ret < 0) {
                PERROR("recvmsg fds");
                goto end;
@@ -431,7 +442,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;
        }
@@ -449,12 +460,14 @@ end:
 ssize_t lttcomm_send_creds_unix_sock(int sock, void *buf, size_t len)
 {
        struct msghdr msg;
-       struct cmsghdr *cmptr;
        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));
 
@@ -463,27 +476,31 @@ ssize_t lttcomm_send_creds_unix_sock(int sock, void *buf, size_t 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);
+       do {
+               ret = sendmsg(sock, &msg, 0);
+       } while (ret < 0 && errno == EINTR);
        if (ret < 0) {
                /*
                 * Only warn about EPIPE when quiet mode is deactivated.
                 * We consider EPIPE as expected.
                 */
-               if (errno != EPIPE || !opt_quiet) {
+               if (errno != EPIPE || !lttng_opt_quiet) {
                        PERROR("sendmsg");
                }
        }
@@ -496,14 +513,16 @@ 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;
-       struct cmsghdr *cmptr;
        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));
 
@@ -519,15 +538,20 @@ 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);
+       do {
+               ret = recvmsg(sock, &msg, 0);
+       } while (ret < 0 && errno == EINTR);
        if (ret < 0) {
                PERROR("recvmsg fds");
                goto end;
        }
 
+#ifdef __linux__
        if (msg.msg_flags & MSG_CTRUNC) {
                fprintf(stderr, "Error: Control message truncated.\n");
                ret = -1;
@@ -542,7 +566,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;
@@ -550,12 +574,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;
@@ -564,6 +600,7 @@ end:
 /*
  * Set socket option to use credentials passing.
  */
+#ifdef __linux__
 int lttcomm_setsockopt_creds_unix_sock(int sock)
 {
        int ret, on = 1;
@@ -573,6 +610,13 @@ int lttcomm_setsockopt_creds_unix_sock(int sock)
        if (ret < 0) {
                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.032603 seconds and 4 git commands to generate.