X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;ds=sidebyside;f=ltt-sessiond%2Fmain.c;h=98bdb6a4d6912c8a97117a59c114a6d54ee065ae;hb=cf3af59ede4474f4e5123699ee2ee9ee85b7cadd;hp=5636700d8fad1cd3127c9c6571b03a648782261d;hpb=d0254c7c0bb43c62abafdf866b16de0da1ad4d5d;p=lttng-tools.git diff --git a/ltt-sessiond/main.c b/ltt-sessiond/main.c index 5636700d8..98bdb6a4d 100644 --- a/ltt-sessiond/main.c +++ b/ltt-sessiond/main.c @@ -146,10 +146,18 @@ static void teardown_kernel_session(struct ltt_session *session) } } +static void stop_threads(void) +{ + /* Stopping all threads */ + DBG("Terminating all threads"); + close(thread_quit_pipe[0]); + close(thread_quit_pipe[1]); +} + /* * Cleanup the daemon */ -static void cleanup() +static void cleanup(void) { int ret; char *cmd; @@ -163,11 +171,6 @@ static void cleanup() 27, 1, 31, 27, 0, 27, 1, 33, 27, 0); /* */ - /* Stopping all threads */ - DBG("Terminating all threads"); - close(thread_quit_pipe[0]); - close(thread_quit_pipe[1]); - DBG("Removing %s directory", LTTNG_RUNDIR); ret = asprintf(&cmd, "rm -rf " LTTNG_RUNDIR); if (ret < 0) { @@ -862,6 +865,23 @@ error: return ret; } +static int join_kconsumerd_thread(void) +{ + void *status; + int ret; + + if (kconsumerd_pid != 0) { + ret = kill(kconsumerd_pid, SIGTERM); + if (ret) { + ERR("Error killing kconsumerd"); + return ret; + } + return pthread_join(kconsumerd_thread, &status); + } else { + return 0; + } +} + /* * Fork and exec a kernel consumer daemon (kconsumerd). * @@ -2347,7 +2367,7 @@ static int parse_args(int argc, char **argv) * apps_sock - The communication socket for all UST apps. * client_sock - The communication of the cli tool (lttng). */ -static int init_daemon_socket() +static int init_daemon_socket(void) { int ret = 0; mode_t old_umask; @@ -2394,7 +2414,7 @@ end: /* * Check if the global socket is available. If yes, error is returned. */ -static int check_existing_daemon() +static int check_existing_daemon(void) { int ret; @@ -2536,26 +2556,27 @@ error: /* * Signal handler for the daemon + * + * Simply stop all worker threads, leaving main() return gracefully + * after joining all threads and calling cleanup(). */ static void sighandler(int sig) { switch (sig) { - case SIGPIPE: - DBG("SIGPIPE catched"); - return; - case SIGINT: - DBG("SIGINT catched"); - cleanup(); - break; - case SIGTERM: - DBG("SIGTERM catched"); - cleanup(); - break; - default: - break; + case SIGPIPE: + DBG("SIGPIPE catched"); + return; + case SIGINT: + DBG("SIGINT catched"); + stop_threads(); + break; + case SIGTERM: + DBG("SIGTERM catched"); + stop_threads(); + break; + default: + break; } - - exit(EXIT_SUCCESS); } /* @@ -2625,14 +2646,14 @@ int main(int argc, char **argv) const char *home_path; /* Create thread quit pipe */ - if (init_thread_quit_pipe() < 0) { - goto exit; + if ((ret = init_thread_quit_pipe()) < 0) { + goto error; } /* Parse arguments */ progname = argv[0]; if ((ret = parse_args(argc, argv) < 0)) { - goto exit; + goto error; } /* Daemonize */ @@ -2640,7 +2661,7 @@ int main(int argc, char **argv) ret = daemon(0, 0); if (ret < 0) { perror("daemon"); - goto exit; + goto error; } } @@ -2650,7 +2671,7 @@ int main(int argc, char **argv) if (is_root) { ret = create_lttng_rundir(); if (ret < 0) { - goto exit; + goto error; } if (strlen(apps_unix_sock_path) == 0) { @@ -2667,7 +2688,8 @@ int main(int argc, char **argv) if (home_path == NULL) { /* TODO: Add --socket PATH option */ ERR("Can't get HOME directory for sockets creation."); - goto exit; + ret = -EPERM; + goto error; } if (strlen(apps_unix_sock_path) == 0) { @@ -2693,10 +2715,10 @@ int main(int argc, char **argv) if ((ret = check_existing_daemon()) == 0) { ERR("Already running daemon.\n"); /* - * We do not goto error because we must not cleanup() because a daemon - * is already running. + * We do not goto exit because we must not cleanup() + * because a daemon is already running. */ - goto exit; + goto error; } /* After this point, we can safely call cleanup() so goto error is used */ @@ -2710,7 +2732,7 @@ int main(int argc, char **argv) if (is_root) { ret = set_kconsumerd_sockets(); if (ret < 0) { - goto error; + goto exit; } /* Setup kernel tracer */ @@ -2720,18 +2742,18 @@ int main(int argc, char **argv) set_ulimit(); } - if (set_signal_handler() < 0) { - goto error; + if ((ret = set_signal_handler()) < 0) { + goto exit; } /* Setup the needed unix socket */ - if (init_daemon_socket() < 0) { - goto error; + if ((ret = init_daemon_socket()) < 0) { + goto exit; } /* Set credentials to socket */ - if (is_root && (set_permissions() < 0)) { - goto error; + if (is_root && ((ret = set_permissions()) < 0)) { + goto exit; } /* Get parent pid if -S, --sig-parent is specified. */ @@ -2740,8 +2762,8 @@ int main(int argc, char **argv) } /* Setup the kernel pipe for waking up the kernel thread */ - if (create_kernel_poll_pipe() < 0) { - goto error; + if ((ret = create_kernel_poll_pipe()) < 0) { + goto exit; } /* @@ -2750,41 +2772,61 @@ int main(int argc, char **argv) */ session_list_ptr = get_session_list(); - while (1) { - /* Create thread to manage the client socket */ - ret = pthread_create(&client_thread, NULL, thread_manage_clients, (void *) NULL); - if (ret != 0) { - perror("pthread_create"); - goto error; - } + /* Create thread to manage the client socket */ + ret = pthread_create(&client_thread, NULL, thread_manage_clients, (void *) NULL); + if (ret != 0) { + perror("pthread_create"); + goto exit_client; + } - /* Create thread to manage application socket */ - ret = pthread_create(&apps_thread, NULL, thread_manage_apps, (void *) NULL); - if (ret != 0) { - perror("pthread_create"); - goto error; - } + /* Create thread to manage application socket */ + ret = pthread_create(&apps_thread, NULL, thread_manage_apps, (void *) NULL); + if (ret != 0) { + perror("pthread_create"); + goto exit_apps; + } - /* Create kernel thread to manage kernel event */ - ret = pthread_create(&kernel_thread, NULL, thread_manage_kernel, (void *) NULL); - if (ret != 0) { - perror("pthread_create"); - goto error; - } + /* Create kernel thread to manage kernel event */ + ret = pthread_create(&kernel_thread, NULL, thread_manage_kernel, (void *) NULL); + if (ret != 0) { + perror("pthread_create"); + goto exit_kernel; + } - ret = pthread_join(client_thread, &status); - if (ret != 0) { - perror("pthread_join"); - goto error; - } + ret = pthread_join(kernel_thread, &status); + if (ret != 0) { + perror("pthread_join"); + goto error; /* join error, exit without cleanup */ } - cleanup(); - exit(EXIT_SUCCESS); +exit_kernel: + ret = pthread_join(apps_thread, &status); + if (ret != 0) { + perror("pthread_join"); + goto error; /* join error, exit without cleanup */ + } -error: - cleanup(); +exit_apps: + ret = pthread_join(client_thread, &status); + if (ret != 0) { + perror("pthread_join"); + goto error; /* join error, exit without cleanup */ + } + + ret = join_kconsumerd_thread(); + if (ret != 0) { + perror("join_kconsumerd"); + goto error; /* join error, exit without cleanup */ + } +exit_client: exit: + /* + * cleanup() is called when no other thread is running. + */ + cleanup(); + if (!ret) + exit(EXIT_SUCCESS); +error: exit(EXIT_FAILURE); }