Revert "Fix: sessiond: erroneous user check logic in session_access_ok"
[lttng-tools.git] / src / bin / lttng-consumerd / health-consumerd.c
index 062e46b9343adda4da3d1edf9a5453eee465535f..ffa0f3d0df2651993196dbe0cd86858955719561 100644 (file)
@@ -1,21 +1,11 @@
 /*
- * Copyright (C) 2013 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * Copyright (C) 2013 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, version 2 only,
- * as published by the Free Software Foundation.
+ * SPDX-License-Identifier: GPL-2.0-only
  *
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#define _GNU_SOURCE
+#define _LGPL_SOURCE
 #include <fcntl.h>
 #include <getopt.h>
 #include <grp.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>
@@ -118,8 +108,6 @@ int setup_health_path(void)
                        goto end;
                }
        } else {
-               static char *rundir;
-
                home_path = utils_get_home_dir();
                if (home_path == NULL) {
                        /* TODO: Add --socket PATH option */
@@ -128,16 +116,6 @@ int setup_health_path(void)
                        goto end;
                }
 
-               /*
-                * Create rundir from home path. This will create something like
-                * $HOME/.lttng
-                */
-               ret = asprintf(&rundir, DEFAULT_LTTNG_HOME_RUNDIR, home_path);
-               if (ret < 0) {
-                       ret = -ENOMEM;
-                       goto end;
-               }
-
                /* Set health check Unix path */
                if (strlen(health_unix_sock_path) != 0) {
                        goto end;
@@ -145,22 +123,21 @@ int setup_health_path(void)
                switch (type) {
                case LTTNG_CONSUMER_KERNEL:
                        snprintf(health_unix_sock_path, sizeof(health_unix_sock_path),
-                               DEFAULT_HOME_KCONSUMER_HEALTH_UNIX_SOCK, rundir);
+                               DEFAULT_HOME_KCONSUMER_HEALTH_UNIX_SOCK, home_path);
                        break;
                case LTTNG_CONSUMER64_UST:
                        snprintf(health_unix_sock_path, sizeof(health_unix_sock_path),
-                               DEFAULT_HOME_USTCONSUMER64_HEALTH_UNIX_SOCK, rundir);
+                               DEFAULT_HOME_USTCONSUMER64_HEALTH_UNIX_SOCK, home_path);
                        break;
                case LTTNG_CONSUMER32_UST:
                        snprintf(health_unix_sock_path, sizeof(health_unix_sock_path),
-                               DEFAULT_HOME_USTCONSUMER32_HEALTH_UNIX_SOCK, rundir);
+                               DEFAULT_HOME_USTCONSUMER32_HEALTH_UNIX_SOCK, home_path);
                        break;
                default:
                        ret = -EINVAL;
                        goto end;
                }
        }
-
 end:
        return ret;
 }
@@ -175,6 +152,7 @@ void *thread_manage_health(void *data)
        struct lttng_poll_event events;
        struct health_comm_msg msg;
        struct health_comm_reply reply;
+       int is_root;
 
        DBG("[thread] Manage health check started");
 
@@ -189,10 +167,39 @@ 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 */
+               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");
+                       err = -1;
+                       goto error;
+               }
+
+               ret = chmod(health_unix_sock_path,
+                               S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+               if (ret < 0) {
+                       ERR("Unable to set permissions on %s", health_unix_sock_path);
+                       PERROR("chmod");
+                       err = -1;
+                       goto error;
+               }
+       }
+
        /*
         * Set the CLOEXEC flag. Return code is useless because either way, the
         * show must go on.
@@ -222,6 +229,10 @@ void *thread_manage_health(void *data)
                goto error;
        }
 
+       /* Perform prior memory accesses before decrementing ready */
+       cmm_smp_mb__before_uatomic_dec();
+       uatomic_dec(&lttng_consumer_ready);
+
        while (1) {
                DBG("Health check ready");
 
@@ -254,7 +265,8 @@ restart:
 
                        /* Event on the registration socket */
                        if (pollfd == sock) {
-                               if (revents & (LPOLLERR | LPOLLHUP | LPOLLRDHUP)) {
+                               if (revents & (LPOLLERR | LPOLLHUP | LPOLLRDHUP)
+                                               && !(revents & LPOLLIN)) {
                                        ERR("Health socket poll error");
                                        goto error;
                                }
@@ -288,47 +300,18 @@ restart:
 
                assert(msg.cmd == HEALTH_CMD_CHECK);
 
-               switch (msg.component) {
-               case LTTNG_HEALTH_CONSUMERD_CHANNEL:
-                       reply.ret_code = health_check_state(health_consumerd, HEALTH_CONSUMERD_TYPE_CHANNEL);
-                       break;
-               case LTTNG_HEALTH_CONSUMERD_METADATA:
-                       reply.ret_code = health_check_state(health_consumerd, HEALTH_CONSUMERD_TYPE_METADATA);
-                       break;
-               case LTTNG_HEALTH_CONSUMERD_DATA:
-                       reply.ret_code = health_check_state(health_consumerd, HEALTH_CONSUMERD_TYPE_DATA);
-                       break;
-               case LTTNG_HEALTH_CONSUMERD_SESSIOND:
-                       reply.ret_code = health_check_state(health_consumerd, HEALTH_CONSUMERD_TYPE_SESSIOND);
-                       break;
-               case LTTNG_HEALTH_CONSUMERD_METADATA_TIMER:
-                       reply.ret_code = health_check_state(health_consumerd, HEALTH_CONSUMERD_TYPE_METADATA_TIMER);
-                       break;
-
-               case LTTNG_HEALTH_CONSUMERD_ALL:
-                       reply.ret_code =
-                               health_check_state(health_consumerd, HEALTH_CONSUMERD_TYPE_CHANNEL) &&
-                               health_check_state(health_consumerd, HEALTH_CONSUMERD_TYPE_METADATA) &&
-                               health_check_state(health_consumerd, HEALTH_CONSUMERD_TYPE_DATA) &&
-                               health_check_state(health_consumerd, HEALTH_CONSUMERD_TYPE_SESSIOND) &&
-                               health_check_state(health_consumerd, HEALTH_CONSUMERD_TYPE_METADATA_TIMER);
-                       break;
-               default:
-                       reply.ret_code = LTTNG_ERR_UND;
-                       break;
-               }
-
-               /*
-                * Flip ret value since 0 is a success and 1 indicates a bad health for
-                * the client where in the sessiond it is the opposite. Again, this is
-                * just to make things easier for us poor developer which enjoy a lot
-                * lazyness.
-                */
-               if (reply.ret_code == 0 || reply.ret_code == 1) {
-                       reply.ret_code = !reply.ret_code;
+               memset(&reply, 0, sizeof(reply));
+               for (i = 0; i < NR_HEALTH_CONSUMERD_TYPES; i++) {
+                       /*
+                        * health_check_state return 0 if thread is in
+                        * error.
+                        */
+                       if (!health_check_state(health_consumerd, i)) {
+                               reply.ret_code |= 1ULL << i;
+                       }
                }
 
-               DBG2("Health check return value %d", reply.ret_code);
+               DBG("Health check return value %" PRIx64, reply.ret_code);
 
                ret = send_unix_sock(new_sock, (void *) &reply, sizeof(reply));
                if (ret < 0) {
This page took 0.026438 seconds and 4 git commands to generate.