X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=ltt-sessiond%2Fmain.c;h=91f79b3c5cdfc363de10dd080550cc251eb6a330;hp=a3335292bc0760746a701f0426d79a6a011dd34a;hb=90014c57e763d8c3f10148800bfb8461a66fb987;hpb=0177d773712c6d6b11e395708ae2cc686d6917a4 diff --git a/ltt-sessiond/main.c b/ltt-sessiond/main.c index a3335292b..91f79b3c5 100644 --- a/ltt-sessiond/main.c +++ b/ltt-sessiond/main.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2011 - David Goulet - * Copyright (C) 2011 - Mathieu Desnoyers + * Mathieu Desnoyers * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -29,11 +29,14 @@ #include #include #include +#include #include #include #include #include #include +#include +#include #include #include @@ -45,6 +48,7 @@ #include "futex.h" #include "kernel-ctl.h" #include "ltt-sessiond.h" +#include "shm.h" #include "traceable-app.h" #include "ust-ctl.h" #include "utils.h" @@ -75,6 +79,7 @@ static char apps_unix_sock_path[PATH_MAX]; /* Global application Unix socket static char client_unix_sock_path[PATH_MAX]; /* Global client Unix socket path */ static char kconsumerd_err_unix_sock_path[PATH_MAX]; /* kconsumerd error Unix socket path */ static char kconsumerd_cmd_unix_sock_path[PATH_MAX]; /* kconsumerd command Unix socket path */ +static char wait_shm_path[PATH_MAX]; /* global wait shm path for UST */ /* Sockets and FDs */ static int client_sock; @@ -107,8 +112,6 @@ static sem_t kconsumerd_sem; static pthread_mutex_t kconsumerd_pid_mutex; /* Mutex to control kconsumerd pid assignation */ -static int modprobe_remove_kernel_modules(void); - /* * UST registration command queue. This queue is tied with a futex and uses a N * wakers / 1 waiter implemented and detailed in futex.c/.h @@ -130,6 +133,44 @@ static struct ust_cmd_queue ust_cmd_queue; */ static struct ltt_session_list *session_list_ptr; +/* + * Remove modules in reverse load order. + */ +static int modprobe_remove_kernel_modules(void) +{ + int ret = 0, i; + char modprobe[256]; + + for (i = ARRAY_SIZE(kernel_modules_list) - 1; i >= 0; i--) { + ret = snprintf(modprobe, sizeof(modprobe), + "/sbin/modprobe --remove --quiet %s", + kernel_modules_list[i].name); + if (ret < 0) { + perror("snprintf modprobe --remove"); + goto error; + } + modprobe[sizeof(modprobe) - 1] = '\0'; + ret = system(modprobe); + if (ret == -1) { + ERR("Unable to launch modprobe --remove for module %s", + kernel_modules_list[i].name); + } else if (kernel_modules_list[i].required + && WEXITSTATUS(ret) != 0) { + ERR("Unable to remove module %s", + kernel_modules_list[i].name); + } else { + DBG("Modprobe removal successful %s", + kernel_modules_list[i].name); + } + } + +error: + return ret; +} + +/* + * Return group ID of the tracing group or -1 if not found. + */ static gid_t allowed_group(void) { struct group *grp; @@ -405,37 +446,30 @@ error: return ret; } -#ifdef DISABLED /* - * Notify apps by writing 42 to a named pipe using name. Every applications - * waiting for a ltt-sessiond will be notified and re-register automatically to - * the session daemon. - * - * Return open or write error value. + * Notify UST applications using the shm mmap futex. */ -static int notify_apps(const char *name) +static int notify_ust_apps(int active) { - int fd; - int ret = -1; + char *wait_shm_mmap; - DBG("Notify the global application pipe"); + DBG("Notifying applications of session daemon state: %d", active); - /* Try opening the global pipe */ - fd = open(name, O_WRONLY); - if (fd < 0) { + /* See shm.c for this call implying mmap, shm and futex calls */ + wait_shm_mmap = shm_ust_get_mmap(wait_shm_path, is_root); + if (wait_shm_mmap == NULL) { goto error; } - /* Notify by writing on the pipe */ - ret = write(fd, "42", 2); - if (ret < 0) { - perror("write"); - } + /* Wake waiting process */ + futex_wait_update((int32_t *) wait_shm_mmap, active); + + /* Apps notified successfully */ + return 0; error: - return ret; + return -1; } -#endif /* DISABLED */ /* * Setup the outgoing data buffer for the response (llm) by allocating the @@ -533,6 +567,8 @@ static int update_kernel_pollfd(void) /* Adding the quit pipe */ kernel_pollfd[nb_fd - 1].fd = thread_quit_pipe[0]; + kernel_pollfd[nb_fd - 1].events = + POLLHUP | POLLNVAL | POLLERR | POLLIN | POLLRDHUP | POLLPRI; return nb_fd; @@ -633,6 +669,8 @@ static void *thread_manage_kernel(void *data) goto error; } else if (ret == 0) { /* Should not happen since timeout is infinite */ + ERR("Return value of poll is 0 with an infinite timeout.\n" + "This should not have happened! Continuing..."); continue; } @@ -826,6 +864,9 @@ static int update_apps_cmd_pollfd(unsigned int nb_fd, unsigned int old_nb_fd, /* First fd is always the quit pipe */ (*pollfd)[0].fd = thread_quit_pipe[0]; + (*pollfd)[0].events = + POLLHUP | POLLNVAL | POLLERR | POLLIN | POLLRDHUP | POLLPRI; + /* Apps command pipe */ (*pollfd)[1].fd = apps_cmd_pipe[0]; (*pollfd)[1].events = POLLIN; @@ -846,6 +887,16 @@ static int update_apps_cmd_pollfd(unsigned int nb_fd, unsigned int old_nb_fd, } } + if (nb_fd < 2) { + /* + * There should *always* be at least two fds in the pollfd. This safety + * check make sure the poll() will actually try on those two pipes at + * best which are the thread_quit_pipe and apps_cmd_pipe. + */ + nb_fd = 2; + MSG("nb_fd < 2 --> Not good! Continuing..."); + } + /* Destroy old pollfd */ free(old_pollfd); @@ -865,7 +916,7 @@ error: */ static void *thread_manage_apps(void *data) { - int i, ret, count; + int i, ret, current_nb_fd; unsigned int nb_fd = 2; int update_poll_flag = 1; struct pollfd *pollfd = NULL; @@ -874,6 +925,7 @@ static void *thread_manage_apps(void *data) DBG("[thread] Manage application started"); ust_cmd.sock = -1; + current_nb_fd = nb_fd; while (1) { /* See if we have a valid socket to add to pollfd */ @@ -884,7 +936,7 @@ static void *thread_manage_apps(void *data) /* The pollfd struct must be updated */ if (update_poll_flag) { - ret = update_apps_cmd_pollfd(nb_fd, ARRAY_SIZE(pollfd), &pollfd); + ret = update_apps_cmd_pollfd(nb_fd, current_nb_fd, &pollfd); if (ret < 0) { /* malloc failed so we quit */ goto error; @@ -944,8 +996,8 @@ static void *thread_manage_apps(void *data) } } - count = nb_fd; - for (i = 2; i < count; i++) { + current_nb_fd = nb_fd; + for (i = 2; i < current_nb_fd; i++) { /* Apps socket is closed/hungup */ switch (pollfd[i].revents) { case POLLERR: @@ -960,7 +1012,7 @@ static void *thread_manage_apps(void *data) } } - if (nb_fd != count) { + if (nb_fd != current_nb_fd) { update_poll_flag = 1; } } @@ -1061,13 +1113,20 @@ static void *thread_registration_apps(void *data) /* First fd is always the quit pipe */ pollfd[0].fd = thread_quit_pipe[0]; + pollfd[0].events = + POLLHUP | POLLNVAL | POLLERR | POLLIN | POLLRDHUP | POLLPRI; /* Apps socket */ pollfd[1].fd = apps_sock; pollfd[1].events = POLLIN; /* Notify all applications to register */ - //notify_apps(default_global_apps_pipe); + ret = notify_ust_apps(1); + if (ret < 0) { + ERR("Failed to notify applications or create the wait shared memory.\n" + "Execution continues but there might be problem for already running\n" + "applications that wishes to register."); + } while (1) { DBG("Accepting application registration"); @@ -1082,71 +1141,79 @@ static void *thread_registration_apps(void *data) /* Thread quit pipe has been closed. Killing thread. */ if (pollfd[0].revents == POLLNVAL) { goto error; - } else if (pollfd[1].revents == POLLERR) { - ERR("Register apps socket poll error"); - goto error; } - sock = lttcomm_accept_unix_sock(apps_sock); - if (sock < 0) { + switch (pollfd[1].revents) { + case POLLNVAL: + case POLLHUP: + case POLLRDHUP: + case POLLERR: + ERR("Register apps socket poll error"); goto error; - } + case POLLIN: + sock = lttcomm_accept_unix_sock(apps_sock); + if (sock < 0) { + goto error; + } - /* Create UST registration command for enqueuing */ - ust_cmd = malloc(sizeof(struct ust_command)); - if (ust_cmd == NULL) { - perror("ust command malloc"); - goto error; - } + /* Create UST registration command for enqueuing */ + ust_cmd = malloc(sizeof(struct ust_command)); + if (ust_cmd == NULL) { + perror("ust command malloc"); + goto error; + } - /* - * Using message-based transmissions to ensure we don't have to deal - * with partially received messages. - */ - ret = lttcomm_recv_unix_sock(sock, &ust_cmd->reg_msg, - sizeof(struct ust_register_msg)); - if (ret < 0 || ret < sizeof(struct ust_register_msg)) { - if (ret < 0) { - perror("lttcomm_recv_unix_sock register apps"); - } else { - ERR("Wrong size received on apps register"); + /* + * Using message-based transmissions to ensure we don't have to deal + * with partially received messages. + */ + ret = lttcomm_recv_unix_sock(sock, &ust_cmd->reg_msg, + sizeof(struct ust_register_msg)); + if (ret < 0 || ret < sizeof(struct ust_register_msg)) { + if (ret < 0) { + perror("lttcomm_recv_unix_sock register apps"); + } else { + ERR("Wrong size received on apps register"); + } + free(ust_cmd); + close(sock); + continue; } - free(ust_cmd); - close(sock); - continue; - } - ust_cmd->sock = sock; + ust_cmd->sock = sock; - DBG("UST registration received with pid:%d ppid:%d uid:%d" - " gid:%d sock:%d name:%s (version %d.%d)", - ust_cmd->reg_msg.pid, ust_cmd->reg_msg.ppid, - ust_cmd->reg_msg.uid, ust_cmd->reg_msg.gid, - ust_cmd->sock, ust_cmd->reg_msg.name, - ust_cmd->reg_msg.major, ust_cmd->reg_msg.minor); - /* - * Lock free enqueue the registration request. - * The red pill has been taken! This apps will be part of the *system* - */ - cds_wfq_enqueue(&ust_cmd_queue.queue, &ust_cmd->node); + DBG("UST registration received with pid:%d ppid:%d uid:%d" + " gid:%d sock:%d name:%s (version %d.%d)", + ust_cmd->reg_msg.pid, ust_cmd->reg_msg.ppid, + ust_cmd->reg_msg.uid, ust_cmd->reg_msg.gid, + ust_cmd->sock, ust_cmd->reg_msg.name, + ust_cmd->reg_msg.major, ust_cmd->reg_msg.minor); + /* + * Lock free enqueue the registration request. + * The red pill has been taken! This apps will be part of the *system* + */ + cds_wfq_enqueue(&ust_cmd_queue.queue, &ust_cmd->node); - /* - * Wake the registration queue futex. - * Implicit memory barrier with the exchange in cds_wfq_enqueue. - */ - futex_nto1_wake(&ust_cmd_queue.futex); + /* + * Wake the registration queue futex. + * Implicit memory barrier with the exchange in cds_wfq_enqueue. + */ + futex_nto1_wake(&ust_cmd_queue.futex); + break; + } } error: - DBG("Register apps thread dying"); - if (apps_sock) { - close(apps_sock); - } - if (sock) { - close(sock); - } + DBG("UST Registration thread dying"); + + /* Notify that the registration thread is gone */ + notify_ust_apps(0); + + close(apps_sock); + close(sock); unlink(apps_unix_sock_path); + return NULL; } @@ -1320,42 +1387,6 @@ error: return ret; } -/* - * modprobe_remove_kernel_modules - * Remove modules in reverse load order. - */ -static int modprobe_remove_kernel_modules(void) -{ - int ret = 0, i; - char modprobe[256]; - - for (i = ARRAY_SIZE(kernel_modules_list) - 1; i >= 0; i--) { - ret = snprintf(modprobe, sizeof(modprobe), - "/sbin/modprobe --remove --quiet %s", - kernel_modules_list[i].name); - if (ret < 0) { - perror("snprintf modprobe --remove"); - goto error; - } - modprobe[sizeof(modprobe) - 1] = '\0'; - ret = system(modprobe); - if (ret == -1) { - ERR("Unable to launch modprobe --remove for module %s", - kernel_modules_list[i].name); - } else if (kernel_modules_list[i].required - && WEXITSTATUS(ret) != 0) { - ERR("Unable to remove module %s", - kernel_modules_list[i].name); - } else { - DBG("Modprobe removal successful %s", - kernel_modules_list[i].name); - } - } - -error: - return ret; -} - /* * mount_debugfs */ @@ -1788,6 +1819,8 @@ static int process_client_msg(struct command_ctx *cmd_ctx) } } break; + case LTTNG_DOMAIN_UST_PID: + break; default: break; } @@ -1999,6 +2032,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) kernel_wait_quiescent(kernel_tracer_fd); break; case LTTNG_DOMAIN_UST_PID: + break; default: ret = LTTCOMM_NOT_IMPLEMENTED; @@ -2602,6 +2636,8 @@ static void *thread_manage_clients(void *data) /* First fd is always the quit pipe */ pollfd[0].fd = thread_quit_pipe[0]; + pollfd[0].events = + POLLHUP | POLLNVAL | POLLERR | POLLIN | POLLRDHUP | POLLPRI; /* Apps socket */ pollfd[1].fd = client_sock; @@ -3134,6 +3170,12 @@ int main(int argc, char **argv) snprintf(client_unix_sock_path, PATH_MAX, DEFAULT_GLOBAL_CLIENT_UNIX_SOCK); } + + /* Set global SHM for ust */ + if (strlen(wait_shm_path) == 0) { + snprintf(wait_shm_path, PATH_MAX, + DEFAULT_GLOBAL_APPS_WAIT_SHM_PATH); + } } else { home_path = get_home_dir(); if (home_path == NULL) { @@ -3153,6 +3195,12 @@ int main(int argc, char **argv) snprintf(client_unix_sock_path, PATH_MAX, DEFAULT_HOME_CLIENT_UNIX_SOCK, home_path); } + + /* Set global SHM for ust */ + if (strlen(wait_shm_path) == 0) { + snprintf(wait_shm_path, PATH_MAX, + DEFAULT_HOME_APPS_WAIT_SHM_PATH, geteuid()); + } } DBG("Client socket path %s", client_unix_sock_path);