Reference count ltt_session objects
[lttng-tools.git] / src / bin / lttng-sessiond / ust-app.c
index 5cf90493947f4de46d9a4738e6cf640ba98fedcf..e2b7a083c0ecb33eb95db9c8789abe34c154f2f8 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);
+       }
 }
 
 /*
@@ -487,9 +490,16 @@ void delete_ust_app_channel(int sock, struct ust_app_channel *ua_chan,
                registry = get_session_registry(ua_chan->session);
                if (registry) {
                        ust_registry_channel_del_free(registry, ua_chan->key,
-                               true);
+                               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);
                }
-               save_per_pid_lost_discarded_counters(ua_chan);
        }
 
        if (ua_chan->obj != NULL) {
@@ -2858,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;
 
@@ -2961,6 +2971,9 @@ send_channel:
        }
 
 error:
+       if (session) {
+               session_put(session);
+       }
        return ret;
 }
 
@@ -2979,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;
 
@@ -3017,7 +3030,7 @@ static int create_channel_per_pid(struct ust_app *app,
        if (ret < 0) {
                ERR("Error creating UST channel \"%s\" on the consumer daemon",
                        ua_chan->name);
-               goto error;
+               goto error_remove_from_registry;
        }
 
        ret = send_channel_pid_to_ust(app, ua_sess, ua_chan);
@@ -3025,7 +3038,7 @@ static int create_channel_per_pid(struct ust_app *app,
                if (ret != -ENOTCONN) {
                        ERR("Error sending channel to application");
                }
-               goto error;
+               goto error_remove_from_registry;
        }
 
        chan_reg_key = ua_chan->key;
@@ -3045,11 +3058,18 @@ static int create_channel_per_pid(struct ust_app *app,
        if (cmd_ret != LTTNG_OK) {
                ret = - (int) cmd_ret;
                ERR("Failed to add channel to notification thread");
-               goto error;
+               goto error_remove_from_registry;
        }
 
+error_remove_from_registry:
+       if (ret) {
+               ust_registry_channel_del_free(registry, ua_chan->key, false);
+       }
 error:
        rcu_read_unlock();
+       if (session) {
+               session_put(session);
+       }
        return ret;
 }
 
@@ -3240,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);
@@ -3331,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;
 }
 
@@ -5429,7 +5452,7 @@ static int reply_ust_register_channel(int sock, int cobjd,
                size_t nr_fields, struct ustctl_field *fields)
 {
        int ret, ret_code = 0;
-       uint32_t chan_id, reg_count;
+       uint32_t chan_id;
        uint64_t chan_reg_key;
        enum ustctl_channel_header type;
        struct ust_app *app;
@@ -5481,13 +5504,12 @@ static int reply_ust_register_channel(int sock, int cobjd,
        assert(chan_reg);
 
        if (!chan_reg->register_done) {
-               reg_count = ust_registry_get_event_count(chan_reg);
-               if (reg_count < 31) {
-                       type = USTCTL_CHANNEL_HEADER_COMPACT;
-               } else {
-                       type = USTCTL_CHANNEL_HEADER_LARGE;
-               }
-
+               /*
+                * TODO: eventually use the registry event count for
+                * this channel to better guess header type for per-pid
+                * buffers.
+                */
+               type = USTCTL_CHANNEL_HEADER_LARGE;
                chan_reg->nr_ctx_fields = nr_fields;
                chan_reg->ctx_fields = fields;
                fields = NULL;
@@ -5942,17 +5964,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);
@@ -5975,11 +5998,16 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess,
                        struct buffer_reg_channel *reg_chan;
                        struct consumer_socket *socket;
 
+                       if (!reg->registry->reg.ust->metadata_key) {
+                               /* Skip since no metadata is present */
+                               continue;
+                       }
+
                        /* Get consumer socket to use to push the metadata.*/
                        socket = consumer_find_socket_by_bitness(reg->bits_per_long,
                                        usess->consumer);
                        if (!socket) {
-                               ret = -EINVAL;
+                               status = LTTNG_ERR_INVALID;
                                goto error;
                        }
 
@@ -5989,27 +6017,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;
                        }
                }
@@ -6034,7 +6063,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;
                        }
 
@@ -6043,35 +6072,45 @@ 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) {
+                               switch (status) {
+                               case LTTNG_OK:
+                                       break;
+                               case LTTNG_ERR_CHAN_NOT_FOUND:
+                                       continue;
+                               default:
                                        goto error;
                                }
                        }
 
                        registry = get_session_registry(ua_sess);
                        if (!registry) {
-                               DBG("Application session is being torn down. Abort snapshot record.");
-                               ret = -1;
-                               goto error;
+                               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) {
+                       switch (status) {
+                       case LTTNG_OK:
+                               break;
+                       case LTTNG_ERR_CHAN_NOT_FOUND:
+                               continue;
+                       default:
                                goto error;
                        }
                }
@@ -6084,7 +6123,10 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess,
 
 error:
        rcu_read_unlock();
-       return ret;
+       if (session) {
+               session_put(session);
+       }
+       return status;
 }
 
 /*
@@ -6321,11 +6363,12 @@ int ust_app_regenerate_statedump_all(struct ltt_ust_session *usess)
 /*
  * Rotate all the channels of a session.
  *
- * Return 0 on success or else a negative value.
+ * Return LTTNG_OK on success or else an LTTng error code.
  */
-int ust_app_rotate_session(struct ltt_session *session, bool *ust_active)
+enum lttng_error_code ust_app_rotate_session(struct ltt_session *session)
 {
-       int ret = 0;
+       int ret;
+       enum lttng_error_code cmd_ret = LTTNG_OK;
        struct lttng_ht_iter iter;
        struct ust_app *app;
        struct ltt_ust_session *usess = session->ust_session;
@@ -6348,23 +6391,7 @@ int ust_app_rotate_session(struct ltt_session *session, bool *ust_active)
                        socket = consumer_find_socket_by_bitness(reg->bits_per_long,
                                        usess->consumer);
                        if (!socket) {
-                               ret = -EINVAL;
-                               goto error;
-                       }
-
-                       /*
-                        * Account the metadata channel first to make sure the
-                        * number of channels waiting for a rotation cannot
-                        * reach 0 before we complete the iteration over all
-                        * the channels.
-                        */
-                       ret = rotate_add_channel_pending(
-                                       reg->registry->reg.ust->metadata_key,
-                                       LTTNG_DOMAIN_UST, session);
-                       if (ret < 0) {
-                               ret = reg->bits_per_long == 32 ?
-                                               -LTTNG_ERR_UST_CONSUMER32_FAIL :
-                                               -LTTNG_ERR_UST_CONSUMER64_FAIL;
+                               cmd_ret = LTTNG_ERR_INVALID;
                                goto error;
                        }
 
@@ -6373,29 +6400,21 @@ int ust_app_rotate_session(struct ltt_session *session, bool *ust_active)
                                        reg->uid, reg->bits_per_long);
                        if (ret < 0 || ret == sizeof(pathname)) {
                                PERROR("Failed to format rotation path");
+                               cmd_ret = LTTNG_ERR_INVALID;
                                goto error;
                        }
 
                        /* Rotate the data channels. */
                        cds_lfht_for_each_entry(reg->registry->channels->ht, &iter.iter,
                                        reg_chan, node.node) {
-                               ret = rotate_add_channel_pending(
-                                               reg_chan->consumer_key,
-                                               LTTNG_DOMAIN_UST, session);
-                               if (ret < 0) {
-                                       ret = reg->bits_per_long == 32 ?
-                                                       -LTTNG_ERR_UST_CONSUMER32_FAIL :
-                                                       -LTTNG_ERR_UST_CONSUMER64_FAIL;
-                                       goto error;
-                               }
                                ret = consumer_rotate_channel(socket,
                                                reg_chan->consumer_key,
                                                usess->uid, usess->gid,
                                                usess->consumer, pathname,
                                                /* is_metadata_channel */ false,
-                                               session->current_archive_id,
-                                               &session->rotate_pending_relay);
+                                               session->current_archive_id);
                                if (ret < 0) {
+                                       cmd_ret = LTTNG_ERR_ROTATION_FAIL_CONSUMER;
                                        goto error;
                                }
                        }
@@ -6407,12 +6426,11 @@ int ust_app_rotate_session(struct ltt_session *session, bool *ust_active)
                                        usess->uid, usess->gid,
                                        usess->consumer, pathname,
                                        /* is_metadata_channel */ true,
-                                       session->current_archive_id,
-                                       &session->rotate_pending_relay);
+                                       session->current_archive_id);
                        if (ret < 0) {
+                               cmd_ret = LTTNG_ERR_ROTATION_FAIL_CONSUMER;
                                goto error;
                        }
-                       *ust_active = true;
                }
                break;
        }
@@ -6435,6 +6453,7 @@ int ust_app_rotate_session(struct ltt_session *session, bool *ust_active)
                                        ua_sess->path);
                        if (ret < 0 || ret == sizeof(pathname)) {
                                PERROR("Failed to format rotation path");
+                               cmd_ret = LTTNG_ERR_INVALID;
                                goto error;
                        }
 
@@ -6442,51 +6461,30 @@ int ust_app_rotate_session(struct ltt_session *session, bool *ust_active)
                        socket = consumer_find_socket_by_bitness(app->bits_per_long,
                                        usess->consumer);
                        if (!socket) {
-                               ret = -EINVAL;
+                               cmd_ret = LTTNG_ERR_INVALID;
                                goto error;
                        }
 
                        registry = get_session_registry(ua_sess);
                        if (!registry) {
-                               DBG("Application session is being torn down. Abort snapshot record.");
-                               ret = -1;
-                               goto error;
+                               DBG("Application session is being torn down. Skip application.");
+                               continue;
                        }
 
-                       /*
-                        * Account the metadata channel first to make sure the
-                        * number of channels waiting for a rotation cannot
-                        * reach 0 before we complete the iteration over all
-                        * the channels.
-                        */
-                       ret = rotate_add_channel_pending(registry->metadata_key,
-                                       LTTNG_DOMAIN_UST, session);
-                       if (ret < 0) {
-                               ret = app->bits_per_long == 32 ?
-                                               -LTTNG_ERR_UST_CONSUMER32_FAIL :
-                                               -LTTNG_ERR_UST_CONSUMER64_FAIL;
-                               goto error;
-                       }
 
                        /* Rotate the data channels. */
                        cds_lfht_for_each_entry(ua_sess->channels->ht, &chan_iter.iter,
                                        ua_chan, node.node) {
-                               ret = rotate_add_channel_pending(
-                                               ua_chan->key, LTTNG_DOMAIN_UST,
-                                               session);
-                               if (ret < 0) {
-                                       ret = app->bits_per_long == 32 ?
-                                                       -LTTNG_ERR_UST_CONSUMER32_FAIL :
-                                                       -LTTNG_ERR_UST_CONSUMER64_FAIL;
-                                       goto error;
-                               }
                                ret = consumer_rotate_channel(socket, ua_chan->key,
                                                ua_sess->euid, ua_sess->egid,
                                                ua_sess->consumer, pathname,
                                                /* is_metadata_channel */ false,
-                                               session->current_archive_id,
-                                               &session->rotate_pending_relay);
+                                               session->current_archive_id);
                                if (ret < 0) {
+                                       /* Per-PID buffer and application going away. */
+                                       if (ret == -LTTNG_ERR_CHAN_NOT_FOUND)
+                                               continue;
+                                       cmd_ret = LTTNG_ERR_ROTATION_FAIL_CONSUMER;
                                        goto error;
                                }
                        }
@@ -6497,12 +6495,14 @@ int ust_app_rotate_session(struct ltt_session *session, bool *ust_active)
                                        ua_sess->euid, ua_sess->egid,
                                        ua_sess->consumer, pathname,
                                        /* is_metadata_channel */ true,
-                                       session->current_archive_id,
-                                       &session->rotate_pending_relay);
+                                       session->current_archive_id);
                        if (ret < 0) {
+                               /* Per-PID buffer and application going away. */
+                               if (ret == -LTTNG_ERR_CHAN_NOT_FOUND)
+                                       continue;
+                               cmd_ret = LTTNG_ERR_ROTATION_FAIL_CONSUMER;
                                goto error;
                        }
-                       *ust_active = true;
                }
                break;
        }
@@ -6511,9 +6511,9 @@ int ust_app_rotate_session(struct ltt_session *session, bool *ust_active)
                break;
        }
 
-       ret = LTTNG_OK;
+       cmd_ret = LTTNG_OK;
 
 error:
        rcu_read_unlock();
-       return ret;
+       return cmd_ret;
 }
This page took 0.031248 seconds and 5 git commands to generate.