Support snapshot max-size limitation
[lttng-tools.git] / src / bin / lttng-sessiond / cmd.c
index 60a4ef2fbd95a9a5d5af29e6b509902ca801a29f..c522d51c2dc27e46efa08ccb7f85085e16e4e4d3 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) {
@@ -2462,7 +2441,8 @@ error:
  * Return 0 on success or else a negative value.
  */
 static int record_kernel_snapshot(struct ltt_kernel_session *ksess,
-               struct snapshot_output *output, struct ltt_session *session, int wait)
+               struct snapshot_output *output, struct ltt_session *session,
+               int wait, int nb_streams)
 {
        int ret;
 
@@ -2478,24 +2458,32 @@ 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);
+       ret = kernel_snapshot_record(ksess, output, wait, nb_streams);
        if (ret < 0) {
-               goto error;
+               ret = -LTTNG_ERR_SNAPSHOT_FAIL;
+               if (ret == -EINVAL) {
+                       ret = -LTTNG_ERR_INVALID;
+               }
+               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;
 }
@@ -2506,7 +2494,8 @@ error:
  * Return 0 on success or else a negative value.
  */
 static int record_ust_snapshot(struct ltt_ust_session *usess,
-               struct snapshot_output *output, struct ltt_session *session, int wait)
+               struct snapshot_output *output, struct ltt_session *session,
+               int wait, int nb_streams)
 {
        int ret;
 
@@ -2522,28 +2511,59 @@ 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);
+       ret = ust_app_snapshot_record(usess, output, wait, nb_streams);
        if (ret < 0) {
-               goto error;
+               ret = -LTTNG_ERR_SNAPSHOT_FAIL;
+               if (ret == -EINVAL) {
+                       ret = -LTTNG_ERR_INVALID;
+               }
+               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;
 }
 
+/*
+ * Returns the total number of streams for a session or a negative value
+ * on error.
+ */
+static unsigned int get_total_nb_stream(struct ltt_session *session)
+{
+       unsigned int total_streams = 0;
+
+       if (session->kernel_session) {
+               struct ltt_kernel_session *ksess = session->kernel_session;
+
+               total_streams += ksess->stream_count_global;
+       }
+
+       if (session->ust_session) {
+               struct ltt_ust_session *usess = session->ust_session;
+
+               total_streams += ust_app_get_nb_stream(usess);
+       }
+
+       return total_streams;
+}
+
 /*
  * Command LTTNG_SNAPSHOT_RECORD from lib lttng ctl.
  *
@@ -2557,6 +2577,7 @@ int cmd_snapshot_record(struct ltt_session *session,
 {
        int ret = LTTNG_OK;
        struct snapshot_output *tmp_sout = NULL;
+       unsigned int nb_streams;
 
        assert(session);
 
@@ -2598,11 +2619,18 @@ int cmd_snapshot_record(struct ltt_session *session,
                }
        }
 
+       /*
+        * Get the total number of stream of that session which is used by the
+        * maximum size of the snapshot feature.
+        */
+       nb_streams = get_total_nb_stream(session);
+
        if (session->kernel_session) {
                struct ltt_kernel_session *ksess = session->kernel_session;
 
                if (tmp_sout) {
-                       ret = record_kernel_snapshot(ksess, tmp_sout, session, wait);
+                       ret = record_kernel_snapshot(ksess, tmp_sout, session,
+                                       wait, nb_streams);
                        if (ret < 0) {
                                goto error;
                        }
@@ -2613,7 +2641,8 @@ int cmd_snapshot_record(struct ltt_session *session,
                        rcu_read_lock();
                        cds_lfht_for_each_entry(session->snapshot.output_ht->ht,
                                        &iter.iter, sout, node.node) {
-                               ret = record_kernel_snapshot(ksess, sout, session, wait);
+                               ret = record_kernel_snapshot(ksess, sout,
+                                               session, wait, nb_streams);
                                if (ret < 0) {
                                        rcu_read_unlock();
                                        goto error;
@@ -2627,7 +2656,8 @@ int cmd_snapshot_record(struct ltt_session *session,
                struct ltt_ust_session *usess = session->ust_session;
 
                if (tmp_sout) {
-                       ret = record_ust_snapshot(usess, tmp_sout, session, wait);
+                       ret = record_ust_snapshot(usess, tmp_sout, session,
+                                       wait, nb_streams);
                        if (ret < 0) {
                                goto error;
                        }
@@ -2638,7 +2668,8 @@ int cmd_snapshot_record(struct ltt_session *session,
                        rcu_read_lock();
                        cds_lfht_for_each_entry(session->snapshot.output_ht->ht,
                                        &iter.iter, sout, node.node) {
-                               ret = record_ust_snapshot(usess, sout, session, wait);
+                               ret = record_ust_snapshot(usess, sout, session,
+                                               wait, nb_streams);
                                if (ret < 0) {
                                        rcu_read_unlock();
                                        goto error;
This page took 0.025875 seconds and 4 git commands to generate.