Fix: sessiond: snapshot: handle consumer return codes
[lttng-tools.git] / src / bin / lttng-sessiond / ust-app.c
index 67dac65d56f6fcc4e108293c8655d1499d0f83e7..0e1907d8e99ed5fef30dd1e52f1bf802b51381ea 100644 (file)
@@ -487,9 +487,11 @@ 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);
+               }
+               if (sock >= 0) {
+                       save_per_pid_lost_discarded_counters(ua_chan);
                }
-               save_per_pid_lost_discarded_counters(ua_chan);
        }
 
        if (ua_chan->obj != NULL) {
@@ -2483,7 +2485,8 @@ error:
  */
 static int do_consumer_create_channel(struct ltt_ust_session *usess,
                struct ust_app_session *ua_sess, struct ust_app_channel *ua_chan,
-               int bitness, struct ust_registry_session *registry)
+               int bitness, struct ust_registry_session *registry,
+               uint64_t trace_archive_id)
 {
        int ret;
        unsigned int nb_fd = 0;
@@ -2518,7 +2521,7 @@ static int do_consumer_create_channel(struct ltt_ust_session *usess,
         * stream we have to expect.
         */
        ret = ust_consumer_ask_channel(ua_sess, ua_chan, usess->consumer, socket,
-                       registry);
+                       registry, trace_archive_id);
        if (ret < 0) {
                goto error_ask;
        }
@@ -2857,6 +2860,9 @@ 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;
+       enum lttng_error_code notification_ret;
+       struct ust_registry_channel *chan_reg;
 
        assert(app);
        assert(usess);
@@ -2887,12 +2893,18 @@ static int create_channel_per_uid(struct ust_app *app,
                goto error;
        }
 
+       session = session_find_by_id(ua_sess->tracing_id);
+       assert(session);
+       assert(pthread_mutex_trylock(&session->lock));
+       assert(session_trylock_list());
+
        /*
         * Create the buffers on the consumer side. This call populates the
         * ust app channel object with all streams and data object.
         */
        ret = do_consumer_create_channel(usess, ua_sess, ua_chan,
-                       app->bits_per_long, reg_uid->registry->reg.ust);
+                       app->bits_per_long, reg_uid->registry->reg.ust,
+                       session->current_archive_id);
        if (ret < 0) {
                ERR("Error creating UST channel \"%s\" on the consumer daemon",
                                ua_chan->name);
@@ -2918,39 +2930,26 @@ static int create_channel_per_uid(struct ust_app *app,
                goto error;
        }
 
-       {
-               enum lttng_error_code cmd_ret;
-               struct ltt_session *session;
-               uint64_t chan_reg_key;
-               struct ust_registry_channel *chan_reg;
-
-               chan_reg_key = ua_chan->tracing_channel_id;
+       /* Notify the notification subsystem of the channel's creation. */
+       pthread_mutex_lock(&reg_uid->registry->reg.ust->lock);
+       chan_reg = ust_registry_channel_find(reg_uid->registry->reg.ust,
+                       ua_chan->tracing_channel_id);
+       assert(chan_reg);
+       chan_reg->consumer_key = ua_chan->key;
+       chan_reg = NULL;
+       pthread_mutex_unlock(&reg_uid->registry->reg.ust->lock);
 
-               pthread_mutex_lock(&reg_uid->registry->reg.ust->lock);
-               chan_reg = ust_registry_channel_find(reg_uid->registry->reg.ust,
-                               chan_reg_key);
-               assert(chan_reg);
-               chan_reg->consumer_key = ua_chan->key;
-               chan_reg = NULL;
-               pthread_mutex_unlock(&reg_uid->registry->reg.ust->lock);
-
-               session = session_find_by_id(ua_sess->tracing_id);
-               assert(session);
-
-               assert(pthread_mutex_trylock(&session->lock));
-               assert(session_trylock_list());
-               cmd_ret = notification_thread_command_add_channel(
-                               notification_thread_handle, session->name,
-                               ua_sess->euid, ua_sess->egid,
-                               ua_chan->name,
-                               ua_chan->key,
-                               LTTNG_DOMAIN_UST,
-                               ua_chan->attr.subbuf_size * ua_chan->attr.num_subbuf);
-               if (cmd_ret != LTTNG_OK) {
-                       ret = - (int) cmd_ret;
-                       ERR("Failed to add channel to notification thread");
-                       goto error;
-               }
+       notification_ret = notification_thread_command_add_channel(
+                       notification_thread_handle, session->name,
+                       ua_sess->euid, ua_sess->egid,
+                       ua_chan->name,
+                       ua_chan->key,
+                       LTTNG_DOMAIN_UST,
+                       ua_chan->attr.subbuf_size * ua_chan->attr.num_subbuf);
+       if (notification_ret != LTTNG_OK) {
+               ret = - (int) notification_ret;
+               ERR("Failed to add channel to notification thread");
+               goto error;
        }
 
 send_channel:
@@ -3007,13 +3006,20 @@ static int create_channel_per_pid(struct ust_app *app,
                goto error;
        }
 
+       session = session_find_by_id(ua_sess->tracing_id);
+       assert(session);
+
+       assert(pthread_mutex_trylock(&session->lock));
+       assert(session_trylock_list());
+
        /* Create and get channel on the consumer side. */
        ret = do_consumer_create_channel(usess, ua_sess, ua_chan,
-                       app->bits_per_long, registry);
+                       app->bits_per_long, registry,
+                       session->current_archive_id);
        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);
@@ -3021,12 +3027,9 @@ 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;
        }
 
-       session = session_find_by_id(ua_sess->tracing_id);
-       assert(session);
-
        chan_reg_key = ua_chan->key;
        pthread_mutex_lock(&registry->lock);
        chan_reg = ust_registry_channel_find(registry, chan_reg_key);
@@ -3034,9 +3037,6 @@ static int create_channel_per_pid(struct ust_app *app,
        chan_reg->consumer_key = ua_chan->key;
        pthread_mutex_unlock(&registry->lock);
 
-       assert(pthread_mutex_trylock(&session->lock));
-       assert(session_trylock_list());
-
        cmd_ret = notification_thread_command_add_channel(
                        notification_thread_handle, session->name,
                        ua_sess->euid, ua_sess->egid,
@@ -3047,9 +3047,13 @@ 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();
        return ret;
@@ -3242,6 +3246,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;
 
        assert(ua_sess);
        assert(app);
@@ -3291,6 +3296,12 @@ static int create_ust_app_metadata(struct ust_app_session *ua_sess,
         */
        registry->metadata_key = metadata->key;
 
+       session = session_find_by_id(ua_sess->tracing_id);
+       assert(session);
+
+       assert(pthread_mutex_trylock(&session->lock));
+       assert(session_trylock_list());
+
        /*
         * Ask the metadata channel creation to the consumer. The metadata object
         * will be created by the consumer and kept their. However, the stream is
@@ -3298,7 +3309,7 @@ static int create_ust_app_metadata(struct ust_app_session *ua_sess,
         * consumer.
         */
        ret = ust_consumer_ask_channel(ua_sess, metadata, consumer, socket,
-                       registry);
+                       registry, session->current_archive_id);
        if (ret < 0) {
                /* Nullify the metadata key so we don't try to close it later on. */
                registry->metadata_key = 0;
@@ -4441,6 +4452,7 @@ int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app)
                                        usess->consumer->dst.session_root_path,
                                        usess->consumer->chunk_path,
                                        usess->consumer->subdir);
+                       free(tmp_path);
                        goto error_unlock;
                }
 
@@ -5419,11 +5431,11 @@ error:
  *
  * On success 0 is returned else a negative value.
  */
-static int reply_ust_register_channel(int sock, int sobjd, int cobjd,
+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;
@@ -5475,13 +5487,12 @@ static int reply_ust_register_channel(int sock, int sobjd, 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;
@@ -5797,7 +5808,7 @@ int ust_app_recv_notify(int sock)
                 * that if needed it will be freed. After this, it's invalid to access
                 * fields or clean it up.
                 */
-               ret = reply_ust_register_channel(sock, sobjd, cobjd, nr_fields,
+               ret = reply_ust_register_channel(sock, cobjd, nr_fields,
                                fields);
                if (ret < 0) {
                        goto error;
@@ -5946,12 +5957,20 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess,
        struct lttng_ht_iter iter;
        struct ust_app *app;
        char pathname[PATH_MAX];
+       struct ltt_session *session;
+       uint64_t trace_archive_id;
 
        assert(usess);
        assert(output);
 
        rcu_read_lock();
 
+       session = session_find_by_id(usess->id);
+       assert(session);
+       assert(pthread_mutex_trylock(&session->lock));
+       assert(session_trylock_list());
+       trace_archive_id = session->current_archive_id;
+
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_UID:
        {
@@ -5961,6 +5980,11 @@ 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);
@@ -5981,16 +6005,20 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess,
                        /* 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, reg_chan->consumer_key,
-                                               output, 0, usess->uid, usess->gid, pathname, wait,
-                                               nb_packets_per_stream);
+                               ret = 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) {
                                        goto error;
                                }
                        }
                        ret = consumer_snapshot_channel(socket,
                                        reg->registry->reg.ust->metadata_key, output, 1,
-                                       usess->uid, usess->gid, pathname, wait, 0);
+                                       usess->uid, usess->gid, pathname, wait, 0,
+                                       trace_archive_id);
                        if (ret < 0) {
                                goto error;
                        }
@@ -6031,23 +6059,34 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess,
 
                        cds_lfht_for_each_entry(ua_sess->channels->ht, &chan_iter.iter,
                                        ua_chan, node.node) {
-                               ret = consumer_snapshot_channel(socket, ua_chan->key, output,
-                                               0, ua_sess->euid, ua_sess->egid, pathname, wait,
-                                               nb_packets_per_stream);
+                               ret = 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;
+                                       }
                                        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, registry->metadata_key, output,
-                                       1, ua_sess->euid, ua_sess->egid, pathname, wait, 0);
+                       ret = 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;
+                               }
                                goto error;
                        }
                }
@@ -6299,7 +6338,7 @@ int ust_app_regenerate_statedump_all(struct ltt_ust_session *usess)
  *
  * Return 0 on success or else a negative value.
  */
-int ust_app_rotate_session(struct ltt_session *session, bool *ust_active)
+int ust_app_rotate_session(struct ltt_session *session)
 {
        int ret = 0;
        struct lttng_ht_iter iter;
@@ -6328,22 +6367,6 @@ int ust_app_rotate_session(struct ltt_session *session, bool *ust_active)
                                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;
-                               goto error;
-                       }
-
                        ret = snprintf(pathname, sizeof(pathname),
                                        DEFAULT_UST_TRACE_DIR "/" DEFAULT_UST_TRACE_UID_PATH,
                                        reg->uid, reg->bits_per_long);
@@ -6355,22 +6378,12 @@ int ust_app_rotate_session(struct ltt_session *session, bool *ust_active)
                        /* 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) {
                                        goto error;
                                }
@@ -6383,12 +6396,10 @@ 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) {
                                goto error;
                        }
-                       *ust_active = true;
                }
                break;
        }
@@ -6424,44 +6435,20 @@ int ust_app_rotate_session(struct ltt_session *session, bool *ust_active)
 
                        registry = get_session_registry(ua_sess);
                        if (!registry) {
-                               DBG("Application session is being torn down. Abort snapshot record.");
+                               DBG("Application session is being torn down. Abort session rotation.");
                                ret = -1;
                                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(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) {
                                        goto error;
                                }
@@ -6473,12 +6460,10 @@ 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) {
                                goto error;
                        }
-                       *ust_active = true;
                }
                break;
        }
This page took 0.030361 seconds and 5 git commands to generate.