Fix: data reception is called event when only FDS are expected for reception
authorJonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Tue, 27 Apr 2021 01:09:35 +0000 (21:09 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 28 Apr 2021 21:33:50 +0000 (17:33 -0400)
In non blocking mode, the FDs reception code can hit EAGAIN. In such
cases, skip the data reception completely when performing the reception.

The same behavior could have been implemented with a noop at the
`lttcomm_recv_unix_sock_non_block` level when the passed `len` is equal
to 0. The handling of it at the notification thread reception level was
chosen to be explicit with regards to the expected behaviour and not
rely on implicit functionality of `lttcomm_recv_unix_sock_non_block`.

While there, augment assertions for code in unix.c

Change-Id: I0fa6df1c9630caa6e877a39372bdfd3d3a01b648
Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
src/bin/lttng-sessiond/notification-thread-events.c
src/common/unix.c

index 414e5dd8aec0afd90a685eb1a23a53f315b2e554..655400f9484c790af2116f1855203a806f562e2d 100644 (file)
@@ -3954,6 +3954,12 @@ int handle_notification_thread_client_in(
                goto end;
        }
 
+       if (client->communication.inbound.bytes_to_receive == 0 &&
+                       client->communication.inbound.fds_to_receive != 0) {
+               /* Only FDs left to receive. */
+               goto receive_fds;
+       }
+
        offset = client->communication.inbound.payload.buffer.size -
                        client->communication.inbound.bytes_to_receive;
        if (client->communication.inbound.expect_creds) {
@@ -3982,6 +3988,7 @@ int handle_notification_thread_client_in(
                goto end;
        }
 
+receive_fds:
        assert(client->communication.inbound.bytes_to_receive == 0);
 
        /* Receive fds. */
index ae2b822af5a57debc7e0288011ab18a36abdd940..023bff847273df004c537593cbbbceb012540681 100644 (file)
@@ -181,6 +181,10 @@ ssize_t lttcomm_recv_unix_sock(int sock, void *buf, size_t len)
        ssize_t ret = -1;
        size_t len_last;
 
+       assert(sock);
+       assert(buf);
+       assert(len > 0);
+
        memset(&msg, 0, sizeof(msg));
 
        iov[0].iov_base = buf;
@@ -223,6 +227,10 @@ ssize_t lttcomm_recv_unix_sock_non_block(int sock, void *buf, size_t len)
        struct iovec iov[1];
        ssize_t ret;
 
+       assert(sock);
+       assert(buf);
+       assert(len > 0);
+
        memset(&msg, 0, sizeof(msg));
 
        iov[0].iov_base = buf;
@@ -271,6 +279,10 @@ ssize_t lttcomm_send_unix_sock(int sock, const void *buf, size_t len)
        struct iovec iov[1];
        ssize_t ret;
 
+       assert(sock);
+       assert(buf);
+       assert(len > 0);
+
        memset(&msg, 0, sizeof(msg));
 
        iov[0].iov_base = (void *) buf;
@@ -321,6 +333,10 @@ ssize_t lttcomm_send_unix_sock_non_block(int sock, const void *buf, size_t len)
        struct iovec iov[1];
        ssize_t ret;
 
+       assert(sock);
+       assert(buf);
+       assert(len > 0);
+
        memset(&msg, 0, sizeof(msg));
 
        iov[0].iov_base = (void *) buf;
@@ -395,6 +411,10 @@ ssize_t lttcomm_send_fds_unix_sock(int sock, const int *fds, size_t nb_fd)
        char tmp[CMSG_SPACE(sizeof_fds)];
        char dummy = 0;
 
+       assert(sock);
+       assert(fds);
+       assert(nb_fd > 0);
+
        memset(&msg, 0, sizeof(msg));
        memset(tmp, 0, sizeof(tmp));
 
@@ -525,6 +545,10 @@ ssize_t lttcomm_send_fds_unix_sock_non_block(int sock, const int *fds, size_t nb
        char tmp[CMSG_SPACE(sizeof_fds)];
        char dummy = 0;
 
+       assert(sock);
+       assert(fds);
+       assert(nb_fd > 0);
+
        memset(&msg, 0, sizeof(msg));
        memset(tmp, 0, sizeof(tmp));
 
@@ -614,6 +638,10 @@ ssize_t lttcomm_recv_fds_unix_sock(int sock, int *fds, size_t nb_fd)
        struct msghdr msg;
        char dummy;
 
+       assert(sock);
+       assert(fds);
+       assert(nb_fd > 0);
+
        memset(&msg, 0, sizeof(msg));
 
        /* Prepare to receive the structures */
@@ -763,6 +791,10 @@ ssize_t _lttcomm_recv_payload_fds_unix_sock(int sock, size_t nb_fd,
        int default_value = -1;
        struct lttng_dynamic_array raw_fds;
 
+       assert(sock);
+       assert(payload);
+       assert(nb_fd > 0);
+
        lttng_dynamic_array_init(&raw_fds, sizeof(int), close_raw_fd);
 
        for (i = 0; i < nb_fd; i++) {
@@ -829,6 +861,10 @@ ssize_t lttcomm_recv_fds_unix_sock_non_block(int sock, int *fds, size_t nb_fd)
        struct cmsghdr *cmsg;
        size_t sizeof_fds = nb_fd * sizeof(int);
 
+       assert(sock);
+       assert(fds);
+       assert(nb_fd > 0);
+
 #ifdef __linux__
 /* Account for the struct ucred cmsg in the buffer size */
 #define LTTNG_SOCK_RECV_FDS_BUF_SIZE CMSG_SPACE(sizeof_fds) + CMSG_SPACE(sizeof(struct ucred))
@@ -967,6 +1003,10 @@ ssize_t lttcomm_send_creds_unix_sock(int sock, const void *buf, size_t len)
 
        memset(&msg, 0, sizeof(msg));
 
+       assert(sock);
+       assert(buf);
+       assert(len > 0);
+
        iov[0].iov_base = (void *) buf;
        iov[0].iov_len = len;
        msg.msg_iov = iov;
@@ -1025,13 +1065,12 @@ ssize_t lttcomm_recv_creds_unix_sock(int sock, void *buf, size_t len,
        char anc_buf[CMSG_SPACE(sizeof_cred)];
 #endif /* __linux__ */
 
-       memset(&msg, 0, sizeof(msg));
+       assert(sock);
+       assert(buf);
+       assert(len > 0);
+       assert(creds);
 
-       /* Not allowed */
-       if (creds == NULL) {
-               ret = -1;
-               goto end;
-       }
+       memset(&msg, 0, sizeof(msg));
 
        /* Prepare to receive the structures */
        iov[0].iov_base = buf;
This page took 0.039709 seconds and 4 git commands to generate.