Merge branch 'master' into benchmark
authorDavid Goulet <dgoulet@efficios.com>
Mon, 16 Jan 2012 15:43:11 +0000 (10:43 -0500)
committerDavid Goulet <dgoulet@efficios.com>
Mon, 16 Jan 2012 15:43:11 +0000 (10:43 -0500)
15 files changed:
common/runas.c
configure.ac
include/lttng/lttng-consumer.h
liblttng-consumer/Makefile.am
liblttng-consumer/lttng-consumer.c
liblttng-ht/lttng-ht.c
liblttng-ustconsumer/lttng-ustconsumer.c
lttng-consumerd/lttng-consumerd.c
lttng-sessiond/channel.c
lttng-sessiond/event.c
lttng-sessiond/lttng-ust-abi.h
lttng-sessiond/main.c
lttng-sessiond/trace-ust.c
lttng-sessiond/ust-app.c
lttng-sessiond/utils.h

index f612ccc7554590a44fdeca167a33f29d4b0ee0d0..b3fa81469824ecc6b69979e6a64e408cbd4a5546 100644 (file)
@@ -230,7 +230,7 @@ int run_as(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid)
         * where the stack grows up (HPPA).
         */
        pid = clone(child_run_as, child_stack + (CHILD_STACK_SIZE / 2),
-               CLONE_FILES | SIGCHLD | CLONE_VM,
+               CLONE_FILES | SIGCHLD,
                &run_as_data, NULL);
        if (pid < 0) {
                perror("clone");
index eb0b3a05a97a4ff8f4356f4f537819bd1796b80c..68845123cc103b3976a77dfd06a53cdd9f936065 100644 (file)
@@ -42,10 +42,10 @@ AC_ARG_WITH([consumer64d-libdir],
        [CONSUMERD64_LIBDIR=''])
 AC_SUBST([CONSUMERD64_LIBDIR])
 
-AC_DEFINE_UNQUOTED([CONFIG_CONSUMERD32_BIN], $CONSUMERD32_BIN, [Location of the 32-bit consumerd executable.])
-AC_DEFINE_UNQUOTED([CONFIG_CONSUMERD64_BIN], $CONSUMERD64_BIN, [Location of the 64-bit consumerd executable])
-AC_DEFINE_UNQUOTED([CONFIG_CONSUMERD32_LIBDIR], $CONSUMERD32_LIBDIR, [Search for consumerd 32-bit libraries in this location.])
-AC_DEFINE_UNQUOTED([CONFIG_CONSUMERD64_LIBDIR], $CONSUMERD64_LIBDIR, [Search for consumerd 64-bit libraries in this location.])
+AC_DEFINE_UNQUOTED([CONFIG_CONSUMERD32_BIN], "$CONSUMERD32_BIN", [Location of the 32-bit consumerd executable.])
+AC_DEFINE_UNQUOTED([CONFIG_CONSUMERD64_BIN], "$CONSUMERD64_BIN", [Location of the 64-bit consumerd executable])
+AC_DEFINE_UNQUOTED([CONFIG_CONSUMERD32_LIBDIR], "$CONSUMERD32_LIBDIR", [Search for consumerd 32-bit libraries in this location.])
+AC_DEFINE_UNQUOTED([CONFIG_CONSUMERD64_LIBDIR], "$CONSUMERD64_LIBDIR", [Search for consumerd 64-bit libraries in this location.])
 
 # Check for pthread
 AC_CHECK_LIB([pthread], [pthread_create], [],
@@ -155,18 +155,81 @@ AC_CONFIG_FILES([
 
 AC_OUTPUT
 
+#
 # Mini-report on what will be built
-AS_ECHO("")
-
+#
+AS_ECHO()
+
+# Target architecture we're building for
+target_arch=$host_cpu
+[
+for f in $CFLAGS; do
+        if test $f = "-m32"; then
+                       target_arch="32-bit"
+        elif test $f = "-m64"; then
+                       target_arch="64-bit"
+        fi
+done
+]
+AS_ECHO_N("Target architecture: ")
+AS_ECHO($target_arch)
+
+# LTTng-UST enabled/disabled
 AS_ECHO_N("Lttng-UST support: ")
-AS_IF([test "x$lttng_ust_support" = "xyes"], [AS_ECHO("Enabled")],
-       [AS_ECHO("Disabled")]
-)
+AS_IF([test "x$lttng_ust_support" = "xyes"],[
+       AS_ECHO("Enabled")
+],[
+       AS_ECHO("Disabled")
+])
 
-AS_IF([test "x$consumerd_only" = "xyes"],
-       [AS_ECHO("Only the consumerd daemon will be built.")],
-       [AS_ECHO("All binaries will be built.")]
-)
+# Do we build only the consumerd, or everything
+AS_IF([test "x$consumerd_only" = "xyes"],[
+       AS_ECHO("Only the consumerd daemon will be built.")
+],[
+       AS_ECHO("All binaries will be built.")
+])
+
+# Print the bindir and libdir this `make install' will install into.
+AS_ECHO()
+AS_ECHO_N("Binaries will be installed in:  ")
+AS_ECHO("`eval eval echo $bindir`")
+AS_ECHO_N("Libraries will be installed in: ")
+AS_ECHO("`eval eval echo $libdir`")
+
+# If we build the sessiond, print the paths it will use
+AS_IF([test "x$consumerd_only" = "xno"],[
+       AS_ECHO()
+       AS_ECHO("The sessiond daemon will look in the following directories: ")
+       AS_ECHO_N("32-bit consumerd executable at: ")
+       AS_IF([test "$CONSUMERD32_BIN" = ""],[
+               AS_ECHO_N("`eval eval echo $bindir`")
+               AS_ECHO("/lttng-consumerd")
+       ],[
+               AS_ECHO("$CONSUMERD32_BIN")
+       ])
+
+       AS_ECHO_N("32-bit consumer libraries in:   ")
+       AS_IF([test "$CONSUMERD32_LIBDIR" = ""],[
+               AS_ECHO("`eval eval echo $libdir`")
+       ],[
+               AS_ECHO("$CONSUMERD32_LIBDIR")
+       ])
+
+       AS_ECHO_N("64-bit consumerd executable at: ")
+       AS_IF([test "$CONSUMERD64_BIN" = ""],[
+               AS_ECHO_N("`eval eval echo $bindir`")
+               AS_ECHO("/lttng-consumerd")
+       ],[
+               AS_ECHO("$CONSUMERD64_BIN")
+       ])
+
+       AS_ECHO_N("64-bit consumer libraries in:   ")
+       AS_IF([test "$CONSUMERD64_LIBDIR" = ""],[
+               AS_ECHO("`eval eval echo $libdir`")
+       ],[
+               AS_ECHO("$CONSUMERD64_LIBDIR")
+       ])
+])
 
-AS_ECHO("")
+AS_ECHO()
 
index 81fd83e0ff4845574f4ddf3762129a2935bf7138..3d16d49732f9175a68ecff669e0ace402d55b2c2 100644 (file)
@@ -23,8 +23,9 @@
 #include <limits.h>
 #include <poll.h>
 #include <unistd.h>
-#include <urcu/list.h>
+
 #include <lttng/lttng.h>
+#include <lttng-ht.h>
 
 /*
  * When the receiving thread dies, we need to have a way to make the polling
@@ -58,14 +59,6 @@ enum lttng_consumer_stream_state {
        LTTNG_CONSUMER_DELETE_STREAM,
 };
 
-struct lttng_consumer_channel_list {
-       struct cds_list_head head;
-};
-
-struct lttng_consumer_stream_list {
-       struct cds_list_head head;
-};
-
 enum lttng_consumer_type {
        LTTNG_CONSUMER_UNKNOWN = 0,
        LTTNG_CONSUMER_KERNEL,
@@ -74,7 +67,7 @@ enum lttng_consumer_type {
 };
 
 struct lttng_consumer_channel {
-       struct cds_list_head list;
+       struct lttng_ht_node_ulong node;
        int key;
        uint64_t max_sb_size; /* the subbuffer size for this channel */
        int refcount; /* Number of streams referencing this channel */
@@ -85,7 +78,6 @@ struct lttng_consumer_channel {
        size_t mmap_len;
        struct lttng_ust_shm_handle *handle;
        int nr_streams;
-       int shm_fd_is_copy;
        int wait_fd_is_copy;
        int cpucount;
 };
@@ -98,7 +90,7 @@ struct lttng_ust_lib_ring_buffer;
  * uniquely a stream.
  */
 struct lttng_consumer_stream {
-       struct cds_list_head list;
+       struct lttng_ht_node_ulong node;
        struct lttng_consumer_channel *chan;    /* associated channel */
        /*
         * key is the key used by the session daemon to refer to the
@@ -187,26 +179,26 @@ struct lttng_consumer_local_data {
  * Library-level data. One instance per process.
  */
 struct lttng_consumer_global_data {
+
        /*
-        * consumer_data.lock protects consumer_data.fd_list,
-        * consumer_data.stream_count, and consumer_data.need_update. It
-        * ensures the count matches the number of items in the fd_list.
-        * It ensures the list updates *always* trigger an fd_array
-        * update (therefore need to make list update vs
-        * consumer_data.need_update flag update atomic, and also flag
-        * read, fd array and flag clear atomic).
+        * At this time, this lock is used to ensure coherence between the count
+        * and number of element in the hash table. It's also a protection for
+        * concurrent read/write between threads.
+        *
+        * XXX: We need to see if this lock is still needed with the lockless RCU
+        * hash tables.
         */
        pthread_mutex_t lock;
+
        /*
-        * Number of streams in the list below. Protected by
-        * consumer_data.lock.
+        * Number of streams in the hash table. Protected by consumer_data.lock.
         */
        int stream_count;
        /*
-        * Lists of streams and channels. Protected by consumer_data.lock.
+        * Hash tables of streams and channels. Protected by consumer_data.lock.
         */
-       struct lttng_consumer_stream_list stream_list;
-       struct lttng_consumer_channel_list channel_list;
+       struct lttng_ht *stream_ht;
+       struct lttng_ht *channel_ht;
        /*
         * Flag specifying if the local array of FDs needs update in the
         * poll function. Protected by consumer_data.lock.
@@ -215,6 +207,11 @@ struct lttng_consumer_global_data {
        enum lttng_consumer_type type;
 };
 
+/*
+ * Init consumer data structures.
+ */
+extern void lttng_consumer_init(void);
+
 /*
  * Set the error socket for communication with a session daemon.
  */
index 80f5843dad5f45490969bba43646f87fbd9020d8..aadba52b5067dbbaed915671ec755ef4b712bfa2 100644 (file)
@@ -6,8 +6,8 @@ liblttng_consumer_la_SOURCES = lttng-consumer.c
 
 liblttng_consumer_la_LIBADD = \
                $(top_builddir)/liblttng-sessiond-comm/liblttng-sessiond-comm.la \
-               $(top_builddir)/liblttng-kconsumer/liblttng-kconsumer.la
-
+               $(top_builddir)/liblttng-kconsumer/liblttng-kconsumer.la \
+               $(top_builddir)/liblttng-ht/liblttng-ht.la
 
 if HAVE_LIBLTTNG_UST_CTL
 liblttng_consumer_la_LIBADD += \
index 0811e68ca8e8368c7695f92f37a44c906b42b7c0..0263aa1d83134bb5edd2937effce7d9cec1e4320 100644 (file)
@@ -37,8 +37,6 @@
 #include <lttngerr.h>
 
 struct lttng_consumer_global_data consumer_data = {
-       .stream_list.head = CDS_LIST_HEAD_INIT(consumer_data.stream_list.head),
-       .channel_list.head = CDS_LIST_HEAD_INIT(consumer_data.channel_list.head),
        .stream_count = 0,
        .need_update = 1,
        .type = LTTNG_CONSUMER_UNKNOWN,
@@ -61,18 +59,26 @@ volatile int consumer_quit = 0;
  */
 static struct lttng_consumer_stream *consumer_find_stream(int key)
 {
-       struct lttng_consumer_stream *iter;
+       struct lttng_ht_iter iter;
+       struct lttng_ht_node_ulong *node;
+       struct lttng_consumer_stream *stream = NULL;
 
        /* Negative keys are lookup failures */
        if (key < 0)
                return NULL;
-       cds_list_for_each_entry(iter, &consumer_data.stream_list.head, list) {
-               if (iter->key == key) {
-                       DBG("Found stream key %d", key);
-                       return iter;
-               }
+
+       rcu_read_lock();
+
+       lttng_ht_lookup(consumer_data.stream_ht, (void *)((unsigned long) key),
+                       &iter);
+       node = lttng_ht_iter_get_node_ulong(&iter);
+       if (node != NULL) {
+               stream = caa_container_of(node, struct lttng_consumer_stream, node);
        }
-       return NULL;
+
+       rcu_read_unlock();
+
+       return stream;
 }
 
 static void consumer_steal_stream_key(int key)
@@ -86,18 +92,26 @@ static void consumer_steal_stream_key(int key)
 
 static struct lttng_consumer_channel *consumer_find_channel(int key)
 {
-       struct lttng_consumer_channel *iter;
+       struct lttng_ht_iter iter;
+       struct lttng_ht_node_ulong *node;
+       struct lttng_consumer_channel *channel = NULL;
 
        /* Negative keys are lookup failures */
        if (key < 0)
                return NULL;
-       cds_list_for_each_entry(iter, &consumer_data.channel_list.head, list) {
-               if (iter->key == key) {
-                       DBG("Found channel key %d", key);
-                       return iter;
-               }
+
+       rcu_read_lock();
+
+       lttng_ht_lookup(consumer_data.channel_ht, (void *)((unsigned long) key),
+                       &iter);
+       node = lttng_ht_iter_get_node_ulong(&iter);
+       if (node != NULL) {
+               channel = caa_container_of(node, struct lttng_consumer_channel, node);
        }
-       return NULL;
+
+       rcu_read_unlock();
+
+       return channel;
 }
 
 static void consumer_steal_channel_key(int key)
@@ -116,6 +130,7 @@ static void consumer_steal_channel_key(int key)
 void consumer_del_stream(struct lttng_consumer_stream *stream)
 {
        int ret;
+       struct lttng_ht_iter iter;
        struct lttng_consumer_channel *free_chan = NULL;
 
        pthread_mutex_lock(&consumer_data.lock);
@@ -139,7 +154,17 @@ void consumer_del_stream(struct lttng_consumer_stream *stream)
                goto end;
        }
 
-       cds_list_del(&stream->list);
+       rcu_read_lock();
+
+       /* Get stream node from hash table */
+       lttng_ht_lookup(consumer_data.stream_ht,
+                       (void *)((unsigned long) stream->key), &iter);
+       /* Remove stream node from hash table */
+       ret = lttng_ht_del(consumer_data.stream_ht, &iter);
+       assert(!ret);
+
+       rcu_read_unlock();
+
        if (consumer_data.stream_count <= 0) {
                goto end;
        }
@@ -153,8 +178,7 @@ void consumer_del_stream(struct lttng_consumer_stream *stream)
        if (stream->wait_fd >= 0 && !stream->wait_fd_is_copy) {
                close(stream->wait_fd);
        }
-       if (stream->shm_fd >= 0 && stream->wait_fd != stream->shm_fd
-                       && !stream->shm_fd_is_copy) {
+       if (stream->shm_fd >= 0 && stream->wait_fd != stream->shm_fd) {
                close(stream->shm_fd);
        }
        if (!--stream->chan->refcount)
@@ -168,6 +192,16 @@ end:
                consumer_del_channel(free_chan);
 }
 
+static void consumer_del_stream_rcu(struct rcu_head *head)
+{
+       struct lttng_ht_node_ulong *node =
+               caa_container_of(head, struct lttng_ht_node_ulong, head);
+       struct lttng_consumer_stream *stream =
+               caa_container_of(node, struct lttng_consumer_stream, node);
+
+       consumer_del_stream(stream);
+}
+
 struct lttng_consumer_stream *consumer_allocate_stream(
                int channel_key, int stream_key,
                int shm_fd, int wait_fd,
@@ -205,6 +239,7 @@ struct lttng_consumer_stream *consumer_allocate_stream(
        stream->gid = gid;
        strncpy(stream->path_name, path_name, PATH_MAX - 1);
        stream->path_name[PATH_MAX - 1] = '\0';
+       lttng_ht_node_init_ulong(&stream->node, stream->key);
 
        switch (consumer_data.type) {
        case LTTNG_CONSUMER_KERNEL:
@@ -243,7 +278,9 @@ int consumer_add_stream(struct lttng_consumer_stream *stream)
        pthread_mutex_lock(&consumer_data.lock);
        /* Steal stream identifier, for UST */
        consumer_steal_stream_key(stream->key);
-       cds_list_add(&stream->list, &consumer_data.stream_list.head);
+       rcu_read_lock();
+       lttng_ht_add_unique_ulong(consumer_data.stream_ht, &stream->node);
+       rcu_read_unlock();
        consumer_data.stream_count++;
        consumer_data.need_update = 1;
 
@@ -290,6 +327,7 @@ void consumer_change_stream_state(int stream_key,
 void consumer_del_channel(struct lttng_consumer_channel *channel)
 {
        int ret;
+       struct lttng_ht_iter iter;
 
        pthread_mutex_lock(&consumer_data.lock);
 
@@ -306,7 +344,15 @@ void consumer_del_channel(struct lttng_consumer_channel *channel)
                goto end;
        }
 
-       cds_list_del(&channel->list);
+       rcu_read_lock();
+
+       lttng_ht_lookup(consumer_data.channel_ht,
+                       (void *)((unsigned long) channel->key), &iter);
+       ret = lttng_ht_del(consumer_data.channel_ht, &iter);
+       assert(!ret);
+
+       rcu_read_unlock();
+
        if (channel->mmap_base != NULL) {
                ret = munmap(channel->mmap_base, channel->mmap_len);
                if (ret != 0) {
@@ -316,8 +362,7 @@ void consumer_del_channel(struct lttng_consumer_channel *channel)
        if (channel->wait_fd >= 0 && !channel->wait_fd_is_copy) {
                close(channel->wait_fd);
        }
-       if (channel->shm_fd >= 0 && channel->wait_fd != channel->shm_fd
-                       && !channel->shm_fd_is_copy) {
+       if (channel->shm_fd >= 0 && channel->wait_fd != channel->shm_fd) {
                close(channel->shm_fd);
        }
        free(channel);
@@ -325,6 +370,16 @@ end:
        pthread_mutex_unlock(&consumer_data.lock);
 }
 
+static void consumer_del_channel_rcu(struct rcu_head *head)
+{
+       struct lttng_ht_node_ulong *node =
+               caa_container_of(head, struct lttng_ht_node_ulong, head);
+       struct lttng_consumer_channel *channel=
+               caa_container_of(node, struct lttng_consumer_channel, node);
+
+       consumer_del_channel(channel);
+}
+
 struct lttng_consumer_channel *consumer_allocate_channel(
                int channel_key,
                int shm_fd, int wait_fd,
@@ -346,6 +401,7 @@ struct lttng_consumer_channel *consumer_allocate_channel(
        channel->max_sb_size = max_sb_size;
        channel->refcount = 0;
        channel->nr_streams = 0;
+       lttng_ht_node_init_ulong(&channel->node, channel->key);
 
        switch (consumer_data.type) {
        case LTTNG_CONSUMER_KERNEL:
@@ -383,7 +439,9 @@ int consumer_add_channel(struct lttng_consumer_channel *channel)
        pthread_mutex_lock(&consumer_data.lock);
        /* Steal channel identifier, for UST */
        consumer_steal_channel_key(channel->key);
-       cds_list_add(&channel->list, &consumer_data.channel_list.head);
+       rcu_read_lock();
+       lttng_ht_add_unique_ulong(consumer_data.channel_ht, &channel->node);
+       rcu_read_unlock();
        pthread_mutex_unlock(&consumer_data.lock);
        return 0;
 }
@@ -399,18 +457,20 @@ int consumer_update_poll_array(
                struct lttng_consumer_local_data *ctx, struct pollfd **pollfd,
                struct lttng_consumer_stream **local_stream)
 {
-       struct lttng_consumer_stream *iter;
        int i = 0;
+       struct lttng_ht_iter iter;
+       struct lttng_consumer_stream *stream;
 
        DBG("Updating poll fd array");
-       cds_list_for_each_entry(iter, &consumer_data.stream_list.head, list) {
-               if (iter->state != LTTNG_CONSUMER_ACTIVE_STREAM) {
+       cds_lfht_for_each_entry(consumer_data.stream_ht->ht, &iter.iter, stream,
+                       node.node) {
+               if (stream->state != LTTNG_CONSUMER_ACTIVE_STREAM) {
                        continue;
                }
-               DBG("Active FD %d", iter->wait_fd);
-               (*pollfd)[i].fd = iter->wait_fd;
+               DBG("Active FD %d", stream->wait_fd);
+               (*pollfd)[i].fd = stream->wait_fd;
                (*pollfd)[i].events = POLLIN | POLLPRI;
-               local_stream[i] = iter;
+               local_stream[i] = stream;
                i++;
        }
 
@@ -486,22 +546,31 @@ int lttng_consumer_send_error(
  */
 void lttng_consumer_cleanup(void)
 {
-       struct lttng_consumer_stream *iter, *tmp;
-       struct lttng_consumer_channel *citer, *ctmp;
+       int ret;
+       struct lttng_ht_iter iter;
+       struct lttng_ht_node_ulong *node;
+
+       rcu_read_lock();
 
        /*
-        * close all outfd. Called when there are no more threads
-        * running (after joining on the threads), no need to protect
-        * list iteration with mutex.
+        * close all outfd. Called when there are no more threads running (after
+        * joining on the threads), no need to protect list iteration with mutex.
         */
-       cds_list_for_each_entry_safe(iter, tmp,
-                       &consumer_data.stream_list.head, list) {
-               consumer_del_stream(iter);
+       cds_lfht_for_each_entry(consumer_data.stream_ht->ht, &iter.iter, node,
+                       node) {
+               ret = lttng_ht_del(consumer_data.stream_ht, &iter);
+               assert(!ret);
+               call_rcu(&node->head, consumer_del_stream_rcu);
        }
-       cds_list_for_each_entry_safe(citer, ctmp,
-                       &consumer_data.channel_list.head, list) {
-               consumer_del_channel(citer);
+
+       cds_lfht_for_each_entry(consumer_data.channel_ht->ht, &iter.iter, node,
+                       node) {
+               ret = lttng_ht_del(consumer_data.channel_ht, &iter);
+               assert(!ret);
+               call_rcu(&node->head, consumer_del_channel_rcu);
        }
+
+       rcu_read_unlock();
 }
 
 /*
@@ -759,7 +828,7 @@ int lttng_consumer_recv_cmd(struct lttng_consumer_local_data *ctx,
 }
 
 /*
- * This thread polls the fds in the ltt_fd_list to consume the data and write
+ * This thread polls the fds in the set to consume the data and write
  * it to tracefile if necessary.
  */
 void *lttng_consumer_thread_poll_fds(void *data)
@@ -774,6 +843,8 @@ void *lttng_consumer_thread_poll_fds(void *data)
        int tmp2;
        struct lttng_consumer_local_data *ctx = data;
 
+       rcu_register_thread();
+
        local_stream = zmalloc(sizeof(struct lttng_consumer_stream));
 
        while (1) {
@@ -781,7 +852,7 @@ void *lttng_consumer_thread_poll_fds(void *data)
                num_hup = 0;
 
                /*
-                * the ltt_fd_list has been updated, we need to update our
+                * the fds set has been updated, we need to update our
                 * local array as well
                 */
                pthread_mutex_lock(&consumer_data.lock);
@@ -868,11 +939,15 @@ void *lttng_consumer_thread_poll_fds(void *data)
                                }
                        } else if (pollfd[i].revents & POLLERR) {
                                ERR("Error returned in polling fd %d.", pollfd[i].fd);
-                               consumer_del_stream(local_stream[i]);
+                               rcu_read_lock();
+                               consumer_del_stream_rcu(&local_stream[i]->node.head);
+                               rcu_read_unlock();
                                num_hup++;
                        } else if (pollfd[i].revents & POLLNVAL) {
                                ERR("Polling fd %d tells fd is not open.", pollfd[i].fd);
-                               consumer_del_stream(local_stream[i]);
+                               rcu_read_lock();
+                               consumer_del_stream_rcu(&local_stream[i]->node.head);
+                               rcu_read_unlock();
                                num_hup++;
                        } else if ((pollfd[i].revents & POLLHUP) &&
                                        !(pollfd[i].revents & POLLIN)) {
@@ -890,7 +965,9 @@ void *lttng_consumer_thread_poll_fds(void *data)
                                } else {
                                        DBG("Polling fd %d tells it has hung up.", pollfd[i].fd);
                                }
-                               consumer_del_stream(local_stream[i]);
+                               rcu_read_lock();
+                               consumer_del_stream_rcu(&local_stream[i]->node.head);
+                               rcu_read_unlock();
                                num_hup++;
                        }
                }
@@ -928,6 +1005,7 @@ end:
                free(local_stream);
                local_stream = NULL;
        }
+       rcu_unregister_thread();
        return NULL;
 }
 
@@ -945,6 +1023,8 @@ void *lttng_consumer_thread_receive_fds(void *data)
        struct pollfd consumer_sockpoll[2];
        struct lttng_consumer_local_data *ctx = data;
 
+       rcu_register_thread();
+
        DBG("Creating command socket %s", ctx->consumer_command_sock_path);
        unlink(ctx->consumer_command_sock_path);
        client_socket = lttcomm_create_unix_sock(ctx->consumer_command_sock_path);
@@ -1040,6 +1120,7 @@ end:
        if (ret < 0) {
                perror("poll pipe write");
        }
+       rcu_unregister_thread();
        return NULL;
 }
 
@@ -1073,3 +1154,13 @@ int lttng_consumer_on_recv_stream(struct lttng_consumer_stream *stream)
                return -ENOSYS;
        }
 }
+
+/*
+ * Allocate and set consumer data hash tables.
+ */
+void lttng_consumer_init(void)
+{
+       consumer_data.stream_ht = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
+       consumer_data.channel_ht = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
+}
+
index 608b3af10bdbd48180bc7f06fee98fa9e47553c4..74e5ed4feb169cf803d90e7debea78b6c507722f 100644 (file)
@@ -62,7 +62,8 @@ struct lttng_ht *lttng_ht_new(unsigned long size, int type)
        struct lttng_ht *ht;
 
        /* Test size */
-       size != 0 ? : (size = DEFAULT_HT_SIZE);
+       if (!size)
+               size = DEFAULT_HT_SIZE;
 
        ht = zmalloc(sizeof(*ht));
        if (ht == NULL) {
@@ -160,7 +161,6 @@ void lttng_ht_lookup(struct lttng_ht *ht, void *key,
 {
        assert(ht);
        assert(ht->ht);
-       assert(key);
 
        cds_lfht_lookup(ht->ht, ht->hash_fct(key, HASH_SEED),
                        ht->match_fct, key, &iter->iter);
index 26e680a9cd757d6bc5974dda20d6a30df3ccb9b2..8305b061a882fff9021037e1716ff32fb3f36935 100644 (file)
@@ -278,11 +278,8 @@ int lttng_ustconsumer_allocate_channel(struct lttng_consumer_channel *chan)
        if (!chan->handle) {
                return -ENOMEM;
        }
-       /*
-        * The channel fds are passed to ustctl, we only keep a copy.
-        */
-       chan->shm_fd_is_copy = 1;
        chan->wait_fd_is_copy = 1;
+       chan->shm_fd = -1;
 
        return 0;
 }
@@ -313,15 +310,14 @@ int lttng_ustconsumer_allocate_stream(struct lttng_consumer_stream *stream)
        stream->buf = ustctl_open_stream_read(stream->chan->handle, stream->cpu);
        if (!stream->buf)
                return -EBUSY;
+       /* ustctl_open_stream_read has closed the shm fd. */
+       stream->wait_fd_is_copy = 1;
+       stream->shm_fd = -1;
+
        stream->mmap_base = ustctl_get_mmap_base(stream->chan->handle, stream->buf);
        if (!stream->mmap_base) {
                return -EINVAL;
        }
-       /*
-        * The stream fds are passed to ustctl, we only keep a copy.
-        */
-       stream->shm_fd_is_copy = 1;
-       stream->wait_fd_is_copy = 1;
 
        return 0;
 }
index cf515a9df7cae5090f4f2537b1fda39342fcfffc..e8e511702d1fefb755239d890d61d3b35975c070 100644 (file)
@@ -267,6 +267,10 @@ int main(int argc, char **argv)
                        goto error;
                }
        }
+
+       /* Init */
+       lttng_consumer_init();
+
        /* create the consumer instance with and assign the callbacks */
        ctx = lttng_consumer_create(opt_type, lttng_consumer_read_subbuffer,
                NULL, lttng_consumer_on_recv_stream, NULL);
index 7ff974da05930c772b5734e1e7de3d4098766df8..0e8b1672086b7031b950ba92b4e32fd7ea28e39e 100644 (file)
@@ -216,7 +216,6 @@ int channel_ust_create(struct ltt_ust_session *usess, int domain,
                struct lttng_channel *attr)
 {
        int ret = LTTCOMM_OK;
-       struct lttng_ht *chan_ht;
        struct ltt_ust_channel *uchan = NULL;
        struct lttng_channel *defattr = NULL;
 
@@ -236,11 +235,11 @@ int channel_ust_create(struct ltt_ust_session *usess, int domain,
                ret = LTTCOMM_FATAL;
                goto error;
        }
+       uchan->enabled = 1;
 
        switch (domain) {
        case LTTNG_DOMAIN_UST:
                DBG2("Channel %s being created in UST global domain", uchan->name);
-               chan_ht = usess->domain_global.channels;
 
                /* Enable channel for global domain */
                ret = ust_app_create_channel_glb(usess, uchan);
@@ -258,14 +257,21 @@ int channel_ust_create(struct ltt_ust_session *usess, int domain,
                goto error_free_chan;
        }
 
-       uchan->enabled = 1;
-       lttng_ht_add_unique_str(chan_ht, &uchan->node);
+       /* Adding the channel to the channel hash table. */
+       rcu_read_lock();
+       lttng_ht_add_unique_str(usess->domain_global.channels, &uchan->node);
+       rcu_read_unlock();
+
        DBG2("Channel %s created successfully", uchan->name);
 
        free(defattr);
        return LTTCOMM_OK;
 
 error_free_chan:
+       /*
+        * No need to remove the channel from the hash table because at this point
+        * it was not added hence the direct call and no call_rcu().
+        */
        trace_ust_destroy_channel(uchan);
 error:
        free(defattr);
index 8582d2f8fc4907e59745feb07c93473ee08c7733..1068707438082e2758e80105599c050967d3e581 100644 (file)
@@ -359,7 +359,7 @@ error:
 int event_ust_enable_tracepoint(struct ltt_ust_session *usess, int domain,
                struct ltt_ust_channel *uchan, struct lttng_event *event)
 {
-       int ret, to_create = 0;
+       int ret = LTTCOMM_OK, to_create = 0;
        struct ltt_ust_event *uevent;
 
        uevent = trace_ust_find_event_by_name(uchan->events, event->name);
@@ -369,6 +369,7 @@ int event_ust_enable_tracepoint(struct ltt_ust_session *usess, int domain,
                        ret = LTTCOMM_FATAL;
                        goto error;
                }
+               /* Valid to set it after the goto error since uevent is still NULL */
                to_create = 1;
        }
 
@@ -377,6 +378,8 @@ int event_ust_enable_tracepoint(struct ltt_ust_session *usess, int domain,
                goto end;
        }
 
+       uevent->enabled = 1;
+
        switch (domain) {
        case LTTNG_DOMAIN_UST:
        {
@@ -407,10 +410,9 @@ int event_ust_enable_tracepoint(struct ltt_ust_session *usess, int domain,
                goto end;
        }
 
-       uevent->enabled = 1;
-       /* Add ltt ust event to channel */
        if (to_create) {
                rcu_read_lock();
+               /* Add ltt ust event to channel */
                lttng_ht_add_unique_str(uchan->events, &uevent->node);
                rcu_read_unlock();
        }
@@ -418,11 +420,23 @@ int event_ust_enable_tracepoint(struct ltt_ust_session *usess, int domain,
        DBG("Event UST %s %s in channel %s", uevent->attr.name,
                        to_create ? "created" : "enabled", uchan->name);
 
+       ret = LTTCOMM_OK;
+
 end:
-       return LTTCOMM_OK;
+       return ret;
 
 error:
-       trace_ust_destroy_event(uevent);
+       /*
+        * Only destroy event on creation time (not enabling time) because if the
+        * event is found in the channel (to_create == 0), it means that at some
+        * point the enable_event worked and it's thus valid to keep it alive.
+        * Destroying it also implies that we also destroy it's shadow copy to sync
+        * everyone up.
+        */
+       if (to_create) {
+               /* In this code path, the uevent was not added to the hash table */
+               trace_ust_destroy_event(uevent);
+       }
        return ret;
 }
 
index cac431307c0150316edec5ec199f307bfe5a880d..28a040763d81c4aabe1158ab3a8c6e3335f55f93 100644 (file)
@@ -42,20 +42,6 @@ struct lttng_ust_channel {
        unsigned int switch_timer_interval;     /* usecs */
        unsigned int read_timer_interval;       /* usecs */
        enum lttng_ust_output output;           /* output mode */
-       /* The following fields are used internally within UST. */
-       int shm_fd;
-       int wait_fd;
-       uint64_t memory_map_size;
-};
-
-/*
- * This structure is only used internally within UST. It is not per-se
- * part of the communication between sessiond and UST.
- */
-struct lttng_ust_stream {
-       int shm_fd;
-       int wait_fd;
-       uint64_t memory_map_size;
 };
 
 struct lttng_ust_event {
@@ -151,8 +137,22 @@ struct lttng_ust_object_data {
 
 struct lttng_ust_obj;
 
+union ust_args {
+       struct {
+               int *shm_fd;
+               int *wait_fd;
+               uint64_t *memory_map_size;
+       } channel;
+       struct {
+               int *shm_fd;
+               int *wait_fd;
+               uint64_t *memory_map_size;
+       } stream;
+};
+
 struct lttng_ust_objd_ops {
-       long (*cmd)(int objd, unsigned int cmd, unsigned long arg);
+       long (*cmd)(int objd, unsigned int cmd, unsigned long arg,
+               union ust_args *args);
        int (*release)(int objd);
 };
 
index 6d6af18e23c35acd599226efb279ab9a71895d5d..ff8141cfb93feb13e081b9191f46501de353d570 100644 (file)
@@ -176,14 +176,10 @@ static struct ltt_session_list *session_list_ptr;
 int ust_consumerd64_fd = -1;
 int ust_consumerd32_fd = -1;
 
-static const char *consumerd32_bin =
-       __stringify(CONFIG_CONSUMERD32_BIN);
-static const char *consumerd64_bin =
-       __stringify(CONFIG_CONSUMERD64_BIN);
-static const char *consumerd32_libdir =
-       __stringify(CONFIG_CONSUMERD32_LIBDIR);
-static const char *consumerd64_libdir =
-       __stringify(CONFIG_CONSUMERD64_LIBDIR);
+static const char *consumerd32_bin = CONFIG_CONSUMERD32_BIN;
+static const char *consumerd64_bin = CONFIG_CONSUMERD64_BIN;
+static const char *consumerd32_libdir = CONFIG_CONSUMERD32_LIBDIR;
+static const char *consumerd64_libdir = CONFIG_CONSUMERD64_LIBDIR;
 
 static
 void setup_consumerd_path(void)
@@ -1590,7 +1586,7 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data)
                /*
                 * Exec consumerd.
                 */
-               if (opt_verbose > 1 || opt_verbose_consumer) {
+               if (opt_verbose_consumer) {
                        verbosity = "--verbose";
                } else {
                        verbosity = "--quiet";
@@ -1603,13 +1599,21 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data)
                         * sessiond's installation directory, and
                         * fallback on the 32-bit one, 
                         */
+                       DBG3("Looking for a kernel consumer at these locations:");
+                       DBG3("  1) %s", consumerd64_bin);
+                       DBG3("  2) %s/%s", INSTALL_BIN_PATH, CONSUMERD_FILE);
+                       DBG3("  3) %s", consumerd32_bin);
                        if (stat(consumerd64_bin, &st) == 0) {
+                               DBG3("Found location #1");
                                consumer_to_use = consumerd64_bin;
                        } else if (stat(INSTALL_BIN_PATH "/" CONSUMERD_FILE, &st) == 0) {
+                               DBG3("Found location #2");
                                consumer_to_use = INSTALL_BIN_PATH "/" CONSUMERD_FILE;
                        } else if (stat(consumerd32_bin, &st) == 0) {
+                               DBG3("Found location #3");
                                consumer_to_use = consumerd32_bin;
                        } else {
+                               DBG("Could not find any valid consumerd executable");
                                break;
                        }
                        DBG("Using kernel consumer at: %s",  consumer_to_use);
@@ -2979,7 +2983,7 @@ static int cmd_stop_trace(struct ltt_session *session)
        usess = session->ust_session;
 
        if (!session->enabled) {
-               ret = LTTCOMM_UST_START_FAIL;
+               ret = LTTCOMM_UST_STOP_FAIL;
                goto error;
        }
 
@@ -3016,7 +3020,7 @@ static int cmd_stop_trace(struct ltt_session *session)
 
                ret = ust_app_stop_trace_all(usess);
                if (ret < 0) {
-                       ret = LTTCOMM_UST_START_FAIL;
+                       ret = LTTCOMM_UST_STOP_FAIL;
                        goto error;
                }
        }
index 0bfcc3bd811ddb3cc4babf55ada1d8fe2686db30..c85e79ce14fba897c280d1efaefa3d3602664cc0 100644 (file)
@@ -322,7 +322,7 @@ static void destroy_context_rcu(struct rcu_head *head)
 /*
  * Cleanup UST context hash table.
  */
-static void destroy_context(struct lttng_ht *ht)
+static void destroy_contexts(struct lttng_ht *ht)
 {
        int ret;
        struct lttng_ht_node_ulong *node;
@@ -344,7 +344,7 @@ static void destroy_context(struct lttng_ht *ht)
 void trace_ust_destroy_event(struct ltt_ust_event *event)
 {
        DBG2("Trace destroy UST event %s", event->attr.name);
-       destroy_context(event->ctx);
+       destroy_contexts(event->ctx);
 
        free(event);
 }
@@ -365,7 +365,7 @@ static void destroy_event_rcu(struct rcu_head *head)
 /*
  * Cleanup UST events hashtable.
  */
-static void destroy_event(struct lttng_ht *events)
+static void destroy_events(struct lttng_ht *events)
 {
        int ret;
        struct lttng_ht_node_str *node;
@@ -373,9 +373,8 @@ static void destroy_event(struct lttng_ht *events)
 
        cds_lfht_for_each_entry(events->ht, &iter.iter, node, node) {
                ret = lttng_ht_del(events, &iter);
-               if (!ret) {
-                       call_rcu(&node->head, destroy_event_rcu);
-               }
+               assert(!ret);
+               call_rcu(&node->head, destroy_event_rcu);
        }
 
        lttng_ht_destroy(events);
@@ -386,22 +385,15 @@ static void destroy_event(struct lttng_ht *events)
  */
 void trace_ust_destroy_channel(struct ltt_ust_channel *channel)
 {
-       int ret;
-       struct lttng_ht_node_str *node;
-       struct lttng_ht_iter iter;
-
        DBG2("Trace destroy UST channel %s", channel->name);
 
        rcu_read_lock();
 
-       cds_lfht_for_each_entry(channel->events->ht, &iter.iter, node, node) {
-               ret = lttng_ht_del(channel->events, &iter);
-               if (!ret) {
-                       destroy_event(channel->events);
-               }
-       }
+       /* Destroying all events of the channel */
+       destroy_events(channel->events);
+       /* Destroying all context of the channel */
+       destroy_contexts(channel->ctx);
 
-       destroy_context(channel->ctx);
        free(channel);
 
        rcu_read_unlock();
@@ -439,14 +431,17 @@ static void destroy_channels(struct lttng_ht *channels)
        struct lttng_ht_node_str *node;
        struct lttng_ht_iter iter;
 
+       rcu_read_lock();
+
        cds_lfht_for_each_entry(channels->ht, &iter.iter, node, node) {
                ret = lttng_ht_del(channels, &iter);
-               if (!ret) {
-                       call_rcu(&node->head, destroy_channel_rcu);
-               }
+               assert(!ret);
+               call_rcu(&node->head, destroy_channel_rcu);
        }
 
        lttng_ht_destroy(channels);
+
+       rcu_read_unlock();
 }
 
 /*
@@ -460,9 +455,8 @@ static void destroy_domain_pid(struct lttng_ht *ht)
 
        cds_lfht_for_each_entry(ht->ht, &iter.iter, dpid, node.node) {
                ret = lttng_ht_del(ht , &iter);
-               if (!ret) {
-                       destroy_channels(dpid->channels);
-               }
+               assert(!ret);
+               destroy_channels(dpid->channels);
        }
 
        lttng_ht_destroy(ht);
@@ -479,9 +473,8 @@ static void destroy_domain_exec(struct lttng_ht *ht)
 
        cds_lfht_for_each_entry(ht->ht, &iter.iter, dexec, node.node) {
                ret = lttng_ht_del(ht , &iter);
-               if (!ret) {
-                       destroy_channels(dexec->channels);
-               }
+               assert(!ret);
+               destroy_channels(dexec->channels);
        }
 
        lttng_ht_destroy(ht);
index d34134e94dbce9ab089c065b570cb01689e772e3..913d2de27acde8c3e276a488430def604f2a1842 100644 (file)
@@ -63,6 +63,7 @@ void delete_ust_app_event(int sock, struct ust_app_event *ua_event)
        struct lttng_ht_iter iter;
        struct ust_app_ctx *ua_ctx;
 
+       /* Destroy each context of event */
        cds_lfht_for_each_entry(ua_event->ctx->ht, &iter.iter, ua_ctx,
                        node.node) {
                ret = lttng_ht_del(ua_event->ctx, &iter);
@@ -542,8 +543,8 @@ static int open_ust_metadata(struct ust_app *app,
        ret = ustctl_open_metadata(app->key.sock, ua_sess->handle, &uattr,
                        &ua_sess->metadata->obj);
        if (ret < 0) {
-               ERR("UST app open metadata failed for app pid:%d",
-                               app->key.pid);
+               ERR("UST app open metadata failed for app pid:%d with ret %d",
+                               app->key.pid, ret);
                goto error;
        }
 
@@ -584,7 +585,7 @@ static int create_ust_channel(struct ust_app *app,
        ret = ustctl_create_channel(app->key.sock, ua_sess->handle,
                        (struct lttng_ust_channel_attr *)&ua_chan->attr, &ua_chan->obj);
        if (ret < 0) {
-               DBG("Error creating channel %s for app (pid: %d, sock: %d) "
+               ERR("Creating channel %s for app (pid: %d, sock: %d) "
                                "and session handle %d with ret %d",
                                ua_chan->name, app->key.pid, app->key.sock,
                                ua_sess->handle, ret);
@@ -592,9 +593,6 @@ static int create_ust_channel(struct ust_app *app,
        }
 
        ua_chan->handle = ua_chan->obj->handle;
-       ua_chan->attr.shm_fd = ua_chan->obj->shm_fd;
-       ua_chan->attr.wait_fd = ua_chan->obj->wait_fd;
-       ua_chan->attr.memory_map_size = ua_chan->obj->memory_map_size;
 
        DBG2("UST app channel %s created successfully for pid:%d and sock:%d",
                        ua_chan->name, app->key.pid, app->key.sock);
@@ -624,6 +622,10 @@ int create_ust_event(struct ust_app *app, struct ust_app_session *ua_sess,
        ret = ustctl_create_event(app->key.sock, &ua_event->attr, ua_chan->obj,
                        &ua_event->obj);
        if (ret < 0) {
+               if (ret == -EEXIST) {
+                       ret = 0;
+                       goto error;
+               }
                ERR("Error ustctl create event %s for app pid: %d with ret %d",
                                ua_event->attr.name, app->key.pid, ret);
                goto error;
@@ -635,9 +637,25 @@ int create_ust_event(struct ust_app *app, struct ust_app_session *ua_sess,
                        ua_event->attr.name, app->key.pid);
 
        /* If event not enabled, disable it on the tracer */
-       if (!ua_event->enabled) {
+       if (ua_event->enabled == 0) {
                ret = disable_ust_event(app, ua_sess, ua_event);
                if (ret < 0) {
+                       /*
+                        * If we hit an EPERM, something is wrong with our disable call. If
+                        * we get an EEXIST, there is a problem on the tracer side since we
+                        * just created it.
+                        */
+                       switch (ret) {
+                       case -EPERM:
+                               /* Code flow problem */
+                               assert(0);
+                       case -EEXIST:
+                               /* It's OK for our use case. */
+                               ret = 0;
+                               break;
+                       default:
+                               break;
+                       }
                        goto error;
                }
        }
@@ -659,14 +677,18 @@ static void shadow_copy_event(struct ust_app_event *ua_event,
        strncpy(ua_event->name, uevent->attr.name, sizeof(ua_event->name));
        ua_event->name[sizeof(ua_event->name) - 1] = '\0';
 
+       ua_event->enabled = uevent->enabled;
+
        /* Copy event attributes */
        memcpy(&ua_event->attr, &uevent->attr, sizeof(ua_event->attr));
 
        cds_lfht_for_each_entry(uevent->ctx->ht, &iter.iter, uctx, node.node) {
                ua_ctx = alloc_ust_app_ctx(&uctx->ctx);
                if (ua_ctx == NULL) {
-                       continue;
+                       /* malloc() failed. We should simply stop */
+                       return;
                }
+
                lttng_ht_node_init_ulong(&ua_ctx->node,
                                (unsigned long) ua_ctx->ctx.ctx);
                lttng_ht_add_unique_ulong(ua_event->ctx, &ua_ctx->node);
@@ -686,13 +708,15 @@ static void shadow_copy_channel(struct ust_app_channel *ua_chan,
        struct ust_app_event *ua_event;
        struct ust_app_ctx *ua_ctx;
 
-       DBG2("Shadow copy of UST app channel %s", ua_chan->name);
+       DBG2("UST app shadow copy of channel %s started", ua_chan->name);
 
        strncpy(ua_chan->name, uchan->name, sizeof(ua_chan->name));
        ua_chan->name[sizeof(ua_chan->name) - 1] = '\0';
        /* Copy event attributes */
        memcpy(&ua_chan->attr, &uchan->attr, sizeof(ua_chan->attr));
 
+       ua_chan->enabled = uchan->enabled;
+
        cds_lfht_for_each_entry(uchan->ctx->ht, &iter.iter, uctx, node.node) {
                ua_ctx = alloc_ust_app_ctx(&uctx->ctx);
                if (ua_ctx == NULL) {
@@ -721,7 +745,7 @@ static void shadow_copy_channel(struct ust_app_channel *ua_chan,
                }
        }
 
-       DBG3("Shadow copy channel done");
+       DBG3("UST app shadow copy of channel %s done", ua_chan->name);
 }
 
 /*
@@ -750,10 +774,8 @@ static void shadow_copy_session(struct ust_app_session *ua_sess,
        ua_sess->uid = usess->uid;
        ua_sess->gid = usess->gid;
 
-       ret = snprintf(ua_sess->path, PATH_MAX,
-                       "%s/%s-%d-%s",
-                       usess->pathname, app->name, app->key.pid,
-                       datetime);
+       ret = snprintf(ua_sess->path, PATH_MAX, "%s/%s-%d-%s", usess->pathname,
+                       app->name, app->key.pid, datetime);
        if (ret < 0) {
                PERROR("asprintf UST shadow copy session");
                /* TODO: We cannot return an error from here.. */
@@ -770,6 +792,7 @@ static void shadow_copy_session(struct ust_app_session *ua_sess,
                lttng_ht_lookup(ua_sess->channels, (void *)uchan->name, &uiter);
                ua_chan_node = lttng_ht_iter_get_node_str(&uiter);
                if (ua_chan_node != NULL) {
+                       /* Session exist. Contiuing. */
                        continue;
                }
 
@@ -777,7 +800,7 @@ static void shadow_copy_session(struct ust_app_session *ua_sess,
                                uchan->name);
                ua_chan = alloc_ust_app_channel(uchan->name, &uchan->attr);
                if (ua_chan == NULL) {
-                       /* malloc failed... continuing */
+                       /* malloc failed FIXME: Might want to do handle ENOMEM .. */
                        continue;
                }
 
@@ -794,7 +817,7 @@ void __lookup_session_by_app(struct ltt_ust_session *usess,
                        struct ust_app *app, struct lttng_ht_iter *iter)
 {
        /* Get right UST app session from app */
-       lttng_ht_lookup(app->sessions, (void *)((unsigned long) usess->uid), iter);
+       lttng_ht_lookup(app->sessions, (void *)((unsigned long) usess->id), iter);
 }
 
 /*
@@ -838,7 +861,7 @@ static struct ust_app_session *create_ust_app_session(
                ua_sess = alloc_ust_app_session();
                if (ua_sess == NULL) {
                        /* Only malloc can failed so something is really wrong */
-                       goto error;
+                       goto end;
                }
                shadow_copy_session(ua_sess, usess, app);
        }
@@ -846,25 +869,24 @@ static struct ust_app_session *create_ust_app_session(
        if (ua_sess->handle == -1) {
                ret = ustctl_create_session(app->key.sock);
                if (ret < 0) {
-                       ERR("Error creating session for app pid %d, sock %d",
-                                       app->key.pid, app->key.sock);
-                       /* TODO: free() ua_sess */
+                       ERR("Creating session for app pid %d", app->key.pid);
                        goto error;
                }
 
-               DBG2("UST app ustctl create session handle %d", ret);
                ua_sess->handle = ret;
 
                /* Add ust app session to app's HT */
-               lttng_ht_node_init_ulong(&ua_sess->node, (unsigned long) ua_sess->uid);
+               lttng_ht_node_init_ulong(&ua_sess->node, (unsigned long) ua_sess->id);
                lttng_ht_add_unique_ulong(app->sessions, &ua_sess->node);
 
                DBG2("UST app session created successfully with handle %d", ret);
        }
 
+end:
        return ua_sess;
 
 error:
+       delete_ust_app_session(-1, ua_sess);
        return NULL;
 }
 
@@ -1054,28 +1076,35 @@ static struct ust_app_channel *create_ust_app_channel(
        /* Lookup channel in the ust app session */
        lttng_ht_lookup(ua_sess->channels, (void *)uchan->name, &iter);
        ua_chan_node = lttng_ht_iter_get_node_str(&iter);
-       if (ua_chan_node == NULL) {
-               DBG2("Unable to find channel %s in ust session id %u",
-                               uchan->name, ua_sess->id);
-               ua_chan = alloc_ust_app_channel(uchan->name, &uchan->attr);
-               if (ua_chan == NULL) {
-                       goto error;
-               }
-               shadow_copy_channel(ua_chan, uchan);
-
-               lttng_ht_add_unique_str(ua_sess->channels, &ua_chan->node);
-       } else {
+       if (ua_chan_node != NULL) {
                ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
+               goto end;
        }
 
+       ua_chan = alloc_ust_app_channel(uchan->name, &uchan->attr);
+       if (ua_chan == NULL) {
+               /* Only malloc can fail here */
+               goto error;
+       }
+       shadow_copy_channel(ua_chan, uchan);
+
        ret = create_ust_channel(app, ua_sess, ua_chan);
        if (ret < 0) {
+               /* Not found previously means that it does not exist on the tracer */
+               assert(ret != -EEXIST);
                goto error;
        }
 
+       lttng_ht_add_unique_str(ua_sess->channels, &ua_chan->node);
+
+       DBG2("UST app create channel %s for PID %d completed", ua_chan->name,
+                       app->key.pid);
+
+end:
        return ua_chan;
 
 error:
+       delete_ust_app_channel(-1, ua_chan);
        return NULL;
 }
 
@@ -1096,8 +1125,7 @@ int create_ust_app_event(struct ust_app_session *ua_sess,
        lttng_ht_lookup(ua_chan->events, (void *)uevent->attr.name, &iter);
        ua_event_node = lttng_ht_iter_get_node_str(&iter);
        if (ua_event_node != NULL) {
-               ERR("UST app event %s already exist. Stopping creation.",
-                               uevent->attr.name);
+               ret = -EEXIST;
                goto end;
        }
 
@@ -1106,28 +1134,29 @@ int create_ust_app_event(struct ust_app_session *ua_sess,
        if (ua_event == NULL) {
                /* Only malloc can failed so something is really wrong */
                ret = -ENOMEM;
-               goto error;
+               goto end;
        }
        shadow_copy_event(ua_event, uevent);
 
        /* Create it on the tracer side */
        ret = create_ust_event(app, ua_sess, ua_chan, ua_event);
        if (ret < 0) {
-               rcu_read_lock();
-               delete_ust_app_event(app->key.sock, ua_event);
-               rcu_read_unlock();
+               /* Not found previously means that it does not exist on the tracer */
+               assert(ret != -EEXIST);
                goto error;
        }
 
-       ua_event->enabled = 1;
-
        lttng_ht_add_unique_str(ua_chan->events, &ua_event->node);
 
-       DBG2("UST app create event %s for PID %d completed",
-                       ua_event->name, app->key.pid);
+       DBG2("UST app create event %s for PID %d completed", ua_event->name,
+                       app->key.pid);
 
 end:
+       return ret;
+
 error:
+       /* Valid. Calling here is already in a read side lock */
+       delete_ust_app_event(-1, ua_event);
        return ret;
 }
 
@@ -1143,13 +1172,14 @@ static int create_ust_app_metadata(struct ust_app_session *ua_sess,
                /* Allocate UST metadata */
                ua_sess->metadata = trace_ust_create_metadata(pathname);
                if (ua_sess->metadata == NULL) {
-                       ERR("UST app session %d creating metadata failed",
-                                       ua_sess->handle);
+                       /* malloc() failed */
                        goto error;
                }
 
                ret = open_ust_metadata(app, ua_sess);
                if (ret < 0) {
+                       /* Cleanup failed metadata struct */
+                       free(ua_sess->metadata);
                        goto error;
                }
 
@@ -1299,6 +1329,11 @@ void ust_app_unregister(int sock)
 
        DBG("PID %d unregistering with sock %d", lta->key.pid, sock);
 
+       /* Remove application from socket hash table */
+       lttng_ht_lookup(ust_app_sock_key_map, (void *)((unsigned long) sock), &iter);
+       ret = lttng_ht_del(ust_app_sock_key_map, &iter);
+       assert(!ret);
+
        /* Get the node reference for a call_rcu */
        lttng_ht_lookup(ust_app_ht, (void *)((unsigned long) lta->key.pid), &iter);
        node = lttng_ht_iter_get_node_ulong(&iter);
@@ -1307,6 +1342,7 @@ void ust_app_unregister(int sock)
                goto error;
        }
 
+       /* Remove application from PID hash table */
        ret = lttng_ht_del(ust_app_ht, &iter);
        assert(!ret);
        call_rcu(&node->head, delete_ust_app_rcu);
@@ -1647,17 +1683,14 @@ int ust_app_disable_all_event_glb(struct ltt_ust_session *usess,
 int ust_app_create_channel_glb(struct ltt_ust_session *usess,
                struct ltt_ust_channel *uchan)
 {
-       int ret = 0;
        struct lttng_ht_iter iter;
        struct ust_app *app;
        struct ust_app_session *ua_sess;
        struct ust_app_channel *ua_chan;
 
-       if (usess == NULL || uchan == NULL) {
-               ERR("Adding UST global channel to NULL values");
-               ret = -1;
-               goto error;
-       }
+       /* Very wrong code flow */
+       assert(usess);
+       assert(uchan);
 
        DBG2("UST app adding channel %s to global domain for session id %d",
                        uchan->name, usess->id);
@@ -1673,20 +1706,24 @@ int ust_app_create_channel_glb(struct ltt_ust_session *usess,
                 */
                ua_sess = create_ust_app_session(usess, app);
                if (ua_sess == NULL) {
-                       continue;
+                       /* Major problem here and it's maybe the tracer or malloc() */
+                       goto error;
                }
 
                /* Create channel onto application */
                ua_chan = create_ust_app_channel(ua_sess, uchan, app);
                if (ua_chan == NULL) {
-                       continue;
+                       /* Major problem here and it's maybe the tracer or malloc() */
+                       goto error;
                }
        }
 
        rcu_read_unlock();
 
+       return 0;
+
 error:
-       return ret;
+       return -1;
 }
 
 /*
@@ -1765,12 +1802,6 @@ int ust_app_create_event_glb(struct ltt_ust_session *usess,
        DBG("UST app creating event %s for all apps for session id %d",
                        uevent->attr.name, usess->id);
 
-       /*
-        * NOTE: At this point, this function is called only if the session and
-        * channel passed are already created for all apps. and enabled on the
-        * tracer also.
-        */
-
        rcu_read_lock();
 
        /* For all registered applications */
@@ -1789,6 +1820,12 @@ int ust_app_create_event_glb(struct ltt_ust_session *usess,
 
                ret = create_ust_app_event(ua_sess, ua_chan, uevent, app);
                if (ret < 0) {
+                       if (ret != -EEXIST) {
+                               /* Possible value at this point: -ENOMEM. If so, we stop! */
+                               break;
+                       }
+                       DBG2("UST app event %s already exist on app PID %d",
+                                       uevent->attr.name, app->key.pid);
                        continue;
                }
        }
index 7bcd1a87eb224f2eb654766f2f2b09bd6ea57510..e20ec4e9e2b5af5ed88be9d64235aeeee26f2a81 100644 (file)
 #ifndef _LTT_UTILS_H
 #define _LTT_UTILS_H
 
-#ifndef __stringify
-#define __stringify1(x)        #x
-#define __stringify(x) __stringify1(x)
-#endif
-
 const char *get_home_dir(void);
 int notify_thread_pipe(int wpipe);
 
This page took 0.096751 seconds and 4 git commands to generate.