From: David Goulet Date: Mon, 14 Nov 2011 17:11:17 +0000 (-0500) Subject: Merge branch 'master' of git://git.lttng.org/lttng-tools X-Git-Tag: v2.0-pre15~118 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=c70c0ca0e8e46b29376d77b5b4483891cb33679d;hp=fa551d12885e275d9988308335b0341e22edacfa Merge branch 'master' of git://git.lttng.org/lttng-tools --- diff --git a/lttng-sessiond/hashtable.c b/lttng-sessiond/hashtable.c index 6bca1dac0..956cfd426 100644 --- a/lttng-sessiond/hashtable.c +++ b/lttng-sessiond/hashtable.c @@ -106,3 +106,8 @@ unsigned long hashtable_get_count(struct cds_lfht *ht) return count; } + +int hashtable_destroy(struct cds_lfht *ht) +{ + return cds_lfht_destroy(ht, NULL); +} diff --git a/lttng-sessiond/hashtable.h b/lttng-sessiond/hashtable.h index 5174eed75..7212fb0e2 100644 --- a/lttng-sessiond/hashtable.h +++ b/lttng-sessiond/hashtable.h @@ -36,5 +36,6 @@ void hashtable_node_init(struct cds_lfht_node *node, int hashtable_del(struct cds_lfht *ht, struct cds_lfht_iter *iter); unsigned long hashtable_get_count(struct cds_lfht *ht); +int hashtable_destroy(struct cds_lfht *ht); #endif /* _LTT_HASHTABLE_H */ diff --git a/lttng-sessiond/main.c b/lttng-sessiond/main.c index d1d184d89..fa196e7b0 100644 --- a/lttng-sessiond/main.c +++ b/lttng-sessiond/main.c @@ -1098,7 +1098,7 @@ static void *thread_manage_apps(void *data) goto error; } - /* Socket closed */ + /* Socket closed on remote end. */ ust_app_unregister(pollfd); break; } @@ -2493,10 +2493,11 @@ static int cmd_start_trace(struct ltt_session *session) { int ret; struct ltt_kernel_session *ksession; - struct ltt_ust_session *usess = session->ust_session; + struct ltt_ust_session *usess; /* Short cut */ ksession = session->kernel_session; + usess = session->ust_session; /* Kernel tracing */ if (ksession != NULL) { @@ -2553,12 +2554,14 @@ static int cmd_start_trace(struct ltt_session *session) } /* Flag session that trace should start automatically */ - usess->start_trace = 1; + if (usess) { + usess->start_trace = 1; - ret = ust_app_start_trace_all(usess); - if (ret < 0) { - ret = LTTCOMM_UST_START_FAIL; - goto error; + ret = ust_app_start_trace_all(usess); + if (ret < 0) { + ret = LTTCOMM_UST_START_FAIL; + goto error; + } } ret = LTTCOMM_OK; diff --git a/lttng-sessiond/trace-ust.c b/lttng-sessiond/trace-ust.c index a7c853530..3916c1f5d 100644 --- a/lttng-sessiond/trace-ust.c +++ b/lttng-sessiond/trace-ust.c @@ -245,7 +245,7 @@ struct ltt_ust_metadata *trace_ust_create_metadata(char *path) int ret; struct ltt_ust_metadata *lum; - lum = malloc(sizeof(struct ltt_ust_metadata)); + lum = zmalloc(sizeof(struct ltt_ust_metadata)); if (lum == NULL) { perror("ust metadata malloc"); goto error; diff --git a/lttng-sessiond/ust-app.c b/lttng-sessiond/ust-app.c index 99fd84f3e..8520efb44 100644 --- a/lttng-sessiond/ust-app.c +++ b/lttng-sessiond/ust-app.c @@ -31,9 +31,107 @@ #include "hashtable.h" #include "ust-app.h" -#include "../hashtable/hash.h" -#include "ust-ctl.h" #include "ust-consumer.h" +#include "ust-ctl.h" + +/* + * Delete ust app event safely. RCU read lock must be held before calling + * this function. + */ +static void delete_ust_app_event(int sock, struct ust_app_event *ua_event) +{ + /* TODO : remove context */ + //struct ust_app_ctx *ltctx; + //cds_lfht_for_each_entry(lte->ctx, &iter, ltctx, node) { + // delete_ust_app_ctx(sock, ltctx); + //} + + ustctl_release_object(sock, ua_event->obj); + free(ua_event); +} + +/* + * Delete ust app stream safely. RCU read lock must be held before calling + * this function. + */ +static void delete_ust_app_stream(int sock, struct ltt_ust_stream *stream) +{ + //TODO + //stream is used for passing to consumer. + //send_channel_streams is responsible for freeing the streams. + //note that this will not play well with flight recorder mode: + //we might need a criterion to discard the streams. +} + +/* + * Delete ust app channel safely. RCU read lock must be held before calling + * this function. + */ +static void delete_ust_app_channel(int sock, struct ust_app_channel *ua_chan) +{ + int ret; + struct cds_lfht_iter iter; + struct ust_app_event *ua_event; + struct ltt_ust_stream *stream, *stmp; + + cds_list_for_each_entry_safe(stream, stmp, &ua_chan->streams.head, list) { + delete_ust_app_stream(sock, stream); + } + + /* TODO : remove channel context */ + //cds_lfht_for_each_entry(ltc->ctx, &iter, ltctx, node) { + // hashtable_del(ltc->ctx, &iter); + // delete_ust_app_ctx(sock, ltctx); + //} + //ret = hashtable_destroy(ltc->ctx); + + cds_lfht_for_each_entry(ua_chan->events, &iter, ua_event, node) { + hashtable_del(ua_chan->events, &iter); + delete_ust_app_event(sock, ua_event); + } + + ret = hashtable_destroy(ua_chan->events); + if (ret < 0) { + ERR("UST app destroy session hashtable failed"); + goto error; + } + +error: + return; +} + +/* + * Delete ust app session safely. RCU read lock must be held before calling + * this function. + */ +static void delete_ust_app_session(int sock, + struct ust_app_session *ua_sess) +{ + int ret; + struct cds_lfht_iter iter; + struct ust_app_channel *ua_chan; + + if (ua_sess->metadata) { + /* + * We do NOT release the stream object and metadata object since they + * are release when fds are sent to the consumer. + */ + } + + cds_lfht_for_each_entry(ua_sess->channels, &iter, ua_chan, node) { + hashtable_del(ua_sess->channels, &iter); + delete_ust_app_channel(sock, ua_chan); + } + + ret = hashtable_destroy(ua_sess->channels); + if (ret < 0) { + ERR("UST app destroy session hashtable failed"); + goto error; + } + +error: + return; +} /* * Delete a traceable application structure from the global list. @@ -43,18 +141,16 @@ static void delete_ust_app(struct ust_app *lta) int ret; struct cds_lfht_node *node; struct cds_lfht_iter iter; + struct ust_app_session *lts; rcu_read_lock(); - /* TODO: clean session hashtable */ - free(lta->sessions); - close(lta->key.sock); - /* Remove from apps hash table */ node = hashtable_lookup(ust_app_ht, (void *) ((unsigned long) lta->key.pid), sizeof(void *), &iter); if (node == NULL) { ERR("UST app pid %d not found in hash table", lta->key.pid); + goto end; } else { ret = hashtable_del(ust_app_ht, &iter); if (ret) { @@ -70,6 +166,7 @@ static void delete_ust_app(struct ust_app *lta) (void *) ((unsigned long) lta->key.sock), sizeof(void *), &iter); if (node == NULL) { ERR("UST app key %d not found in key hash table", lta->key.sock); + goto end; } else { ret = hashtable_del(ust_app_sock_key_map, &iter); if (ret) { @@ -81,8 +178,30 @@ static void delete_ust_app(struct ust_app *lta) } } - free(lta); + /* Socket is already closed at this point */ + + /* Delete ust app sessions info */ + if (lta->sock_closed) { + lta->key.sock = -1; + } + + cds_lfht_for_each_entry(lta->sessions, &iter, lts, node) { + hashtable_del(lta->sessions, &iter); + delete_ust_app_session(lta->key.sock, lts); + } + ret = hashtable_destroy(lta->sessions); + if (ret < 0) { + ERR("UST app destroy session hashtable failed"); + goto end; + } + + if (lta->key.sock >= 0) { + close(lta->key.sock); + } + + free(lta); +end: rcu_read_unlock(); } @@ -124,7 +243,6 @@ static struct ust_app *find_app_by_sock(int sock) DBG2("UST app find by sock %d not found", sock); goto error; } - return caa_container_of(node, struct ust_app, node); error: @@ -175,7 +293,7 @@ int ust_app_register(struct ust_register_msg *msg, int sock) { struct ust_app *lta; - lta = malloc(sizeof(struct ust_app)); + lta = zmalloc(sizeof(struct ust_app)); if (lta == NULL) { PERROR("malloc"); return -ENOMEM; @@ -241,8 +359,11 @@ void ust_app_unregister(int sock) goto error; } + /* We got called because the socket was closed on the remote end. */ + close(sock); + /* Using a flag because we still need "sock" as a key. */ + lta->sock_closed = 1; call_rcu(&node->head, delete_ust_app_rcu); - error: rcu_read_unlock(); return; diff --git a/lttng-sessiond/ust-app.h b/lttng-sessiond/ust-app.h index bcde8bc9c..a69ed8451 100644 --- a/lttng-sessiond/ust-app.h +++ b/lttng-sessiond/ust-app.h @@ -97,6 +97,7 @@ struct ust_app { struct cds_lfht *sessions; struct cds_lfht_node node; struct ust_app_key key; + int sock_closed; }; #ifdef HAVE_LIBLTTNG_UST_CTL diff --git a/lttng-sessiond/ust-consumer.c b/lttng-sessiond/ust-consumer.c index ca008d4ad..df569368a 100644 --- a/lttng-sessiond/ust-consumer.c +++ b/lttng-sessiond/ust-consumer.c @@ -38,7 +38,7 @@ static int send_channel_streams(int sock, { int ret, fd; struct lttcomm_consumer_msg lum; - struct ltt_ust_stream *stream; + struct ltt_ust_stream *stream, *tmp; DBG("Sending streams of channel %s to UST consumer", uchan->name); @@ -65,7 +65,7 @@ static int send_channel_streams(int sock, goto error; } - cds_list_for_each_entry(stream, &uchan->streams.head, list) { + cds_list_for_each_entry_safe(stream, tmp, &uchan->streams.head, list) { int fds[2]; if (!stream->obj->shm_fd) { @@ -97,7 +97,18 @@ static int send_channel_streams(int sock, perror("send consumer stream ancillary data"); goto error; } + + /* + * We release the stream object here, as we have passed + * it to the consumer. + */ + /* Ensure we don't let the app know (sock = -1). */ + ustctl_release_object(-1, stream->obj); + cds_list_del(&stream->list); + free(stream); } + /* Ensure we don't let the app know (sock = -1). */ + ustctl_release_object(-1, uchan->obj); DBG("consumer channel streams sent"); @@ -165,6 +176,10 @@ int ust_consumer_send_session(int consumer_fd, struct ust_app_session *usess) perror("send consumer stream"); goto error; } + /* Metadata fds passed to consumer, release them. */ + /* Ensure we don't let the app know (sock = -1). */ + ustctl_release_object(-1, usess->metadata->stream_obj); + ustctl_release_object(-1, usess->metadata->obj); } /* Send each channel fd streams of session */ diff --git a/lttng/commands/enable_events.c b/lttng/commands/enable_events.c index 005214b8e..dd1a04928 100644 --- a/lttng/commands/enable_events.c +++ b/lttng/commands/enable_events.c @@ -70,10 +70,10 @@ static struct poptOption long_options[] = { {"pid", 'p', POPT_ARG_INT, &opt_pid, 0, 0, 0}, {"tracepoint", 0, POPT_ARG_NONE, 0, OPT_TRACEPOINT, 0, 0}, {"marker", 0, POPT_ARG_NONE, 0, OPT_MARKER, 0, 0}, - {"probe", 0, POPT_ARG_STRING, &opt_probe, OPT_PROBE, 0, 0}, + {"probe", 0, POPT_ARG_STRING, &opt_probe, OPT_PROBE, 0, 0}, {"function", 0, POPT_ARG_STRING, &opt_function, OPT_FUNCTION, 0, 0}, {"function:entry", 0, POPT_ARG_STRING, &opt_function_entry_symbol, OPT_FUNCTION_ENTRY, 0, 0}, - {"syscall", 0, POPT_ARG_NONE, 0, OPT_SYSCALL, 0, 0}, + {"syscall", 0, POPT_ARG_NONE, 0, OPT_SYSCALL, 0, 0}, {0, 0, 0, 0, 0, 0, 0} };