From 84cd17c63cde7ea5d7a0ad037dd41e8297658812 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Sat, 19 Nov 2011 09:43:11 -0500 Subject: [PATCH] Implement UST destroy session Signed-off-by: Mathieu Desnoyers --- lttng-sessiond/main.c | 8 +++ lttng-sessiond/ust-app.c | 103 ++++++++++++++++++++++++++++++---- lttng-sessiond/ust-app.h | 3 +- lttng-sessiond/ust-consumer.c | 15 ----- 4 files changed, 101 insertions(+), 28 deletions(-) diff --git a/lttng-sessiond/main.c b/lttng-sessiond/main.c index 9464c2c1b..3651e6c3e 100644 --- a/lttng-sessiond/main.c +++ b/lttng-sessiond/main.c @@ -305,8 +305,14 @@ static void teardown_kernel_session(struct ltt_session *session) */ static void teardown_ust_session(struct ltt_session *session) { + int ret; + DBG("Tearing down UST session(s)"); + ret = ust_app_destroy_trace_all(session->ust_session); + if (ret) { + ERR("Error in ust_app_destroy_trace_all"); + } trace_ust_destroy_session(session->ust_session); } @@ -2676,6 +2682,8 @@ static int cmd_destroy_session(struct ltt_session *session, char *name) /* Clean kernel session teardown */ teardown_kernel_session(session); + /* UST session teardown */ + teardown_ust_session(session); /* * Must notify the kernel thread here to update it's poll setin order diff --git a/lttng-sessiond/ust-app.c b/lttng-sessiond/ust-app.c index 3547679f8..356887026 100644 --- a/lttng-sessiond/ust-app.c +++ b/lttng-sessiond/ust-app.c @@ -47,6 +47,7 @@ static void delete_ust_app_event(int sock, struct ust_app_event *ua_event) //} ustctl_release_object(sock, ua_event->obj); + free(ua_event->obj); free(ua_event); } @@ -56,11 +57,9 @@ static void delete_ust_app_event(int sock, struct ust_app_event *ua_event) */ 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. + ustctl_release_object(sock, stream->obj); + free(stream->obj); + free(stream); } /* @@ -75,6 +74,7 @@ static void delete_ust_app_channel(int sock, struct ust_app_channel *ua_chan) struct ltt_ust_stream *stream, *stmp; cds_list_for_each_entry_safe(stream, stmp, &ua_chan->streams.head, list) { + cds_list_del(&stream->list); delete_ust_app_stream(sock, stream); } @@ -95,6 +95,9 @@ static void delete_ust_app_channel(int sock, struct ust_app_channel *ua_chan) ERR("UST app destroy session hashtable failed"); goto error; } + ustctl_release_object(sock, ua_chan->obj); + free(ua_chan->obj); + free(ua_chan); error: return; @@ -112,10 +115,10 @@ static void delete_ust_app_session(int sock, 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. - */ + ustctl_release_object(sock, ua_sess->metadata->stream_obj); + free(ua_sess->metadata->stream_obj); + ustctl_release_object(sock, ua_sess->metadata->obj); + free(ua_sess->metadata->obj); } cds_lfht_for_each_entry(ua_sess->channels, &iter, ua_chan, node) { @@ -565,6 +568,16 @@ static void shadow_copy_session(struct ust_app_session *ua_sess, } } +static +void __lookup_session_by_app(struct ltt_ust_session *usess, + struct ust_app *app, struct cds_lfht_iter *iter) +{ + /* Get right UST app session from app */ + (void) hashtable_lookup(app->sessions, + (void *) ((unsigned long) usess->uid), sizeof(void *), + iter); +} + /* * Return ust app session from the app session hashtable using the UST session * uid. @@ -575,9 +588,8 @@ static struct ust_app_session *lookup_session_by_app( struct cds_lfht_iter iter; struct cds_lfht_node *node; - /* Get right UST app session from app */ - node = hashtable_lookup(app->sessions, - (void *) ((unsigned long) usess->uid), sizeof(void *), &iter); + __lookup_session_by_app(usess, app, &iter); + node = hashtable_iter_get_node(&iter); if (node == NULL) { goto error; } @@ -1244,6 +1256,47 @@ error_rcu_unlock: return -1; } +/* + * Destroy a specific UST session in apps. + */ +int ust_app_destroy_trace(struct ltt_ust_session *usess, struct ust_app *app) +{ + struct ust_app_session *ua_sess; + struct lttng_ust_object_data obj; + struct cds_lfht_iter iter; + struct cds_lfht_node *node; + + DBG("Destroy tracing for ust app pid %d", app->key.pid); + + rcu_read_lock(); + + __lookup_session_by_app(usess, app, &iter); + node = hashtable_iter_get_node(&iter); + if (node == NULL) { + /* Only malloc can failed so something is really wrong */ + goto error_rcu_unlock; + } + ua_sess = caa_container_of(node, struct ust_app_session, node); + hashtable_del(app->sessions, &iter); + delete_ust_app_session(app->key.sock, ua_sess); + obj.handle = ua_sess->handle; + obj.shm_fd = -1; + obj.wait_fd = -1; + obj.memory_map_size = 0; + ustctl_release_object(app->key.sock, &obj); + + rcu_read_unlock(); + + /* Quiescent wait after stopping trace */ + ustctl_wait_quiescent(app->key.sock); + + return 0; + +error_rcu_unlock: + rcu_read_unlock(); + return -1; +} + /* * Start tracing for the UST session. */ @@ -1296,6 +1349,32 @@ int ust_app_stop_trace_all(struct ltt_ust_session *usess) return 0; } +/* + * Destroy app UST session. + */ +int ust_app_destroy_trace_all(struct ltt_ust_session *usess) +{ + int ret = 0; + struct cds_lfht_iter iter; + struct ust_app *app; + + DBG("Destroy all UST traces"); + + rcu_read_lock(); + + cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) { + ret = ust_app_destroy_trace(usess, app); + if (ret < 0) { + /* Continue to next apps even on error */ + continue; + } + } + + rcu_read_unlock(); + + return 0; +} + /* * Add channels/events from UST global domain to registered apps at sock. */ diff --git a/lttng-sessiond/ust-app.h b/lttng-sessiond/ust-app.h index 3159ba5cb..e92458e2b 100644 --- a/lttng-sessiond/ust-app.h +++ b/lttng-sessiond/ust-app.h @@ -83,7 +83,6 @@ struct ust_app_session { int handle; /* Used has unique identifier */ unsigned int uid; struct ltt_ust_metadata *metadata; - struct lttng_ust_object_data *obj; struct cds_lfht *channels; /* Registered channels */ struct cds_lfht_node node; char path[PATH_MAX]; @@ -118,6 +117,8 @@ int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app); int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app); int ust_app_start_trace_all(struct ltt_ust_session *usess); int ust_app_stop_trace_all(struct ltt_ust_session *usess); +int ust_app_destroy_trace(struct ltt_ust_session *usess, struct ust_app *app); +int ust_app_destroy_trace_all(struct ltt_ust_session *usess); int ust_app_list_events(struct lttng_event **events); void ust_app_global_update(struct ltt_ust_session *usess, int sock); diff --git a/lttng-sessiond/ust-consumer.c b/lttng-sessiond/ust-consumer.c index 46558417e..866d7bd56 100644 --- a/lttng-sessiond/ust-consumer.c +++ b/lttng-sessiond/ust-consumer.c @@ -100,18 +100,7 @@ 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"); @@ -179,10 +168,6 @@ 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 */ -- 2.34.1