Fix: correctly close metadata on sessiond thread shutdown
[lttng-tools.git] / src / common / ust-consumer / ust-consumer.c
index 336466a470bd453da46248ecb4e699341e942f94..6a692b9ba5a8bffd7826bd164dfc3f1de9f8c9df 100644 (file)
@@ -605,6 +605,45 @@ error:
        rcu_read_unlock();
        return ret;
 }
+/*
+ * Close metadata stream wakeup_fd using the given key to retrieve the channel.
+ * RCU read side lock MUST be acquired before calling this function.
+ *
+ * NOTE: This function does NOT take any channel nor stream lock.
+ *
+ * Return 0 on success else LTTng error code.
+ */
+static int _close_metadata(struct lttng_consumer_channel *channel)
+{
+       int ret = LTTNG_OK;
+
+       assert(channel);
+       assert(channel->type == CONSUMER_CHANNEL_TYPE_METADATA);
+
+       if (channel->switch_timer_enabled == 1) {
+               DBG("Deleting timer on metadata channel");
+               consumer_timer_switch_stop(channel);
+       }
+
+       if (channel->metadata_stream) {
+               ret = ustctl_stream_close_wakeup_fd(channel->metadata_stream->ustream);
+               if (ret < 0) {
+                       ERR("UST consumer unable to close fd of metadata (ret: %d)", ret);
+                       ret = LTTCOMM_CONSUMERD_ERROR_METADATA;
+               }
+
+               if (channel->monitor) {
+                       /* Close the read-side in consumer_del_metadata_stream */
+                       ret = close(channel->metadata_stream->ust_metadata_poll_pipe[1]);
+                       if (ret < 0) {
+                               PERROR("Close UST metadata write-side poll pipe");
+                               ret = LTTCOMM_CONSUMERD_ERROR_METADATA;
+                       }
+               }
+       }
+
+       return ret;
+}
 
 /*
  * Close metadata stream wakeup_fd using the given key to retrieve the channel.
@@ -639,26 +678,7 @@ static int close_metadata(uint64_t chan_key)
                goto error_unlock;
        }
 
-       if (channel->switch_timer_enabled == 1) {
-               DBG("Deleting timer on metadata channel");
-               consumer_timer_switch_stop(channel);
-       }
-
-       if (channel->metadata_stream) {
-               ret = ustctl_stream_close_wakeup_fd(channel->metadata_stream->ustream);
-               if (ret < 0) {
-                       ERR("UST consumer unable to close fd of metadata (ret: %d)", ret);
-                       ret = LTTCOMM_CONSUMERD_ERROR_METADATA;
-                       goto error_unlock;
-               }
-               if (channel->monitor) {
-                       /* close the read-side in consumer_del_metadata_stream */
-                       ret = close(channel->metadata_stream->ust_metadata_poll_pipe[1]);
-                       if (ret < 0) {
-                               PERROR("Close UST metadata write-side poll pipe");
-                       }
-               }
-       }
+       ret = _close_metadata(channel);
 
 error_unlock:
        pthread_mutex_unlock(&channel->lock);
@@ -767,7 +787,8 @@ static int snapshot_metadata(uint64_t key, char *path, uint64_t relayd_id,
 
        metadata_channel = consumer_find_channel(key);
        if (!metadata_channel) {
-               ERR("UST snapshot metadata channel not found for key %lu", key);
+               ERR("UST snapshot metadata channel not found for key %" PRIu64,
+                       key);
                ret = -1;
                goto error;
        }
@@ -863,12 +884,12 @@ static int snapshot_channel(uint64_t key, char *path, uint64_t relayd_id,
 
        channel = consumer_find_channel(key);
        if (!channel) {
-               ERR("UST snapshot channel not found for key %lu", key);
+               ERR("UST snapshot channel not found for key %" PRIu64, key);
                ret = -1;
                goto error;
        }
        assert(!channel->monitor);
-       DBG("UST consumer snapshot channel %lu", key);
+       DBG("UST consumer snapshot channel %" PRIu64, key);
 
        cds_list_for_each_entry(stream, &channel->streams.head, send_node) {
                /* Lock stream because we are about to change its state. */
@@ -957,12 +978,12 @@ static int snapshot_channel(uint64_t key, char *path, uint64_t relayd_id,
                                        padded_len - len);
                        if (use_relayd) {
                                if (read_len != len) {
-                                       ret = -1;
+                                       ret = -EPERM;
                                        goto error_put_subbuf;
                                }
                        } else {
                                if (read_len != padded_len) {
-                                       ret = -1;
+                                       ret = -EPERM;
                                        goto error_put_subbuf;
                                }
                        }
@@ -1177,6 +1198,13 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                        goto end_channel_error;
                }
 
+               /*
+                * Assign UST application UID to the channel. This value is ignored for
+                * per PID buffers. This is specific to UST thus setting this after the
+                * allocation.
+                */
+               channel->ust_app_uid = msg.u.ask_channel.ust_app_uid;
+
                /* Build channel attributes from received message. */
                attr.subbuf_size = msg.u.ask_channel.subbuf_size;
                attr.num_subbuf = msg.u.ask_channel.num_subbuf;
@@ -1738,6 +1766,12 @@ int lttng_ustconsumer_data_pending(struct lttng_consumer_stream *stream)
        }
 
        if (stream->chan->type == CONSUMER_CHANNEL_TYPE_METADATA) {
+               uint64_t contiguous, pushed;
+
+               /* Ease our life a bit. */
+               contiguous = stream->chan->metadata_cache->contiguous;
+               pushed = stream->ust_metadata_pushed;
+
                /*
                 * We can simply check whether all contiguously available data
                 * has been pushed to the ring buffer, since the push operation
@@ -1749,10 +1783,10 @@ int lttng_ustconsumer_data_pending(struct lttng_consumer_stream *stream)
                 * metadata has been consumed from the metadata stream.
                 */
                DBG("UST consumer metadata pending check: contiguous %" PRIu64 " vs pushed %" PRIu64,
-                       stream->chan->metadata_cache->contiguous,
-                       stream->ust_metadata_pushed);
-               if (stream->chan->metadata_cache->contiguous
-                               != stream->ust_metadata_pushed) {
+                               contiguous, pushed);
+               assert(((int64_t) contiguous - pushed) >= 0);
+               if ((contiguous != pushed) ||
+                               (((int64_t) contiguous - pushed) > 0 || contiguous == 0)) {
                        ret = 1;        /* Data is pending */
                        goto end;
                }
@@ -1788,7 +1822,6 @@ end:
  */
 void lttng_ustconsumer_close_metadata(struct lttng_ht *metadata_ht)
 {
-       int ret;
        struct lttng_ht_iter iter;
        struct lttng_consumer_stream *stream;
 
@@ -1800,17 +1833,16 @@ void lttng_ustconsumer_close_metadata(struct lttng_ht *metadata_ht)
        rcu_read_lock();
        cds_lfht_for_each_entry(metadata_ht->ht, &iter.iter, stream,
                        node.node) {
-               int fd = stream->wait_fd;
-
+               pthread_mutex_lock(&stream->chan->lock);
                /*
-                * Whatever happens here we have to continue to try to close every
-                * streams. Let's report at least the error on failure.
+                * Whatever returned value, we must continue to try to close everything
+                * so ignore it.
                 */
-               ret = ustctl_stream_close_wakeup_fd(stream->ustream);
-               if (ret) {
-                       ERR("Unable to close metadata stream fd %d ret %d", fd, ret);
-               }
-               DBG("Metadata wait fd %d closed", fd);
+               (void) _close_metadata(stream->chan);
+               DBG("Metadata wait fd %d and poll pipe fd %d closed", stream->wait_fd,
+                               stream->ust_metadata_poll_pipe[1]);
+               pthread_mutex_unlock(&stream->chan->lock);
+
        }
        rcu_read_unlock();
 }
@@ -1858,12 +1890,18 @@ int lttng_ustconsumer_request_metadata(struct lttng_consumer_local_data *ctx,
 
        request.session_id = channel->session_id;
        request.session_id_per_pid = channel->session_id_per_pid;
-       request.uid = channel->uid;
+       /*
+        * Request the application UID here so the metadata of that application can
+        * be sent back. The channel UID corresponds to the user UID of the session
+        * used for the rights on the stream file(s).
+        */
+       request.uid = channel->ust_app_uid;
        request.key = channel->key;
+
        DBG("Sending metadata request to sessiond, session id %" PRIu64
-                       ", per-pid %" PRIu64,
-                       channel->session_id,
-                       channel->session_id_per_pid);
+                       ", per-pid %" PRIu64 ", app UID %u and channek key %" PRIu64,
+                       request.session_id, request.session_id_per_pid, request.uid,
+                       request.key);
 
        pthread_mutex_lock(&ctx->metadata_socket_lock);
        ret = lttcomm_send_unix_sock(ctx->consumer_metadata_socket, &request,
This page took 0.02652 seconds and 4 git commands to generate.