From 4a4ab2c346036eebfa794e4f638ad529f462a051 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Thu, 27 Feb 2014 14:00:13 -0500 Subject: [PATCH] Fix: index JUL event by name *and* loglevel This is to support multiple loglevels for a JUL event. Signed-off-by: David Goulet --- src/bin/lttng-sessiond/event.c | 4 +- src/bin/lttng-sessiond/jul.c | 142 +++++++++++++++++++++++++++++++-- src/bin/lttng-sessiond/jul.h | 10 ++- 3 files changed, 147 insertions(+), 9 deletions(-) diff --git a/src/bin/lttng-sessiond/event.c b/src/bin/lttng-sessiond/event.c index 499a2490e..1efa5a1ba 100644 --- a/src/bin/lttng-sessiond/event.c +++ b/src/bin/lttng-sessiond/event.c @@ -663,7 +663,7 @@ int event_jul_enable(struct ltt_ust_session *usess, struct lttng_event *event) "and loglevel %d", event->name, usess->id, event->loglevel_type, event->loglevel); - jevent = jul_find_by_name(event->name, &usess->domain_jul); + jevent = jul_find_event(event->name, event->loglevel, &usess->domain_jul); if (!jevent) { jevent = jul_create_event(event->name); if (!jevent) { @@ -715,7 +715,7 @@ int event_jul_disable(struct ltt_ust_session *usess, char *event_name) DBG("Event JUL disabling %s for session %" PRIu64, event_name, usess->id); - jevent = jul_find_by_name(event_name, &usess->domain_jul); + jevent = jul_find_event_by_name(event_name, &usess->domain_jul); if (!jevent) { ret = LTTNG_ERR_UST_EVENT_NOT_FOUND; goto error; diff --git a/src/bin/lttng-sessiond/jul.c b/src/bin/lttng-sessiond/jul.c index 40730bb4f..7bb0d75bc 100644 --- a/src/bin/lttng-sessiond/jul.c +++ b/src/bin/lttng-sessiond/jul.c @@ -26,6 +26,91 @@ #include "ust-app.h" #include "utils.h" +/* + * Match function for the events hash table lookup by name. + */ +static int ht_match_event_by_name(struct cds_lfht_node *node, + const void *_key) +{ + struct jul_event *event; + const struct jul_ht_key *key; + + assert(node); + assert(_key); + + event = caa_container_of(node, struct jul_event, node.node); + key = _key; + + /* Match 1 elements of the key: name. */ + + /* Event name */ + if (strncmp(event->name, key->name, sizeof(event->name)) != 0) { + goto no_match; + } + /* Match. */ + return 1; + +no_match: + return 0; +} + +/* + * Match function for the events hash table lookup by name and loglevel. + */ +static int ht_match_event(struct cds_lfht_node *node, + const void *_key) +{ + struct jul_event *event; + const struct jul_ht_key *key; + + assert(node); + assert(_key); + + event = caa_container_of(node, struct jul_event, node.node); + key = _key; + + /* Match 2 elements of the key: name and loglevel. */ + + /* Event name */ + if (strncmp(event->name, key->name, sizeof(event->name)) != 0) { + goto no_match; + } + + if (event->loglevel != key->loglevel) { + if (event->loglevel_type == LTTNG_EVENT_LOGLEVEL_ALL && + key->loglevel == 0 && event->loglevel == -1) { + goto match; + } + goto no_match; + } +match: + return 1; + +no_match: + return 0; +} + +/* + * Add unique JUL event based on the event name and loglevel. + */ +static void add_unique_jul_event(struct lttng_ht *ht, struct jul_event *event) +{ + struct cds_lfht_node *node_ptr; + struct jul_ht_key key; + + assert(ht); + assert(ht->ht); + assert(event); + + key.name = event->name; + key.loglevel = event->loglevel; + + node_ptr = cds_lfht_add_unique(ht->ht, + ht->hash_fct(event->node.key, lttng_ht_seed), + ht_match_event, &key, &event->node.node); + assert(node_ptr == &event->node.node); +} + /* * URCU delayed JUL event reclaim. */ @@ -668,38 +753,83 @@ void jul_add_event(struct jul_event *event, struct jul_domain *dom) DBG3("JUL adding event %s to domain", event->name); rcu_read_lock(); - lttng_ht_add_unique_str(dom->events, &event->node); + add_unique_jul_event(dom->events, event); rcu_read_unlock(); dom->being_used = 1; } /* - * Find a JUL event in the given domain using name. + * Find a JUL event in the given domain using name and loglevel. + * + * RCU read side lock MUST be acquired. + * + * Return object if found else NULL. + */ +struct jul_event *jul_find_event_by_name(const char *name, + struct jul_domain *dom) +{ + struct lttng_ht_node_str *node; + struct lttng_ht_iter iter; + struct lttng_ht *ht; + struct jul_ht_key key; + + assert(name); + assert(dom); + assert(dom->events); + + ht = dom->events; + key.name = name; + + cds_lfht_lookup(ht->ht, ht->hash_fct((void *) name, lttng_ht_seed), + ht_match_event_by_name, &key, &iter.iter); + node = lttng_ht_iter_get_node_str(&iter); + if (node == NULL) { + goto error; + } + + DBG3("JUL event found %s by name.", name); + return caa_container_of(node, struct jul_event, node); + +error: + DBG3("JUL NOT found by name %s.", name); + return NULL; +} + +/* + * Find a JUL event in the given domain using name and loglevel. * * RCU read side lock MUST be acquired. * * Return object if found else NULL. */ -struct jul_event *jul_find_by_name(const char *name, struct jul_domain *dom) +struct jul_event *jul_find_event(const char *name, + enum lttng_loglevel_jul loglevel, struct jul_domain *dom) { struct lttng_ht_node_str *node; struct lttng_ht_iter iter; + struct lttng_ht *ht; + struct jul_ht_key key; assert(name); assert(dom); assert(dom->events); - lttng_ht_lookup(dom->events, (void *)name, &iter); + ht = dom->events; + key.name = name; + key.loglevel = loglevel; + + cds_lfht_lookup(ht->ht, ht->hash_fct((void *) name, lttng_ht_seed), + ht_match_event, &key, &iter.iter); node = lttng_ht_iter_get_node_str(&iter); if (node == NULL) { goto error; } - DBG3("JUL found by name %s in domain.", name); + DBG3("JUL event found %s.", name); return caa_container_of(node, struct jul_event, node); error: - DBG3("JUL NOT found by name %s in domain.", name); + DBG3("JUL NOT found %s.", name); return NULL; } diff --git a/src/bin/lttng-sessiond/jul.h b/src/bin/lttng-sessiond/jul.h index ccd59bc72..55c9e18c7 100644 --- a/src/bin/lttng-sessiond/jul.h +++ b/src/bin/lttng-sessiond/jul.h @@ -30,6 +30,11 @@ */ struct lttng_ht *jul_apps_ht_by_sock; +struct jul_ht_key { + const char *name; + enum lttng_loglevel_jul loglevel; +}; + /* * Registration message payload from a JUL application. The PID is used to find * back the corresponding UST app object so both socket can be linked. @@ -109,7 +114,10 @@ void jul_destroy_domain(struct jul_domain *dom); /* JUL event API. */ struct jul_event *jul_create_event(const char *name); void jul_add_event(struct jul_event *event, struct jul_domain *dom); -struct jul_event *jul_find_by_name(const char *name, struct jul_domain *dom); +struct jul_event *jul_find_event(const char *name, + enum lttng_loglevel_jul loglevel, struct jul_domain *dom); +struct jul_event *jul_find_event_by_name(const char *name, + struct jul_domain *dom); void jul_delete_event(struct jul_event *event, struct jul_domain *dom); void jul_destroy_event(struct jul_event *event); -- 2.34.1