X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fmain.c;h=3feb3298927218354ea6e8d0974d46499f325ee6;hb=25258405ed9590fcbcfb02c10dd8c018dba3a7bd;hp=6113f49ade90cea6e02e7a4c74c296fa82acdbc1;hpb=3c515f4d801e86fda78630aea2a4ec74454a3e5a;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index 6113f49ad..3feb32989 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -291,7 +291,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 4 +#define NR_LTTNG_SESSIOND_READY 5 int lttng_sessiond_ready = NR_LTTNG_SESSIOND_READY; int sessiond_check_thread_quit_pipe(int fd, uint32_t events) @@ -599,21 +599,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 @@ -1270,6 +1255,7 @@ restart: if (!cmd_socket_wrapper) { goto error; } + cmd_socket_wrapper->lock = &consumer_data->lock; ret = consumer_send_channel_monitor_pipe(cmd_socket_wrapper, consumer_data->channel_monitor_pipe); @@ -2450,20 +2436,18 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data) if (!tmp) { tmp = ""; } - tmplen = strlen("LD_LIBRARY_PATH=") - + strlen(config.consumerd64_lib_dir.value) + 1 /* : */ + strlen(tmp); + tmplen = strlen(config.consumerd64_lib_dir.value) + 1 /* : */ + strlen(tmp); tmpnew = zmalloc(tmplen + 1 /* \0 */); if (!tmpnew) { ret = -ENOMEM; goto error; } - strcpy(tmpnew, "LD_LIBRARY_PATH="); strcat(tmpnew, config.consumerd64_lib_dir.value); if (tmp[0] != '\0') { strcat(tmpnew, ":"); strcat(tmpnew, tmp); } - ret = putenv(tmpnew); + ret = setenv("LD_LIBRARY_PATH", tmpnew, 1); if (ret) { ret = -errno; free(tmpnew); @@ -2491,20 +2475,18 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data) if (!tmp) { tmp = ""; } - tmplen = strlen("LD_LIBRARY_PATH=") - + strlen(config.consumerd32_lib_dir.value) + 1 /* : */ + strlen(tmp); + tmplen = strlen(config.consumerd32_lib_dir.value) + 1 /* : */ + strlen(tmp); tmpnew = zmalloc(tmplen + 1 /* \0 */); if (!tmpnew) { ret = -ENOMEM; goto error; } - strcpy(tmpnew, "LD_LIBRARY_PATH="); strcat(tmpnew, config.consumerd32_lib_dir.value); if (tmp[0] != '\0') { strcat(tmpnew, ":"); strcat(tmpnew, tmp); } - ret = putenv(tmpnew); + ret = setenv("LD_LIBRARY_PATH", tmpnew, 1); if (ret) { ret = -errno; free(tmpnew); @@ -4305,12 +4287,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; @@ -4723,7 +4734,7 @@ static int set_option(int opt, const char *arg, const char *optname) } else if (string_match(optname, "no-kernel")) { config.no_kernel = true; } else if (string_match(optname, "quiet") || opt == 'q') { - lttng_opt_quiet = true; + config.quiet = true; } else if (string_match(optname, "verbose") || opt == 'v') { /* Verbose level can increase using multiple -v */ if (arg) { @@ -5126,18 +5137,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"); + } + } } /* @@ -5396,14 +5446,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. */ @@ -5524,6 +5566,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; @@ -5538,9 +5592,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); } } @@ -5579,12 +5636,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 */ @@ -5603,12 +5654,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; @@ -5639,19 +5684,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. @@ -6063,6 +6095,7 @@ exit_health_sessiond_cleanup: exit_create_run_as_worker_cleanup: exit_options: + sessiond_cleanup_lock_file(); sessiond_cleanup_options(); exit_set_signal_handler: