X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=liblttng-ust%2Flttng-events.c;h=7afee7fc4043ac58a1be6a46df6852a93e10882c;hb=8306baea3da8b1f429e14218b1ef7413ee56ed19;hp=fa54a025a967226b5527384c9217849e97ea1c83;hpb=196ec2df2bce805b8c26582f10f2964a8d1da443;p=lttng-ust.git diff --git a/liblttng-ust/lttng-events.c b/liblttng-ust/lttng-events.c index fa54a025..7afee7fc 100644 --- a/liblttng-ust/lttng-events.c +++ b/liblttng-ust/lttng-events.c @@ -257,21 +257,19 @@ int lttng_enum_create(const struct lttng_enum_desc *desc, const char *enum_name = desc->name; struct lttng_enum *_enum; struct cds_hlist_head *head; - struct cds_hlist_node *node; int ret = 0; size_t name_len = strlen(enum_name); uint32_t hash; int notify_socket; + /* Check if this enum is already registered for this session. */ hash = jhash(enum_name, name_len, 0); head = &session->enums_ht.table[hash & (LTTNG_UST_ENUM_HT_SIZE - 1)]; - cds_hlist_for_each_entry(_enum, node, head, hlist) { - assert(_enum->desc); - if (!strncmp(_enum->desc->name, desc->name, - LTTNG_UST_SYM_NAME_LEN - 1)) { - ret = -EEXIST; - goto exist; - } + + _enum = lttng_ust_enum_get_from_desc(session, desc); + if (_enum) { + ret = -EEXIST; + goto exist; } notify_socket = lttng_get_notify_socket(session->owner); @@ -417,6 +415,9 @@ 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 * we need to use. @@ -460,9 +461,6 @@ 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; @@ -537,7 +535,6 @@ int lttng_event_create(const struct lttng_event_desc *desc, struct lttng_event *event; struct lttng_session *session = chan->session; struct cds_hlist_head *head; - struct cds_hlist_node *node; int ret = 0; size_t name_len = strlen(event_name); uint32_t hash; @@ -546,15 +543,6 @@ int lttng_event_create(const struct lttng_event_desc *desc, hash = jhash(event_name, name_len, 0); head = &chan->session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)]; - cds_hlist_for_each_entry(event, node, head, hlist) { - assert(event->desc); - if (!strncmp(event->desc->name, desc->name, - LTTNG_UST_SYM_NAME_LEN - 1) - && chan == event->chan) { - ret = -EEXIST; - goto exist; - } - } notify_socket = lttng_get_notify_socket(session->owner); if (notify_socket < 0) { @@ -612,8 +600,6 @@ int lttng_event_create(const struct lttng_event_desc *desc, goto sessiond_register_error; } - /* Populate lttng_event structure before tracepoint registration. */ - cmm_smp_wmb(); cds_list_add(&event->node, &chan->session->events_head); cds_hlist_add_head(&event->hlist, head); return 0; @@ -623,7 +609,6 @@ sessiond_register_error: cache_error: create_enum_error: socket_error: -exist: return ret; } @@ -635,8 +620,8 @@ int lttng_desc_match_star_glob_enabler(const struct lttng_event_desc *desc, unsigned int has_loglevel = 0; assert(enabler->type == LTTNG_ENABLER_STAR_GLOB); - if (!strutils_star_glob_match(enabler->event_param.name, -1ULL, - desc->name, -1ULL)) + if (!strutils_star_glob_match(enabler->event_param.name, SIZE_MAX, + desc->name, SIZE_MAX)) return 0; if (desc->loglevel) { loglevel = *(*desc->loglevel); @@ -699,7 +684,7 @@ int lttng_desc_match_enabler(const struct lttng_event_desc *desc, excluder_name = (char *) (excluder->excluder.names) + count * LTTNG_UST_SYM_NAME_LEN; len = strnlen(excluder_name, LTTNG_UST_SYM_NAME_LEN); - if (len > 0 && strutils_star_glob_match(excluder_name, len, desc->name, -1ULL)) + if (len > 0 && strutils_star_glob_match(excluder_name, len, desc->name, SIZE_MAX)) return 0; } } @@ -799,6 +784,111 @@ void lttng_create_event_if_missing(struct lttng_enabler *enabler) } } +/* + * Iterate over all the UST sessions to unregister and destroy all probes from + * the probe provider descriptor received as argument. Must me called with the + * ust_lock held. + */ +void lttng_probe_provider_unregister_events(struct lttng_probe_desc *provider_desc) +{ + struct cds_hlist_node *node, *tmp_node; + struct cds_list_head *sessionsp; + struct lttng_session *session; + struct cds_hlist_head *head; + struct lttng_event *event; + unsigned int i, j; + + /* Get handle on list of sessions. */ + sessionsp = _lttng_get_sessions(); + + /* + * Iterate over all events in the probe provider descriptions and sessions + * to queue the unregistration of the events. + */ + for (i = 0; i < provider_desc->nr_events; i++) { + const struct lttng_event_desc *event_desc; + const char *event_name; + size_t name_len; + uint32_t hash; + + event_desc = provider_desc->event_desc[i]; + event_name = event_desc->name; + name_len = strlen(event_name); + hash = jhash(event_name, name_len, 0); + + /* Iterate over all session to find the current event description. */ + cds_list_for_each_entry(session, sessionsp, node) { + /* + * Get the list of events in the hashtable bucket and iterate to + * find the event matching this descriptor. + */ + head = &session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)]; + cds_hlist_for_each_entry(event, node, head, hlist) { + if (event_desc == event->desc) { + /* Queue the unregistration of this event. */ + _lttng_event_unregister(event); + break; + } + } + } + } + + /* Wait for grace period. */ + synchronize_trace(); + /* Prune the unregistration queue. */ + __tracepoint_probe_prune_release_queue(); + + /* + * It is now safe to destroy the events and remove them from the event list + * and hashtables. + */ + for (i = 0; i < provider_desc->nr_events; i++) { + const struct lttng_event_desc *event_desc; + const char *event_name; + size_t name_len; + uint32_t hash; + + event_desc = provider_desc->event_desc[i]; + event_name = event_desc->name; + name_len = strlen(event_name); + hash = jhash(event_name, name_len, 0); + + /* Iterate over all sessions to find the current event description. */ + cds_list_for_each_entry(session, sessionsp, node) { + /* + * Get the list of events in the hashtable bucket and iterate to + * find the event matching this descriptor. + */ + head = &session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)]; + cds_hlist_for_each_entry_safe(event, node, tmp_node, head, hlist) { + if (event_desc == event->desc) { + /* Destroy enums of the current event. */ + for (j = 0; j < event->desc->nr_fields; j++) { + const struct lttng_enum_desc *enum_desc; + const struct lttng_event_field *field; + struct lttng_enum *curr_enum; + + field = &(event->desc->fields[j]); + if (field->type.atype != atype_enum) { + continue; + } + + enum_desc = field->type.u.basic.enumeration.desc; + curr_enum = lttng_ust_enum_get_from_desc(session, enum_desc); + if (curr_enum) { + _lttng_enum_destroy(curr_enum); + } + } + + /* Destroy event. */ + _lttng_event_destroy(event); + break; + } + } + } + } +} + /* * Create events associated with an enabler (if not already present), * and add backward reference from the event to the enabler. @@ -894,7 +984,11 @@ void _lttng_event_destroy(struct lttng_event *event) { struct lttng_enabler_ref *enabler_ref, *tmp_enabler_ref; + /* Remove from event list. */ cds_list_del(&event->node); + /* Remove from event hash table. */ + cds_hlist_del(&event->hlist); + lttng_destroy_context(event->ctx); lttng_free_event_filter_runtime(event); /* Free event enabler refs */ @@ -908,6 +1002,7 @@ static void _lttng_enum_destroy(struct lttng_enum *_enum) { cds_list_del(&_enum->node); + cds_hlist_del(&_enum->hlist); free(_enum); } @@ -1015,6 +1110,32 @@ int lttng_attach_context(struct lttng_ust_context *context_param, case LTTNG_UST_CONTEXT_APP_CONTEXT: return lttng_ust_add_app_context_to_ctx_rcu(uargs->app_context.ctxname, ctx); + case LTTNG_UST_CONTEXT_CGROUP_NS: + return lttng_add_cgroup_ns_to_ctx(ctx); + case LTTNG_UST_CONTEXT_IPC_NS: + return lttng_add_ipc_ns_to_ctx(ctx); + case LTTNG_UST_CONTEXT_MNT_NS: + return lttng_add_mnt_ns_to_ctx(ctx); + case LTTNG_UST_CONTEXT_NET_NS: + return lttng_add_net_ns_to_ctx(ctx); + case LTTNG_UST_CONTEXT_PID_NS: + return lttng_add_pid_ns_to_ctx(ctx); + case LTTNG_UST_CONTEXT_USER_NS: + return lttng_add_user_ns_to_ctx(ctx); + case LTTNG_UST_CONTEXT_UTS_NS: + return lttng_add_uts_ns_to_ctx(ctx); + case LTTNG_UST_CONTEXT_VUID: + return lttng_add_vuid_to_ctx(ctx); + case LTTNG_UST_CONTEXT_VEUID: + return lttng_add_veuid_to_ctx(ctx); + case LTTNG_UST_CONTEXT_VSUID: + return lttng_add_vsuid_to_ctx(ctx); + case LTTNG_UST_CONTEXT_VGID: + return lttng_add_vgid_to_ctx(ctx); + case LTTNG_UST_CONTEXT_VEGID: + return lttng_add_vegid_to_ctx(ctx); + case LTTNG_UST_CONTEXT_VSGID: + return lttng_add_vsgid_to_ctx(ctx); default: return -EINVAL; }