Fix: sessiond: don't allocate buffers and files for inactive sessions
[lttng-tools.git] / src / bin / lttng-sessiond / ust-app.c
index 5b37a8e7444a93da9600eaa9b96354309117a923..0b0a62532125e6bc7ecd4a72728f1b8e997a18ba 100644 (file)
@@ -437,6 +437,9 @@ void save_per_pid_lost_discarded_counters(struct ust_app_channel *ua_chan)
 
 end:
        rcu_read_unlock();
+       if (session) {
+               session_put(session);
+       }
 }
 
 /*
@@ -489,6 +492,11 @@ void delete_ust_app_channel(int sock, struct ust_app_channel *ua_chan,
                        ust_registry_channel_del_free(registry, ua_chan->key,
                                sock >= 0);
                }
+               /*
+                * A negative socket can be used by the caller when
+                * cleaning-up a ua_chan in an error path. Skip the
+                * accounting in this case.
+                */
                if (sock >= 0) {
                        save_per_pid_lost_discarded_counters(ua_chan);
                }
@@ -2860,7 +2868,7 @@ static int create_channel_per_uid(struct ust_app *app,
        int ret;
        struct buffer_reg_uid *reg_uid;
        struct buffer_reg_channel *reg_chan;
-       struct ltt_session *session;
+       struct ltt_session *session = NULL;
        enum lttng_error_code notification_ret;
        struct ust_registry_channel *chan_reg;
 
@@ -2963,6 +2971,9 @@ send_channel:
        }
 
 error:
+       if (session) {
+               session_put(session);
+       }
        return ret;
 }
 
@@ -2981,7 +2992,7 @@ static int create_channel_per_pid(struct ust_app *app,
        int ret;
        struct ust_registry_session *registry;
        enum lttng_error_code cmd_ret;
-       struct ltt_session *session;
+       struct ltt_session *session = NULL;
        uint64_t chan_reg_key;
        struct ust_registry_channel *chan_reg;
 
@@ -3056,6 +3067,9 @@ error_remove_from_registry:
        }
 error:
        rcu_read_unlock();
+       if (session) {
+               session_put(session);
+       }
        return ret;
 }
 
@@ -3246,7 +3260,7 @@ static int create_ust_app_metadata(struct ust_app_session *ua_sess,
        struct ust_app_channel *metadata;
        struct consumer_socket *socket;
        struct ust_registry_session *registry;
-       struct ltt_session *session;
+       struct ltt_session *session = NULL;
 
        assert(ua_sess);
        assert(app);
@@ -3337,6 +3351,9 @@ error_consumer:
        delete_ust_app_channel(-1, metadata, app);
 error:
        pthread_mutex_unlock(&registry->lock);
+       if (session) {
+               session_put(session);
+       }
        return ret;
 }
 
@@ -3904,6 +3921,24 @@ void ust_app_clean_list(void)
 
        rcu_read_lock();
 
+       /* Cleanup notify socket hash table */
+       if (ust_app_ht_by_notify_sock) {
+               cds_lfht_for_each_entry(ust_app_ht_by_notify_sock->ht, &iter.iter, app,
+                               notify_sock_n.node) {
+                       struct cds_lfht_node *node;
+                       struct ust_app *app;
+
+                       node = cds_lfht_iter_get_node(&iter.iter);
+                       if (!node) {
+                               continue;
+                       }
+
+                       app = container_of(node, struct ust_app,
+                                       notify_sock_n.node);
+                       ust_app_notify_sock_unregister(app->notify_sock);
+               }
+       }
+
        if (ust_app_ht) {
                cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
                        ret = lttng_ht_del(ust_app_ht, &iter);
@@ -3921,14 +3956,6 @@ void ust_app_clean_list(void)
                }
        }
 
-       /* Cleanup notify socket hash table */
-       if (ust_app_ht_by_notify_sock) {
-               cds_lfht_for_each_entry(ust_app_ht_by_notify_sock->ht, &iter.iter, app,
-                               notify_sock_n.node) {
-                       ret = lttng_ht_del(ust_app_ht_by_notify_sock, &iter);
-                       assert(!ret);
-               }
-       }
        rcu_read_unlock();
 
        /* Destroy is done only when the ht is empty */
@@ -3985,6 +4012,10 @@ int ust_app_disable_channel_glb(struct ltt_ust_session *usess,
        DBG2("UST app disabling channel %s from global domain for session id %" PRIu64,
                        uchan->name, usess->id);
 
+       if (!usess->active) {
+               goto end;
+       }
+
        rcu_read_lock();
 
        /* For every registered applications */
@@ -4023,6 +4054,7 @@ int ust_app_disable_channel_glb(struct ltt_ust_session *usess,
        rcu_read_unlock();
 
 error:
+end:
        return ret;
 }
 
@@ -4046,6 +4078,10 @@ int ust_app_enable_channel_glb(struct ltt_ust_session *usess,
        DBG2("UST app enabling channel %s to global domain for session id %" PRIu64,
                        uchan->name, usess->id);
 
+       if (!usess->active) {
+               goto end;
+       }
+
        rcu_read_lock();
 
        /* For every registered applications */
@@ -4073,6 +4109,7 @@ int ust_app_enable_channel_glb(struct ltt_ust_session *usess,
        rcu_read_unlock();
 
 error:
+end:
        return ret;
 }
 
@@ -4094,6 +4131,10 @@ int ust_app_disable_event_glb(struct ltt_ust_session *usess,
                        "%s for session id %" PRIu64,
                        uevent->attr.name, uchan->name, usess->id);
 
+       if (!usess->active) {
+               goto end;
+       }
+
        rcu_read_lock();
 
        /* For all registered applications */
@@ -4138,7 +4179,7 @@ int ust_app_disable_event_glb(struct ltt_ust_session *usess,
        }
 
        rcu_read_unlock();
-
+end:
        return ret;
 }
 
@@ -4160,6 +4201,10 @@ int ust_app_create_channel_glb(struct ltt_ust_session *usess,
        DBG2("UST app adding channel %s to UST domain for session id %" PRIu64,
                        uchan->name, usess->id);
 
+       if (!usess->active) {
+               goto end;
+       }
+
        rcu_read_lock();
 
        /* For every registered applications */
@@ -4239,6 +4284,7 @@ int ust_app_create_channel_glb(struct ltt_ust_session *usess,
 
 error_rcu_unlock:
        rcu_read_unlock();
+end:
        return ret;
 }
 
@@ -4259,6 +4305,10 @@ int ust_app_enable_event_glb(struct ltt_ust_session *usess,
        DBG("UST app enabling event %s for all apps for session id %" PRIu64,
                        uevent->attr.name, usess->id);
 
+       if (!usess->active) {
+               goto end;
+       }
+
        /*
         * NOTE: At this point, this function is called only if the session and
         * channel passed are already created for all apps. and enabled on the
@@ -4324,6 +4374,7 @@ int ust_app_enable_event_glb(struct ltt_ust_session *usess,
 
 error:
        rcu_read_unlock();
+end:
        return ret;
 }
 
@@ -4344,6 +4395,10 @@ int ust_app_create_event_glb(struct ltt_ust_session *usess,
        DBG("UST app creating event %s for all apps for session id %" PRIu64,
                        uevent->attr.name, usess->id);
 
+       if (!usess->active) {
+               goto end;
+       }
+
        rcu_read_lock();
 
        /* For all registered applications */
@@ -4390,7 +4445,7 @@ int ust_app_create_event_glb(struct ltt_ust_session *usess,
        }
 
        rcu_read_unlock();
-
+end:
        return ret;
 }
 
@@ -4969,6 +5024,12 @@ int ust_app_start_trace_all(struct ltt_ust_session *usess)
 
        DBG("Starting all UST traces");
 
+       /*
+        * Even though the start trace might fail, flag this session active so
+        * other application coming in are started by default.
+        */
+       usess->active = 1;
+
        rcu_read_lock();
 
        /*
@@ -4979,6 +5040,10 @@ int ust_app_start_trace_all(struct ltt_ust_session *usess)
         */
        (void) ust_app_clear_quiescent_session(usess);
 
+       cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+               ust_app_global_update(usess, app);
+       }
+
        cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
                ret = ust_app_start_trace(usess, app);
                if (ret < 0) {
@@ -5004,6 +5069,12 @@ int ust_app_stop_trace_all(struct ltt_ust_session *usess)
 
        DBG("Stopping all UST traces");
 
+       /*
+        * Even though the stop trace might fail, flag this session inactive so
+        * other application coming in are not started by default.
+        */
+       usess->active = 0;
+
        rcu_read_lock();
 
        cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
@@ -5067,6 +5138,9 @@ void ust_app_global_create(struct ltt_ust_session *usess, struct ust_app *app)
                /* App session already created. */
                goto end;
        }
+       if (!usess->active) {
+               goto end;
+       }
        assert(ua_sess);
 
        pthread_mutex_lock(&ua_sess->lock);
@@ -5120,14 +5194,12 @@ void ust_app_global_create(struct ltt_ust_session *usess, struct ust_app *app)
 
        pthread_mutex_unlock(&ua_sess->lock);
 
-       if (usess->active) {
-               ret = ust_app_start_trace(usess, app);
-               if (ret < 0) {
-                       goto error;
-               }
-
-               DBG2("UST trace started for app pid %d", app->pid);
+       ret = ust_app_start_trace(usess, app);
+       if (ret < 0) {
+               goto error;
        }
+
+       DBG2("UST trace started for app pid %d", app->pid);
 end:
        /* Everything went well at this point. */
        return;
@@ -5169,7 +5241,9 @@ void ust_app_global_update(struct ltt_ust_session *usess, struct ust_app *app)
        if (!app->compatible) {
                return;
        }
-
+       if (!usess->active) {
+               return;
+       }
        if (trace_ust_pid_tracker_lookup(usess, app->pid)) {
                ust_app_global_create(usess, app);
        } else {
@@ -5185,6 +5259,9 @@ void ust_app_global_update_all(struct ltt_ust_session *usess)
        struct lttng_ht_iter iter;
        struct ust_app *app;
 
+       if (!usess->active) {
+               return;
+       }
        rcu_read_lock();
        cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
                ust_app_global_update(usess, app);
@@ -5205,6 +5282,10 @@ int ust_app_add_ctx_channel_glb(struct ltt_ust_session *usess,
        struct ust_app_session *ua_sess;
        struct ust_app *app;
 
+       if (!usess->active) {
+               goto end;
+       }
+
        rcu_read_lock();
 
        cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
@@ -5244,6 +5325,7 @@ int ust_app_add_ctx_channel_glb(struct ltt_ust_session *usess,
        }
 
        rcu_read_unlock();
+end:
        return ret;
 }
 
@@ -5947,17 +6029,18 @@ void ust_app_destroy(struct ust_app *app)
  * Take a snapshot for a given UST session. The snapshot is sent to the given
  * output.
  *
- * Return 0 on success or else a negative value.
+ * Returns LTTNG_OK on success or a LTTNG_ERR error code.
  */
-int ust_app_snapshot_record(struct ltt_ust_session *usess,
+enum lttng_error_code ust_app_snapshot_record(struct ltt_ust_session *usess,
                struct snapshot_output *output, int wait,
                uint64_t nb_packets_per_stream)
 {
        int ret = 0;
+       enum lttng_error_code status = LTTNG_OK;
        struct lttng_ht_iter iter;
        struct ust_app *app;
        char pathname[PATH_MAX];
-       struct ltt_session *session;
+       struct ltt_session *session = NULL;
        uint64_t trace_archive_id;
 
        assert(usess);
@@ -5989,7 +6072,7 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess,
                        socket = consumer_find_socket_by_bitness(reg->bits_per_long,
                                        usess->consumer);
                        if (!socket) {
-                               ret = -EINVAL;
+                               status = LTTNG_ERR_INVALID;
                                goto error;
                        }
 
@@ -5999,27 +6082,28 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess,
                                        reg->uid, reg->bits_per_long);
                        if (ret < 0) {
                                PERROR("snprintf snapshot path");
+                               status = LTTNG_ERR_INVALID;
                                goto error;
                        }
 
                        /* Add the UST default trace dir to path. */
                        cds_lfht_for_each_entry(reg->registry->channels->ht, &iter.iter,
                                        reg_chan, node.node) {
-                               ret = consumer_snapshot_channel(socket,
+                               status = consumer_snapshot_channel(socket,
                                                reg_chan->consumer_key,
                                                output, 0, usess->uid,
                                                usess->gid, pathname, wait,
                                                nb_packets_per_stream,
                                                trace_archive_id);
-                               if (ret < 0) {
+                               if (status != LTTNG_OK) {
                                        goto error;
                                }
                        }
-                       ret = consumer_snapshot_channel(socket,
+                       status = consumer_snapshot_channel(socket,
                                        reg->registry->reg.ust->metadata_key, output, 1,
                                        usess->uid, usess->gid, pathname, wait, 0,
                                        trace_archive_id);
-                       if (ret < 0) {
+                       if (status != LTTNG_OK) {
                                goto error;
                        }
                }
@@ -6044,7 +6128,7 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess,
                        socket = consumer_find_socket_by_bitness(app->bits_per_long,
                                        output->consumer);
                        if (!socket) {
-                               ret = -EINVAL;
+                               status = LTTNG_ERR_INVALID;
                                goto error;
                        }
 
@@ -6053,22 +6137,25 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess,
                        ret = snprintf(pathname, sizeof(pathname), DEFAULT_UST_TRACE_DIR "/%s",
                                        ua_sess->path);
                        if (ret < 0) {
+                               status = LTTNG_ERR_INVALID;
                                PERROR("snprintf snapshot path");
                                goto error;
                        }
 
                        cds_lfht_for_each_entry(ua_sess->channels->ht, &chan_iter.iter,
                                        ua_chan, node.node) {
-                               ret = consumer_snapshot_channel(socket,
+                               status = consumer_snapshot_channel(socket,
                                                ua_chan->key, output,
                                                0, ua_sess->euid, ua_sess->egid,
                                                pathname, wait,
                                                nb_packets_per_stream,
                                                trace_archive_id);
-                               if (ret < 0) {
-                                       if (ret == -LTTNG_ERR_CHAN_NOT_FOUND) {
-                                               continue;
-                                       }
+                               switch (status) {
+                               case LTTNG_OK:
+                                       break;
+                               case LTTNG_ERR_CHAN_NOT_FOUND:
+                                       continue;
+                               default:
                                        goto error;
                                }
                        }
@@ -6078,15 +6165,17 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess,
                                DBG("Application session is being torn down. Skip application.");
                                continue;
                        }
-                       ret = consumer_snapshot_channel(socket,
+                       status = consumer_snapshot_channel(socket,
                                        registry->metadata_key, output,
                                        1, ua_sess->euid, ua_sess->egid,
                                        pathname, wait, 0,
                                        trace_archive_id);
-                       if (ret < 0) {
-                               if (ret == -LTTNG_ERR_CHAN_NOT_FOUND) {
-                                       continue;
-                               }
+                       switch (status) {
+                       case LTTNG_OK:
+                               break;
+                       case LTTNG_ERR_CHAN_NOT_FOUND:
+                               continue;
+                       default:
                                goto error;
                        }
                }
@@ -6099,7 +6188,10 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess,
 
 error:
        rcu_read_unlock();
-       return ret;
+       if (session) {
+               session_put(session);
+       }
+       return status;
 }
 
 /*
This page took 0.030201 seconds and 4 git commands to generate.