Fix: release reference to ltt_session on error instead of free()
[lttng-tools.git] / src / bin / lttng-sessiond / snapshot.c
index d2fc8ca691a15de1455dbb5cb3019f41cd756b09..c4c3bf1f8c13d9f0433a57d61461568304a83523 100644 (file)
@@ -15,7 +15,7 @@
  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#define _GNU_SOURCE
+#define _LGPL_SOURCE
 #include <assert.h>
 #include <inttypes.h>
 #include <string.h>
@@ -24,6 +24,7 @@
 #include <common/defaults.h>
 
 #include "snapshot.h"
+#include "utils.h"
 
 /*
  * Return the atomically incremented value of next_output_id.
@@ -45,8 +46,11 @@ static int output_init(uint64_t max_size, const char *name,
 {
        int ret = 0, i;
 
-       assert(output);
+       memset(output, 0, sizeof(struct snapshot_output));
 
+       /*
+        * max_size of -1ULL means unset. Set to default (unlimited).
+        */
        if (max_size == (uint64_t) -1ULL) {
                max_size = 0;
        }
@@ -58,7 +62,10 @@ static int output_init(uint64_t max_size, const char *name,
        lttng_ht_node_init_ulong(&output->node, (unsigned long) output->id);
 
        if (name && name[0] != '\0') {
-               strncpy(output->name, name, sizeof(output->name));
+               if (lttng_strncpy(output->name, name, sizeof(output->name))) {
+                       ret = -LTTNG_ERR_INVALID;
+                       goto error;
+               }
        } else {
                /* Set default name. */
                ret = snprintf(output->name, sizeof(output->name), "%s-%" PRIu32,
@@ -78,6 +85,7 @@ static int output_init(uint64_t max_size, const char *name,
                ret = -ENOMEM;
                goto error;
        }
+       output->consumer->snapshot = 1;
 
        /* No URL given. */
        if (nb_uri == 0) {
@@ -86,10 +94,14 @@ static int output_init(uint64_t max_size, const char *name,
        }
 
        if (uris[0].dtype == LTTNG_DST_PATH) {
-               memset(output->consumer->dst.trace_path, 0,
-                               sizeof(output->consumer->dst.trace_path));
-               strncpy(output->consumer->dst.trace_path, uris[0].dst.path,
-                               sizeof(output->consumer->dst.trace_path));
+               memset(output->consumer->dst.session_root_path, 0,
+                               sizeof(output->consumer->dst.session_root_path));
+               if (lttng_strncpy(output->consumer->dst.session_root_path,
+                               uris[0].dst.path,
+                               sizeof(output->consumer->dst.session_root_path))) {
+                       ret = -LTTNG_ERR_INVALID;
+                       goto error;
+               }
                output->consumer->type = CONSUMER_DST_LOCAL;
                ret = 0;
                goto end;
@@ -217,11 +229,37 @@ void snapshot_output_destroy(struct snapshot_output *obj)
 
        if (obj->consumer) {
                consumer_output_send_destroy_relayd(obj->consumer);
-               consumer_destroy_output(obj->consumer);
+               consumer_output_put(obj->consumer);
        }
        free(obj);
 }
 
+/*
+ * RCU read side lock MUST be acquired before calling this since the returned
+ * pointer is in a RCU hash table.
+ *
+ * Return the reference on success or else NULL.
+ */
+struct snapshot_output *snapshot_find_output_by_name(const char *name,
+               struct snapshot *snapshot)
+{
+       struct lttng_ht_iter iter;
+       struct snapshot_output *output = NULL;
+
+       assert(snapshot);
+       assert(name);
+
+       cds_lfht_for_each_entry(snapshot->output_ht->ht, &iter.iter, output,
+               node.node) {
+               if (!strncmp(output->name, name, strlen(name))) {
+                       return output;
+               }
+       }
+
+       /* Not found */
+       return NULL;
+}
+
 /*
  * RCU read side lock MUST be acquired before calling this since the returned
  * pointer is in a RCU hash table.
@@ -283,7 +321,9 @@ void snapshot_destroy(struct snapshot *obj)
        struct lttng_ht_iter iter;
        struct snapshot_output *output;
 
-       assert(obj);
+       if (!obj->output_ht) {
+               return;
+       }
 
        rcu_read_lock();
        cds_lfht_for_each_entry(obj->output_ht->ht, &iter.iter, output,
@@ -292,4 +332,5 @@ void snapshot_destroy(struct snapshot *obj)
                snapshot_output_destroy(output);
        }
        rcu_read_unlock();
+       ht_cleanup_push(obj->output_ht);
 }
This page took 0.025798 seconds and 5 git commands to generate.