X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=lttng-sessiond%2Fust-app.c;h=8520efb440e71cb84499609c1beb83bcccca8e36;hp=e063fb292ad80511f45331896704bba555898d14;hb=d5cd1f3415b6d3cafa347b8e0068de2245014f25;hpb=dbdbd482ead909120dc3c4e4b6e41413b7fa57a1 diff --git a/lttng-sessiond/ust-app.c b/lttng-sessiond/ust-app.c index e063fb292..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(); } @@ -113,7 +232,6 @@ static struct ust_app *find_app_by_sock(int sock) (void *)((unsigned long) sock), sizeof(void *), &iter); if (node == NULL) { DBG2("UST app find by sock %d key not found", sock); - rcu_read_unlock(); goto error; } @@ -123,10 +241,8 @@ static struct ust_app *find_app_by_sock(int sock) (void *)((unsigned long) key->pid), sizeof(void *), &iter); if (node == NULL) { DBG2("UST app find by sock %d not found", sock); - rcu_read_unlock(); goto error; } - return caa_container_of(node, struct ust_app, node); error: @@ -153,7 +269,6 @@ struct ust_app *ust_app_find_by_pid(pid_t pid) node = hashtable_lookup(ust_app_ht, (void *)((unsigned long) pid), sizeof(void *), &iter); if (node == NULL) { - rcu_read_unlock(); DBG2("UST app no found with pid %d", pid); goto error; } @@ -164,6 +279,7 @@ struct ust_app *ust_app_find_by_pid(pid_t pid) return caa_container_of(node, struct ust_app, node); error: + rcu_read_unlock(); return NULL; } @@ -177,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; @@ -243,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; @@ -808,7 +927,7 @@ int ust_app_add_channel_all(struct ltt_ust_session *usess, /* Create session on the tracer side and add it to app session HT */ ua_sess = create_ust_app_session(usess, app); - if (ret < 0) { + if (ua_sess == NULL) { goto next; } @@ -851,7 +970,7 @@ int ust_app_add_event_all(struct ltt_ust_session *usess, /* Create session on the tracer side and add it to app session HT */ ua_sess = create_ust_app_session(usess, app); - if (ret < 0) { + if (ua_sess == NULL) { goto next; } @@ -889,15 +1008,17 @@ int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app) DBG("Starting tracing for ust app pid %d", app->key.pid); + rcu_read_lock(); + ua_sess = lookup_session_by_app(usess, app); if (ua_sess == NULL) { /* Only malloc can failed so something is really wrong */ - goto error; + goto error_rcu_unlock; } ret = create_ust_app_metadata(ua_sess, usess->pathname, app); if (ret < 0) { - goto error; + goto error_rcu_unlock; } /* For each channel */ @@ -912,7 +1033,7 @@ int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app) ustream = zmalloc(sizeof(*ustream)); if (ustream == NULL) { PERROR("zmalloc ust stream"); - continue; + goto error_rcu_unlock; } ret = ustctl_create_stream(app->key.sock, ua_chan->obj, @@ -943,22 +1064,24 @@ int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app) /* Setup UST consumer socket and send fds to it */ ret = ust_consumer_send_session(usess->consumer_fd, ua_sess); if (ret < 0) { - goto error; + goto error_rcu_unlock; } /* This start the UST tracing */ ret = ustctl_start_session(app->key.sock, ua_sess->handle); if (ret < 0) { ERR("Error starting tracing for app pid: %d", app->key.pid); - goto error; + goto error_rcu_unlock; } + rcu_read_unlock(); /* Quiescent wait after starting trace */ ustctl_wait_quiescent(app->key.sock); return 0; -error: +error_rcu_unlock: + rcu_read_unlock(); return -1; }