Fix: sessiond consumer thread should register as RCU thread
[lttng-tools.git] / src / bin / lttng-sessiond / consumer.c
index 166d6c0440202d9798a6bbad8b656fb35bb9432b..3c08041b0110f340aaec10daf7fdd1c9e44c9413 100644 (file)
@@ -472,6 +472,7 @@ struct consumer_output *consumer_create_output(enum consumer_dst_type type)
        output->enabled = 1;
        output->type = type;
        output->net_seq_index = (uint64_t) -1ULL;
+       urcu_ref_init(&output->ref);
 
        output->socks = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
 
@@ -506,11 +507,10 @@ void consumer_destroy_output_sockets(struct consumer_output *obj)
  *
  * Should *NOT* be called with RCU read-side lock held.
  */
-void consumer_destroy_output(struct consumer_output *obj)
+static void consumer_release_output(struct urcu_ref *ref)
 {
-       if (obj == NULL) {
-               return;
-       }
+       struct consumer_output *obj =
+               caa_container_of(ref, struct consumer_output, ref);
 
        consumer_destroy_output_sockets(obj);
 
@@ -522,6 +522,27 @@ void consumer_destroy_output(struct consumer_output *obj)
        free(obj);
 }
 
+/*
+ * Get the consumer_output object.
+ */
+void consumer_output_get(struct consumer_output *obj)
+{
+       urcu_ref_get(&obj->ref);
+}
+
+/*
+ * Put the consumer_output object.
+ *
+ * Should *NOT* be called with RCU read-side lock held.
+ */
+void consumer_output_put(struct consumer_output *obj)
+{
+       if (!obj) {
+               return;
+       }
+       urcu_ref_put(&obj->ref, consumer_release_output);
+}
+
 /*
  * Copy consumer output and returned the newly allocated copy.
  *
@@ -530,33 +551,28 @@ void consumer_destroy_output(struct consumer_output *obj)
 struct consumer_output *consumer_copy_output(struct consumer_output *obj)
 {
        int ret;
-       struct lttng_ht *tmp_ht_ptr;
        struct consumer_output *output;
 
        assert(obj);
 
        output = consumer_create_output(obj->type);
        if (output == NULL) {
-               goto error;
+               goto end;
        }
-       /* Avoid losing the HT reference after the memcpy() */
-       tmp_ht_ptr = output->socks;
-
-       memcpy(output, obj, sizeof(struct consumer_output));
-
-       /* Putting back the HT pointer and start copying socket(s). */
-       output->socks = tmp_ht_ptr;
-
+       output->enabled = obj->enabled;
+       output->net_seq_index = obj->net_seq_index;
+       memcpy(output->subdir, obj->subdir, PATH_MAX);
+       output->snapshot = obj->snapshot;
+       memcpy(&output->dst, &obj->dst, sizeof(output->dst));
        ret = consumer_copy_sockets(output, obj);
        if (ret < 0) {
-               goto malloc_error;
+               goto error_put;
        }
-
-error:
+end:
        return output;
 
-malloc_error:
-       consumer_destroy_output(output);
+error_put:
+       consumer_output_put(output);
        return NULL;
 }
 
@@ -1157,7 +1173,8 @@ end:
 }
 
 /*
- * Send a close metdata command to consumer using the given channel key.
+ * Send a close metadata command to consumer using the given channel key.
+ * Called with registry lock held.
  *
  * Return 0 on success else a negative value.
  */
@@ -1223,7 +1240,8 @@ end:
 }
 
 /*
- * Send metadata string to consumer. Socket lock MUST be acquired.
+ * Send metadata string to consumer.
+ * RCU read-side lock must be held to guarantee existence of socket.
  *
  * Return 0 on success else a negative value.
  */
@@ -1238,6 +1256,8 @@ int consumer_push_metadata(struct consumer_socket *socket,
 
        DBG2("Consumer push metadata to consumer socket %d", *socket->fd_ptr);
 
+       pthread_mutex_lock(socket->lock);
+
        memset(&msg, 0, sizeof(msg));
        msg.cmd_type = LTTNG_CONSUMER_PUSH_METADATA;
        msg.u.push_metadata.key = metadata_key;
@@ -1265,6 +1285,7 @@ int consumer_push_metadata(struct consumer_socket *socket,
        }
 
 end:
+       pthread_mutex_unlock(socket->lock);
        health_code_update();
        return ret;
 }
@@ -1321,7 +1342,7 @@ int consumer_snapshot_channel(struct consumer_socket *socket, uint64_t key,
                ret = run_as_mkdir_recursive(msg.u.snapshot_channel.pathname,
                                S_IRWXU | S_IRWXG, uid, gid);
                if (ret < 0) {
-                       if (ret != -EEXIST) {
+                       if (errno != EEXIST) {
                                ERR("Trace directory creation error");
                                goto error;
                        }
This page took 0.025344 seconds and 4 git commands to generate.