Clean-up: sessiond: return an lttng_error_code from list_triggers
[lttng-tools.git] / src / bin / lttng-sessiond / main.c
index bca33a4f8a0f669d6e4f278ce15a9c65c444478d..ee4d0c78ec499800cd5e149c95a02afa4f3a53e4 100644 (file)
@@ -75,6 +75,7 @@
 #include "manage-apps.h"
 #include "manage-kernel.h"
 #include "modprobe.h"
+#include "ust-sigbus.h"
 
 static const char *help_msg =
 #ifdef LTTNG_EMBED_HELP
@@ -85,6 +86,13 @@ NULL
 ;
 
 #define EVENT_NOTIFIER_ERROR_COUNTER_NUMBER_OF_BUCKET_MAX 65535
+#define EVENT_NOTIFIER_ERROR_BUFFER_SIZE_BASE_OPTION_STR \
+               "event-notifier-error-buffer-size"
+#define EVENT_NOTIFIER_ERROR_BUFFER_SIZE_KERNEL_OPTION_STR \
+               EVENT_NOTIFIER_ERROR_BUFFER_SIZE_BASE_OPTION_STR "-kernel"
+#define EVENT_NOTIFIER_ERROR_BUFFER_SIZE_USERSPACE_OPTION_STR \
+               EVENT_NOTIFIER_ERROR_BUFFER_SIZE_BASE_OPTION_STR "-userspace"
+
 
 const char *progname;
 static int lockfile_fd = -1;
@@ -123,7 +131,8 @@ 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' },
+       { EVENT_NOTIFIER_ERROR_BUFFER_SIZE_KERNEL_OPTION_STR, required_argument, 0, '\0' },
+       { EVENT_NOTIFIER_ERROR_BUFFER_SIZE_USERSPACE_OPTION_STR, required_argument, 0, '\0' },
        { NULL, 0, 0, 0 }
 };
 
@@ -713,22 +722,43 @@ static int set_option(int opt, const char *arg, const char *optname)
                                ret = -ENOMEM;
                        }
                }
-       } else if (string_match(optname, "event-notifier-error-number-of-bucket")) {
+       } else if (string_match(optname, EVENT_NOTIFIER_ERROR_BUFFER_SIZE_KERNEL_OPTION_STR)) {
                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);
+                       ERR("Wrong value in --%s parameter: %s",
+                                       EVENT_NOTIFIER_ERROR_BUFFER_SIZE_KERNEL_OPTION_STR, 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);
+                       ERR("Value out of range for --%s parameter: %s",
+                                       EVENT_NOTIFIER_ERROR_BUFFER_SIZE_KERNEL_OPTION_STR, 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);
+               the_config.event_notifier_buffer_size_kernel = (int) v;
+               DBG3("Number of event notifier error buffer kernel size to non default: %i",
+                               the_config.event_notifier_buffer_size_kernel);
+               goto end;
+       } else if (string_match(optname, EVENT_NOTIFIER_ERROR_BUFFER_SIZE_USERSPACE_OPTION_STR)) {
+               unsigned long v;
+
+               errno = 0;
+               v = strtoul(arg, NULL, 0);
+               if (errno != 0 || !isdigit(arg[0])) {
+                       ERR("Wrong value in --%s parameter: %s",
+                                       EVENT_NOTIFIER_ERROR_BUFFER_SIZE_USERSPACE_OPTION_STR, arg);
+                       return -1;
+               }
+               if (v == 0 || v >= EVENT_NOTIFIER_ERROR_COUNTER_NUMBER_OF_BUCKET_MAX) {
+                       ERR("Value out of range for --%s parameter: %s",
+                                       EVENT_NOTIFIER_ERROR_BUFFER_SIZE_USERSPACE_OPTION_STR, arg);
+                       return -1;
+               }
+               the_config.event_notifier_buffer_size_userspace = (int) v;
+               DBG3("Number of event notifier error buffer userspace size to non default: %i",
+                               the_config.event_notifier_buffer_size_userspace);
                goto end;
        } else if (string_match(optname, "config") || opt == 'f') {
                /* This is handled in set_options() thus silent skip. */
@@ -827,7 +857,7 @@ static int set_options(int argc, char **argv)
        int ret = 0, c = 0, option_index = 0;
        int orig_optopt = optopt, orig_optind = optind;
        char *optstring;
-       const char *config_path = NULL;
+       char *config_path = NULL;
 
        optstring = utils_generate_optstring(long_options,
                        sizeof(long_options) / sizeof(struct option));
@@ -851,6 +881,7 @@ static int set_options(int argc, char **argv)
                        WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
                                "-f, --config");
                } else {
+                       free(config_path);
                        config_path = utils_expand_path(optarg);
                        if (!config_path) {
                                ERR("Failed to resolve path: %s", optarg);
@@ -896,6 +927,7 @@ static int set_options(int argc, char **argv)
        }
 
 end:
+       free(config_path);
        free(optstring);
        return ret;
 }
@@ -1139,7 +1171,7 @@ error:
  * Simply stop all worker threads, leaving main() return gracefully after
  * joining all threads and calling cleanup().
  */
-static void sighandler(int sig)
+static void sighandler(int sig, siginfo_t *siginfo, void *arg)
 {
        switch (sig) {
        case SIGINT:
@@ -1153,6 +1185,23 @@ static void sighandler(int sig)
        case SIGUSR1:
                CMM_STORE_SHARED(recv_child_signal, 1);
                break;
+       case SIGBUS:
+       {
+               int write_ret;
+               const char msg[] = "Received SIGBUS, aborting program.\n";
+
+               lttng_ust_handle_sigbus(siginfo->si_addr);
+               /*
+                * If ustctl did not catch this signal (triggering a
+                * siglongjmp), abort the program. Otherwise, the execution
+                * will resume from the ust-ctl call which caused this error.
+                *
+                * The return value is ignored since the program aborts anyhow.
+                */
+               write_ret = write(STDERR_FILENO, msg, sizeof(msg));
+               (void) write_ret;
+               abort();
+       }
        default:
                break;
        }
@@ -1174,9 +1223,9 @@ static int set_signal_handler(void)
        }
 
        sa.sa_mask = sigset;
-       sa.sa_flags = 0;
+       sa.sa_flags = SA_SIGINFO;
 
-       sa.sa_handler = sighandler;
+       sa.sa_sigaction = sighandler;
        if ((ret = sigaction(SIGTERM, &sa, NULL)) < 0) {
                PERROR("sigaction");
                return ret;
@@ -1192,13 +1241,19 @@ static int set_signal_handler(void)
                return ret;
        }
 
+       if ((ret = sigaction(SIGBUS, &sa, NULL)) < 0) {
+               PERROR("sigaction");
+               return ret;
+       }
+
+       sa.sa_flags = 0;
        sa.sa_handler = SIG_IGN;
        if ((ret = sigaction(SIGPIPE, &sa, NULL)) < 0) {
                PERROR("sigaction");
                return ret;
        }
 
-       DBG("Signal handler set for SIGTERM, SIGUSR1, SIGPIPE and SIGINT");
+       DBG("Signal handler set for SIGTERM, SIGUSR1, SIGPIPE, SIGINT, and SIGBUS");
 
        return ret;
 }
@@ -1302,7 +1357,7 @@ static void unregister_all_triggers(void)
        struct lttng_triggers *triggers = NULL;
        unsigned int trigger_count, i;
        const struct lttng_credentials creds = {
-                       .uid = LTTNG_OPTIONAL_INIT_VALUE(0),
+               .uid = LTTNG_OPTIONAL_INIT_VALUE(0),
        };
 
        DBG("Unregistering all triggers");
@@ -1334,7 +1389,8 @@ static void unregister_all_triggers(void)
                assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
 
                trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
-               assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
+               trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ?
+                               trigger_name : "(anonymous)";
 
                DBG("Unregistering trigger: trigger owner uid = %d, trigger name = '%s'",
                                (int) trigger_owner, trigger_name);
@@ -1399,6 +1455,7 @@ int main(int argc, char **argv)
        struct lttng_thread *client_thread = NULL;
        struct lttng_thread *notification_thread = NULL;
        struct lttng_thread *register_apps_thread = NULL;
+       enum event_notifier_error_accounting_status event_notifier_error_accounting_status;
 
        logger_set_thread_name("Main", false);
        init_kernel_workarounds();
@@ -1627,7 +1684,14 @@ int main(int argc, char **argv)
                goto stop_threads;
        }
 
-       event_notifier_error_accounting_init(the_config.event_notifier_error_counter_bucket);
+       event_notifier_error_accounting_status = event_notifier_error_accounting_init(
+                       the_config.event_notifier_buffer_size_kernel,
+                       the_config.event_notifier_buffer_size_userspace);
+       if (event_notifier_error_accounting_status != EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK) {
+               ERR("Failed to initialize event notifier error accounting system");
+               retval = -1;
+               goto stop_threads;
+       }
 
        /*
         * Initialize agent app hash table. We allocate the hash table here
This page took 0.026186 seconds and 4 git commands to generate.