X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fmain.c;h=cec8e835e04881c20c65787c19a560bc19756c58;hb=79445cf0e236eb0f9c08ed535f719994b68632aa;hp=8e8b83b0f54a48d7d063f6cc668645ba804de7be;hpb=0dbc2034c9571ec342d382bf87231775563f8624;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index 8e8b83b0f..cec8e835e 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -304,7 +304,7 @@ struct lttng_ht *agent_apps_ht_by_sock = NULL; * NR_LTTNG_SESSIOND_READY must match the number of calls to * sessiond_notify_ready(). */ -#define NR_LTTNG_SESSIOND_READY 5 +#define NR_LTTNG_SESSIOND_READY 6 int lttng_sessiond_ready = NR_LTTNG_SESSIOND_READY; int sessiond_check_thread_quit_pipe(int fd, uint32_t events) @@ -631,21 +631,6 @@ static void sessiond_cleanup(void) free(load_info); } - /* - * Cleanup lock file by deleting it and finaly closing it which will - * release the file system lock. - */ - if (lockfile_fd >= 0) { - ret = remove(config.lock_file_path.value); - if (ret < 0) { - PERROR("remove lock file"); - } - ret = close(lockfile_fd); - if (ret < 0) { - PERROR("close lock file"); - } - } - /* * We do NOT rmdir rundir because there are other processes * using it, for instance lttng-relayd, which can start in @@ -4511,12 +4496,41 @@ static void *thread_manage_clients(void *data) } sessiond_notify_ready(); + ret = sem_post(&load_info->message_thread_ready); if (ret) { PERROR("sem_post message_thread_ready"); goto error; } + /* + * Wait until all support threads are initialized before accepting + * commands. + */ + while (uatomic_read(<tng_sessiond_ready) != 0) { + fd_set read_fds; + struct timeval timeout; + + FD_ZERO(&read_fds); + FD_SET(thread_quit_pipe[0], &read_fds); + memset(&timeout, 0, sizeof(timeout)); + timeout.tv_usec = 1000; + + /* + * If a support thread failed to launch, it may signal that + * we must exit and the sessiond would never be marked as + * "ready". + * + * The timeout is set to 1ms, which serves as a way to + * pace down this check. + */ + ret = select(thread_quit_pipe[0] + 1, &read_fds, NULL, NULL, + &timeout); + if (ret > 0 || (ret < 0 && errno != EINTR)) { + goto exit; + } + } + /* This testpoint is after we signal readiness to the parent. */ if (testpoint(sessiond_thread_manage_clients)) { goto error; @@ -5332,18 +5346,57 @@ end: return ret; } +/* + * Create lockfile using the rundir and return its fd. + */ +static int create_lockfile(void) +{ + return utils_create_lock_file(config.lock_file_path.value); +} + /* * Check if the global socket is available, and if a daemon is answering at the * other side. If yes, error is returned. + * + * Also attempts to create and hold the lock file. */ static int check_existing_daemon(void) { + int ret = 0; + /* Is there anybody out there ? */ if (lttng_session_daemon_alive()) { - return -EEXIST; + ret = -EEXIST; + goto end; } - return 0; + lockfile_fd = create_lockfile(); + if (lockfile_fd < 0) { + ret = -EEXIST; + goto end; + } +end: + return ret; +} + +static void sessiond_cleanup_lock_file(void) +{ + int ret; + + /* + * Cleanup lock file by deleting it and finaly closing it which will + * release the file system lock. + */ + if (lockfile_fd >= 0) { + ret = remove(config.lock_file_path.value); + if (ret < 0) { + PERROR("remove lock file"); + } + ret = close(lockfile_fd); + if (ret < 0) { + PERROR("close lock file"); + } + } } /* @@ -5602,14 +5655,6 @@ static int write_pidfile(void) return utils_create_pid_file(getpid(), config.pid_file_path.value); } -/* - * Create lockfile using the rundir and return its fd. - */ -static int create_lockfile(void) -{ - return utils_create_lock_file(config.lock_file_path.value); -} - /* * Write agent TCP port using the rundir. */ @@ -5701,9 +5746,9 @@ int main(int argc, char **argv) struct lttng_pipe *ust32_channel_monitor_pipe = NULL, *ust64_channel_monitor_pipe = NULL, *kernel_channel_monitor_pipe = NULL; - bool notification_thread_running = false; - bool rotation_thread_running = false; - bool timer_thread_running = false; + bool notification_thread_launched = false; + bool rotation_thread_launched = false; + bool timer_thread_launched = false; struct lttng_pipe *ust32_channel_rotate_pipe = NULL, *ust64_channel_rotate_pipe = NULL, *kernel_channel_rotate_pipe = NULL; @@ -5786,6 +5831,18 @@ int main(int argc, char **argv) sessiond_config_log(&config); + if (create_lttng_rundir()) { + retval = -1; + goto exit_options; + } + + /* Abort launch if a session daemon is already running. */ + if (check_existing_daemon()) { + ERR("A session daemon is already running."); + retval = -1; + goto exit_options; + } + /* Daemonize */ if (config.daemonize || config.background) { int i; @@ -5800,9 +5857,12 @@ int main(int argc, char **argv) /* * We are in the child. Make sure all other file descriptors are * closed, in case we are called with more opened file - * descriptors than the standard ones. + * descriptors than the standard ones and the lock file. */ for (i = 3; i < sysconf(_SC_OPEN_MAX); i++) { + if (i == lockfile_fd) { + continue; + } (void) close(i); } } @@ -5841,12 +5901,6 @@ int main(int argc, char **argv) /* Check if daemon is UID = 0 */ is_root = !getuid(); - - if (create_lttng_rundir()) { - retval = -1; - goto exit_init_data; - } - if (is_root) { /* Create global run dir with root access */ @@ -5878,12 +5932,6 @@ int main(int argc, char **argv) } } - lockfile_fd = create_lockfile(); - if (lockfile_fd < 0) { - retval = -1; - goto exit_init_data; - } - /* Set consumer initial state */ kernel_consumerd_state = CONSUMER_STOPPED; ust_consumerd_state = CONSUMER_STOPPED; @@ -5950,19 +5998,6 @@ int main(int argc, char **argv) goto exit_init_data; } - /* - * See if daemon already exist. - */ - if (check_existing_daemon()) { - ERR("Already running daemon.\n"); - /* - * We do not goto exit because we must not cleanup() - * because a daemon is already running. - */ - retval = -1; - goto exit_init_data; - } - /* * Init UST app hash table. Alloc hash table before this point since * cleanup() can get called after that point. @@ -6148,7 +6183,7 @@ int main(int argc, char **argv) stop_threads(); goto exit_notification; } - notification_thread_running = true; + notification_thread_launched = true; /* Create timer thread. */ ret = pthread_create(&timer_thread, default_pthread_attr(), @@ -6160,7 +6195,7 @@ int main(int argc, char **argv) stop_threads(); goto exit_notification; } - timer_thread_running = true; + timer_thread_launched = true; /* rotation_thread_data acquires the pipes' read side. */ rotation_thread_handle = rotation_thread_handle_create( @@ -6188,7 +6223,7 @@ int main(int argc, char **argv) stop_threads(); goto exit_rotation; } - rotation_thread_running = true; + rotation_thread_launched = true; /* Create thread to manage the client socket */ ret = pthread_create(&client_thread, default_pthread_attr(), @@ -6394,7 +6429,7 @@ exit_init_data: * of the active session and channels at the moment of the teardown. */ if (notification_thread_handle) { - if (notification_thread_running) { + if (notification_thread_launched) { notification_thread_command_quit( notification_thread_handle); ret = pthread_join(notification_thread, &status); @@ -6408,7 +6443,7 @@ exit_init_data: } if (rotation_thread_handle) { - if (rotation_thread_running) { + if (rotation_thread_launched) { ret = pthread_join(rotation_thread, &status); if (ret) { errno = ret; @@ -6419,7 +6454,7 @@ exit_init_data: rotation_thread_handle_destroy(rotation_thread_handle); } - if (timer_thread_running) { + if (timer_thread_launched) { kill(getpid(), LTTNG_SESSIOND_SIG_EXIT); ret = pthread_join(timer_thread, &status); if (ret) { @@ -6455,6 +6490,7 @@ exit_health_sessiond_cleanup: exit_create_run_as_worker_cleanup: exit_options: + sessiond_cleanup_lock_file(); sessiond_cleanup_options(); exit_set_signal_handler: