Merge branch 'master' of git://git.lttng.org/lttng-tools
authorDavid Goulet <david.goulet@polymtl.ca>
Mon, 14 Nov 2011 17:11:17 +0000 (12:11 -0500)
committerDavid Goulet <david.goulet@polymtl.ca>
Mon, 14 Nov 2011 17:11:17 +0000 (12:11 -0500)
lttng-sessiond/hashtable.c
lttng-sessiond/hashtable.h
lttng-sessiond/main.c
lttng-sessiond/trace-ust.c
lttng-sessiond/ust-app.c
lttng-sessiond/ust-app.h
lttng-sessiond/ust-consumer.c
lttng/commands/enable_events.c

index 6bca1dac010e1ae3457db98c9c254e9c01ba7935..956cfd426ea4ab106fee376ba922378ebacae677 100644 (file)
@@ -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);
+}
index 5174eed7563d9577fb3d9c55b890a4a315d1809d..7212fb0e2b10dbec587c3853352e2f322c890da7 100644 (file)
@@ -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 */
index d1d184d89eae8915d8d8808a638ca245e0b98765..fa196e7b033bfe07f97ac994803afc384c6f274c 100644 (file)
@@ -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;
index a7c853530d0ab7db9906c588d7da72c9a4e3ced5..3916c1f5de97c8dc46fdb650b2f91edd6d971bbe 100644 (file)
@@ -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;
index 99fd84f3e07ca5982875ab257dd7f2146d9c225f..8520efb440e71cb84499609c1beb83bcccca8e36 100644 (file)
 
 #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;
index bcde8bc9cd326e4b5de5a025c58dd130ccff43b8..a69ed845162ac71adb7ca88f1aee70e9a9b1f35b 100644 (file)
@@ -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
index ca008d4adf65d0165d3eaca6f06f149361081594..df569368ae04f2e8faafb1b9ebbfde069fc618aa 100644 (file)
@@ -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 */
index 005214b8e8552ea0b48ad8a429f340a24842f9b3..dd1a049288c55807ce682fa0faf406d67797a07b 100644 (file)
@@ -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}
 };
 
This page took 0.03468 seconds and 4 git commands to generate.