Fix: wait for the completion of implicit session rotations
[lttng-tools.git] / src / bin / lttng-sessiond / main.c
index 1fbfb1b0549383cd77e5334aad25338320cb6d56..ac7f7c910317d45158ac75991fa55cea17af7610 100644 (file)
@@ -69,7 +69,7 @@
 #include "fd-limit.h"
 #include "health-sessiond.h"
 #include "testpoint.h"
-#include "ust-thread.h"
+#include "notify-apps.h"
 #include "agent-thread.h"
 #include "save.h"
 #include "notification-thread.h"
@@ -1023,7 +1023,11 @@ static int set_permissions(char *rundir)
        int ret;
        gid_t gid;
 
-       gid = utils_get_group_id(config.tracing_group_name.value);
+       ret = utils_get_group_id(config.tracing_group_name.value, true, &gid);
+       if (ret) {
+               /* Default to root group. */
+               gid = 0;
+       }
 
        /* Set lttng run dir */
        ret = chown(rundir, 0, gid);
@@ -1134,7 +1138,16 @@ static int set_consumer_sockets(struct consumer_data *consumer_data)
                goto error;
        }
        if (is_root) {
-               ret = chown(path, 0, utils_get_group_id(config.tracing_group_name.value));
+               gid_t gid;
+
+               ret = utils_get_group_id(config.tracing_group_name.value, true,
+                               &gid);
+               if (ret) {
+                       /* Default to root group. */
+                       gid = 0;
+               }
+
+               ret = chown(path, 0, gid);
                if (ret < 0) {
                        ERR("Unable to set group on %s", path);
                        PERROR("chown");
@@ -1322,8 +1335,8 @@ static void destroy_all_sessions_and_wait(void)
                        goto unlock_session;
                }
                (void) cmd_stop_trace(session);
-               (void) cmd_destroy_session(session,
-                               notification_thread_handle);
+               (void) cmd_destroy_session(session, notification_thread_handle,
+                               NULL);
        unlock_session:
                session_unlock(session);
                session_put(session);
@@ -1336,6 +1349,34 @@ static void destroy_all_sessions_and_wait(void)
        DBG("Destruction of all sessions completed");
 }
 
+static int run_as_worker_post_fork_cleanup(void *data)
+{
+       struct sessiond_config *sessiond_config = data;
+
+       sessiond_config_fini(sessiond_config);
+       return 0;
+}
+
+static int launch_run_as_worker(const char *procname)
+{
+       /*
+        * Clean-up before forking the run-as worker. Any dynamically
+        * allocated memory of which the worker is not aware will
+        * be leaked as the process forks a run-as worker (and performs
+        * no exec*()). The same would apply to any opened fd.
+        */
+       return run_as_create_worker(procname, run_as_worker_post_fork_cleanup,
+                       &config);
+}
+
+static void sessiond_uuid_log(void)
+{
+       char uuid_str[UUID_STR_LEN];
+
+       lttng_uuid_to_str(sessiond_uuid, uuid_str);
+       DBG("Starting lttng-sessiond {%s}", uuid_str);
+}
+
 /*
  * main
  */
@@ -1353,6 +1394,8 @@ int main(int argc, char **argv)
        /* Queue of rotation jobs populated by the sessiond-timer. */
        struct rotation_thread_timer_queue *rotation_timer_queue = NULL;
        struct lttng_thread *client_thread = NULL;
+       struct lttng_thread *notification_thread = NULL;
+       struct lttng_thread *register_apps_thread = NULL;
 
        init_kernel_workarounds();
 
@@ -1430,6 +1473,7 @@ int main(int argc, char **argv)
        set_clock_plugin_env();
 
        sessiond_config_log(&config);
+       sessiond_uuid_log();
 
        if (create_lttng_rundir()) {
                retval = -1;
@@ -1467,7 +1511,7 @@ int main(int argc, char **argv)
                }
        }
 
-       if (run_as_create_worker(argv[0]) < 0) {
+       if (launch_run_as_worker(argv[0]) < 0) {
                goto exit_create_run_as_worker_cleanup;
        }
 
@@ -1484,20 +1528,20 @@ int main(int argc, char **argv)
        if (!health_sessiond) {
                PERROR("health_app_create error");
                retval = -1;
-               goto exit_health_sessiond_cleanup;
+               goto stop_threads;
        }
 
        /* Create thread to clean up RCU hash tables */
        ht_cleanup_thread = launch_ht_cleanup_thread();
        if (!ht_cleanup_thread) {
                retval = -1;
-               goto exit_ht_cleanup;
+               goto stop_threads;
        }
 
        /* Create thread quit pipe */
        if (sessiond_init_thread_quit_pipe()) {
                retval = -1;
-               goto exit_init_data;
+               goto stop_threads;
        }
 
        /* Check if daemon is UID = 0 */
@@ -1509,14 +1553,14 @@ int main(int argc, char **argv)
                if (!kernel_channel_monitor_pipe) {
                        ERR("Failed to create kernel consumer channel monitor pipe");
                        retval = -1;
-                       goto exit_init_data;
+                       goto stop_threads;
                }
                kconsumer_data.channel_monitor_pipe =
                                lttng_pipe_release_writefd(
                                        kernel_channel_monitor_pipe);
                if (kconsumer_data.channel_monitor_pipe < 0) {
                        retval = -1;
-                       goto exit_init_data;
+                       goto stop_threads;
                }
        }
 
@@ -1528,13 +1572,13 @@ int main(int argc, char **argv)
        if (!ust32_channel_monitor_pipe) {
                ERR("Failed to create 32-bit user space consumer channel monitor pipe");
                retval = -1;
-               goto exit_init_data;
+               goto stop_threads;
        }
        ustconsumer32_data.channel_monitor_pipe = lttng_pipe_release_writefd(
                        ust32_channel_monitor_pipe);
        if (ustconsumer32_data.channel_monitor_pipe < 0) {
                retval = -1;
-               goto exit_init_data;
+               goto stop_threads;
        }
 
        /*
@@ -1545,7 +1589,7 @@ int main(int argc, char **argv)
        rotation_timer_queue = rotation_thread_timer_queue_create();
        if (!rotation_timer_queue) {
                retval = -1;
-               goto exit_init_data;
+               goto stop_threads;
        }
        timer_thread_parameters.rotation_thread_job_queue =
                        rotation_timer_queue;
@@ -1554,13 +1598,13 @@ int main(int argc, char **argv)
        if (!ust64_channel_monitor_pipe) {
                ERR("Failed to create 64-bit user space consumer channel monitor pipe");
                retval = -1;
-               goto exit_init_data;
+               goto stop_threads;
        }
        ustconsumer64_data.channel_monitor_pipe = lttng_pipe_release_writefd(
                        ust64_channel_monitor_pipe);
        if (ustconsumer64_data.channel_monitor_pipe < 0) {
                retval = -1;
-               goto exit_init_data;
+               goto stop_threads;
        }
 
        /*
@@ -1570,7 +1614,7 @@ int main(int argc, char **argv)
        if (ust_app_ht_alloc()) {
                ERR("Failed to allocate UST app hash table");
                retval = -1;
-               goto exit_init_data;
+               goto stop_threads;
        }
 
        /*
@@ -1580,7 +1624,7 @@ int main(int argc, char **argv)
        if (agent_app_ht_alloc()) {
                ERR("Failed to allocate Agent app hash table");
                retval = -1;
-               goto exit_init_data;
+               goto stop_threads;
        }
 
        /*
@@ -1592,7 +1636,7 @@ int main(int argc, char **argv)
        if (is_root) {
                if (set_consumer_sockets(&kconsumer_data)) {
                        retval = -1;
-                       goto exit_init_data;
+                       goto stop_threads;
                }
 
                /* Setup kernel tracer */
@@ -1616,18 +1660,12 @@ int main(int argc, char **argv)
 
        if (set_consumer_sockets(&ustconsumer64_data)) {
                retval = -1;
-               goto exit_init_data;
+               goto stop_threads;
        }
 
        if (set_consumer_sockets(&ustconsumer32_data)) {
                retval = -1;
-               goto exit_init_data;
-       }
-
-       /* Set credentials to socket */
-       if (is_root && set_permissions(config.rundir.value)) {
-               retval = -1;
-               goto exit_init_data;
+               goto stop_threads;
        }
 
        /* Get parent pid if -S, --sig-parent is specified. */
@@ -1639,20 +1677,20 @@ int main(int argc, char **argv)
        if (is_root && !config.no_kernel) {
                if (utils_create_pipe_cloexec(kernel_poll_pipe)) {
                        retval = -1;
-                       goto exit_init_data;
+                       goto stop_threads;
                }
        }
 
        /* Setup the thread apps communication pipe. */
        if (utils_create_pipe_cloexec(apps_cmd_pipe)) {
                retval = -1;
-               goto exit_init_data;
+               goto stop_threads;
        }
 
        /* Setup the thread apps notify communication pipe. */
        if (utils_create_pipe_cloexec(apps_cmd_notify_pipe)) {
                retval = -1;
-               goto exit_init_data;
+               goto stop_threads;
        }
 
        /* Initialize global buffer per UID and PID registry. */
@@ -1676,7 +1714,7 @@ int main(int argc, char **argv)
        if (ret) {
                ERR("Error in write_pidfile");
                retval = -1;
-               goto exit_init_data;
+               goto stop_threads;
        }
 
        /* Initialize communication library */
@@ -1687,7 +1725,7 @@ int main(int argc, char **argv)
        /* Create health-check thread. */
        if (!launch_health_management_thread()) {
                retval = -1;
-               goto exit_health;
+               goto stop_threads;
        }
 
        /* notification_thread_data acquires the pipes' read side. */
@@ -1698,19 +1736,21 @@ int main(int argc, char **argv)
        if (!notification_thread_handle) {
                retval = -1;
                ERR("Failed to create notification thread shared data");
-               goto exit_notification;
+               goto stop_threads;
        }
 
        /* Create notification thread. */
-       if (!launch_notification_thread(notification_thread_handle)) {
+       notification_thread = launch_notification_thread(
+                       notification_thread_handle);
+       if (!notification_thread) {
                retval = -1;
-               goto exit_notification;
+               goto stop_threads;
        }
 
        /* Create timer thread. */
        if (!launch_timer_thread(&timer_thread_parameters)) {
                retval = -1;
-               goto exit_notification;
+               goto stop_threads;
        }
 
        /* rotation_thread_data acquires the pipes' read side. */
@@ -1721,50 +1761,58 @@ int main(int argc, char **argv)
                retval = -1;
                ERR("Failed to create rotation thread shared data");
                stop_threads();
-               goto exit_rotation;
+               goto stop_threads;
        }
 
        /* Create rotation thread. */
        if (!launch_rotation_thread(rotation_thread_handle)) {
                retval = -1;
-               goto exit_rotation;
+               goto stop_threads;
        }
 
        /* Create thread to manage the client socket */
        client_thread = launch_client_thread();
        if (!client_thread) {
                retval = -1;
-               goto exit_client;
+               goto stop_threads;
+       }
+
+       /* Set credentials of the client socket and rundir */
+       if (is_root && set_permissions(config.rundir.value)) {
+               retval = -1;
+               goto stop_threads;
        }
 
        if (!launch_ust_dispatch_thread(&ust_cmd_queue, apps_cmd_pipe[1],
                        apps_cmd_notify_pipe[1])) {
                retval = -1;
-               goto exit_dispatch;
+               goto stop_threads;
        }
 
        /* Create thread to manage application registration. */
-       if (!launch_application_registration_thread(&ust_cmd_queue)) {
+       register_apps_thread = launch_application_registration_thread(
+                       &ust_cmd_queue);
+       if (!register_apps_thread) {
                retval = -1;
-               goto exit_reg_apps;
+               goto stop_threads;
        }
 
        /* Create thread to manage application socket */
        if (!launch_application_management_thread(apps_cmd_pipe[0])) {
                retval = -1;
-               goto exit_apps;
+               goto stop_threads;
        }
 
        /* Create thread to manage application notify socket */
        if (!launch_application_notification_thread(apps_cmd_notify_pipe[0])) {
                retval = -1;
-               goto exit_apps_notify;
+               goto stop_threads;
        }
 
        /* Create agent management thread. */
        if (!launch_agent_management_thread()) {
                retval = -1;
-               goto exit_agent_reg;
+               goto stop_threads;
        }
 
        /* Don't start this thread if kernel tracing is not requested nor root */
@@ -1772,7 +1820,7 @@ int main(int argc, char **argv)
                /* Create kernel thread to manage kernel event */
                if (!launch_kernel_management_thread(kernel_poll_pipe[0])) {
                        retval = -1;
-                       goto exit_kernel;
+                       goto stop_threads;
                }
        }
 
@@ -1782,7 +1830,7 @@ int main(int argc, char **argv)
        if (ret) {
                ERR("Session load failed: %s", error_get_str(ret));
                retval = -1;
-               goto exit_load_session;
+               goto stop_threads;
        }
 
        /* Initialization completed. */
@@ -1796,33 +1844,23 @@ int main(int argc, char **argv)
        /* Initiate teardown once activity occurs on the quit pipe. */
        sessiond_wait_for_quit_pipe(-1U);
 
+stop_threads:
        /*
         * Ensure that the client thread is no longer accepting new commands,
         * which could cause new sessions to be created.
         */
-       if (!lttng_thread_shutdown(client_thread)) {
-               ERR("Failed to shutdown the client thread, continuing teardown");
+       if (client_thread) {
+               lttng_thread_shutdown(client_thread);
                lttng_thread_put(client_thread);
-               client_thread = NULL;
        }
 
        destroy_all_sessions_and_wait();
-exit_load_session:
-exit_kernel:
-exit_agent_reg:
-exit_apps_notify:
-exit_apps:
-exit_reg_apps:
-exit_dispatch:
-exit_client:
-exit_rotation:
-exit_notification:
-       lttng_thread_list_shutdown_orphans();
-exit_health:
-exit_init_data:
-       if (client_thread) {
-               lttng_thread_put(client_thread);
+
+       if (register_apps_thread) {
+               lttng_thread_shutdown(register_apps_thread);
+               lttng_thread_put(register_apps_thread);
        }
+       lttng_thread_list_shutdown_orphans();
 
        /*
         * Wait for all pending call_rcu work to complete before tearing
@@ -1837,6 +1875,11 @@ exit_init_data:
        rcu_thread_online();
        sessiond_cleanup();
 
+       if (notification_thread) {
+               lttng_thread_shutdown(notification_thread);
+               lttng_thread_put(notification_thread);
+       }
+
        /*
         * Ensure all prior call_rcu are done. call_rcu callbacks may push
         * hash tables to the ht_cleanup thread. Therefore, we ensure that
@@ -1872,12 +1915,9 @@ exit_init_data:
        lttng_pipe_destroy(ust32_channel_monitor_pipe);
        lttng_pipe_destroy(ust64_channel_monitor_pipe);
        lttng_pipe_destroy(kernel_channel_monitor_pipe);
-exit_ht_cleanup:
 
        health_app_destroy(health_sessiond);
-exit_health_sessiond_cleanup:
 exit_create_run_as_worker_cleanup:
-
 exit_options:
        sessiond_cleanup_lock_file();
        sessiond_cleanup_options();
This page took 0.030099 seconds and 4 git commands to generate.