X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fmain.c;h=ee4d0c78ec499800cd5e149c95a02afa4f3a53e4;hb=70eb2f6fb8b5ee08fce4c970a498c0cdc3e69bf3;hp=d733f7061a854d4d846954704018383a1acd1aa2;hpb=412d7227e69ec845e44c49082a417f9454d9b55d;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index d733f7061..ee4d0c78e 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -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"); @@ -1322,7 +1377,6 @@ static void unregister_all_triggers(void) assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); for (i = 0; i < trigger_count; i++) { - enum lttng_error_code ret_code; uid_t trigger_owner; const char *trigger_name; const struct lttng_trigger *trigger = @@ -1335,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); @@ -1400,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(); @@ -1628,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