X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=liblttng-ust%2Flttng-events.c;h=68c024c4647e9206f6b9bec37d17f63e40425be8;hb=353c9dc0b929bf980baabc384ac6a15d1fe856ea;hp=e4faf605e6e0eb1d5642fc5dea1b2d4bd0ae5946;hpb=5f733922ed1e2db5b397292ede81303a9e538a08;p=lttng-ust.git diff --git a/liblttng-ust/lttng-events.c b/liblttng-ust/lttng-events.c index e4faf605..68c024c4 100644 --- a/liblttng-ust/lttng-events.c +++ b/liblttng-ust/lttng-events.c @@ -45,7 +45,7 @@ #include #include -#include +#include #include #include "error.h" #include "compat.h" @@ -54,29 +54,23 @@ #include "tracepoint-internal.h" #include "lttng-tracer.h" #include "lttng-tracer-core.h" +#include "lttng-ust-baddr.h" #include "wait.h" #include "../libringbuffer/shm.h" #include "jhash.h" /* - * The sessions mutex is the centralized mutex across UST tracing - * control and probe registration. All operations within this file are - * called by the communication thread, under ust_lock protection. + * All operations within this file are called by the communication + * thread, under ust_lock protection. */ -static pthread_mutex_t sessions_mutex = PTHREAD_MUTEX_INITIALIZER; -void ust_lock(void) -{ - pthread_mutex_lock(&sessions_mutex); -} +static CDS_LIST_HEAD(sessions); -void ust_unlock(void) +struct cds_list_head *_lttng_get_sessions(void) { - pthread_mutex_unlock(&sessions_mutex); + return &sessions; } -static CDS_LIST_HEAD(sessions); - static void _lttng_event_destroy(struct lttng_event *event); static @@ -106,8 +100,6 @@ int lttng_loglevel_match(int loglevel, enum lttng_ust_loglevel_type req_type, int req_loglevel) { - if (req_type == LTTNG_UST_LOGLEVEL_ALL) - return 1; if (!has_loglevel) loglevel = TRACE_DEFAULT; switch (req_type) { @@ -251,8 +243,6 @@ int lttng_session_enable(struct lttng_session *session) /* Set transient enabler state to "enabled" */ session->tstate = 1; - /* We need to sync enablers with session before activation. */ - lttng_session_sync_enablers(session); /* * Snapshot the number of events per channel to know the type of header @@ -260,7 +250,7 @@ int lttng_session_enable(struct lttng_session *session) */ cds_list_for_each_entry(chan, &session->chan_head, node) { const struct lttng_ctx *ctx; - const struct lttng_event_field *fields = NULL; + const struct lttng_ctx_field *fields = NULL; size_t nr_fields = 0; uint32_t chan_id; @@ -270,7 +260,7 @@ int lttng_session_enable(struct lttng_session *session) ctx = chan->ctx; if (ctx) { nr_fields = ctx->nr_fields; - fields = &ctx->fields->event_field; + fields = ctx->fields; } ret = ustcomm_register_channel(notify_socket, session->objd, @@ -290,9 +280,15 @@ int lttng_session_enable(struct lttng_session *session) } } + /* We need to sync enablers with session before activation. */ + lttng_session_sync_enablers(session); + /* Set atomically the state to "active" */ CMM_ACCESS_ONCE(session->active) = 1; CMM_ACCESS_ONCE(session->been_active) = 1; + + session->statedump_pending = 1; + lttng_ust_sockinfo_session_enabled(session->owner); end: return ret; } @@ -491,6 +487,31 @@ static int lttng_desc_match_enabler(const struct lttng_event_desc *desc, struct lttng_enabler *enabler) { + struct lttng_ust_excluder_node *excluder; + + /* If event matches with an excluder, return 'does not match' */ + cds_list_for_each_entry(excluder, &enabler->excluder_head, node) { + int count; + + for (count = 0; count < excluder->excluder.count; count++) { + int found, len; + char *excluder_name; + + excluder_name = (char *) (excluder->excluder.names) + + count * LTTNG_UST_SYM_NAME_LEN; + len = strnlen(excluder_name, LTTNG_UST_SYM_NAME_LEN); + if (len > 0 && excluder_name[len - 1] == '*') { + found = !strncmp(desc->name, excluder_name, + len - 1); + } else { + found = !strncmp(desc->name, excluder_name, + LTTNG_UST_SYM_NAME_LEN - 1); + } + if (found) { + return 0; + } + } + } switch (enabler->type) { case LTTNG_ENABLER_WILDCARD: return lttng_desc_match_wildcard_enabler(desc, enabler); @@ -647,6 +668,34 @@ int lttng_fix_pending_events(void) return 0; } +/* + * For each session of the owner thread, execute pending statedump. + * Only dump state for the sessions owned by the caller thread, because + * we don't keep ust_lock across the entire iteration. + */ +void lttng_handle_pending_statedump(void *owner) +{ + struct lttng_session *session; + + /* Execute state dump */ + lttng_ust_baddr_statedump(owner); + + /* Clear pending state dump */ + if (ust_lock()) { + goto end; + } + cds_list_for_each_entry(session, &sessions, node) { + if (session->owner != owner) + continue; + if (!session->statedump_pending) + continue; + session->statedump_pending = 0; + } +end: + ust_unlock(); + return; +} + /* * Only used internally at session destruction. */ @@ -687,11 +736,21 @@ struct lttng_enabler *lttng_enabler_create(enum lttng_enabler_type type, return NULL; enabler->type = type; CDS_INIT_LIST_HEAD(&enabler->filter_bytecode_head); + CDS_INIT_LIST_HEAD(&enabler->excluder_head); memcpy(&enabler->event_param, event_param, sizeof(enabler->event_param)); enabler->chan = chan; /* ctx left NULL */ - enabler->enabled = 1; + /* + * The "disable" event create comm field has been added to fix a + * race between event creation (of a started trace) and enabling + * filtering. New session daemon always set the "disable" field + * to 1, and are aware that they need to explicitly enable the + * event. Older session daemon (within same ABI) leave it at 0, + * and therefore we need to enable it here, keeping the original + * racy behavior. + */ + enabler->enabled = !event_param->disabled; cds_list_add(&enabler->node, &enabler->chan->session->enablers_head); lttng_session_lazy_sync_enablers(enabler->chan->session); return enabler; @@ -720,6 +779,15 @@ int lttng_enabler_attach_bytecode(struct lttng_enabler *enabler, return 0; } +int lttng_enabler_attach_exclusion(struct lttng_enabler *enabler, + struct lttng_ust_excluder_node *excluder) +{ + excluder->enabler = enabler; + cds_list_add_tail(&excluder->node, &enabler->excluder_head); + lttng_session_lazy_sync_enablers(enabler->chan->session); + return 0; +} + int lttng_attach_context(struct lttng_ust_context *context_param, struct lttng_ctx **ctx, struct lttng_session *session) { @@ -740,6 +808,8 @@ int lttng_attach_context(struct lttng_ust_context *context_param, return lttng_add_vpid_to_ctx(ctx); case LTTNG_UST_CONTEXT_PROCNAME: return lttng_add_procname_to_ctx(ctx); + case LTTNG_UST_CONTEXT_IP: + return lttng_add_ip_to_ctx(ctx); default: return -EINVAL; } @@ -765,6 +835,7 @@ static void lttng_enabler_destroy(struct lttng_enabler *enabler) { struct lttng_ust_filter_bytecode_node *filter_node, *tmp_filter_node; + struct lttng_ust_excluder_node *excluder_node, *tmp_excluder_node; /* Destroy filter bytecode */ cds_list_for_each_entry_safe(filter_node, tmp_filter_node, @@ -772,6 +843,12 @@ void lttng_enabler_destroy(struct lttng_enabler *enabler) free(filter_node); } + /* Destroy excluders */ + cds_list_for_each_entry_safe(excluder_node, tmp_excluder_node, + &enabler->excluder_head, node) { + free(excluder_node); + } + /* Destroy contexts */ lttng_destroy_context(enabler->ctx);