From 0475c50c4d3d2cea973fe4d1f17875d231dea96c Mon Sep 17 00:00:00 2001 From: David Goulet Date: Mon, 30 Sep 2013 15:06:27 -0400 Subject: [PATCH] Add jul.c/.h to sessiond code This adds data structures to handle the JUL domain. The domain is added to a ust session and created/destroyed in the trace-ust.c API. Nothing is working yet, just putting the piece together. Signed-off-by: David Goulet --- src/bin/lttng-sessiond/Makefile.am | 3 +- src/bin/lttng-sessiond/jul.c | 195 +++++++++++++++++++++++++++++ src/bin/lttng-sessiond/jul.h | 64 ++++++++++ src/bin/lttng-sessiond/trace-ust.c | 7 ++ src/bin/lttng-sessiond/trace-ust.h | 2 + src/common/defaults.h | 3 + tests/unit/Makefile.am | 1 + 7 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 src/bin/lttng-sessiond/jul.c create mode 100644 src/bin/lttng-sessiond/jul.h diff --git a/src/bin/lttng-sessiond/Makefile.am b/src/bin/lttng-sessiond/Makefile.am index 3d96907de..21b585910 100644 --- a/src/bin/lttng-sessiond/Makefile.am +++ b/src/bin/lttng-sessiond/Makefile.am @@ -26,7 +26,8 @@ lttng_sessiond_SOURCES = utils.c utils.h \ cmd.c cmd.h \ buffer-registry.c buffer-registry.h \ testpoint.h ht-cleanup.c \ - snapshot.c snapshot.h + snapshot.c snapshot.h \ + jul.c jul.h if HAVE_LIBLTTNG_UST_CTL lttng_sessiond_SOURCES += trace-ust.c ust-registry.c ust-app.c \ diff --git a/src/bin/lttng-sessiond/jul.c b/src/bin/lttng-sessiond/jul.c new file mode 100644 index 000000000..a38738c3b --- /dev/null +++ b/src/bin/lttng-sessiond/jul.c @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2013 - David Goulet + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License, version 2 only, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#define _GNU_SOURCE +#include + +#include + +#include "jul.h" +#include "utils.h" + +/* + * URCU intermediate call to complete destroy a JUL event. + */ +static void destroy_event_jul_rcu(struct rcu_head *head) +{ + struct lttng_ht_node_str *node = + caa_container_of(head, struct lttng_ht_node_str, head); + struct jul_event *event = + caa_container_of(node, struct jul_event, node); + + free(event); +} + +/* + * Initialize an already allocated JUL domain object. + * + * Return 0 on success or else a negative errno value. + */ +int jul_init_domain(struct jul_domain *dom) +{ + int ret; + + assert(dom); + + dom->events = lttng_ht_new(0, LTTNG_HT_TYPE_STRING); + if (!dom->events) { + ret = -ENOMEM; + goto error; + } + + return 0; + +error: + return ret; +} + +/* + * Create a newly allocated JUL event data structure. If name is valid, it's + * copied into the created event. + * + * Return a new object else NULL on error. + */ +struct jul_event *jul_create_event(const char *name) +{ + struct jul_event *event; + + DBG3("JUL create new event with name %s", name); + + event = zmalloc(sizeof(*event)); + if (!event) { + goto error; + } + + if (name) { + strncpy(event->name, name, sizeof(event->name)); + event->name[sizeof(event->name) - 1] = '\0'; + } + +error: + return event; +} + +/* + * Unique add of a JUL event to a given domain. + */ +void jul_add_event(struct jul_event *event, struct jul_domain *dom) +{ + assert(event); + assert(dom); + assert(dom->events); + + DBG3("JUL adding event %s to domain", event->name); + + lttng_ht_add_unique_str(dom->events, &event->node); +} + +/* + * Find a JUL event in the given domain using name. + * + * 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 lttng_ht_node_str *node; + struct lttng_ht_iter iter; + + assert(name); + assert(dom); + assert(dom->events); + + lttng_ht_lookup(dom->events, (void *)name, &iter); + node = lttng_ht_iter_get_node_str(&iter); + if (node == NULL) { + goto error; + } + + DBG3("JUL found by name %s in domain.", name); + return caa_container_of(node, struct jul_event, node); + +error: + DBG3("JUL NOT found by name %s in domain.", name); + return NULL; +} + +/* + * Delete JUL event from given domain. Events hash table MUST be initialized. + */ +void jul_delete_event(struct jul_event *event, struct jul_domain *dom) +{ + int ret; + struct lttng_ht_iter iter; + + assert(event); + assert(dom); + assert(dom->events); + + DBG3("JUL deleting event %s from domain", event->name); + + iter.iter.node = &event->node.node; + rcu_read_lock(); + ret = lttng_ht_del(dom->events, &iter); + rcu_read_unlock(); + assert(!ret); +} + +/* + * Free given JUl event. After this call, the pointer is not usable anymore. + */ +void jul_destroy_event(struct jul_event *event) +{ + assert(event); + + free(event); +} + +/* + * Destroy a JUL domain completely. Note that the given pointer is NOT freed + * thus a reference can be passed to this function. + */ +void jul_destroy_domain(struct jul_domain *dom) +{ + struct lttng_ht_node_str *node; + struct lttng_ht_iter iter; + + assert(dom); + + DBG3("JUL destroy domain"); + + /* + * Just ignore if no events hash table exists. This is possible if for + * instance a JUL domain object was allocated but not initialized. + */ + if (!dom->events) { + return; + } + + rcu_read_lock(); + cds_lfht_for_each_entry(dom->events->ht, &iter.iter, node, node) { + int ret; + + ret = lttng_ht_del(dom->events, &iter); + assert(!ret); + call_rcu(&node->head, destroy_event_jul_rcu); + } + rcu_read_unlock(); + + ht_cleanup_push(dom->events); +} diff --git a/src/bin/lttng-sessiond/jul.h b/src/bin/lttng-sessiond/jul.h new file mode 100644 index 000000000..1f7f6cdcd --- /dev/null +++ b/src/bin/lttng-sessiond/jul.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2013 - David Goulet + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License, version 2 only, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef _JUL_H +#define _JUL_H + +#include +#include + +/* + * Java Util Logging event representation. + */ +struct jul_event { + /* + * Name of the event which is directly mapped to a Logger object name in + * the JUL API. + */ + char name[LTTNG_SYMBOL_NAME_LEN]; + + /* + * Tells if the event is enabled or not on the JUL Agent. + */ + unsigned int enabled:1; + + /* + * Hash table nodes of the JUL domain. Indexed by name string. + */ + struct lttng_ht_node_str node; +}; + +/* + * Top level data structure in a UST session containing JUL event name created + * for it. + */ +struct jul_domain { + /* + * Contains JUL event indexed by name. + */ + struct lttng_ht *events; +}; + +int jul_init_domain(struct jul_domain *dom); +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); +void jul_delete_event(struct jul_event *event, struct jul_domain *dom); +void jul_destroy_event(struct jul_event *event); +void jul_destroy_domain(struct jul_domain *dom); + +#endif /* _JUL_H */ diff --git a/src/bin/lttng-sessiond/trace-ust.c b/src/bin/lttng-sessiond/trace-ust.c index 8363ae295..b64597599 100644 --- a/src/bin/lttng-sessiond/trace-ust.c +++ b/src/bin/lttng-sessiond/trace-ust.c @@ -191,6 +191,7 @@ error: */ struct ltt_ust_session *trace_ust_create_session(uint64_t session_id) { + int ret; struct ltt_ust_session *lus; /* Allocate a new ltt ust session */ @@ -218,6 +219,10 @@ struct ltt_ust_session *trace_ust_create_session(uint64_t session_id) /* Alloc UST global domain channels' HT */ lus->domain_global.channels = lttng_ht_new(0, LTTNG_HT_TYPE_STRING); + ret = jul_init_domain(&lus->domain_jul); + if (ret < 0) { + goto error_consumer; + } lus->consumer = consumer_create_output(CONSUMER_DST_LOCAL); if (lus->consumer == NULL) { @@ -238,6 +243,7 @@ struct ltt_ust_session *trace_ust_create_session(uint64_t session_id) error_consumer: ht_cleanup_push(lus->domain_global.channels); + jul_destroy_domain(&lus->domain_jul); free(lus); error: return NULL; @@ -677,6 +683,7 @@ void trace_ust_destroy_session(struct ltt_ust_session *session) /* Cleaning up UST domain */ destroy_domain_global(&session->domain_global); + jul_destroy_domain(&session->domain_jul); /* Cleanup UID buffer registry object(s). */ cds_list_for_each_entry_safe(reg, sreg, &session->buffer_reg_uid_list, diff --git a/src/bin/lttng-sessiond/trace-ust.h b/src/bin/lttng-sessiond/trace-ust.h index aa6ac408f..f25573a80 100644 --- a/src/bin/lttng-sessiond/trace-ust.h +++ b/src/bin/lttng-sessiond/trace-ust.h @@ -27,6 +27,7 @@ #include #include "consumer.h" +#include "jul.h" #include "ust-ctl.h" struct ltt_ust_ht_key { @@ -84,6 +85,7 @@ struct ltt_ust_session { uint64_t id; /* Unique identifier of session */ int start_trace; struct ltt_ust_domain_global domain_global; + struct jul_domain domain_jul; /* UID/GID of the user owning the session */ uid_t uid; gid_t gid; diff --git a/src/common/defaults.h b/src/common/defaults.h index 0c9f134a9..0682af63d 100644 --- a/src/common/defaults.h +++ b/src/common/defaults.h @@ -132,6 +132,9 @@ /* Default channel attributes */ #define DEFAULT_CHANNEL_NAME "channel0" +/* Default JUL domain channel name. */ +#define DEFAULT_JUL_CHANNEL_NAME "jul_channel" +/* JUL default channel name. */ #define DEFAULT_CHANNEL_OVERWRITE 0 #define DEFAULT_CHANNEL_TRACEFILE_SIZE 0 #define DEFAULT_CHANNEL_TRACEFILE_COUNT 0 diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am index 871be3859..a8dec2bd9 100644 --- a/tests/unit/Makefile.am +++ b/tests/unit/Makefile.am @@ -56,6 +56,7 @@ UST_DATA_TRACE=$(top_builddir)/src/bin/lttng-sessiond/trace-ust.o \ $(top_builddir)/src/bin/lttng-sessiond/fd-limit.o \ $(top_builddir)/src/bin/lttng-sessiond/session.o \ $(top_builddir)/src/bin/lttng-sessiond/snapshot.o \ + $(top_builddir)/src/bin/lttng-sessiond/jul.o \ $(top_builddir)/src/common/.libs/uri.o \ $(top_builddir)/src/common/.libs/utils.o \ $(top_builddir)/src/common/health/libhealth.la \ -- 2.34.1