/*
- * 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>
goto end;
}
} else {
- static char *rundir;
-
home_path = utils_get_home_dir();
if (home_path == NULL) {
/* TODO: Add --socket PATH option */
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;
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;
}
struct lttng_poll_event events;
struct health_comm_msg msg;
struct health_comm_reply reply;
+ int is_root;
DBG("[thread] Manage health check started");
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.
goto error;
}
+ /* Perform prior memory accesses before decrementing ready */
+ cmm_smp_mb__before_uatomic_dec();
+ uatomic_dec(<tng_consumer_ready);
+
while (1) {
DBG("Health check ready");
/* 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;
}
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) {