Clean-up: lttng-session: fix -Wshadow error in unregister_all_triggers
[lttng-tools.git] / src / bin / lttng-sessiond / main.c
index 7f66a7271222d16b11dbb501ddf7dd5c0e291fb2..bca33a4f8a0f669d6e4f278ce15a9c65c444478d 100644 (file)
@@ -1,20 +1,10 @@
 /*
- * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
- *                      Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *               2013 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
+ * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * Copyright (C) 2013 Jérémie Galarneau <jeremie.galarneau@efficios.com>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2 only,
- * as published by the Free Software Foundation.
+ * SPDX-License-Identifier: GPL-2.0-only
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #define _LGPL_SOURCE
 #include "consumer.h"
 #include "context.h"
 #include "event.h"
+#include "event-notifier-error-accounting.h"
 #include "kernel.h"
 #include "kernel-consumer.h"
-#include "modprobe.h"
-#include "shm.h"
-#include "ust-ctl.h"
+#include "lttng-ust-ctl.h"
 #include "ust-consumer.h"
 #include "utils.h"
 #include "fd-limit.h"
@@ -75,7 +64,6 @@
 #include "notification-thread.h"
 #include "notification-thread-commands.h"
 #include "rotation-thread.h"
-#include "lttng-syscall.h"
 #include "agent.h"
 #include "ht-cleanup.h"
 #include "sessiond-config.h"
@@ -86,6 +74,7 @@
 #include "register.h"
 #include "manage-apps.h"
 #include "manage-kernel.h"
+#include "modprobe.h"
 
 static const char *help_msg =
 #ifdef LTTNG_EMBED_HELP
@@ -95,8 +84,11 @@ NULL
 #endif
 ;
 
+#define EVENT_NOTIFIER_ERROR_COUNTER_NUMBER_OF_BUCKET_MAX 65535
+
 const char *progname;
 static int lockfile_fd = -1;
+static int opt_print_version;
 
 /* Set to 1 when a SIGUSR1 signal is received. */
 static int recv_child_signal;
@@ -131,6 +123,7 @@ static const struct option long_options[] = {
        { "load", required_argument, 0, 'l' },
        { "kmod-probes", required_argument, 0, '\0' },
        { "extra-kmod-probes", required_argument, 0, '\0' },
+       { "event-notifier-error-number-of-bucket", required_argument, 0, '\0' },
        { NULL, 0, 0, 0 }
 };
 
@@ -155,8 +148,6 @@ static int apps_cmd_notify_pipe[2] = { -1, -1 };
  */
 static struct ust_cmd_queue ust_cmd_queue;
 
-static const char *module_proc_lttng = "/proc/lttng";
-
 /*
  * Section name to look for in the daemon configuration file.
  */
@@ -187,56 +178,56 @@ static void close_consumer_sockets(void)
 {
        int ret;
 
-       if (kconsumer_data.err_sock >= 0) {
-               ret = close(kconsumer_data.err_sock);
+       if (the_kconsumer_data.err_sock >= 0) {
+               ret = close(the_kconsumer_data.err_sock);
                if (ret < 0) {
                        PERROR("kernel consumer err_sock close");
                }
        }
-       if (ustconsumer32_data.err_sock >= 0) {
-               ret = close(ustconsumer32_data.err_sock);
+       if (the_ustconsumer32_data.err_sock >= 0) {
+               ret = close(the_ustconsumer32_data.err_sock);
                if (ret < 0) {
                        PERROR("UST consumerd32 err_sock close");
                }
        }
-       if (ustconsumer64_data.err_sock >= 0) {
-               ret = close(ustconsumer64_data.err_sock);
+       if (the_ustconsumer64_data.err_sock >= 0) {
+               ret = close(the_ustconsumer64_data.err_sock);
                if (ret < 0) {
                        PERROR("UST consumerd64 err_sock close");
                }
        }
-       if (kconsumer_data.cmd_sock >= 0) {
-               ret = close(kconsumer_data.cmd_sock);
+       if (the_kconsumer_data.cmd_sock >= 0) {
+               ret = close(the_kconsumer_data.cmd_sock);
                if (ret < 0) {
                        PERROR("kernel consumer cmd_sock close");
                }
        }
-       if (ustconsumer32_data.cmd_sock >= 0) {
-               ret = close(ustconsumer32_data.cmd_sock);
+       if (the_ustconsumer32_data.cmd_sock >= 0) {
+               ret = close(the_ustconsumer32_data.cmd_sock);
                if (ret < 0) {
                        PERROR("UST consumerd32 cmd_sock close");
                }
        }
-       if (ustconsumer64_data.cmd_sock >= 0) {
-               ret = close(ustconsumer64_data.cmd_sock);
+       if (the_ustconsumer64_data.cmd_sock >= 0) {
+               ret = close(the_ustconsumer64_data.cmd_sock);
                if (ret < 0) {
                        PERROR("UST consumerd64 cmd_sock close");
                }
        }
-       if (kconsumer_data.channel_monitor_pipe >= 0) {
-               ret = close(kconsumer_data.channel_monitor_pipe);
+       if (the_kconsumer_data.channel_monitor_pipe >= 0) {
+               ret = close(the_kconsumer_data.channel_monitor_pipe);
                if (ret < 0) {
                        PERROR("kernel consumer channel monitor pipe close");
                }
        }
-       if (ustconsumer32_data.channel_monitor_pipe >= 0) {
-               ret = close(ustconsumer32_data.channel_monitor_pipe);
+       if (the_ustconsumer32_data.channel_monitor_pipe >= 0) {
+               ret = close(the_ustconsumer32_data.channel_monitor_pipe);
                if (ret < 0) {
                        PERROR("UST consumerd32 channel monitor pipe close");
                }
        }
-       if (ustconsumer64_data.channel_monitor_pipe >= 0) {
-               ret = close(ustconsumer64_data.channel_monitor_pipe);
+       if (the_ustconsumer64_data.channel_monitor_pipe >= 0) {
+               ret = close(the_ustconsumer64_data.channel_monitor_pipe);
                if (ret < 0) {
                        PERROR("UST consumerd64 channel monitor pipe close");
                }
@@ -287,72 +278,65 @@ static void sessiond_cleanup(void)
        sessiond_close_quit_pipe();
        utils_close_pipe(apps_cmd_pipe);
        utils_close_pipe(apps_cmd_notify_pipe);
-       utils_close_pipe(kernel_poll_pipe);
+       utils_close_pipe(the_kernel_poll_pipe);
 
-       ret = remove(config.pid_file_path.value);
+       ret = remove(the_config.pid_file_path.value);
        if (ret < 0) {
-               PERROR("remove pidfile %s", config.pid_file_path.value);
+               PERROR("remove pidfile %s", the_config.pid_file_path.value);
        }
 
        DBG("Removing sessiond and consumerd content of directory %s",
-               config.rundir.value);
+                       the_config.rundir.value);
 
        /* sessiond */
-       DBG("Removing %s", config.pid_file_path.value);
-       (void) unlink(config.pid_file_path.value);
+       DBG("Removing %s", the_config.pid_file_path.value);
+       (void) unlink(the_config.pid_file_path.value);
 
-       DBG("Removing %s", config.agent_port_file_path.value);
-       (void) unlink(config.agent_port_file_path.value);
+       DBG("Removing %s", the_config.agent_port_file_path.value);
+       (void) unlink(the_config.agent_port_file_path.value);
 
        /* kconsumerd */
-       DBG("Removing %s", kconsumer_data.err_unix_sock_path);
-       (void) unlink(kconsumer_data.err_unix_sock_path);
+       DBG("Removing %s", the_kconsumer_data.err_unix_sock_path);
+       (void) unlink(the_kconsumer_data.err_unix_sock_path);
 
-       DBG("Removing directory %s", config.kconsumerd_path.value);
-       (void) rmdir(config.kconsumerd_path.value);
+       DBG("Removing directory %s", the_config.kconsumerd_path.value);
+       (void) rmdir(the_config.kconsumerd_path.value);
 
        /* ust consumerd 32 */
-       DBG("Removing %s", config.consumerd32_err_unix_sock_path.value);
-       (void) unlink(config.consumerd32_err_unix_sock_path.value);
+       DBG("Removing %s", the_config.consumerd32_err_unix_sock_path.value);
+       (void) unlink(the_config.consumerd32_err_unix_sock_path.value);
 
-       DBG("Removing directory %s", config.consumerd32_path.value);
-       (void) rmdir(config.consumerd32_path.value);
+       DBG("Removing directory %s", the_config.consumerd32_path.value);
+       (void) rmdir(the_config.consumerd32_path.value);
 
        /* ust consumerd 64 */
-       DBG("Removing %s", config.consumerd64_err_unix_sock_path.value);
-       (void) unlink(config.consumerd64_err_unix_sock_path.value);
+       DBG("Removing %s", the_config.consumerd64_err_unix_sock_path.value);
+       (void) unlink(the_config.consumerd64_err_unix_sock_path.value);
 
-       DBG("Removing directory %s", config.consumerd64_path.value);
-       (void) rmdir(config.consumerd64_path.value);
+       DBG("Removing directory %s", the_config.consumerd64_path.value);
+       (void) rmdir(the_config.consumerd64_path.value);
 
        pthread_mutex_destroy(&session_list->lock);
 
-       wait_consumer(&kconsumer_data);
-       wait_consumer(&ustconsumer64_data);
-       wait_consumer(&ustconsumer32_data);
+       DBG("Cleaning up all per-event notifier domain agents");
+       agent_by_event_notifier_domain_ht_destroy();
 
        DBG("Cleaning up all agent apps");
        agent_app_ht_clean();
-
        DBG("Closing all UST sockets");
        ust_app_clean_list();
        buffer_reg_destroy_registries();
 
-       if (is_root && !config.no_kernel) {
-               DBG2("Closing kernel fd");
-               if (kernel_tracer_fd >= 0) {
-                       ret = close(kernel_tracer_fd);
-                       if (ret) {
-                               PERROR("close");
-                       }
-               }
-               DBG("Unloading kernel modules");
-               modprobe_remove_lttng_all();
-               free(syscall_table);
-       }
-
        close_consumer_sockets();
 
+       wait_consumer(&the_kconsumer_data);
+       wait_consumer(&the_ustconsumer64_data);
+       wait_consumer(&the_ustconsumer32_data);
+
+       if (is_root && !the_config.no_kernel) {
+               cleanup_kernel_tracer();
+       }
+
        /*
         * We do NOT rmdir rundir because there are other processes
         * using it, for instance lttng-relayd, which can start in
@@ -367,86 +351,11 @@ static void sessiond_cleanup_options(void)
 {
        DBG("Cleaning up options");
 
-       sessiond_config_fini(&config);
+       sessiond_config_fini(&the_config);
 
        run_as_destroy_worker();
 }
 
-/*
- * Setup necessary data for kernel tracer action.
- */
-static int init_kernel_tracer(void)
-{
-       int ret;
-
-       /* Modprobe lttng kernel modules */
-       ret = modprobe_lttng_control();
-       if (ret < 0) {
-               goto error;
-       }
-
-       /* Open debugfs lttng */
-       kernel_tracer_fd = open(module_proc_lttng, O_RDWR);
-       if (kernel_tracer_fd < 0) {
-               DBG("Failed to open %s", module_proc_lttng);
-               goto error_open;
-       }
-
-       /* Validate kernel version */
-       ret = kernel_validate_version(kernel_tracer_fd, &kernel_tracer_version,
-                       &kernel_tracer_abi_version);
-       if (ret < 0) {
-               goto error_version;
-       }
-
-       ret = modprobe_lttng_data();
-       if (ret < 0) {
-               goto error_modules;
-       }
-
-       ret = kernel_supports_ring_buffer_snapshot_sample_positions(
-                       kernel_tracer_fd);
-       if (ret < 0) {
-               goto error_modules;
-       }
-
-       if (ret < 1) {
-               WARN("Kernel tracer does not support buffer monitoring. "
-                       "The monitoring timer of channels in the kernel domain "
-                       "will be set to 0 (disabled).");
-       }
-
-       DBG("Kernel tracer fd %d", kernel_tracer_fd);
-       return 0;
-
-error_version:
-       modprobe_remove_lttng_control();
-       ret = close(kernel_tracer_fd);
-       if (ret) {
-               PERROR("close");
-       }
-       kernel_tracer_fd = -1;
-       return LTTNG_ERR_KERN_VERSION;
-
-error_modules:
-       ret = close(kernel_tracer_fd);
-       if (ret) {
-               PERROR("close");
-       }
-
-error_open:
-       modprobe_remove_lttng_control();
-
-error:
-       WARN("No kernel tracer available");
-       kernel_tracer_fd = -1;
-       if (!is_root) {
-               return LTTNG_ERR_NEED_ROOT_SESSIOND;
-       } else {
-               return LTTNG_ERR_KERN_NA;
-       }
-}
-
 static int string_match(const char *str1, const char *str2)
 {
        return (str1 && str2) && !strcmp(str1, str2);
@@ -471,9 +380,9 @@ static int set_option(int opt, const char *arg, const char *optname)
                        WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
                                "-c, --client-sock");
                } else {
-                       config_string_set(&config.client_unix_sock_path,
+                       config_string_set(&the_config.client_unix_sock_path,
                                        strdup(arg));
-                       if (!config.client_unix_sock_path.value) {
+                       if (!the_config.client_unix_sock_path.value) {
                                ret = -ENOMEM;
                                PERROR("strdup");
                        }
@@ -487,17 +396,17 @@ static int set_option(int opt, const char *arg, const char *optname)
                        WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
                                "-a, --apps-sock");
                } else {
-                       config_string_set(&config.apps_unix_sock_path,
+                       config_string_set(&the_config.apps_unix_sock_path,
                                        strdup(arg));
-                       if (!config.apps_unix_sock_path.value) {
+                       if (!the_config.apps_unix_sock_path.value) {
                                ret = -ENOMEM;
                                PERROR("strdup");
                        }
                }
        } else if (string_match(optname, "daemonize") || opt == 'd') {
-               config.daemonize = true;
+               the_config.daemonize = true;
        } else if (string_match(optname, "background") || opt == 'b') {
-               config.background = true;
+               the_config.background = true;
        } else if (string_match(optname, "group") || opt == 'g') {
                if (!arg || *arg == '\0') {
                        ret = -EINVAL;
@@ -507,9 +416,9 @@ static int set_option(int opt, const char *arg, const char *optname)
                        WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
                                "-g, --group");
                } else {
-                       config_string_set(&config.tracing_group_name,
+                       config_string_set(&the_config.tracing_group_name,
                                        strdup(arg));
-                       if (!config.tracing_group_name.value) {
+                       if (!the_config.tracing_group_name.value) {
                                ret = -ENOMEM;
                                PERROR("strdup");
                        }
@@ -522,10 +431,9 @@ static int set_option(int opt, const char *arg, const char *optname)
                }
                exit(ret ? EXIT_FAILURE : EXIT_SUCCESS);
        } else if (string_match(optname, "version") || opt == 'V') {
-               fprintf(stdout, "%s\n", VERSION);
-               exit(EXIT_SUCCESS);
+               opt_print_version = 1;
        } else if (string_match(optname, "sig-parent") || opt == 'S') {
-               config.sig_parent = true;
+               the_config.sig_parent = true;
        } else if (string_match(optname, "kconsumerd-err-sock")) {
                if (!arg || *arg == '\0') {
                        ret = -EINVAL;
@@ -535,9 +443,10 @@ static int set_option(int opt, const char *arg, const char *optname)
                        WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
                                "--kconsumerd-err-sock");
                } else {
-                       config_string_set(&config.kconsumerd_err_unix_sock_path,
+                       config_string_set(
+                                       &the_config.kconsumerd_err_unix_sock_path,
                                        strdup(arg));
-                       if (!config.kconsumerd_err_unix_sock_path.value) {
+                       if (!the_config.kconsumerd_err_unix_sock_path.value) {
                                ret = -ENOMEM;
                                PERROR("strdup");
                        }
@@ -551,9 +460,10 @@ static int set_option(int opt, const char *arg, const char *optname)
                        WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
                                "--kconsumerd-cmd-sock");
                } else {
-                       config_string_set(&config.kconsumerd_cmd_unix_sock_path,
+                       config_string_set(
+                                       &the_config.kconsumerd_cmd_unix_sock_path,
                                        strdup(arg));
-                       if (!config.kconsumerd_cmd_unix_sock_path.value) {
+                       if (!the_config.kconsumerd_cmd_unix_sock_path.value) {
                                ret = -ENOMEM;
                                PERROR("strdup");
                        }
@@ -567,9 +477,10 @@ static int set_option(int opt, const char *arg, const char *optname)
                        WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
                                "--ustconsumerd64-err-sock");
                } else {
-                       config_string_set(&config.consumerd64_err_unix_sock_path,
+                       config_string_set(
+                                       &the_config.consumerd64_err_unix_sock_path,
                                        strdup(arg));
-                       if (!config.consumerd64_err_unix_sock_path.value) {
+                       if (!the_config.consumerd64_err_unix_sock_path.value) {
                                ret = -ENOMEM;
                                PERROR("strdup");
                        }
@@ -583,9 +494,10 @@ static int set_option(int opt, const char *arg, const char *optname)
                        WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
                                "--ustconsumerd64-cmd-sock");
                } else {
-                       config_string_set(&config.consumerd64_cmd_unix_sock_path,
+                       config_string_set(
+                                       &the_config.consumerd64_cmd_unix_sock_path,
                                        strdup(arg));
-                       if (!config.consumerd64_cmd_unix_sock_path.value) {
+                       if (!the_config.consumerd64_cmd_unix_sock_path.value) {
                                ret = -ENOMEM;
                                PERROR("strdup");
                        }
@@ -599,9 +511,10 @@ static int set_option(int opt, const char *arg, const char *optname)
                        WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
                                "--ustconsumerd32-err-sock");
                } else {
-                       config_string_set(&config.consumerd32_err_unix_sock_path,
+                       config_string_set(
+                                       &the_config.consumerd32_err_unix_sock_path,
                                        strdup(arg));
-                       if (!config.consumerd32_err_unix_sock_path.value) {
+                       if (!the_config.consumerd32_err_unix_sock_path.value) {
                                ret = -ENOMEM;
                                PERROR("strdup");
                        }
@@ -615,34 +528,37 @@ static int set_option(int opt, const char *arg, const char *optname)
                        WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
                                "--ustconsumerd32-cmd-sock");
                } else {
-                       config_string_set(&config.consumerd32_cmd_unix_sock_path,
+                       config_string_set(
+                                       &the_config.consumerd32_cmd_unix_sock_path,
                                        strdup(arg));
-                       if (!config.consumerd32_cmd_unix_sock_path.value) {
+                       if (!the_config.consumerd32_cmd_unix_sock_path.value) {
                                ret = -ENOMEM;
                                PERROR("strdup");
                        }
                }
        } else if (string_match(optname, "no-kernel")) {
-               config.no_kernel = true;
+               the_config.no_kernel = true;
        } else if (string_match(optname, "quiet") || opt == 'q') {
-               config.quiet = true;
+               the_config.quiet = true;
        } else if (string_match(optname, "verbose") || opt == 'v') {
                /* Verbose level can increase using multiple -v */
                if (arg) {
                        /* Value obtained from config file */
-                       config.verbose = config_parse_value(arg);
+                       the_config.verbose = config_parse_value(arg);
                } else {
                        /* -v used on command line */
-                       config.verbose++;
+                       the_config.verbose++;
                }
                /* Clamp value to [0, 3] */
-               config.verbose = config.verbose < 0 ? 0 :
-                       (config.verbose <= 3 ? config.verbose : 3);
+               the_config.verbose = the_config.verbose < 0 ?
+                                     0 :
+                                     (the_config.verbose <= 3 ? the_config.verbose :
+                                                                3);
        } else if (string_match(optname, "verbose-consumer")) {
                if (arg) {
-                       config.verbose_consumer = config_parse_value(arg);
+                       the_config.verbose_consumer = config_parse_value(arg);
                } else {
-                       config.verbose_consumer++;
+                       the_config.verbose_consumer++;
                }
        } else if (string_match(optname, "consumerd32-path")) {
                if (!arg || *arg == '\0') {
@@ -653,9 +569,9 @@ static int set_option(int opt, const char *arg, const char *optname)
                        WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
                                "--consumerd32-path");
                } else {
-                       config_string_set(&config.consumerd32_bin_path,
+                       config_string_set(&the_config.consumerd32_bin_path,
                                        strdup(arg));
-                       if (!config.consumerd32_bin_path.value) {
+                       if (!the_config.consumerd32_bin_path.value) {
                                PERROR("strdup");
                                ret = -ENOMEM;
                        }
@@ -669,9 +585,9 @@ static int set_option(int opt, const char *arg, const char *optname)
                        WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
                                "--consumerd32-libdir");
                } else {
-                       config_string_set(&config.consumerd32_lib_dir,
+                       config_string_set(&the_config.consumerd32_lib_dir,
                                        strdup(arg));
-                       if (!config.consumerd32_lib_dir.value) {
+                       if (!the_config.consumerd32_lib_dir.value) {
                                PERROR("strdup");
                                ret = -ENOMEM;
                        }
@@ -685,9 +601,9 @@ static int set_option(int opt, const char *arg, const char *optname)
                        WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
                                "--consumerd64-path");
                } else {
-                       config_string_set(&config.consumerd64_bin_path,
+                       config_string_set(&the_config.consumerd64_bin_path,
                                        strdup(arg));
-                       if (!config.consumerd64_bin_path.value) {
+                       if (!the_config.consumerd64_bin_path.value) {
                                PERROR("strdup");
                                ret = -ENOMEM;
                        }
@@ -701,9 +617,9 @@ static int set_option(int opt, const char *arg, const char *optname)
                        WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
                                "--consumerd64-libdir");
                } else {
-                       config_string_set(&config.consumerd64_lib_dir,
+                       config_string_set(&the_config.consumerd64_lib_dir,
                                        strdup(arg));
-                       if (!config.consumerd64_lib_dir.value) {
+                       if (!the_config.consumerd64_lib_dir.value) {
                                PERROR("strdup");
                                ret = -ENOMEM;
                        }
@@ -717,8 +633,9 @@ static int set_option(int opt, const char *arg, const char *optname)
                        WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
                                "-p, --pidfile");
                } else {
-                       config_string_set(&config.pid_file_path, strdup(arg));
-                       if (!config.pid_file_path.value) {
+                       config_string_set(
+                                       &the_config.pid_file_path, strdup(arg));
+                       if (!the_config.pid_file_path.value) {
                                PERROR("strdup");
                                ret = -ENOMEM;
                        }
@@ -744,7 +661,8 @@ static int set_option(int opt, const char *arg, const char *optname)
                                ERR("Port overflow in --agent-tcp-port parameter: %s", arg);
                                return -1;
                        }
-                       config.agent_tcp_port.begin = config.agent_tcp_port.end = (int) v;
+                       the_config.agent_tcp_port.begin =
+                                       the_config.agent_tcp_port.end = (int) v;
                        DBG3("Agent TCP port set to non default: %i", (int) v);
                }
        } else if (string_match(optname, "load") || opt == 'l') {
@@ -756,8 +674,9 @@ static int set_option(int opt, const char *arg, const char *optname)
                        WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
                                "-l, --load");
                } else {
-                       config_string_set(&config.load_session_path, strdup(arg));
-                       if (!config.load_session_path.value) {
+                       config_string_set(&the_config.load_session_path,
+                                       strdup(arg));
+                       if (!the_config.load_session_path.value) {
                                PERROR("strdup");
                                ret = -ENOMEM;
                        }
@@ -771,8 +690,9 @@ static int set_option(int opt, const char *arg, const char *optname)
                        WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
                                "--kmod-probes");
                } else {
-                       config_string_set(&config.kmod_probes_list, strdup(arg));
-                       if (!config.kmod_probes_list.value) {
+                       config_string_set(&the_config.kmod_probes_list,
+                                       strdup(arg));
+                       if (!the_config.kmod_probes_list.value) {
                                PERROR("strdup");
                                ret = -ENOMEM;
                        }
@@ -786,13 +706,30 @@ static int set_option(int opt, const char *arg, const char *optname)
                        WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
                                "--extra-kmod-probes");
                } else {
-                       config_string_set(&config.kmod_extra_probes_list,
+                       config_string_set(&the_config.kmod_extra_probes_list,
                                        strdup(arg));
-                       if (!config.kmod_extra_probes_list.value) {
+                       if (!the_config.kmod_extra_probes_list.value) {
                                PERROR("strdup");
                                ret = -ENOMEM;
                        }
                }
+       } else if (string_match(optname, "event-notifier-error-number-of-bucket")) {
+               unsigned long v;
+
+               errno = 0;
+               v = strtoul(arg, NULL, 0);
+               if (errno != 0 || !isdigit(arg[0])) {
+                       ERR("Wrong value in --event-notifier-error-number-of-bucket parameter: %s", arg);
+                       return -1;
+               }
+               if (v == 0 || v >= EVENT_NOTIFIER_ERROR_COUNTER_NUMBER_OF_BUCKET_MAX) {
+                       ERR("Value out of range for --event-notifier-error-number-of-bucket parameter: %s", arg);
+                       return -1;
+               }
+               the_config.event_notifier_error_counter_bucket = (int) v;
+               DBG3("Number of event notifier error counter set to non default: %i",
+                               the_config.event_notifier_error_counter_bucket);
+               goto end;
        } else if (string_match(optname, "config") || opt == 'f') {
                /* This is handled in set_options() thus silent skip. */
                goto end;
@@ -878,6 +815,10 @@ end:
        return ret;
 }
 
+static void print_version(void) {
+       fprintf(stdout, "%s\n", VERSION);
+}
+
 /*
  * daemon configuration loading and argument parsing
  */
@@ -964,7 +905,7 @@ end:
  */
 static int create_lockfile(void)
 {
-        return utils_create_lock_file(config.lock_file_path.value);
+       return utils_create_lock_file(the_config.lock_file_path.value);
 }
 
 /*
@@ -1001,7 +942,7 @@ static void sessiond_cleanup_lock_file(void)
         * release the file system lock.
         */
        if (lockfile_fd >= 0) {
-               ret = remove(config.lock_file_path.value);
+               ret = remove(the_config.lock_file_path.value);
                if (ret < 0) {
                        PERROR("remove lock file");
                }
@@ -1023,7 +964,12 @@ 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(
+                       the_config.tracing_group_name.value, true, &gid);
+       if (ret) {
+               /* Default to root group. */
+               gid = 0;
+       }
 
        /* Set lttng run dir */
        ret = chown(rundir, 0, gid);
@@ -1044,30 +990,34 @@ static int set_permissions(char *rundir)
        }
 
        /* lttng client socket path */
-       ret = chown(config.client_unix_sock_path.value, 0, gid);
+       ret = chown(the_config.client_unix_sock_path.value, 0, gid);
        if (ret < 0) {
-               ERR("Unable to set group on %s", config.client_unix_sock_path.value);
+               ERR("Unable to set group on %s",
+                               the_config.client_unix_sock_path.value);
                PERROR("chown");
        }
 
        /* kconsumer error socket path */
-       ret = chown(kconsumer_data.err_unix_sock_path, 0, 0);
+       ret = chown(the_kconsumer_data.err_unix_sock_path, 0, 0);
        if (ret < 0) {
-               ERR("Unable to set group on %s", kconsumer_data.err_unix_sock_path);
+               ERR("Unable to set group on %s",
+                               the_kconsumer_data.err_unix_sock_path);
                PERROR("chown");
        }
 
        /* 64-bit ustconsumer error socket path */
-       ret = chown(ustconsumer64_data.err_unix_sock_path, 0, 0);
+       ret = chown(the_ustconsumer64_data.err_unix_sock_path, 0, 0);
        if (ret < 0) {
-               ERR("Unable to set group on %s", ustconsumer64_data.err_unix_sock_path);
+               ERR("Unable to set group on %s",
+                               the_ustconsumer64_data.err_unix_sock_path);
                PERROR("chown");
        }
 
        /* 32-bit ustconsumer compat32 error socket path */
-       ret = chown(ustconsumer32_data.err_unix_sock_path, 0, 0);
+       ret = chown(the_ustconsumer32_data.err_unix_sock_path, 0, 0);
        if (ret < 0) {
-               ERR("Unable to set group on %s", ustconsumer32_data.err_unix_sock_path);
+               ERR("Unable to set group on %s",
+                               the_ustconsumer32_data.err_unix_sock_path);
                PERROR("chown");
        }
 
@@ -1083,12 +1033,12 @@ static int create_lttng_rundir(void)
 {
        int ret;
 
-       DBG3("Creating LTTng run directory: %s", config.rundir.value);
+       DBG3("Creating LTTng run directory: %s", the_config.rundir.value);
 
-       ret = mkdir(config.rundir.value, S_IRWXU);
+       ret = mkdir(the_config.rundir.value, S_IRWXU);
        if (ret < 0) {
                if (errno != EEXIST) {
-                       ERR("Unable to create %s", config.rundir.value);
+                       ERR("Unable to create %s", the_config.rundir.value);
                        goto error;
                } else {
                        ret = 0;
@@ -1110,13 +1060,13 @@ static int set_consumer_sockets(struct consumer_data *consumer_data)
 
        switch (consumer_data->type) {
        case LTTNG_CONSUMER_KERNEL:
-               path = config.kconsumerd_path.value;
+               path = the_config.kconsumerd_path.value;
                break;
        case LTTNG_CONSUMER64_UST:
-               path = config.consumerd64_path.value;
+               path = the_config.consumerd64_path.value;
                break;
        case LTTNG_CONSUMER32_UST:
-               path = config.consumerd32_path.value;
+               path = the_config.consumerd32_path.value;
                break;
        default:
                ERR("Consumer type unknown");
@@ -1134,7 +1084,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(the_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");
@@ -1265,7 +1224,7 @@ static void set_ulimit(void)
 
 static int write_pidfile(void)
 {
-        return utils_create_pid_file(getpid(), config.pid_file_path.value);
+       return utils_create_pid_file(getpid(), the_config.pid_file_path.value);
 }
 
 static int set_clock_plugin_env(void)
@@ -1273,12 +1232,12 @@ static int set_clock_plugin_env(void)
        int ret = 0;
        char *env_value = NULL;
 
-       if (!config.lttng_ust_clock_plugin.value) {
+       if (!the_config.lttng_ust_clock_plugin.value) {
                goto end;
        }
 
-        ret = asprintf(&env_value, "LTTNG_UST_CLOCK_PLUGIN=%s",
-                       config.lttng_ust_clock_plugin.value);
+       ret = asprintf(&env_value, "LTTNG_UST_CLOCK_PLUGIN=%s",
+                       the_config.lttng_ust_clock_plugin.value);
        if (ret < 0) {
                PERROR("asprintf");
                goto end;
@@ -1292,7 +1251,7 @@ static int set_clock_plugin_env(void)
        }
 
        DBG("Updated LTTNG_UST_CLOCK_PLUGIN environment variable to \"%s\"",
-                       config.lttng_ust_clock_plugin.value);
+                       the_config.lttng_ust_clock_plugin.value);
 end:
        return ret;
 }
@@ -1322,8 +1281,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, the_notification_thread_handle, NULL);
        unlock_session:
                session_unlock(session);
                session_put(session);
@@ -1336,6 +1295,91 @@ static void destroy_all_sessions_and_wait(void)
        DBG("Destruction of all sessions completed");
 }
 
+static void unregister_all_triggers(void)
+{
+       enum lttng_error_code ret_code;
+       enum lttng_trigger_status trigger_status;
+       struct lttng_triggers *triggers = NULL;
+       unsigned int trigger_count, i;
+       const struct lttng_credentials creds = {
+                       .uid = LTTNG_OPTIONAL_INIT_VALUE(0),
+       };
+
+       DBG("Unregistering all triggers");
+
+       /*
+        * List all triggers as "root" since we wish to unregister all triggers.
+        */
+       ret_code = notification_thread_command_list_triggers(
+                       the_notification_thread_handle, creds.uid.value,
+                       &triggers);
+       if (ret_code != LTTNG_OK) {
+               ERR("Failed to list triggers while unregistering all triggers");
+               goto end;
+       }
+
+       trigger_status = lttng_triggers_get_count(triggers, &trigger_count);
+       assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
+
+       for (i = 0; i < trigger_count; i++) {
+               uid_t trigger_owner;
+               const char *trigger_name;
+               const struct lttng_trigger *trigger =
+                               lttng_triggers_get_at_index(triggers, i);
+
+               assert(trigger);
+
+               trigger_status = lttng_trigger_get_owner_uid(
+                               trigger, &trigger_owner);
+               assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
+
+               trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
+               assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
+
+               DBG("Unregistering trigger: trigger owner uid = %d, trigger name = '%s'",
+                               (int) trigger_owner, trigger_name);
+
+               ret_code = cmd_unregister_trigger(&creds, trigger,
+                               the_notification_thread_handle);
+               if (ret_code != LTTNG_OK) {
+                       ERR("Failed to unregister trigger: trigger owner uid = %d, trigger name = '%s', error: '%s'",
+                                       (int) trigger_owner, trigger_name,
+                                       lttng_strerror(-ret_code));
+                       /* Continue to unregister the remaining triggers. */
+               }
+       }
+end:
+       lttng_triggers_destroy(triggers);
+}
+
+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, &the_config);
+}
+
+static void sessiond_uuid_log(void)
+{
+       char uuid_str[LTTNG_UUID_STR_LEN];
+
+       lttng_uuid_to_str(the_sessiond_uuid, uuid_str);
+       DBG("Starting lttng-sessiond {%s}", uuid_str);
+}
+
 /*
  * main
  */
@@ -1356,6 +1400,7 @@ int main(int argc, char **argv)
        struct lttng_thread *notification_thread = NULL;
        struct lttng_thread *register_apps_thread = NULL;
 
+       logger_set_thread_name("Main", false);
        init_kernel_workarounds();
 
        rcu_register_thread();
@@ -1370,14 +1415,14 @@ int main(int argc, char **argv)
                goto exit_set_signal_handler;
        }
 
-       page_size = sysconf(_SC_PAGESIZE);
-       if (page_size < 0) {
+       the_page_size = sysconf(_SC_PAGESIZE);
+       if (the_page_size < 0) {
                PERROR("sysconf _SC_PAGESIZE");
-               page_size = LONG_MAX;
-               WARN("Fallback page size to %ld", page_size);
+               the_page_size = LONG_MAX;
+               WARN("Fallback page size to %ld", the_page_size);
        }
 
-       ret = sessiond_config_init(&config);
+       ret = sessiond_config_init(&the_config);
        if (ret) {
                retval = -1;
                goto exit_set_signal_handler;
@@ -1387,7 +1432,7 @@ int main(int argc, char **argv)
         * Init config from environment variables.
         * Command line option override env configuration per-doc. Do env first.
         */
-       sessiond_config_apply_env_config(&config);
+       sessiond_config_apply_env_config(&the_config);
 
        /*
         * Parse arguments and load the daemon configuration file.
@@ -1409,29 +1454,36 @@ int main(int argc, char **argv)
         * since daemonizing causes the sessiond's current working directory
         * to '/'.
         */
-       ret = sessiond_config_resolve_paths(&config);
+       ret = sessiond_config_resolve_paths(&the_config);
        if (ret) {
                goto exit_options;
        }
 
        /* Apply config. */
-       lttng_opt_verbose = config.verbose;
-       lttng_opt_quiet = config.quiet;
-       kconsumer_data.err_unix_sock_path =
-                       config.kconsumerd_err_unix_sock_path.value;
-       kconsumer_data.cmd_unix_sock_path =
-                       config.kconsumerd_cmd_unix_sock_path.value;
-       ustconsumer32_data.err_unix_sock_path =
-                       config.consumerd32_err_unix_sock_path.value;
-       ustconsumer32_data.cmd_unix_sock_path =
-                       config.consumerd32_cmd_unix_sock_path.value;
-       ustconsumer64_data.err_unix_sock_path =
-                       config.consumerd64_err_unix_sock_path.value;
-       ustconsumer64_data.cmd_unix_sock_path =
-                       config.consumerd64_cmd_unix_sock_path.value;
+       lttng_opt_verbose = the_config.verbose;
+       lttng_opt_quiet = the_config.quiet;
+       the_kconsumer_data.err_unix_sock_path =
+                       the_config.kconsumerd_err_unix_sock_path.value;
+       the_kconsumer_data.cmd_unix_sock_path =
+                       the_config.kconsumerd_cmd_unix_sock_path.value;
+       the_ustconsumer32_data.err_unix_sock_path =
+                       the_config.consumerd32_err_unix_sock_path.value;
+       the_ustconsumer32_data.cmd_unix_sock_path =
+                       the_config.consumerd32_cmd_unix_sock_path.value;
+       the_ustconsumer64_data.err_unix_sock_path =
+                       the_config.consumerd64_err_unix_sock_path.value;
+       the_ustconsumer64_data.cmd_unix_sock_path =
+                       the_config.consumerd64_cmd_unix_sock_path.value;
        set_clock_plugin_env();
 
-       sessiond_config_log(&config);
+       sessiond_config_log(&the_config);
+       sessiond_uuid_log();
+
+       if (opt_print_version) {
+               print_version();
+               retval = 0;
+               goto exit_options;
+       }
 
        if (create_lttng_rundir()) {
                retval = -1;
@@ -1446,11 +1498,11 @@ int main(int argc, char **argv)
        }
 
        /* Daemonize */
-       if (config.daemonize || config.background) {
+       if (the_config.daemonize || the_config.background) {
                int i;
 
-               ret = lttng_daemonize(&child_ppid, &recv_child_signal,
-                       !config.background);
+               ret = lttng_daemonize(&the_child_ppid, &recv_child_signal,
+                               !the_config.background);
                if (ret < 0) {
                        retval = -1;
                        goto exit_options;
@@ -1469,7 +1521,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;
        }
 
@@ -1482,8 +1534,8 @@ int main(int argc, char **argv)
         * Initialize the health check subsystem. This call should set the
         * appropriate time values.
         */
-       health_sessiond = health_app_create(NR_HEALTH_SESSIOND_TYPES);
-       if (!health_sessiond) {
+       the_health_sessiond = health_app_create(NR_HEALTH_SESSIOND_TYPES);
+       if (!the_health_sessiond) {
                PERROR("health_app_create error");
                retval = -1;
                goto stop_threads;
@@ -1513,18 +1565,18 @@ int main(int argc, char **argv)
                        retval = -1;
                        goto stop_threads;
                }
-               kconsumer_data.channel_monitor_pipe =
+               the_kconsumer_data.channel_monitor_pipe =
                                lttng_pipe_release_writefd(
-                                       kernel_channel_monitor_pipe);
-               if (kconsumer_data.channel_monitor_pipe < 0) {
+                                               kernel_channel_monitor_pipe);
+               if (the_kconsumer_data.channel_monitor_pipe < 0) {
                        retval = -1;
                        goto stop_threads;
                }
        }
 
        /* Set consumer initial state */
-       kernel_consumerd_state = CONSUMER_STOPPED;
-       ust_consumerd_state = CONSUMER_STOPPED;
+       the_kernel_consumerd_state = CONSUMER_STOPPED;
+       the_ust_consumerd_state = CONSUMER_STOPPED;
 
        ust32_channel_monitor_pipe = lttng_pipe_open(0);
        if (!ust32_channel_monitor_pipe) {
@@ -1532,9 +1584,9 @@ int main(int argc, char **argv)
                retval = -1;
                goto stop_threads;
        }
-       ustconsumer32_data.channel_monitor_pipe = lttng_pipe_release_writefd(
-                       ust32_channel_monitor_pipe);
-       if (ustconsumer32_data.channel_monitor_pipe < 0) {
+       the_ustconsumer32_data.channel_monitor_pipe =
+                       lttng_pipe_release_writefd(ust32_channel_monitor_pipe);
+       if (the_ustconsumer32_data.channel_monitor_pipe < 0) {
                retval = -1;
                goto stop_threads;
        }
@@ -1558,9 +1610,9 @@ int main(int argc, char **argv)
                retval = -1;
                goto stop_threads;
        }
-       ustconsumer64_data.channel_monitor_pipe = lttng_pipe_release_writefd(
-                       ust64_channel_monitor_pipe);
-       if (ustconsumer64_data.channel_monitor_pipe < 0) {
+       the_ustconsumer64_data.channel_monitor_pipe =
+                       lttng_pipe_release_writefd(ust64_channel_monitor_pipe);
+       if (the_ustconsumer64_data.channel_monitor_pipe < 0) {
                retval = -1;
                goto stop_threads;
        }
@@ -1575,6 +1627,8 @@ int main(int argc, char **argv)
                goto stop_threads;
        }
 
+       event_notifier_error_accounting_init(the_config.event_notifier_error_counter_bucket);
+
        /*
         * Initialize agent app hash table. We allocate the hash table here
         * since cleanup() can get called after this point.
@@ -1585,6 +1639,11 @@ int main(int argc, char **argv)
                goto stop_threads;
        }
 
+       if (agent_by_event_notifier_domain_ht_create()) {
+               ERR("Failed to allocate per-event notifier domain agent hash table");
+               retval = -1;
+               goto stop_threads;
+       }
        /*
         * These actions must be executed as root. We do that *after* setting up
         * the sockets path because we MUST make the check for another daemon using
@@ -1592,22 +1651,14 @@ int main(int argc, char **argv)
         * kernel tracer.
         */
        if (is_root) {
-               if (set_consumer_sockets(&kconsumer_data)) {
+               if (set_consumer_sockets(&the_kconsumer_data)) {
                        retval = -1;
                        goto stop_threads;
                }
 
                /* Setup kernel tracer */
-               if (!config.no_kernel) {
+               if (!the_config.no_kernel) {
                        init_kernel_tracer();
-                       if (kernel_tracer_fd >= 0) {
-                               ret = syscall_init_table();
-                               if (ret < 0) {
-                                       ERR("Unable to populate syscall table. "
-                                               "Syscall tracing won't work "
-                                               "for this session daemon.");
-                               }
-                       }
                }
 
                /* Set ulimit for open files */
@@ -1616,30 +1667,24 @@ int main(int argc, char **argv)
        /* init lttng_fd tracking must be done after set_ulimit. */
        lttng_fd_init();
 
-       if (set_consumer_sockets(&ustconsumer64_data)) {
-               retval = -1;
-               goto stop_threads;
-       }
-
-       if (set_consumer_sockets(&ustconsumer32_data)) {
+       if (set_consumer_sockets(&the_ustconsumer64_data)) {
                retval = -1;
                goto stop_threads;
        }
 
-       /* Set credentials to socket */
-       if (is_root && set_permissions(config.rundir.value)) {
+       if (set_consumer_sockets(&the_ustconsumer32_data)) {
                retval = -1;
                goto stop_threads;
        }
 
        /* Get parent pid if -S, --sig-parent is specified. */
-       if (config.sig_parent) {
-               ppid = getppid();
+       if (the_config.sig_parent) {
+               the_ppid = getppid();
        }
 
        /* Setup the kernel pipe for waking up the kernel thread */
-       if (is_root && !config.no_kernel) {
-               if (utils_create_pipe_cloexec(kernel_poll_pipe)) {
+       if (is_root && !the_config.no_kernel) {
+               if (utils_create_pipe_cloexec(the_kernel_poll_pipe)) {
                        retval = -1;
                        goto stop_threads;
                }
@@ -1669,9 +1714,9 @@ int main(int argc, char **argv)
        /* Check for the application socket timeout env variable. */
        env_app_timeout = getenv(DEFAULT_APP_SOCKET_TIMEOUT_ENV);
        if (env_app_timeout) {
-               config.app_socket_timeout = atoi(env_app_timeout);
+               the_config.app_socket_timeout = atoi(env_app_timeout);
        } else {
-               config.app_socket_timeout = DEFAULT_APP_SOCKET_RW_TIMEOUT;
+               the_config.app_socket_timeout = DEFAULT_APP_SOCKET_RW_TIMEOUT;
        }
 
        ret = write_pidfile();
@@ -1693,11 +1738,10 @@ int main(int argc, char **argv)
        }
 
        /* notification_thread_data acquires the pipes' read side. */
-       notification_thread_handle = notification_thread_handle_create(
-                       ust32_channel_monitor_pipe,
-                       ust64_channel_monitor_pipe,
+       the_notification_thread_handle = notification_thread_handle_create(
+                       ust32_channel_monitor_pipe, ust64_channel_monitor_pipe,
                        kernel_channel_monitor_pipe);
-       if (!notification_thread_handle) {
+       if (!the_notification_thread_handle) {
                retval = -1;
                ERR("Failed to create notification thread shared data");
                goto stop_threads;
@@ -1705,7 +1749,7 @@ int main(int argc, char **argv)
 
        /* Create notification thread. */
        notification_thread = launch_notification_thread(
-                       notification_thread_handle);
+                       the_notification_thread_handle);
        if (!notification_thread) {
                retval = -1;
                goto stop_threads;
@@ -1719,8 +1763,7 @@ int main(int argc, char **argv)
 
        /* rotation_thread_data acquires the pipes' read side. */
        rotation_thread_handle = rotation_thread_handle_create(
-                       rotation_timer_queue,
-                       notification_thread_handle);
+                       rotation_timer_queue, the_notification_thread_handle);
        if (!rotation_thread_handle) {
                retval = -1;
                ERR("Failed to create rotation thread shared data");
@@ -1741,6 +1784,12 @@ int main(int argc, char **argv)
                goto stop_threads;
        }
 
+       /* Set credentials of the client socket and rundir */
+       if (is_root && set_permissions(the_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;
@@ -1774,17 +1823,29 @@ int main(int argc, char **argv)
        }
 
        /* Don't start this thread if kernel tracing is not requested nor root */
-       if (is_root && !config.no_kernel) {
+       if (is_root && !the_config.no_kernel) {
                /* Create kernel thread to manage kernel event */
-               if (!launch_kernel_management_thread(kernel_poll_pipe[0])) {
+               if (!launch_kernel_management_thread(the_kernel_poll_pipe[0])) {
                        retval = -1;
                        goto stop_threads;
                }
+
+               if (kernel_get_notification_fd() >= 0) {
+                       ret = notification_thread_command_add_tracer_event_source(
+                                       the_notification_thread_handle,
+                                       kernel_get_notification_fd(),
+                                       LTTNG_DOMAIN_KERNEL);
+                       if (ret != LTTNG_OK) {
+                               ERR("Failed to add kernel trigger event source to notification thread");
+                               retval = -1;
+                               goto stop_threads;
+                       }
+               }
        }
 
        /* Load sessions. */
-       ret = config_load_session(config.load_session_path.value,
-                       NULL, 1, 1, NULL);
+       ret = config_load_session(
+                       the_config.load_session_path.value, NULL, 1, 1, NULL);
        if (ret) {
                ERR("Session load failed: %s", error_get_str(ret));
                retval = -1;
@@ -1800,9 +1861,10 @@ int main(int argc, char **argv)
         */
 
        /* Initiate teardown once activity occurs on the quit pipe. */
-       sessiond_wait_for_quit_pipe(-1U);
+       sessiond_wait_for_quit_pipe(-1);
 
 stop_threads:
+
        /*
         * Ensure that the client thread is no longer accepting new commands,
         * which could cause new sessions to be created.
@@ -1814,6 +1876,13 @@ stop_threads:
 
        destroy_all_sessions_and_wait();
 
+       /*
+        * At this point no new trigger can be registered (no sessions are
+        * running/rotating) and clients can't connect to the session daemon
+        * anymore. Unregister all triggers.
+        */
+       unregister_all_triggers();
+
        if (register_apps_thread) {
                lttng_thread_shutdown(register_apps_thread);
                lttng_thread_put(register_apps_thread);
@@ -1833,11 +1902,39 @@ stop_threads:
        rcu_thread_online();
        sessiond_cleanup();
 
+       /*
+        * Wait for all pending call_rcu work to complete before shutting down
+        * the notification thread. This call_rcu work includes shutting down
+        * UST apps and event notifier pipes.
+        */
+       rcu_barrier();
+
        if (notification_thread) {
                lttng_thread_shutdown(notification_thread);
                lttng_thread_put(notification_thread);
        }
 
+       /*
+        * Error accounting teardown has to be done after the teardown of all
+        * event notifier pipes to ensure that no tracer may try to use the
+        * error accounting facilities.
+        */
+       event_notifier_error_accounting_fini();
+
+       /*
+        * Unloading the kernel modules needs to be done after all kernel
+        * ressources have been released. In our case, this includes the
+        * notification fd, the event notifier group fd, error accounting fd,
+        * all event and event notifier fds, etc.
+        *
+        * In short, at this point, we need to have called close() on all fds
+        * received from the kernel tracer.
+        */
+       if (is_root && !the_config.no_kernel) {
+               DBG("Unloading kernel modules");
+               modprobe_remove_lttng_all();
+       }
+
        /*
         * Ensure all prior call_rcu are done. call_rcu callbacks may push
         * hash tables to the ht_cleanup thread. Therefore, we ensure that
@@ -1867,14 +1964,17 @@ stop_threads:
         * session daemon's teardown in order to allow it to be notified
         * of the active session and channels at the moment of the teardown.
         */
-       if (notification_thread_handle) {
-               notification_thread_handle_destroy(notification_thread_handle);
+       if (the_notification_thread_handle) {
+               notification_thread_handle_destroy(
+                               the_notification_thread_handle);
        }
        lttng_pipe_destroy(ust32_channel_monitor_pipe);
        lttng_pipe_destroy(ust64_channel_monitor_pipe);
        lttng_pipe_destroy(kernel_channel_monitor_pipe);
 
-       health_app_destroy(health_sessiond);
+       if (the_health_sessiond) {
+               health_app_destroy(the_health_sessiond);
+       }
 exit_create_run_as_worker_cleanup:
 exit_options:
        sessiond_cleanup_lock_file();
This page took 0.043686 seconds and 4 git commands to generate.