Fix: snapshot support for UST and kernel in same session
authorDavid Goulet <dgoulet@efficios.com>
Tue, 9 Jul 2013 14:50:25 +0000 (10:50 -0400)
committerDavid Goulet <dgoulet@efficios.com>
Fri, 12 Jul 2013 15:07:08 +0000 (11:07 -0400)
Signed-off-by: David Goulet <dgoulet@efficios.com>
src/bin/lttng-sessiond/cmd.c
src/bin/lttng-sessiond/consumer.c
src/bin/lttng-sessiond/consumer.h
src/bin/lttng-sessiond/ust-app.c

index 60a4ef2fbd95a9a5d5af29e6b509902ca801a29f..903dfd36defb5f8591aa7532f7b0a202d8be863d 100644 (file)
@@ -2254,27 +2254,6 @@ int cmd_snapshot_add_output(struct ltt_session *session,
                goto free_error;
        }
 
-       /*
-        * Copy sockets so the snapshot output can use them on destroy.
-        */
-
-       if (session->ust_session) {
-               ret = consumer_copy_sockets(new_output->consumer,
-                               session->ust_session->consumer);
-               if (ret < 0) {
-                       goto free_error;
-               }
-               new_output->ust_sockets_copied = 1;
-       }
-       if (session->kernel_session) {
-               ret = consumer_copy_sockets(new_output->consumer,
-                               session->kernel_session->consumer);
-               if (ret < 0) {
-                       goto free_error;
-               }
-               new_output->kernel_sockets_copied = 1;
-       }
-
        rcu_read_lock();
        snapshot_add_output(&session->snapshot, new_output);
        if (id) {
@@ -2478,24 +2457,28 @@ static int record_kernel_snapshot(struct ltt_kernel_session *ksess,
                goto error;
        }
 
-       if (!output->kernel_sockets_copied) {
-               ret = consumer_copy_sockets(output->consumer, ksess->consumer);
-               if (ret < 0) {
-                       goto error;
-               }
-               output->kernel_sockets_copied = 1;
+       /*
+        * Copy kernel session sockets so we can communicate with the right
+        * consumer for the snapshot record command.
+        */
+       ret = consumer_copy_sockets(output->consumer, ksess->consumer);
+       if (ret < 0) {
+               goto error;
        }
 
        ret = set_relayd_for_snapshot(ksess->consumer, output, session);
        if (ret < 0) {
-               goto error;
+               goto error_snapshot;
        }
 
        ret = kernel_snapshot_record(ksess, output, wait);
        if (ret < 0) {
-               goto error;
+               goto error_snapshot;
        }
 
+error_snapshot:
+       /* Clean up copied sockets so this output can use some other later on. */
+       consumer_destroy_output_sockets(output->consumer);
 error:
        return ret;
 }
@@ -2522,24 +2505,28 @@ static int record_ust_snapshot(struct ltt_ust_session *usess,
                goto error;
        }
 
-       if (!output->ust_sockets_copied) {
-               ret = consumer_copy_sockets(output->consumer, usess->consumer);
-               if (ret < 0) {
-                       goto error;
-               }
-               output->ust_sockets_copied = 1;
+       /*
+        * Copy kernel session sockets so we can communicate with the right
+        * consumer for the snapshot record command.
+        */
+       ret = consumer_copy_sockets(output->consumer, usess->consumer);
+       if (ret < 0) {
+               goto error;
        }
 
        ret = set_relayd_for_snapshot(usess->consumer, output, session);
        if (ret < 0) {
-               goto error;
+               goto error_snapshot;
        }
 
        ret = ust_app_snapshot_record(usess, output, wait);
        if (ret < 0) {
-               goto error;
+               goto error_snapshot;
        }
 
+error_snapshot:
+       /* Clean up copied sockets so this output can use some other later on. */
+       consumer_destroy_output_sockets(output->consumer);
 error:
        return ret;
 }
index d3c561c9ec6932531fc3c46a1a464835dc45e12f..b1ccbc1082c7728e306bdccfa680652063bc358a 100644 (file)
@@ -408,6 +408,28 @@ error:
        return output;
 }
 
+/*
+ * Iterate over the consumer output socket hash table and destroy them. The
+ * socket file descriptor are only closed if the consumer output was
+ * registered meaning it's an external consumer.
+ */
+void consumer_destroy_output_sockets(struct consumer_output *obj)
+{
+       struct lttng_ht_iter iter;
+       struct consumer_socket *socket;
+
+       if (!obj->socks) {
+               return;
+       }
+
+       rcu_read_lock();
+       cds_lfht_for_each_entry(obj->socks->ht, &iter.iter, socket, node.node) {
+               consumer_del_socket(socket, obj);
+               consumer_destroy_socket(socket);
+       }
+       rcu_read_unlock();
+}
+
 /*
  * Delete the consumer_output object from the list and free the ptr.
  *
@@ -419,17 +441,9 @@ void consumer_destroy_output(struct consumer_output *obj)
                return;
        }
 
-       if (obj->socks) {
-               struct lttng_ht_iter iter;
-               struct consumer_socket *socket;
-
-               rcu_read_lock();
-               cds_lfht_for_each_entry(obj->socks->ht, &iter.iter, socket, node.node) {
-                       consumer_del_socket(socket, obj);
-                       consumer_destroy_socket(socket);
-               }
-               rcu_read_unlock();
+       consumer_destroy_output_sockets(obj);
 
+       if (obj->socks) {
                /* Finally destroy HT */
                ht_cleanup_push(obj->socks);
        }
index c3c8dfb7f1a15386c45dbd236bd34e2811df87f1..c219420cacb34c08acca28e560020d9f918f3902 100644 (file)
@@ -165,6 +165,7 @@ void consumer_del_socket(struct consumer_socket *sock,
 void consumer_destroy_socket(struct consumer_socket *sock);
 int consumer_copy_sockets(struct consumer_output *dst,
                struct consumer_output *src);
+void consumer_destroy_output_sockets(struct consumer_output *obj);
 
 struct consumer_output *consumer_create_output(enum consumer_dst_type type);
 struct consumer_output *consumer_copy_output(struct consumer_output *obj);
index c329650c9b4de709f3e810229d4d19b7ab23a905..60b55d25a56e9832a261941ecf34007d6bd752d7 100644 (file)
@@ -4876,6 +4876,7 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess,
        int ret = 0;
        struct lttng_ht_iter iter;
        struct ust_app *app;
+       char pathname[PATH_MAX];
 
        assert(usess);
        assert(output);
@@ -4903,10 +4904,19 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess,
                        goto error;
                }
 
+               /* Add the UST default trace dir to path. */
+               memset(pathname, 0, sizeof(pathname));
+               ret = snprintf(pathname, sizeof(pathname), DEFAULT_UST_TRACE_DIR "/%s",
+                               ua_sess->path);
+               if (ret < 0) {
+                       PERROR("snprintf snapshot path");
+                       goto error;
+               }
+
                cds_lfht_for_each_entry(ua_sess->channels->ht, &chan_iter.iter,
                                ua_chan, node.node) {
                        ret = consumer_snapshot_channel(socket, ua_chan->key, output, 0,
-                                       ua_sess->euid, ua_sess->egid, ua_sess->path, wait);
+                                       ua_sess->euid, ua_sess->egid, pathname, wait);
                        if (ret < 0) {
                                goto error;
                        }
@@ -4915,7 +4925,7 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess,
                registry = get_session_registry(ua_sess);
                assert(registry);
                ret = consumer_snapshot_channel(socket, registry->metadata_key, output,
-                               1, ua_sess->euid, ua_sess->egid, ua_sess->path, wait);
+                               1, ua_sess->euid, ua_sess->egid, pathname, wait);
                if (ret < 0) {
                        goto error;
                }
This page took 0.034858 seconds and 5 git commands to generate.