X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fhealth.c;fp=src%2Fbin%2Flttng-sessiond%2Fhealth.c;h=0000000000000000000000000000000000000000;hp=7fc557da5f8d28164af0cc9129d89768bda9949f;hb=7966af5763c4aaca39df9bbfa9277ff15715c720;hpb=3a5f70173aa04d11ccb22694d5d31a702cad33ab diff --git a/src/bin/lttng-sessiond/health.c b/src/bin/lttng-sessiond/health.c deleted file mode 100644 index 7fc557da5..000000000 --- a/src/bin/lttng-sessiond/health.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (C) 2012 David Goulet - * Copyright (C) 2018 Jérémie Galarneau - * - * SPDX-License-Identifier: GPL-2.0-only - * - */ - -#include "lttng-sessiond.h" -#include "health-sessiond.h" -#include -#include -#include -#include -#include -#include -#include "utils.h" -#include "thread.h" - -struct thread_notifiers { - struct lttng_pipe *quit_pipe; - sem_t ready; -}; - -static -void mark_thread_as_ready(struct thread_notifiers *notifiers) -{ - DBG("Marking health management thread as ready"); - sem_post(¬ifiers->ready); -} - -static -void wait_until_thread_is_ready(struct thread_notifiers *notifiers) -{ - DBG("Waiting for health management thread to be ready"); - sem_wait(¬ifiers->ready); - DBG("Health management thread is ready"); -} - -static void cleanup_health_management_thread(void *data) -{ - struct thread_notifiers *notifiers = data; - - lttng_pipe_destroy(notifiers->quit_pipe); - sem_destroy(¬ifiers->ready); - free(notifiers); -} - -/* - * Thread managing health check socket. - */ -static void *thread_manage_health(void *data) -{ - const bool is_root = (getuid() == 0); - int sock = -1, new_sock = -1, ret, i, pollfd, err = -1; - uint32_t revents, nb_fd; - struct lttng_poll_event events; - struct health_comm_msg msg; - struct health_comm_reply reply; - /* Thread-specific quit pipe. */ - struct thread_notifiers *notifiers = data; - const int quit_pipe_read_fd = lttng_pipe_get_readfd( - notifiers->quit_pipe); - - DBG("[thread] Manage health check started"); - - rcu_register_thread(); - - /* - * Created with a size of two for: - * - client socket - * - thread quit pipe - */ - ret = lttng_poll_create(&events, 2, LTTNG_CLOEXEC); - if (ret < 0) { - goto error; - } - - /* Create unix socket */ - sock = lttcomm_create_unix_sock(the_config.health_unix_sock_path.value); - if (sock < 0) { - ERR("Unable to create health check Unix socket"); - goto error; - } - - if (is_root) { - /* lttng health client socket path permissions */ - gid_t gid; - - ret = utils_get_group_id(the_config.tracing_group_name.value, true, &gid); - if (ret) { - /* Default to root group. */ - gid = 0; - } - - ret = chown(the_config.health_unix_sock_path.value, 0, gid); - if (ret < 0) { - ERR("Unable to set group on %s", the_config.health_unix_sock_path.value); - PERROR("chown"); - goto error; - } - - ret = chmod(the_config.health_unix_sock_path.value, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); - if (ret < 0) { - ERR("Unable to set permissions on %s", the_config.health_unix_sock_path.value); - PERROR("chmod"); - goto error; - } - } - - /* - * Set the CLOEXEC flag. Return code is useless because either way, the - * show must go on. - */ - (void) utils_set_fd_cloexec(sock); - - ret = lttcomm_listen_unix_sock(sock); - if (ret < 0) { - goto error; - } - - ret = lttng_poll_add(&events, quit_pipe_read_fd, LPOLLIN | LPOLLERR); - if (ret < 0) { - goto error; - } - - /* Add the application registration socket */ - ret = lttng_poll_add(&events, sock, LPOLLIN | LPOLLPRI); - if (ret < 0) { - goto error; - } - - mark_thread_as_ready(notifiers); - while (1) { - DBG("Health check ready"); - - /* Infinite blocking call, waiting for transmission */ -restart: - ret = lttng_poll_wait(&events, -1); - if (ret < 0) { - /* - * Restart interrupted system call. - */ - if (errno == EINTR) { - goto restart; - } - goto error; - } - - nb_fd = ret; - - for (i = 0; i < nb_fd; i++) { - /* Fetch once the poll data */ - revents = LTTNG_POLL_GETEV(&events, i); - pollfd = LTTNG_POLL_GETFD(&events, i); - - /* Event on the registration socket */ - if (pollfd == sock) { - 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; - } - } else { - /* Event on the thread's quit pipe. */ - err = 0; - goto exit; - } - } - - new_sock = lttcomm_accept_unix_sock(sock); - if (new_sock < 0) { - goto error; - } - - /* - * Set the CLOEXEC flag. Return code is useless because either way, the - * show must go on. - */ - (void) utils_set_fd_cloexec(new_sock); - - DBG("Receiving data from client for health..."); - ret = lttcomm_recv_unix_sock(new_sock, (void *)&msg, sizeof(msg)); - if (ret <= 0) { - DBG("Nothing recv() from client... continuing"); - ret = close(new_sock); - if (ret) { - PERROR("close"); - } - continue; - } - - rcu_thread_online(); - - memset(&reply, 0, sizeof(reply)); - for (i = 0; i < NR_HEALTH_SESSIOND_TYPES; i++) { - /* - * health_check_state returns 0 if health is - * bad. - */ - if (!health_check_state(the_health_sessiond, i)) { - reply.ret_code |= 1ULL << i; - } - } - - DBG2("Health check return value %" PRIx64, reply.ret_code); - - ret = lttcomm_send_unix_sock(new_sock, (void *) &reply, - sizeof(reply)); - if (ret < 0) { - ERR("Failed to send health data back to client"); - } - - /* End of transmission */ - ret = close(new_sock); - if (ret) { - PERROR("close"); - } - } - -exit: -error: - if (err) { - ERR("Health error occurred in %s", __func__); - } - DBG("Health check thread dying"); - unlink(the_config.health_unix_sock_path.value); - if (sock >= 0) { - ret = close(sock); - if (ret) { - PERROR("close"); - } - } - - lttng_poll_clean(&events); - rcu_unregister_thread(); - return NULL; -} - -static bool shutdown_health_management_thread(void *data) -{ - struct thread_notifiers *notifiers = data; - const int write_fd = lttng_pipe_get_writefd(notifiers->quit_pipe); - - return notify_thread_pipe(write_fd) == 1; -} - -bool launch_health_management_thread(void) -{ - struct thread_notifiers *notifiers; - struct lttng_thread *thread; - - notifiers = zmalloc(sizeof(*notifiers)); - if (!notifiers) { - goto error_alloc; - } - - sem_init(¬ifiers->ready, 0, 0); - notifiers->quit_pipe = lttng_pipe_open(FD_CLOEXEC); - if (!notifiers->quit_pipe) { - goto error; - } - thread = lttng_thread_create("Health management", - thread_manage_health, - shutdown_health_management_thread, - cleanup_health_management_thread, - notifiers); - if (!thread) { - goto error; - } - - wait_until_thread_is_ready(notifiers); - lttng_thread_put(thread); - return true; -error: - cleanup_health_management_thread(notifiers); -error_alloc: - return false; -}