relayd: track clients of the health unix socket with the fd-tracker
[lttng-tools.git] / src / bin / lttng-relayd / health-relayd.c
index af375e26d4b049d5d3d2f0be75c6e302f7a95c10..bf3bb8d82cd48bc3fb4ff02a7b56b198aa7ba881 100644 (file)
@@ -15,7 +15,6 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#define _GNU_SOURCE
 #define _LGPL_SOURCE
 #include <fcntl.h>
 #include <getopt.h>
 #include <unistd.h>
 #include <sys/mman.h>
 #include <assert.h>
-#include <config.h>
 #include <urcu/compiler.h>
-#include <ulimit.h>
 #include <inttypes.h>
 
 #include <common/defaults.h>
 #include <common/common.h>
-#include <common/consumer.h>
-#include <common/consumer-timer.h>
+#include <common/consumer/consumer.h>
+#include <common/consumer/consumer-timer.h>
 #include <common/compat/poll.h>
 #include <common/sessiond-comm/sessiond-comm.h>
 #include <common/utils.h>
+#include <common/compat/getenv.h>
+#include <common/fd-tracker/utils.h>
 
 #include "lttng-relayd.h"
 #include "health-relayd.h"
@@ -57,7 +56,7 @@
 static
 char health_unix_sock_path[PATH_MAX];
 
-int health_quit_pipe[2];
+int health_quit_pipe[2] = { -1, -1 };
 
 /*
  * Check if the thread quit pipe was triggered.
@@ -107,8 +106,15 @@ static int create_lttng_rundir_with_perm(const char *rundir)
                int is_root = !getuid();
 
                if (is_root) {
-                       ret = chown(rundir, 0,
-                                       utils_get_group_id(tracing_group_name));
+                       gid_t gid;
+
+                       ret = utils_get_group_id(tracing_group_name, true, &gid);
+                       if (ret) {
+                               /* Default to root group. */
+                               gid = 0;
+                       }
+
+                       ret = chown(rundir, 0, gid);
                        if (ret < 0) {
                                ERR("Unable to set group on %s", rundir);
                                PERROR("chown");
@@ -136,7 +142,7 @@ int parse_health_env(void)
 {
        const char *health_path;
 
-       health_path = getenv(LTTNG_RELAYD_HEALTH_ENV);
+       health_path = lttng_secure_getenv(LTTNG_RELAYD_HEALTH_ENV);
        if (health_path) {
                strncpy(health_unix_sock_path, health_path,
                        PATH_MAX);
@@ -150,7 +156,8 @@ static
 int setup_health_path(void)
 {
        int is_root, ret = 0;
-       char *home_path = NULL, *rundir = NULL, *relayd_path;
+       const char *home_path = NULL;
+       char *rundir = NULL, *relayd_path = NULL;
 
        ret = parse_health_env();
        if (ret) {
@@ -208,7 +215,7 @@ int setup_health_path(void)
                }
                snprintf(health_unix_sock_path, sizeof(health_unix_sock_path),
                        DEFAULT_GLOBAL_RELAY_HEALTH_UNIX_SOCK,
-                       getpid());
+                       (int) getpid());
        } else {
                /* Set health check Unix path */
                if (strlen(health_unix_sock_path) != 0) {
@@ -217,11 +224,29 @@ int setup_health_path(void)
 
                snprintf(health_unix_sock_path, sizeof(health_unix_sock_path),
                        DEFAULT_HOME_RELAY_HEALTH_UNIX_SOCK,
-                       home_path, getpid());
+                       home_path, (int) getpid());
        }
 
 end:
        free(rundir);
+       free(relayd_path);
+       return ret;
+}
+
+static
+int accept_unix_socket(void *data, int *out_fd)
+{
+       int ret;
+       int accepting_sock = *((int *) data);
+
+       ret = lttcomm_accept_unix_sock(accepting_sock);
+       if (ret < 0) {
+               goto end;
+       }
+
+       *out_fd = ret;
+       ret = 0;
+end:
        return ret;
 }
 
@@ -250,19 +275,26 @@ void *thread_manage_health(void *data)
        sock = lttcomm_create_unix_sock(health_unix_sock_path);
        if (sock < 0) {
                ERR("Unable to create health check Unix socket");
-               ret = -1;
+               err = -1;
                goto error;
        }
 
        is_root = !getuid();
        if (is_root) {
                /* lttng health client socket path permissions */
-               ret = chown(health_unix_sock_path, 0,
-                               utils_get_group_id(tracing_group_name));
+               gid_t gid;
+
+               ret = utils_get_group_id(tracing_group_name, true, &gid);
+               if (ret) {
+                       /* Default to root group. */
+                       gid = 0;
+               }
+
+               ret = chown(health_unix_sock_path, 0, gid);
                if (ret < 0) {
                        ERR("Unable to set group on %s", health_unix_sock_path);
                        PERROR("chown");
-                       ret = -1;
+                       err = -1;
                        goto error;
                }
 
@@ -271,7 +303,7 @@ void *thread_manage_health(void *data)
                if (ret < 0) {
                        ERR("Unable to set permissions on %s", health_unix_sock_path);
                        PERROR("chmod");
-                       ret = -1;
+                       err = -1;
                        goto error;
                }
        }
@@ -308,6 +340,8 @@ void *thread_manage_health(void *data)
        lttng_relay_notify_ready();
 
        while (1) {
+               char *accepted_socket_name;
+
                DBG("Health check ready");
 
                /* Inifinite blocking call, waiting for transmission */
@@ -339,15 +373,30 @@ restart:
 
                        /* Event on the registration socket */
                        if (pollfd == sock) {
-                               if (revents & (LPOLLERR | LPOLLHUP | LPOLLRDHUP)) {
+                               if (revents & LPOLLIN) {
+                                       continue;
+                               } else if (revents & (LPOLLERR | LPOLLHUP | LPOLLRDHUP)) {
                                        ERR("Health socket poll error");
                                        goto error;
+                               } else {
+                                       ERR("Unexpected poll events %u for sock %d", revents, pollfd);
+                                       goto error;
                                }
                        }
                }
 
-               new_sock = lttcomm_accept_unix_sock(sock);
-               if (new_sock < 0) {
+               ret = asprintf(&accepted_socket_name, "Socket accepted from unix socket @ %s",
+                               health_unix_sock_path);
+               if (ret == -1) {
+                       PERROR("Failed to allocate name of accepted socket from unix socket @ %s",
+                                       health_unix_sock_path);
+                       goto error;
+               }
+               ret = fd_tracker_open_unsuspendable_fd(the_fd_tracker, &new_sock,
+                               (const char **) &accepted_socket_name, 1,
+                               accept_unix_socket, &sock);
+               free(accepted_socket_name);
+               if (ret < 0) {
                        goto error;
                }
 
@@ -361,7 +410,9 @@ restart:
                ret = lttcomm_recv_unix_sock(new_sock, (void *)&msg, sizeof(msg));
                if (ret <= 0) {
                        DBG("Nothing recv() from client... continuing");
-                       ret = close(new_sock);
+                       ret = fd_tracker_close_unsuspendable_fd(the_fd_tracker,
+                                       &new_sock, 1, fd_tracker_util_close_fd,
+                                       NULL);
                        if (ret) {
                                PERROR("close");
                        }
@@ -392,15 +443,18 @@ restart:
                }
 
                /* End of transmission */
-               ret = close(new_sock);
+               ret = fd_tracker_close_unsuspendable_fd(the_fd_tracker,
+                               &new_sock, 1, fd_tracker_util_close_fd,
+                               NULL);
                if (ret) {
                        PERROR("close");
                }
                new_sock = -1;
        }
 
-exit:
 error:
+       lttng_relay_stop_threads();
+exit:
        if (err) {
                ERR("Health error occurred in %s", __func__);
        }
This page took 0.027608 seconds and 5 git commands to generate.