From 90aa04a116a8be510b9d256b47de6bbb4144fb8b Mon Sep 17 00:00:00 2001 From: Francis Deslauriers Date: Wed, 14 Oct 2020 15:33:19 -0400 Subject: [PATCH] sessiond: Implement kernel event notifier error counter MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Francis Deslauriers Signed-off-by: Jérémie Galarneau Change-Id: I390113873567a98d7e53db605d48b59a60a1074e --- configure.ac | 1 + include/lttng/lttng-error.h | 3 + src/bin/lttng-sessiond/Makefile.am | 1 + .../event-notifier-error-accounting.c | 459 ++++++++++++++++++ .../event-notifier-error-accounting.h | 44 ++ src/bin/lttng-sessiond/kernel.c | 16 +- src/bin/lttng-sessiond/main.c | 31 ++ src/bin/lttng-sessiond/modprobe.c | 8 + .../notification-thread-events.c | 160 ++++++ src/bin/lttng-sessiond/sessiond-config.c | 1 + src/bin/lttng-sessiond/sessiond-config.h | 2 + src/bin/lttng-sessiond/trace-kernel.c | 2 + src/bin/lttng-sessiond/trace-kernel.h | 2 + src/bin/lttng/commands/list_triggers.c | 6 + src/common/defaults.h | 3 + src/common/error.c | 3 + src/common/kernel-ctl/kernel-ctl.c | 21 + src/common/kernel-ctl/kernel-ctl.h | 7 + src/common/kernel-ctl/kernel-ioctl.h | 15 +- src/common/lttng-kernel.h | 66 ++- .../tools/trigger/test_list_triggers_cli | 26 + .../tools/trigger/test_remove_trigger_cli | 3 + tests/unit/Makefile.am | 1 + 23 files changed, 878 insertions(+), 3 deletions(-) create mode 100644 src/bin/lttng-sessiond/event-notifier-error-accounting.c create mode 100644 src/bin/lttng-sessiond/event-notifier-error-accounting.h diff --git a/configure.ac b/configure.ac index 9a40705af..04f9cef4c 100644 --- a/configure.ac +++ b/configure.ac @@ -422,6 +422,7 @@ _AC_DEFINE_QUOTED_AND_SUBST([DEFAULT_NETWORK_DATA_BIND_ADDRESS], [0.0.0.0]) _AC_DEFINE_QUOTED_AND_SUBST([DEFAULT_NETWORK_VIEWER_BIND_ADDRESS], [localhost]) _AC_DEFINE_AND_SUBST([DEFAULT_NETWORK_RELAYD_CTRL_MAX_PAYLOAD_SIZE], [134217728]) _AC_DEFINE_AND_SUBST([DEFAULT_ROTATE_PENDING_TIMER], [500000]) +_AC_DEFINE_AND_SUBST([DEFAULT_EVENT_NOTIFIER_ERROR_COUNT_MAP_SIZE], [4096]) # Command short descriptions _AC_DEFINE_QUOTED_AND_SUBST([CMD_DESCR_ADD_CONTEXT], [Add context fields to a channel]) diff --git a/include/lttng/lttng-error.h b/include/lttng/lttng-error.h index 606d8b0b2..fa4876be6 100644 --- a/include/lttng/lttng-error.h +++ b/include/lttng/lttng-error.h @@ -176,6 +176,9 @@ enum lttng_error_code { LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY = 163, /* Operation does not apply to the process attribute tracker's tracking policy */ LTTNG_ERR_EVENT_NOTIFIER_GROUP_NOTIFICATION_FD = 164, /* Error initializing event notifier group notification file descriptor */ LTTNG_ERR_INVALID_CAPTURE_EXPRESSION = 165, /* Invalid capture expression. */ + LTTNG_ERR_EVENT_NOTIFIER_REGISTRATION = 166, /* Error registering event notifier to the tracer. */ + LTTNG_ERR_EVENT_NOTIFIER_ERROR_ACCOUNTING = 167, /* Error initializing event notifier error accounting. */ + LTTNG_ERR_EVENT_NOTIFIER_ERROR_ACCOUNTING_FULL = 168, /* Error event notifier error accounting full. */ /* MUST be last element of the manually-assigned section of the enum */ LTTNG_ERR_NR, diff --git a/src/bin/lttng-sessiond/Makefile.am b/src/bin/lttng-sessiond/Makefile.am index e71c10814..e3ee7612d 100644 --- a/src/bin/lttng-sessiond/Makefile.am +++ b/src/bin/lttng-sessiond/Makefile.am @@ -55,6 +55,7 @@ lttng_sessiond_SOURCES = utils.c utils.h \ manage-consumer.c manage-consumer.h \ clear.c clear.h \ tracker.c tracker.h \ + event-notifier-error-accounting.c event-notifier-error-accounting.h \ action-executor.c action-executor.h if HAVE_LIBLTTNG_UST_CTL diff --git a/src/bin/lttng-sessiond/event-notifier-error-accounting.c b/src/bin/lttng-sessiond/event-notifier-error-accounting.c new file mode 100644 index 000000000..628ddcfbf --- /dev/null +++ b/src/bin/lttng-sessiond/event-notifier-error-accounting.c @@ -0,0 +1,459 @@ +/* + * Copyright (C) 2020 Francis Deslauriers + * + * SPDX-License-Identifier: GPL-2.0-only + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "event-notifier-error-accounting.h" + +#define ERROR_COUNTER_INDEX_HT_INITIAL_SIZE 16 + +struct index_ht_entry { + struct lttng_ht_node_u64 node; + uint64_t error_counter_index; + struct rcu_head rcu_head; +}; + +struct kernel_error_account_entry { + int kernel_event_notifier_error_counter_fd; +}; + +static struct kernel_error_account_entry kernel_error_accountant; + +/* Hashtable mapping event notifier token to index_ht_entry. */ +static struct lttng_ht *error_counter_indexes_ht; + +static uint64_t error_counter_size; +static struct lttng_index_allocator *index_allocator; + +static inline +const char *error_accounting_status_str( + enum event_notifier_error_accounting_status status) +{ + switch (status) { + case EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK: + return "OK"; + case EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_ERR: + return "ERROR"; + case EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_NOT_FOUND: + return "NOT_FOUND"; + case EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_NOMEM: + return "NOMEM"; + case EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_NO_INDEX_AVAILABLE: + return "NO_INDEX_AVAILABLE"; + default: + abort(); + } +} + +enum event_notifier_error_accounting_status +event_notifier_error_accounting_init(uint64_t nb_bucket) +{ + enum event_notifier_error_accounting_status status; + + index_allocator = lttng_index_allocator_create(nb_bucket); + if (!index_allocator) { + ERR("Failed to allocate event notifier error counter index"); + status = EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_NOMEM; + goto error_index_allocator; + } + + error_counter_indexes_ht = lttng_ht_new( + ERROR_COUNTER_INDEX_HT_INITIAL_SIZE, LTTNG_HT_TYPE_U64); + if (!error_counter_indexes_ht) { + status = EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_NOMEM; + goto error_index_allocator; + } + + error_counter_size = nb_bucket; + + status = EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK; + +error_index_allocator: + return status; +} + +static +enum event_notifier_error_accounting_status get_error_counter_index_for_token( + uint64_t tracer_token, uint64_t *error_counter_index) +{ + struct lttng_ht_node_u64 *node; + struct lttng_ht_iter iter; + const struct index_ht_entry *index_entry; + enum event_notifier_error_accounting_status status; + + rcu_read_lock(); + lttng_ht_lookup(error_counter_indexes_ht, &tracer_token, &iter); + node = lttng_ht_iter_get_node_u64(&iter); + if (node) { + index_entry = caa_container_of( + node, const struct index_ht_entry, node); + *error_counter_index = index_entry->error_counter_index; + status = EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK; + } else { + status = EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_NOT_FOUND; + } + + rcu_read_unlock(); + return status; +} + +static +enum event_notifier_error_accounting_status +event_notifier_error_accounting_kernel_clear( + const struct lttng_trigger *trigger) +{ + int ret; + uint64_t error_counter_index; + enum event_notifier_error_accounting_status status; + struct lttng_kernel_counter_clear counter_clear = {}; + + status = get_error_counter_index_for_token( + lttng_trigger_get_tracer_token(trigger), + &error_counter_index); + if (status != EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK) { + uid_t trigger_owner_uid; + const char *trigger_name; + const enum lttng_trigger_status trigger_status = + lttng_trigger_get_owner_uid( + trigger, &trigger_owner_uid); + + assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); + if (lttng_trigger_get_name(trigger, &trigger_name) != + LTTNG_TRIGGER_STATUS_OK) { + trigger_name = "(unnamed)"; + } + + ERR("Failed to get event notifier error counter index: trigger owner uid = %d, trigger name = '%s'", + trigger_owner_uid, trigger_name); + goto end; + } + + counter_clear.index.number_dimensions = 1; + counter_clear.index.dimension_indexes[0] = error_counter_index; + + ret = kernctl_counter_clear( + kernel_error_accountant.kernel_event_notifier_error_counter_fd, + &counter_clear); + if (ret) { + ERR("Failed to clear event notifier error counter"); + status = EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_ERR; + goto end; + } + + status = EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK; +end: + return status; +} + +enum event_notifier_error_accounting_status +event_notifier_error_accounting_register_kernel( + int kernel_event_notifier_group_fd) +{ + int error_counter_fd = -1, ret; + enum event_notifier_error_accounting_status status; + const struct lttng_kernel_counter_conf error_counter_conf = { + .arithmetic = LTTNG_KERNEL_COUNTER_ARITHMETIC_MODULAR, + .bitness = sizeof(void *) == sizeof(uint32_t) ? + LTTNG_KERNEL_COUNTER_BITNESS_32 : + LTTNG_KERNEL_COUNTER_BITNESS_64, + .global_sum_step = 0, + .number_dimensions = 1, + .dimensions[0].size = error_counter_size, + .dimensions[0].has_underflow = false, + .dimensions[0].has_overflow = false, + }; + + ret = kernctl_create_event_notifier_group_error_counter( + kernel_event_notifier_group_fd, &error_counter_conf); + if (ret < 0) { + PERROR("Failed to create event notifier group error counter through kernel ioctl: kernel_event_notifier_group_fd = %d", + kernel_event_notifier_group_fd); + status = EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_ERR; + goto error; + } + + error_counter_fd = ret; + + /* Prevent fd duplication after execlp(). */ + ret = fcntl(error_counter_fd, F_SETFD, FD_CLOEXEC); + if (ret < 0) { + PERROR("Failed to set FD_CLOEXEC flag on event notifier error counter file descriptor: error_counter_fd = %d", + error_counter_fd); + status = EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_ERR; + goto error; + } + + DBG("Created kernel event notifier group error counter: fd = %d", + error_counter_fd); + + kernel_error_accountant.kernel_event_notifier_error_counter_fd = + error_counter_fd; + status = EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK; + +error: + return status; +} + +static +enum event_notifier_error_accounting_status create_error_counter_index_for_token( + uint64_t tracer_token, uint64_t *error_counter_index) +{ + struct index_ht_entry *index_entry; + enum lttng_index_allocator_status index_alloc_status; + uint64_t local_error_counter_index; + enum event_notifier_error_accounting_status status; + + /* Allocate a new index for that counter. */ + index_alloc_status = lttng_index_allocator_alloc(index_allocator, + &local_error_counter_index); + switch (index_alloc_status) { + case LTTNG_INDEX_ALLOCATOR_STATUS_EMPTY: + DBG("No indices left in the configured event notifier error counter: " + "number-of-indices = %"PRIu64, + lttng_index_allocator_get_index_count( + index_allocator)); + status = EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_NO_INDEX_AVAILABLE; + goto end; + case LTTNG_INDEX_ALLOCATOR_STATUS_OK: + break; + default: + status = EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_ERR; + goto end; + } + + index_entry = zmalloc(sizeof(*index_entry)); + if (index_entry == NULL) { + PERROR("Failed to allocate event notifier error counter hash table entry"); + status = EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_NOMEM; + goto end; + } + + index_entry->error_counter_index = local_error_counter_index; + lttng_ht_node_init_u64(&index_entry->node, tracer_token); + lttng_ht_add_unique_u64(error_counter_indexes_ht, &index_entry->node); + + DBG("Allocated error counter index for tracer token: tracer token = %" PRIu64 ", index = %" PRIu64, + tracer_token, local_error_counter_index); + *error_counter_index = local_error_counter_index; + status = EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK; +end: + return status; +} + +enum event_notifier_error_accounting_status +event_notifier_error_accounting_register_event_notifier( + const struct lttng_trigger *trigger, + uint64_t *error_counter_index) +{ + enum event_notifier_error_accounting_status status; + uint64_t local_error_counter_index; + + /* + * Check if this event notifier already has a error counter index + * assigned. + */ + status = get_error_counter_index_for_token( + lttng_trigger_get_tracer_token(trigger), + &local_error_counter_index); + switch (status) { + case EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_NOT_FOUND: + { + uid_t trigger_owner_uid; + const char *trigger_name; + const enum lttng_trigger_status trigger_status = + lttng_trigger_get_owner_uid( + trigger, &trigger_owner_uid); + + assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); + if (lttng_trigger_get_name(trigger, &trigger_name) != + LTTNG_TRIGGER_STATUS_OK) { + trigger_name = "(unnamed)"; + } + + DBG("Event notifier error counter index not found for tracer token (allocating a new one): trigger owner = %d, trigger name = '%s', tracer token = %" PRIu64, + trigger_owner_uid, trigger_name, + lttng_trigger_get_tracer_token(trigger)); + status = create_error_counter_index_for_token( + lttng_trigger_get_tracer_token(trigger), + &local_error_counter_index); + if (status != EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK) { + goto end; + } + /* fall-through. */ + } + case EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK: + *error_counter_index = local_error_counter_index; + status = EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK; + break; + default: + break; + } + +end: + return status; +} + +static +enum event_notifier_error_accounting_status +event_notifier_error_accounting_kernel_get_count( + const struct lttng_trigger *trigger, uint64_t *count) +{ + struct lttng_kernel_counter_aggregate counter_aggregate = {}; + enum event_notifier_error_accounting_status status; + uint64_t error_counter_index; + int ret; + + status = get_error_counter_index_for_token( + lttng_trigger_get_tracer_token(trigger), &error_counter_index); + if (status != EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK) { + goto end; + } + + counter_aggregate.index.number_dimensions = 1; + counter_aggregate.index.dimension_indexes[0] = error_counter_index; + + assert(kernel_error_accountant.kernel_event_notifier_error_counter_fd); + + ret = kernctl_counter_get_aggregate_value( + kernel_error_accountant.kernel_event_notifier_error_counter_fd, + &counter_aggregate); + if (ret || counter_aggregate.value.value < 0) { + uid_t trigger_owner_uid; + const char *trigger_name; + const enum lttng_trigger_status trigger_status = + lttng_trigger_get_owner_uid( + trigger, &trigger_owner_uid); + + assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); + if (lttng_trigger_get_name(trigger, &trigger_name) != + LTTNG_TRIGGER_STATUS_OK) { + trigger_name = "(unnamed)"; + } + + if (counter_aggregate.value.value < 0) { + ERR("Invalid negative event notifier error counter value: trigger owner = %d, trigger name = '%s', value = %" PRId64, + trigger_owner_uid, trigger_name, + counter_aggregate.value.value); + } else { + ERR("Failed to getting event notifier error count: trigger owner = %d, trigger name = '%s', ret = %d", + trigger_owner_uid, trigger_name, ret); + } + + status = EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_ERR; + goto end; + } + + /* Error count can't be negative. */ + assert(counter_aggregate.value.value >= 0); + *count = (uint64_t) counter_aggregate.value.value; + + status = EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK; + +end: + return status; +} + +enum event_notifier_error_accounting_status +event_notifier_error_accounting_get_count( + const struct lttng_trigger *trigger, uint64_t *count) +{ + switch (lttng_trigger_get_underlying_domain_type_restriction(trigger)) { + case LTTNG_DOMAIN_KERNEL: + return event_notifier_error_accounting_kernel_get_count( + trigger, count); + case LTTNG_DOMAIN_UST: + return EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK; + default: + abort(); + } +} + +static +enum event_notifier_error_accounting_status +event_notifier_error_accounting_clear(const struct lttng_trigger *trigger) +{ + switch (lttng_trigger_get_underlying_domain_type_restriction(trigger)) { + case LTTNG_DOMAIN_KERNEL: + return event_notifier_error_accounting_kernel_clear(trigger); + case LTTNG_DOMAIN_UST: + return EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK; + default: + abort(); + } +} + +static void free_index_ht_entry(struct rcu_head *head) +{ + struct index_ht_entry *entry = caa_container_of(head, + struct index_ht_entry, rcu_head); + + free(entry); +} + +void event_notifier_error_accounting_unregister_event_notifier( + const struct lttng_trigger *trigger) +{ + struct lttng_ht_iter iter; + struct lttng_ht_node_u64 *node; + struct index_ht_entry *index_entry; + enum event_notifier_error_accounting_status status; + enum lttng_index_allocator_status index_alloc_status; + uint64_t tracer_token = lttng_trigger_get_tracer_token(trigger); + + status = event_notifier_error_accounting_clear(trigger); + if (status != EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK) { + ERR("Failed to clear event notifier error counter index"); + } + + rcu_read_lock(); + lttng_ht_lookup(error_counter_indexes_ht, &tracer_token, &iter); + node = lttng_ht_iter_get_node_u64(&iter); + if(node) { + index_entry = caa_container_of(node, struct index_ht_entry, node); + index_alloc_status = lttng_index_allocator_release( + index_allocator, + index_entry->error_counter_index); + if (index_alloc_status != LTTNG_INDEX_ALLOCATOR_STATUS_OK) { + ERR("Failed to release event notifier error counter index: index = %" PRIu64, + index_entry->error_counter_index); + } + + lttng_ht_del(error_counter_indexes_ht, &iter); + call_rcu(&index_entry->rcu_head, free_index_ht_entry); + } + + rcu_read_unlock(); +} + +void event_notifier_error_accounting_fini(void) +{ + lttng_index_allocator_destroy(index_allocator); + + if (kernel_error_accountant.kernel_event_notifier_error_counter_fd) { + const int ret = close(kernel_error_accountant.kernel_event_notifier_error_counter_fd); + + if (ret) { + PERROR("Failed to close kernel event notifier error counter"); + } + } + + /* + * Will assert if some error counters were not released (an internal + * error). + */ + lttng_ht_destroy(error_counter_indexes_ht); +} diff --git a/src/bin/lttng-sessiond/event-notifier-error-accounting.h b/src/bin/lttng-sessiond/event-notifier-error-accounting.h new file mode 100644 index 000000000..1dea73948 --- /dev/null +++ b/src/bin/lttng-sessiond/event-notifier-error-accounting.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 Francis Deslauriers + * + * SPDX-License-Identifier: GPL-2.0-only + * + */ + +#ifndef _EVENT_NOTIFIER_ERROR_ACCOUNTING_H +#define _EVENT_NOTIFIER_ERROR_ACCOUNTING_H + +#include +#include + +enum event_notifier_error_accounting_status { + EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK, + EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_ERR, + EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_NOT_FOUND, + EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_NOMEM, + EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_NO_INDEX_AVAILABLE, +}; + +enum event_notifier_error_accounting_status +event_notifier_error_accounting_init(uint64_t nb_bucket); + +enum event_notifier_error_accounting_status +event_notifier_error_accounting_register_kernel( + int kernel_event_notifier_group_fd); + +enum event_notifier_error_accounting_status +event_notifier_error_accounting_register_event_notifier( + const struct lttng_trigger *trigger, + uint64_t *error_counter_index); + +enum event_notifier_error_accounting_status +event_notifier_error_accounting_get_count( + const struct lttng_trigger *trigger, + uint64_t *count); + +void event_notifier_error_accounting_unregister_event_notifier( + const struct lttng_trigger *trigger); + +void event_notifier_error_accounting_fini(void); + +#endif /* _EVENT_NOTIFIER_ERROR_ACCOUNTING_H */ diff --git a/src/bin/lttng-sessiond/kernel.c b/src/bin/lttng-sessiond/kernel.c index 03a358a0d..afeb181c9 100644 --- a/src/bin/lttng-sessiond/kernel.c +++ b/src/bin/lttng-sessiond/kernel.c @@ -34,6 +34,7 @@ #include #include +#include "event-notifier-error-accounting.h" #include "lttng-sessiond.h" #include "lttng-syscall.h" #include "condition-internal.h" @@ -41,6 +42,7 @@ #include "kernel.h" #include "kernel-consumer.h" #include "kern-modules.h" +#include "sessiond-config.h" #include "utils.h" #include "rotate.h" #include "modprobe.h" @@ -1989,7 +1991,8 @@ int init_kernel_tracer(void) WARN("Failed to create kernel event notifier group"); kernel_tracer_event_notifier_group_fd = -1; } else { - const enum lttng_error_code error_code_ret = + enum event_notifier_error_accounting_status error_accounting_status; + enum lttng_error_code error_code_ret = kernel_create_event_notifier_group_notification_fd( &kernel_tracer_event_notifier_group_notification_fd); @@ -1997,6 +2000,14 @@ int init_kernel_tracer(void) goto error_modules; } + error_accounting_status = event_notifier_error_accounting_register_kernel( + kernel_tracer_event_notifier_group_fd); + if (error_accounting_status != EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK) { + ERR("Failed to initialize event notifier error accounting for kernel tracer"); + error_code_ret = LTTNG_ERR_EVENT_NOTIFIER_ERROR_ACCOUNTING; + goto error_modules; + } + kernel_token_to_event_notifier_rule_ht = cds_lfht_new( DEFAULT_HT_SIZE, 1, 0, CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, @@ -2322,6 +2333,7 @@ static enum lttng_error_code kernel_create_event_notifier_rule( assert(event_rule_type != LTTNG_EVENT_RULE_TYPE_UNKNOWN); error_code_ret = trace_kernel_create_event_notifier_rule(trigger, token, + lttng_condition_on_event_get_error_counter_index(condition), &event_notifier_rule); if (error_code_ret != LTTNG_OK) { goto error; @@ -2334,6 +2346,8 @@ static enum lttng_error_code kernel_create_event_notifier_rule( } kernel_event_notifier.event.token = event_notifier_rule->token; + kernel_event_notifier.error_counter_idx = + lttng_condition_on_event_get_error_counter_index(condition); fd = kernctl_create_event_notifier( kernel_tracer_event_notifier_group_fd, diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index 40a418d0c..bb84be1ad 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -49,6 +49,7 @@ #include "consumer.h" #include "context.h" #include "event.h" +#include "event-notifier-error-accounting.h" #include "kernel.h" #include "kernel-consumer.h" #include "lttng-ust-ctl.h" @@ -82,6 +83,8 @@ 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; @@ -119,6 +122,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 } }; @@ -696,6 +700,23 @@ 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")) { + 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; + } + config.event_notifier_error_counter_bucket = (int) v; + DBG3("Number of event notifier error counter set to non default: %i", + 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; @@ -1588,6 +1609,8 @@ int main(int argc, char **argv) goto stop_threads; } + event_notifier_error_accounting_init(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. @@ -1825,6 +1848,7 @@ int main(int argc, char **argv) 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. @@ -1874,6 +1898,13 @@ stop_threads: lttng_thread_put(notification_thread); } + /* + * Teardown of error accounting needs be done after the teardown of the + * notification thread as all error buckets must have been released by + * their users (conditions). + */ + event_notifier_error_accounting_fini(); + /* * Ensure all prior call_rcu are done. call_rcu callbacks may push * hash tables to the ht_cleanup thread. Therefore, we ensure that diff --git a/src/bin/lttng-sessiond/modprobe.c b/src/bin/lttng-sessiond/modprobe.c index 28385ea39..bc2a86d75 100644 --- a/src/bin/lttng-sessiond/modprobe.c +++ b/src/bin/lttng-sessiond/modprobe.c @@ -56,6 +56,14 @@ struct kern_modules_param kern_modules_control_core[] = { .name = (char *) "lttng-ring-buffer-event_notifier-client", .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL, }, + { + .name = (char *) "lttng-counter-client-percpu-64-modular", + .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL, + }, + { + .name = (char *) "lttng-counter-client-percpu-32-modular", + .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL, + }, }; /* LTTng kerneltracer probe modules list */ diff --git a/src/bin/lttng-sessiond/notification-thread-events.c b/src/bin/lttng-sessiond/notification-thread-events.c index 816456cd8..99b6642d6 100644 --- a/src/bin/lttng-sessiond/notification-thread-events.c +++ b/src/bin/lttng-sessiond/notification-thread-events.c @@ -41,6 +41,7 @@ #include #include "condition-internal.h" +#include "event-notifier-error-accounting.h" #include "notification-thread.h" #include "notification-thread-events.h" #include "notification-thread-commands.h" @@ -2123,6 +2124,40 @@ end: return ret; } +static +int condition_on_event_update_error_count(struct lttng_trigger *trigger) +{ + int ret = 0; + uint64_t error_count = 0; + struct lttng_condition *condition; + enum event_notifier_error_accounting_status status; + + condition = lttng_trigger_get_condition(trigger); + assert(lttng_condition_get_type(condition) == + LTTNG_CONDITION_TYPE_ON_EVENT); + + status = event_notifier_error_accounting_get_count(trigger, &error_count); + if (status != EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK) { + uid_t trigger_owner_uid; + const char *trigger_name; + const enum lttng_trigger_status trigger_status = + lttng_trigger_get_owner_uid( + trigger, &trigger_owner_uid); + + assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); + if (lttng_trigger_get_name(trigger, &trigger_name) != LTTNG_TRIGGER_STATUS_OK) { + trigger_name = "(unnamed)"; + } + + ERR("Failed to get event notifier error count of trigger for update: trigger owner = %d, trigger name = '%s'", + trigger_owner_uid, trigger_name); + ret = -1; + } + + lttng_condition_on_event_set_error_count(condition, error_count); + return ret; +} + int handle_notification_thread_remove_tracer_event_source_no_result( struct notification_thread_state *state, int tracer_event_source_fd) @@ -2136,6 +2171,94 @@ int handle_notification_thread_remove_tracer_event_source_no_result( return ret; } +static +bool action_type_needs_tracer_notifier(enum lttng_action_type action_type) +{ + switch (action_type) { + case LTTNG_ACTION_TYPE_NOTIFY: + case LTTNG_ACTION_TYPE_START_SESSION: + case LTTNG_ACTION_TYPE_STOP_SESSION: + case LTTNG_ACTION_TYPE_SNAPSHOT_SESSION: + case LTTNG_ACTION_TYPE_ROTATE_SESSION: + return true; + case LTTNG_ACTION_TYPE_GROUP: + case LTTNG_ACTION_TYPE_UNKNOWN: + default: + abort(); + } +} + +static +bool action_needs_tracer_notifier(const struct lttng_action *action) +{ + bool needs_tracer_notifier = false; + unsigned int i, count; + enum lttng_action_status action_status; + enum lttng_action_type action_type; + + assert(action); + /* If there is only one action. Check if it needs a tracer notifier. */ + action_type = lttng_action_get_type(action); + if (action_type != LTTNG_ACTION_TYPE_GROUP) { + needs_tracer_notifier = action_type_needs_tracer_notifier( + action_type); + goto end; + } + + /* + * Iterate over all the actions of the action group and check if any of + * them needs a tracer notifier. + */ + action_status = lttng_action_group_get_count(action, &count); + assert(action_status == LTTNG_ACTION_STATUS_OK); + for (i = 0; i < count; i++) { + const struct lttng_action *inner_action = + lttng_action_group_get_at_index(action, i); + + action_type = lttng_action_get_type(inner_action); + if (action_type_needs_tracer_notifier(action_type)) { + needs_tracer_notifier = true; + goto end; + } + } + +end: + return needs_tracer_notifier; +} + +/* + * A given trigger needs a tracer notifier if + * it has an event-rule condition, + * AND + * it has one or more sessiond-execution action. + */ +static +bool trigger_needs_tracer_notifier(const struct lttng_trigger *trigger) +{ + bool needs_tracer_notifier = false; + const struct lttng_condition *condition = + lttng_trigger_get_const_condition(trigger); + const struct lttng_action *action = + lttng_trigger_get_const_action(trigger); + + switch (lttng_condition_get_type(condition)) { + case LTTNG_CONDITION_TYPE_ON_EVENT: + needs_tracer_notifier = action_needs_tracer_notifier(action); + goto end; + case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE: + case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH: + case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW: + case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING: + case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED: + goto end; + case LTTNG_CONDITION_TYPE_UNKNOWN: + default: + abort(); + } +end: + return needs_tracer_notifier; +} + static int handle_notification_thread_command_list_triggers( struct notification_thread_handle *handle, struct notification_thread_state *state, @@ -2170,6 +2293,12 @@ static int handle_notification_thread_command_list_triggers( continue; } + if (trigger_needs_tracer_notifier(trigger_ht_element->trigger)) { + ret = condition_on_event_update_error_count( + trigger_ht_element->trigger); + assert(!ret); + } + ret = lttng_triggers_add(local_triggers, trigger_ht_element->trigger); if (ret < 0) { @@ -2569,6 +2698,32 @@ int handle_notification_thread_command_register_trigger( &trigger_ht_element->node_by_name_uid); goto error_free_ht_element; } + + if (trigger_needs_tracer_notifier(trigger)) { + uint64_t error_counter_index = 0; + enum event_notifier_error_accounting_status error_accounting_status; + + error_accounting_status = event_notifier_error_accounting_register_event_notifier( + trigger, &error_counter_index); + if (error_accounting_status != EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK) { + if (error_accounting_status == EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_NO_INDEX_AVAILABLE) { + DBG("Event notifier group error accounting map is full"); + *cmd_result = LTTNG_ERR_EVENT_NOTIFIER_ERROR_ACCOUNTING_FULL; + } else { + ERR("Failed to register event notifier for error accounting"); + *cmd_result = LTTNG_ERR_EVENT_NOTIFIER_REGISTRATION; + } + + cds_lfht_del(state->triggers_ht, &trigger_ht_element->node); + cds_lfht_del(state->triggers_by_name_uid_ht, &trigger_ht_element->node_by_name_uid); + cds_lfht_del(state->trigger_tokens_ht, &trigger_tokens_ht_element->node); + goto error_free_ht_element; + } + + lttng_condition_on_event_set_error_counter_index( + condition, error_counter_index); + } + } /* @@ -2841,6 +2996,11 @@ int handle_notification_thread_command_unregister_trigger( continue; } + if (trigger_needs_tracer_notifier(trigger_tokens_ht_element->trigger)) { + event_notifier_error_accounting_unregister_event_notifier( + trigger_tokens_ht_element->trigger); + } + DBG("[notification-thread] Removed trigger from tokens_ht"); cds_lfht_del(state->trigger_tokens_ht, &trigger_tokens_ht_element->node); diff --git a/src/bin/lttng-sessiond/sessiond-config.c b/src/bin/lttng-sessiond/sessiond-config.c index c7a918307..f8dba15e7 100644 --- a/src/bin/lttng-sessiond/sessiond-config.c +++ b/src/bin/lttng-sessiond/sessiond-config.c @@ -24,6 +24,7 @@ struct sessiond_config sessiond_config_build_defaults = { .verbose_consumer = 0, .agent_tcp_port = { .begin = DEFAULT_AGENT_TCP_PORT_RANGE_BEGIN, .end = DEFAULT_AGENT_TCP_PORT_RANGE_END }, + .event_notifier_error_counter_bucket = DEFAULT_EVENT_NOTIFIER_ERROR_COUNT_MAP_SIZE, .app_socket_timeout = DEFAULT_APP_SOCKET_RW_TIMEOUT, .no_kernel = false, diff --git a/src/bin/lttng-sessiond/sessiond-config.h b/src/bin/lttng-sessiond/sessiond-config.h index 9ce036e70..9369f4cc0 100644 --- a/src/bin/lttng-sessiond/sessiond-config.h +++ b/src/bin/lttng-sessiond/sessiond-config.h @@ -29,6 +29,8 @@ struct sessiond_config { int verbose_consumer; /* Agent TCP port range for registration. Used by the agent thread. */ struct config_int_range agent_tcp_port; + + int event_notifier_error_counter_bucket; /* Socket timeout for receiving and sending (in seconds). */ int app_socket_timeout; diff --git a/src/bin/lttng-sessiond/trace-kernel.c b/src/bin/lttng-sessiond/trace-kernel.c index a453fd8b7..f779952a0 100644 --- a/src/bin/lttng-sessiond/trace-kernel.c +++ b/src/bin/lttng-sessiond/trace-kernel.c @@ -485,6 +485,7 @@ error: enum lttng_error_code trace_kernel_create_event_notifier_rule( struct lttng_trigger *trigger, uint64_t token, + uint64_t error_counter_index, struct ltt_kernel_event_notifier_rule **event_notifier_rule) { enum lttng_error_code ret = LTTNG_OK; @@ -522,6 +523,7 @@ enum lttng_error_code trace_kernel_create_event_notifier_rule( local_kernel_token_event_rule->fd = -1; local_kernel_token_event_rule->enabled = 1; local_kernel_token_event_rule->token = token; + local_kernel_token_event_rule->error_counter_index = error_counter_index; /* Get the reference of the event rule. */ lttng_trigger_get(trigger); diff --git a/src/bin/lttng-sessiond/trace-kernel.h b/src/bin/lttng-sessiond/trace-kernel.h index b89162b7d..c0a244ef0 100644 --- a/src/bin/lttng-sessiond/trace-kernel.h +++ b/src/bin/lttng-sessiond/trace-kernel.h @@ -55,6 +55,7 @@ struct ltt_kernel_event { /* Kernel event */ struct ltt_kernel_event_notifier_rule { int fd; + uint64_t error_counter_index; int enabled; enum lttng_event_type type; struct lttng_trigger *trigger; @@ -168,6 +169,7 @@ struct ltt_kernel_context *trace_kernel_create_context( enum lttng_error_code trace_kernel_create_event_notifier_rule( struct lttng_trigger *trigger, uint64_t token, + uint64_t error_counter_index, struct ltt_kernel_event_notifier_rule **event_notifier_rule); struct ltt_kernel_context *trace_kernel_copy_context( struct ltt_kernel_context *ctx); diff --git a/src/bin/lttng/commands/list_triggers.c b/src/bin/lttng/commands/list_triggers.c index b8fb64a0a..329fd293a 100644 --- a/src/bin/lttng/commands/list_triggers.c +++ b/src/bin/lttng/commands/list_triggers.c @@ -14,6 +14,8 @@ #include "common/mi-lttng.h" /* For lttng_condition_type_str(). */ #include "lttng/condition/condition-internal.h" +#include "lttng/condition/on-event.h" +#include "lttng/condition/on-event-internal.h" /* For lttng_domain_type_str(). */ #include "lttng/domain-internal.h" #include "../loglevel.h" @@ -416,6 +418,7 @@ void print_condition_on_event(const struct lttng_condition *condition) const struct lttng_event_rule *event_rule; enum lttng_condition_status condition_status; unsigned int cap_desc_count, i; + uint64_t error_count; condition_status = lttng_condition_on_event_get_rule(condition, &event_rule); @@ -428,6 +431,9 @@ void print_condition_on_event(const struct lttng_condition *condition) condition, &cap_desc_count); assert(condition_status == LTTNG_CONDITION_STATUS_OK); + error_count = lttng_condition_on_event_get_error_count(condition); + MSG(" tracer notifications discarded: %ld", error_count); + if (cap_desc_count > 0) { MSG(" captures:"); diff --git a/src/common/defaults.h b/src/common/defaults.h index 1e4b7fac7..faff595c6 100644 --- a/src/common/defaults.h +++ b/src/common/defaults.h @@ -279,6 +279,9 @@ #define DEFAULT_AGENT_TCP_PORT_RANGE_BEGIN CONFIG_DEFAULT_AGENT_TCP_PORT_RANGE_BEGIN #define DEFAULT_AGENT_TCP_PORT_RANGE_END CONFIG_DEFAULT_AGENT_TCP_PORT_RANGE_END +/* Number of buckets in the event notifier error count map. */ +#define DEFAULT_EVENT_NOTIFIER_ERROR_COUNT_MAP_SIZE CONFIG_DEFAULT_EVENT_NOTIFIER_ERROR_COUNT_MAP_SIZE + /* * If a thread stalls for this amount of time, it will be considered bogus (bad * health). diff --git a/src/common/error.c b/src/common/error.c index e03bee350..469bee19b 100644 --- a/src/common/error.c +++ b/src/common/error.c @@ -241,6 +241,9 @@ static const char *error_string_array[] = { [ ERROR_INDEX(LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY) ] = "Operation does not apply to the process attribute tracker's tracking policy", [ ERROR_INDEX(LTTNG_ERR_EVENT_NOTIFIER_GROUP_NOTIFICATION_FD) ] = "Failed to create an event notifier group notification file descriptor", [ ERROR_INDEX(LTTNG_ERR_INVALID_CAPTURE_EXPRESSION) ] = "Invalid capture expression", + [ ERROR_INDEX(LTTNG_ERR_EVENT_NOTIFIER_REGISTRATION) ] = "Failed to create event notifier", + [ ERROR_INDEX(LTTNG_ERR_EVENT_NOTIFIER_ERROR_ACCOUNTING) ] = "Failed to initialize event notifier error accounting", + [ ERROR_INDEX(LTTNG_ERR_EVENT_NOTIFIER_ERROR_ACCOUNTING_FULL) ] = "No index available in event notifier error accounting", /* Last element */ [ ERROR_INDEX(LTTNG_ERR_NR) ] = "Unknown error code" diff --git a/src/common/kernel-ctl/kernel-ctl.c b/src/common/kernel-ctl/kernel-ctl.c index 94e22ff06..592e1a2f4 100644 --- a/src/common/kernel-ctl/kernel-ctl.c +++ b/src/common/kernel-ctl/kernel-ctl.c @@ -430,6 +430,27 @@ int kernctl_create_event_notifier_group_notification_fd(int group_fd) LTTNG_KERNEL_EVENT_NOTIFIER_GROUP_NOTIFICATION_FD); } +int kernctl_create_event_notifier_group_error_counter(int group_fd, + const struct lttng_kernel_counter_conf *error_counter_conf) +{ + return LTTNG_IOCTL_NO_CHECK(group_fd, LTTNG_KERNEL_COUNTER, + error_counter_conf); +} + +int kernctl_counter_get_aggregate_value(int counter_fd, + struct lttng_kernel_counter_aggregate *value) +{ + return LTTNG_IOCTL_NO_CHECK(counter_fd, LTTNG_KERNEL_COUNTER_AGGREGATE, + value); +} + +int kernctl_counter_clear(int counter_fd, + struct lttng_kernel_counter_clear *clear) +{ + return LTTNG_IOCTL_NO_CHECK(counter_fd, LTTNG_KERNEL_COUNTER_CLEAR, + clear); +} + int kernctl_create_event_notifier(int group_fd, const struct lttng_kernel_event_notifier *event_notifier) { diff --git a/src/common/kernel-ctl/kernel-ctl.h b/src/common/kernel-ctl/kernel-ctl.h index 25cb3b52b..d3645a678 100644 --- a/src/common/kernel-ctl/kernel-ctl.h +++ b/src/common/kernel-ctl/kernel-ctl.h @@ -32,9 +32,16 @@ int kernctl_create_event_notifier_group(int fd); /* Apply on event notifier_group file descriptor. */ int kernctl_create_event_notifier_group_notification_fd(int fd); +int kernctl_create_event_notifier_group_error_counter(int fd, + const struct lttng_kernel_counter_conf *error_counter_conf); int kernctl_create_event_notifier(int fd, const struct lttng_kernel_event_notifier *event_notifier); +int kernctl_counter_get_aggregate_value(int counter_fd, + struct lttng_kernel_counter_aggregate *value); +int kernctl_counter_clear(int counter_fd, + struct lttng_kernel_counter_clear *clear); + /* Apply on event file descriptor. */ int kernctl_filter(int fd, const struct lttng_bytecode *filter); int kernctl_add_callsite(int fd, struct lttng_kernel_event_callsite *callsite); diff --git a/src/common/kernel-ctl/kernel-ioctl.h b/src/common/kernel-ctl/kernel-ioctl.h index f68d5d156..5ee916b70 100644 --- a/src/common/kernel-ctl/kernel-ioctl.h +++ b/src/common/kernel-ctl/kernel-ioctl.h @@ -160,6 +160,10 @@ #define LTTNG_KERNEL_ENABLE _IO(0xF6, 0x82) #define LTTNG_KERNEL_DISABLE _IO(0xF6, 0x83) +/* Event notifier group ioctl */ +#define LTTNG_KERNEL_COUNTER \ + _IOW(0xF6, 0x84, struct lttng_kernel_counter_conf) + /* Event and event notifier FD ioctl */ #define LTTNG_KERNEL_FILTER _IO(0xF6, 0x90) #define LTTNG_KERNEL_ADD_CALLSITE _IO(0xF6, 0x91) @@ -178,7 +182,16 @@ #define LTTNG_KERNEL_EVENT_NOTIFIER_GROUP_NOTIFICATION_FD \ _IO(0xF6, 0xB1) -/* Trigger file descriptor ioctl */ +/* Event notifier file descriptor ioctl */ #define LTTNG_KERNEL_CAPTURE _IO(0xF6, 0xB8) +/* Counter file descriptor ioctl */ +#define LTTNG_KERNEL_COUNTER_READ \ + IOWR(0xF6, 0xC0, struct lttng_kernel_counter_read) +#define LTTNG_KERNEL_COUNTER_AGGREGATE \ + _IOWR(0xF6, 0xC1, struct lttng_kernel_counter_aggregate) +#define LTTNG_KERNEL_COUNTER_CLEAR \ + _IOW(0xF6, 0xC2, struct lttng_kernel_counter_clear) + + #endif /* _LTT_KERNEL_IOCTL_H */ diff --git a/src/common/lttng-kernel.h b/src/common/lttng-kernel.h index e8647f439..aeab89d98 100644 --- a/src/common/lttng-kernel.h +++ b/src/common/lttng-kernel.h @@ -178,12 +178,76 @@ struct lttng_kernel_event { } u; } LTTNG_PACKED; -#define LTTNG_KERNEL_EVENT_NOTIFIER_PADDING 40 +#define LTTNG_KERNEL_EVENT_NOTIFIER_PADDING 32 struct lttng_kernel_event_notifier { struct lttng_kernel_event event; + uint64_t error_counter_idx; + char padding[LTTNG_KERNEL_EVENT_NOTIFIER_PADDING]; } LTTNG_PACKED; +#define LTTNG_KERNEL_COUNTER_DIMENSION_MAX 4 + +enum lttng_kernel_counter_arithmetic { + LTTNG_KERNEL_COUNTER_ARITHMETIC_MODULAR = 0, +}; + +enum lttng_kernel_counter_bitness { + LTTNG_KERNEL_COUNTER_BITNESS_32 = 0, + LTTNG_KERNEL_COUNTER_BITNESS_64 = 1, +}; + +struct lttng_kernel_counter_dimension { + uint64_t size; + uint64_t underflow_index; + uint64_t overflow_index; + uint8_t has_underflow; + uint8_t has_overflow; +} LTTNG_PACKED; + +#define LTTNG_KERNEL_COUNTER_CONF_PADDING1 67 +struct lttng_kernel_counter_conf { + uint32_t arithmetic; /* enum lttng_kernel_counter_arithmetic */ + uint32_t bitness; /* enum lttng_kernel_counter_bitness */ + uint32_t number_dimensions; + int64_t global_sum_step; + struct lttng_kernel_counter_dimension dimensions[LTTNG_KERNEL_COUNTER_DIMENSION_MAX]; + uint8_t coalesce_hits; + char padding[LTTNG_KERNEL_COUNTER_CONF_PADDING1]; +} LTTNG_PACKED; + +struct lttng_kernel_counter_index { + uint32_t number_dimensions; + uint64_t dimension_indexes[LTTNG_KERNEL_COUNTER_DIMENSION_MAX]; +} LTTNG_PACKED; + +struct lttng_kernel_counter_value { + int64_t value; + uint8_t underflow; + uint8_t overflow; +} LTTNG_PACKED; + +#define LTTNG_KERNEL_COUNTER_READ_PADDING 32 +struct lttng_kernel_counter_read { + struct lttng_kernel_counter_index index; + int32_t cpu; /* -1 for global counter, >= 0 for specific cpu. */ + struct lttng_kernel_counter_value value; /* output */ + char padding[LTTNG_KERNEL_COUNTER_READ_PADDING]; +} LTTNG_PACKED; + +#define LTTNG_KERNEL_COUNTER_AGGREGATE_PADDING 32 +struct lttng_kernel_counter_aggregate { + struct lttng_kernel_counter_index index; + struct lttng_kernel_counter_value value; /* output */ + char padding[LTTNG_KERNEL_COUNTER_AGGREGATE_PADDING]; +} LTTNG_PACKED; + +#define LTTNG_KERNEL_COUNTER_CLEAR_PADDING 32 +struct lttng_kernel_counter_clear { + struct lttng_kernel_counter_index index; + char padding[LTTNG_KERNEL_COUNTER_CLEAR_PADDING]; +} LTTNG_PACKED; + #define LTTNG_KERNEL_EVENT_NOTIFIER_NOTIFICATION_PADDING 32 struct lttng_kernel_event_notifier_notification { uint64_t token; diff --git a/tests/regression/tools/trigger/test_list_triggers_cli b/tests/regression/tools/trigger/test_list_triggers_cli index 6a189231a..a11f8eca9 100755 --- a/tests/regression/tools/trigger/test_list_triggers_cli +++ b/tests/regression/tools/trigger/test_list_triggers_cli @@ -72,6 +72,7 @@ test_top_level_options () firing policy: once after 123 occurences condition: event rule hit rule: test-fire-once-after (type: tracepoint, domain: ust) + tracer notifications discarded: 0 actions: notify - id: T1 @@ -79,12 +80,14 @@ test_top_level_options () firing policy: after every 124 occurences condition: event rule hit rule: test-fire-every (type: tracepoint, domain: ust) + tracer notifications discarded: 0 actions: notify - id: hello user id: ${uid} condition: event rule hit rule: test-id (type: tracepoint, domain: ust) + tracer notifications discarded: 0 actions: notify EOF @@ -115,36 +118,42 @@ test_on_event_tracepoint () user id: ${uid} condition: event rule hit rule: aaa (type: tracepoint, domain: ust, filter: p == 2) + tracer notifications discarded: 0 actions: notify - id: B user id: ${uid} condition: event rule hit rule: gerboise (type: tracepoint, domain: ust, log level at least INFO) + tracer notifications discarded: 0 actions: notify - id: C user id: ${uid} condition: event rule hit rule: * (type: tracepoint, domain: ust) + tracer notifications discarded: 0 actions: notify - id: D user id: ${uid} condition: event rule hit rule: hello* (type: tracepoint, domain: ust, exclusions: hello2,hello3,hello4) + tracer notifications discarded: 0 actions: notify - id: E user id: ${uid} condition: event rule hit rule: lemming (type: tracepoint, domain: ust, log level is WARNING) + tracer notifications discarded: 0 actions: notify - id: F user id: ${uid} condition: event rule hit rule: capture-payload-field (type: tracepoint, domain: ust) + tracer notifications discarded: 0 captures: - a actions: @@ -153,6 +162,7 @@ test_on_event_tracepoint () user id: ${uid} condition: event rule hit rule: capture-array (type: tracepoint, domain: ust) + tracer notifications discarded: 0 captures: - a[2] - \$ctx.tourlou[18] @@ -162,6 +172,7 @@ test_on_event_tracepoint () user id: ${uid} condition: event rule hit rule: capture-chan-ctx (type: tracepoint, domain: ust) + tracer notifications discarded: 0 captures: - \$ctx.vpid actions: @@ -170,6 +181,7 @@ test_on_event_tracepoint () user id: ${uid} condition: event rule hit rule: capture-app-ctx (type: tracepoint, domain: ust) + tracer notifications discarded: 0 captures: - \$app.iga:active_clients actions: @@ -214,18 +226,21 @@ test_on_event_probe () user id: ${uid} condition: event rule hit rule: my_channel_enable (type: probe, location: lttng_channel_enable) + tracer notifications discarded: 0 actions: notify - id: T1 user id: ${uid} condition: event rule hit rule: my_channel_enable (type: probe, location: ${base_symbol}+${offset_hex}) + tracer notifications discarded: 0 actions: notify - id: T2 user id: ${uid} condition: event rule hit rule: my_channel_enable (type: probe, location: 0x${channel_enable_addr}) + tracer notifications discarded: 0 actions: notify EOF @@ -247,6 +262,7 @@ test_on_event_userspace_probe () user id: ${uid} condition: event rule hit rule: ma-probe (type: userspace probe, location: ${uprobe_elf_binary}:test_function) + tracer notifications discarded: 0 actions: notify EOF @@ -269,12 +285,14 @@ test_on_event_syscall () user id: ${uid} condition: event rule hit rule: open (type: syscall) + tracer notifications discarded: 0 actions: notify - id: T1 user id: ${uid} condition: event rule hit rule: ptrace (type: syscall, filter: a > 2) + tracer notifications discarded: 0 actions: notify EOF @@ -303,48 +321,56 @@ test_snapshot_action () user id: ${uid} condition: event rule hit rule: some-event (type: tracepoint, domain: ust) + tracer notifications discarded: 0 actions: snapshot session \`ze-session\` - id: T1 user id: ${uid} condition: event rule hit rule: some-event (type: tracepoint, domain: ust) + tracer notifications discarded: 0 actions: snapshot session \`ze-session\`, path: /some/path - id: T2 user id: ${uid} condition: event rule hit rule: some-event (type: tracepoint, domain: ust) + tracer notifications discarded: 0 actions: snapshot session \`ze-session\`, path: /some/other/path - id: T3 user id: ${uid} condition: event rule hit rule: some-event (type: tracepoint, domain: ust) + tracer notifications discarded: 0 actions: snapshot session \`ze-session\`, url: net://1.2.3.4 - id: T4 user id: ${uid} condition: event rule hit rule: some-event (type: tracepoint, domain: ust) + tracer notifications discarded: 0 actions: snapshot session \`ze-session\`, url: net://1.2.3.4:1234:1235 - id: T5 user id: ${uid} condition: event rule hit rule: some-event (type: tracepoint, domain: ust) + tracer notifications discarded: 0 actions: snapshot session \`ze-session\`, control url: tcp://1.2.3.4:1111, data url: tcp://1.2.3.4:1112 - id: T6 user id: ${uid} condition: event rule hit rule: some-event (type: tracepoint, domain: ust) + tracer notifications discarded: 0 actions: snapshot session \`ze-session\`, path: /some/path, max size: 1234 - id: T7 user id: ${uid} condition: event rule hit rule: some-event (type: tracepoint, domain: ust) + tracer notifications discarded: 0 actions: snapshot session \`ze-session\`, path: /some/path, name: meh EOF diff --git a/tests/regression/tools/trigger/test_remove_trigger_cli b/tests/regression/tools/trigger/test_remove_trigger_cli index ffaefbb44..582cce7ef 100755 --- a/tests/regression/tools/trigger/test_remove_trigger_cli +++ b/tests/regression/tools/trigger/test_remove_trigger_cli @@ -76,12 +76,14 @@ cat > "${tmp_expected_stdout}" <<- EOF user id: ${uid} condition: event rule hit rule: aaa (type: tracepoint, domain: ust, filter: p == 2) + tracer notifications discarded: 0 actions: notify - id: DEF user id: ${uid} condition: event rule hit rule: * (type: tracepoint, domain: ust) + tracer notifications discarded: 0 actions: notify EOF @@ -94,6 +96,7 @@ cat > "${tmp_expected_stdout}" <<- EOF user id: ${uid} condition: event rule hit rule: * (type: tracepoint, domain: ust) + tracer notifications discarded: 0 actions: notify EOF diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am index 01e7e82c0..b972c3585 100644 --- a/tests/unit/Makefile.am +++ b/tests/unit/Makefile.am @@ -98,6 +98,7 @@ SESSIOND_OBJS = $(top_builddir)/src/bin/lttng-sessiond/buffer-registry.$(OBJEXT) $(top_builddir)/src/bin/lttng-sessiond/fd-limit.$(OBJEXT) \ $(top_builddir)/src/bin/lttng-sessiond/notification-thread-events.$(OBJEXT) \ $(top_builddir)/src/bin/lttng-sessiond/event.$(OBJEXT) \ + $(top_builddir)/src/bin/lttng-sessiond/event-notifier-error-accounting.$(OBJEXT) \ $(top_builddir)/src/bin/lttng-sessiond/timer.$(OBJEXT) \ $(top_builddir)/src/bin/lttng-sessiond/snapshot.$(OBJEXT) \ $(top_builddir)/src/bin/lttng-sessiond/sessiond-config.$(OBJEXT) \ -- 2.34.1