Introduce "--blocking-timeout" channel parameter
[lttng-tools.git] / src / bin / lttng-sessiond / ust-app.c
index d292779d156dca47d2ce1d861ac35d216811d731..eb0f837160edf5b533bbc822ef0e8ddd768962f4 100644 (file)
@@ -92,6 +92,7 @@ static void copy_channel_attr_to_ustctl(
        attr->switch_timer_interval = uattr->switch_timer_interval;
        attr->read_timer_interval = uattr->read_timer_interval;
        attr->output = uattr->output;
+       attr->blocking_timeout = uattr->u.s.blocking_timeout;
 }
 
 /*
@@ -813,6 +814,7 @@ void delete_ust_app_session(int sock, struct ust_app_session *ua_sess,
        ua_sess->deleted = true;
 
        registry = get_session_registry(ua_sess);
+       /* Registry can be null on error path during initialization. */
        if (registry) {
                /* Push metadata for application before freeing the application. */
                (void) push_metadata(registry, ua_sess->consumer);
@@ -840,6 +842,10 @@ void delete_ust_app_session(int sock, struct ust_app_session *ua_sess,
        if (ua_sess->buffer_type == LTTNG_BUFFER_PER_PID) {
                struct buffer_reg_pid *reg_pid = buffer_reg_pid_find(ua_sess->id);
                if (reg_pid) {
+                       /*
+                        * Registry can be null on error path during
+                        * initialization.
+                        */
                        buffer_reg_pid_remove(reg_pid);
                        buffer_reg_pid_destroy(reg_pid);
                }
@@ -1035,6 +1041,7 @@ struct ust_app_channel *alloc_ust_app_channel(char *name,
                ua_chan->attr.switch_timer_interval = attr->switch_timer_interval;
                ua_chan->attr.read_timer_interval = attr->read_timer_interval;
                ua_chan->attr.output = attr->output;
+               ua_chan->attr.blocking_timeout = attr->u.s.blocking_timeout;
        }
        /* By default, the channel is a per cpu channel. */
        ua_chan->attr.type = LTTNG_UST_CHAN_PER_CPU;
@@ -1798,6 +1805,8 @@ static void shadow_copy_channel(struct ust_app_channel *ua_chan,
        ua_chan->attr.read_timer_interval = uchan->attr.read_timer_interval;
        ua_chan->monitor_timer_interval = uchan->monitor_timer_interval;
        ua_chan->attr.output = uchan->attr.output;
+       ua_chan->attr.blocking_timeout = uchan->attr.u.s.blocking_timeout;
+
        /*
         * Note that the attribute channel type is not set since the channel on the
         * tracing registry side does not have this information.
@@ -2468,6 +2477,8 @@ error:
 /*
  * Ask the consumer to create a channel and get it if successful.
  *
+ * Called with UST app session lock held.
+ *
  * Return 0 on success or else a negative value.
  */
 static int do_consumer_create_channel(struct ltt_ust_session *usess,
@@ -2957,6 +2968,8 @@ error:
 /*
  * Create and send to the application the created buffers with per PID buffers.
  *
+ * Called with UST app session lock held.
+ *
  * Return 0 on success else a negative value.
  */
 static int create_channel_per_pid(struct ust_app *app,
@@ -2980,6 +2993,7 @@ static int create_channel_per_pid(struct ust_app *app,
        rcu_read_lock();
 
        registry = get_session_registry(ua_sess);
+       /* The UST app session lock is held, registry shall not be null. */
        assert(registry);
 
        /* Create and add a new channel registry to session. */
@@ -3040,6 +3054,8 @@ error:
  * need and send it to the application. This MUST be called with a RCU read
  * side lock acquired.
  *
+ * Called with UST app session lock held.
+ *
  * Return 0 on success or else a negative value. Returns -ENOTCONN if
  * the application exited concurrently.
  */
@@ -3226,6 +3242,7 @@ static int create_ust_app_metadata(struct ust_app_session *ua_sess,
        assert(consumer);
 
        registry = get_session_registry(ua_sess);
+       /* The UST app session is held registry shall not be null. */
        assert(registry);
 
        pthread_mutex_lock(&registry->lock);
@@ -4362,6 +4379,9 @@ int ust_app_create_event_glb(struct ltt_ust_session *usess,
 
 /*
  * Start tracing for a specific UST session and app.
+ *
+ * Called with UST app session lock held.
+ *
  */
 static
 int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app)
@@ -4545,6 +4565,8 @@ int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app)
        health_code_update();
 
        registry = get_session_registry(ua_sess);
+
+       /* The UST app session is held registry shall not be null. */
        assert(registry);
 
        /* Push metadata for application before freeing the application. */
@@ -5386,19 +5408,17 @@ static int reply_ust_register_channel(int sock, int sobjd, int cobjd,
        /* Lookup application. If not found, there is a code flow error. */
        app = find_app_by_notify_sock(sock);
        if (!app) {
-               DBG("Application socket %d is being teardown. Abort event notify",
+               DBG("Application socket %d is being torn down. Abort event notify",
                                sock);
                ret = 0;
-               free(fields);
                goto error_rcu_unlock;
        }
 
        /* Lookup channel by UST object descriptor. */
        ua_chan = find_channel_by_objd(app, cobjd);
        if (!ua_chan) {
-               DBG("Application channel is being teardown. Abort event notify");
+               DBG("Application channel is being torn down. Abort event notify");
                ret = 0;
-               free(fields);
                goto error_rcu_unlock;
        }
 
@@ -5407,7 +5427,11 @@ static int reply_ust_register_channel(int sock, int sobjd, int cobjd,
 
        /* Get right session registry depending on the session buffer type. */
        registry = get_session_registry(ua_sess);
-       assert(registry);
+       if (!registry) {
+               DBG("Application session is being torn down. Abort event notify");
+               ret = 0;
+               goto error_rcu_unlock;
+       };
 
        /* Depending on the buffer type, a different channel key is used. */
        if (ua_sess->buffer_type == LTTNG_BUFFER_PER_UID) {
@@ -5431,13 +5455,11 @@ static int reply_ust_register_channel(int sock, int sobjd, int cobjd,
 
                chan_reg->nr_ctx_fields = nr_fields;
                chan_reg->ctx_fields = fields;
+               fields = NULL;
                chan_reg->header_type = type;
        } else {
                /* Get current already assigned values. */
                type = chan_reg->header_type;
-               free(fields);
-               /* Set to NULL so the error path does not do a double free. */
-               fields = NULL;
        }
        /* Channel id is set during the object creation. */
        chan_id = chan_reg->chan_id;
@@ -5473,9 +5495,7 @@ error:
        pthread_mutex_unlock(&registry->lock);
 error_rcu_unlock:
        rcu_read_unlock();
-       if (ret) {
-               free(fields);
-       }
+       free(fields);
        return ret;
 }
 
@@ -5505,23 +5525,17 @@ static int add_event_ust_registry(int sock, int sobjd, int cobjd, char *name,
        /* Lookup application. If not found, there is a code flow error. */
        app = find_app_by_notify_sock(sock);
        if (!app) {
-               DBG("Application socket %d is being teardown. Abort event notify",
+               DBG("Application socket %d is being torn down. Abort event notify",
                                sock);
                ret = 0;
-               free(sig);
-               free(fields);
-               free(model_emf_uri);
                goto error_rcu_unlock;
        }
 
        /* Lookup channel by UST object descriptor. */
        ua_chan = find_channel_by_objd(app, cobjd);
        if (!ua_chan) {
-               DBG("Application channel is being teardown. Abort event notify");
+               DBG("Application channel is being torn down. Abort event notify");
                ret = 0;
-               free(sig);
-               free(fields);
-               free(model_emf_uri);
                goto error_rcu_unlock;
        }
 
@@ -5529,7 +5543,11 @@ static int add_event_ust_registry(int sock, int sobjd, int cobjd, char *name,
        ua_sess = ua_chan->session;
 
        registry = get_session_registry(ua_sess);
-       assert(registry);
+       if (!registry) {
+               DBG("Application session is being torn down. Abort event notify");
+               ret = 0;
+               goto error_rcu_unlock;
+       }
 
        if (ua_sess->buffer_type == LTTNG_BUFFER_PER_UID) {
                chan_reg_key = ua_chan->tracing_channel_id;
@@ -5548,6 +5566,9 @@ static int add_event_ust_registry(int sock, int sobjd, int cobjd, char *name,
                        sobjd, cobjd, name, sig, nr_fields, fields,
                        loglevel_value, model_emf_uri, ua_sess->buffer_type,
                        &event_id, app);
+       sig = NULL;
+       fields = NULL;
+       model_emf_uri = NULL;
 
        /*
         * The return value is returned to ustctl so in case of an error, the
@@ -5575,6 +5596,9 @@ error:
        pthread_mutex_unlock(&registry->lock);
 error_rcu_unlock:
        rcu_read_unlock();
+       free(sig);
+       free(fields);
+       free(model_emf_uri);
        return ret;
 }
 
@@ -5611,13 +5635,17 @@ static int add_enum_ust_registry(int sock, int sobjd, char *name,
        ua_sess = find_session_by_objd(app, sobjd);
        if (!ua_sess) {
                /* Return an error since this is not an error */
-               DBG("Application session is being torn down. Aborting enum registration.");
+               DBG("Application session is being torn down (session not found). Aborting enum registration.");
                free(entries);
                goto error_rcu_unlock;
        }
 
        registry = get_session_registry(ua_sess);
-       assert(registry);
+       if (!registry) {
+               DBG("Application session is being torn down (registry not found). Aborting enum registration.");
+               free(entries);
+               goto error_rcu_unlock;
+       }
 
        pthread_mutex_lock(&registry->lock);
 
@@ -5983,7 +6011,11 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess,
                        }
 
                        registry = get_session_registry(ua_sess);
-                       assert(registry);
+                       if (!registry) {
+                               DBG("Application session is being torn down. Abort snapshot record.");
+                               ret = -1;
+                               goto error;
+                       }
                        ret = consumer_snapshot_channel(socket, registry->metadata_key, output,
                                        1, ua_sess->euid, ua_sess->egid, pathname, wait, 0);
                        if (ret < 0) {
@@ -6083,21 +6115,24 @@ int ust_app_uid_get_channel_runtime_stats(uint64_t ust_session_id,
        int ret;
        uint64_t consumer_chan_key;
 
+       *discarded = 0;
+       *lost = 0;
+
        ret = buffer_reg_uid_consumer_channel_key(
                        buffer_reg_uid_list, ust_session_id,
                        uchan_id, &consumer_chan_key);
        if (ret < 0) {
+               /* Not found */
+               ret = 0;
                goto end;
        }
 
        if (overwrite) {
                ret = consumer_get_lost_packets(ust_session_id,
                                consumer_chan_key, consumer, lost);
-               *discarded = 0;
        } else {
                ret = consumer_get_discarded_events(ust_session_id,
                                consumer_chan_key, consumer, discarded);
-               *lost = 0;
        }
 
 end:
@@ -6116,10 +6151,13 @@ int ust_app_pid_get_channel_runtime_stats(struct ltt_ust_session *usess,
        struct ust_app_session *ua_sess;
        struct ust_app_channel *ua_chan;
 
+       *discarded = 0;
+       *lost = 0;
+
        rcu_read_lock();
        /*
-        * Iterate over every registered applications, return when we
-        * found one in the right session and channel.
+        * Iterate over every registered applications. Sum counters for
+        * all applications containing requested session and channel.
         */
        cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
                struct lttng_ht_iter uiter;
@@ -6138,19 +6176,26 @@ int ust_app_pid_get_channel_runtime_stats(struct ltt_ust_session *usess,
                ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
 
                if (overwrite) {
+                       uint64_t _lost;
+
                        ret = consumer_get_lost_packets(usess->id, ua_chan->key,
-                                       consumer, lost);
-                       *discarded = 0;
-                       goto end;
+                                       consumer, &_lost);
+                       if (ret < 0) {
+                               break;
+                       }
+                       (*lost) += _lost;
                } else {
+                       uint64_t _discarded;
+
                        ret = consumer_get_discarded_events(usess->id,
-                                       ua_chan->key, consumer, discarded);
-                       *lost = 0;
-                       goto end;
+                                       ua_chan->key, consumer, &_discarded);
+                       if (ret < 0) {
+                               break;
+                       }
+                       (*discarded) += _discarded;
                }
        }
 
-end:
        rcu_read_unlock();
        return ret;
 }
This page took 0.028825 seconds and 4 git commands to generate.