X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fnotification-thread-events.c;h=bbf77329190b915affe0df11ed3cbd7001402291;hb=7e802d0a78ee4010dc540db15b7c747b28c2eacf;hp=7ba78ba312536435c5adb41737612122794bea48;hpb=e8f7fa117487c9b57f5a9699364c3bebf53c5cec;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/notification-thread-events.c b/src/bin/lttng-sessiond/notification-thread-events.c index 7ba78ba31..bbf773291 100644 --- a/src/bin/lttng-sessiond/notification-thread-events.c +++ b/src/bin/lttng-sessiond/notification-thread-events.c @@ -26,8 +26,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -35,6 +37,7 @@ #include #include +#include "condition-internal.h" #include "notification-thread.h" #include "notification-thread-events.h" #include "notification-thread-commands.h" @@ -368,105 +371,6 @@ unsigned long hash_trigger_by_name_uid(const struct lttng_trigger *trigger) return hash; } -static -unsigned long lttng_condition_buffer_usage_hash( - const struct lttng_condition *_condition) -{ - unsigned long hash; - unsigned long condition_type; - struct lttng_condition_buffer_usage *condition; - - condition = container_of(_condition, - struct lttng_condition_buffer_usage, parent); - - condition_type = (unsigned long) condition->parent.type; - hash = hash_key_ulong((void *) condition_type, lttng_ht_seed); - if (condition->session_name) { - hash ^= hash_key_str(condition->session_name, lttng_ht_seed); - } - if (condition->channel_name) { - hash ^= hash_key_str(condition->channel_name, lttng_ht_seed); - } - if (condition->domain.set) { - hash ^= hash_key_ulong( - (void *) condition->domain.type, - lttng_ht_seed); - } - if (condition->threshold_ratio.set) { - uint64_t val; - - val = condition->threshold_ratio.value * (double) UINT32_MAX; - hash ^= hash_key_u64(&val, lttng_ht_seed); - } else if (condition->threshold_bytes.set) { - uint64_t val; - - val = condition->threshold_bytes.value; - hash ^= hash_key_u64(&val, lttng_ht_seed); - } - return hash; -} - -static -unsigned long lttng_condition_session_consumed_size_hash( - const struct lttng_condition *_condition) -{ - unsigned long hash; - unsigned long condition_type = - (unsigned long) LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE; - struct lttng_condition_session_consumed_size *condition; - uint64_t val; - - condition = container_of(_condition, - struct lttng_condition_session_consumed_size, parent); - - hash = hash_key_ulong((void *) condition_type, lttng_ht_seed); - if (condition->session_name) { - hash ^= hash_key_str(condition->session_name, lttng_ht_seed); - } - val = condition->consumed_threshold_bytes.value; - hash ^= hash_key_u64(&val, lttng_ht_seed); - return hash; -} - -static -unsigned long lttng_condition_session_rotation_hash( - const struct lttng_condition *_condition) -{ - unsigned long hash, condition_type; - struct lttng_condition_session_rotation *condition; - - condition = container_of(_condition, - struct lttng_condition_session_rotation, parent); - condition_type = (unsigned long) condition->parent.type; - hash = hash_key_ulong((void *) condition_type, lttng_ht_seed); - assert(condition->session_name); - hash ^= hash_key_str(condition->session_name, lttng_ht_seed); - return hash; -} - -/* - * The lttng_condition hashing code is kept in this file (rather than - * condition.c) since it makes use of GPLv2 code (hashtable utils), which we - * don't want to link in liblttng-ctl. - */ -static -unsigned long lttng_condition_hash(const struct lttng_condition *condition) -{ - switch (condition->type) { - case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW: - case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH: - return lttng_condition_buffer_usage_hash(condition); - case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE: - return lttng_condition_session_consumed_size_hash(condition); - case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING: - case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED: - return lttng_condition_session_rotation_hash(condition); - default: - ERR("[notification-thread] Unexpected condition type caught"); - abort(); - } -} - static unsigned long hash_channel_key(struct channel_key *key) { @@ -509,6 +413,8 @@ enum lttng_object_type get_condition_binding_object( case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING: case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED: return LTTNG_OBJECT_TYPE_SESSION; + case LTTNG_CONDITION_TYPE_EVENT_RULE_HIT: + return LTTNG_OBJECT_TYPE_NONE; default: return LTTNG_OBJECT_TYPE_UNKNOWN; } @@ -1019,6 +925,7 @@ int evaluate_condition_for_client(const struct lttng_trigger *trigger, &evaluation, &object_uid, &object_gid); break; case LTTNG_OBJECT_TYPE_NONE: + DBG("[notification-thread] Newly subscribed-to condition not bound to object, nothing to evaluate"); ret = 0; goto end; case LTTNG_OBJECT_TYPE_UNKNOWN: @@ -2040,25 +1947,23 @@ end: } static -int condition_is_supported(struct lttng_condition *condition) +bool condition_is_supported(struct lttng_condition *condition) { - int ret; + bool is_supported; switch (lttng_condition_get_type(condition)) { case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW: case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH: { + int ret; enum lttng_domain_type domain; ret = lttng_condition_buffer_usage_get_domain_type(condition, &domain); - if (ret) { - ret = -1; - goto end; - } + assert(ret == 0); if (domain != LTTNG_DOMAIN_KERNEL) { - ret = 1; + is_supported = true; goto end; } @@ -2066,15 +1971,43 @@ int condition_is_supported(struct lttng_condition *condition) * Older kernel tracers don't expose the API to monitor their * buffers. Therefore, we reject triggers that require that * mechanism to be available to be evaluated. + * + * Assume unsupported on error. + */ + is_supported = kernel_supports_ring_buffer_snapshot_sample_positions() == 1; + break; + } + case LTTNG_CONDITION_TYPE_EVENT_RULE_HIT: + { + const struct lttng_event_rule *event_rule; + enum lttng_domain_type domain; + const enum lttng_condition_status status = + lttng_condition_event_rule_get_rule( + condition, &event_rule); + + assert(status == LTTNG_CONDITION_STATUS_OK); + + domain = lttng_event_rule_get_domain_type(event_rule); + if (domain != LTTNG_DOMAIN_KERNEL) { + is_supported = true; + goto end; + } + + /* + * Older kernel tracers can't emit notification. Therefore, we + * reject triggers that require that mechanism to be available + * to be evaluated. + * + * Assume unsupported on error. */ - ret = kernel_supports_ring_buffer_snapshot_sample_positions(); + is_supported = kernel_supports_event_notifiers() == 1; break; } default: - ret = 1; + is_supported = true; } end: - return ret; + return is_supported; } /* Must be called with RCU read lock held. */ @@ -2316,15 +2249,10 @@ int handle_notification_thread_command_register_trigger( condition = lttng_trigger_get_condition(trigger); assert(condition); - ret = condition_is_supported(condition); - if (ret < 0) { - goto error; - } else if (ret == 0) { + /* Some conditions require tracers to implement a minimal ABI version. */ + if (!condition_is_supported(condition)) { *cmd_result = LTTNG_ERR_NOT_SUPPORTED; goto error; - } else { - /* Feature is supported, continue. */ - ret = 0; } trigger_ht_element = zmalloc(sizeof(*trigger_ht_element)); @@ -2609,17 +2537,19 @@ int handle_notification_thread_command_unregister_trigger( } } - /* - * Remove and release the client list from - * notification_trigger_clients_ht. - */ - client_list = get_client_list_from_condition(state, condition); - assert(client_list); + if (is_trigger_action_notify(trigger)) { + /* + * Remove and release the client list from + * notification_trigger_clients_ht. + */ + client_list = get_client_list_from_condition(state, condition); + assert(client_list); - /* Put new reference and the hashtable's reference. */ - notification_client_list_put(client_list); - notification_client_list_put(client_list); - client_list = NULL; + /* Put new reference and the hashtable's reference. */ + notification_client_list_put(client_list); + notification_client_list_put(client_list); + client_list = NULL; + } /* Remove trigger from triggers_ht. */ trigger_ht_element = caa_container_of(triggers_ht_node,