X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fust-app.c;h=cf4b7ca772f467712f2f0d1c715ca98e77d8b353;hb=92db7cdc97f4bb5776fa698442d8af4e5c1e3bf3;hp=223fb77c0c936e0b81d678e4787a2c5f46e80bdc;hpb=5c786dedd0156b93984f89ba47ec841277ed7dae;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index 223fb77c0..cf4b7ca77 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -364,6 +364,7 @@ void delete_ust_app_channel(int sock, struct ust_app_channel *ua_chan, /* Wipe context */ cds_lfht_for_each_entry(ua_chan->ctx->ht, &iter.iter, ua_ctx, node.node) { + cds_list_del(&ua_ctx->list); ret = lttng_ht_del(ua_chan->ctx, &iter); assert(!ret); delete_ust_app_ctx(sock, ua_ctx); @@ -825,6 +826,7 @@ struct ust_app_channel *alloc_ust_app_channel(char *name, lttng_ht_node_init_str(&ua_chan->node, ua_chan->name); CDS_INIT_LIST_HEAD(&ua_chan->streams.head); + CDS_INIT_LIST_HEAD(&ua_chan->ctx_list); /* Copy attributes */ if (attr) { @@ -916,6 +918,8 @@ struct ust_app_ctx *alloc_ust_app_ctx(struct lttng_ust_context *uctx) goto error; } + CDS_INIT_LIST_HEAD(&ua_ctx->list); + if (uctx) { memcpy(&ua_ctx->ctx, uctx, sizeof(ua_ctx->ctx)); } @@ -1395,7 +1399,7 @@ static void shadow_copy_channel(struct ust_app_channel *ua_chan, ua_chan->enabled = uchan->enabled; ua_chan->tracing_channel_id = uchan->id; - cds_lfht_for_each_entry(uchan->ctx->ht, &iter.iter, uctx, node.node) { + cds_list_for_each_entry(uctx, &uchan->ctx_list, list) { ua_ctx = alloc_ust_app_ctx(&uctx->ctx); if (ua_ctx == NULL) { continue; @@ -1403,6 +1407,7 @@ static void shadow_copy_channel(struct ust_app_channel *ua_chan, lttng_ht_node_init_ulong(&ua_ctx->node, (unsigned long) ua_ctx->ctx.ctx); lttng_ht_add_unique_ulong(ua_chan->ctx, &ua_ctx->node); + cds_list_add_tail(&ua_ctx->list, &ua_chan->ctx_list); } /* Copy all events from ltt ust channel to ust app channel */ @@ -1795,6 +1800,7 @@ int create_ust_app_channel_context(struct ust_app_session *ua_sess, lttng_ht_node_init_ulong(&ua_ctx->node, (unsigned long) ua_ctx->ctx.ctx); lttng_ht_add_unique_ulong(ua_chan->ctx, &ua_ctx->node); + cds_list_add_tail(&ua_ctx->list, &ua_chan->ctx_list); ret = create_ust_channel_context(ua_chan, ua_ctx, app); if (ret < 0) { @@ -2134,6 +2140,7 @@ static int create_buffer_reg_channel(struct buffer_reg_session *reg_sess, } assert(reg_chan); reg_chan->consumer_key = ua_chan->key; + reg_chan->subbuf_size = ua_chan->attr.subbuf_size; /* Create and add a channel registry to session. */ ret = ust_registry_channel_add(reg_sess->reg.ust, @@ -3961,7 +3968,7 @@ int ust_app_stop_trace_all(struct ltt_ust_session *usess) } } - /* Flush buffers */ + /* Flush buffers and push metadata (for UID buffers). */ switch (usess->buffer_type) { case LTTNG_BUFFER_PER_UID: { @@ -3969,6 +3976,7 @@ int ust_app_stop_trace_all(struct ltt_ust_session *usess) /* Flush all per UID buffers associated to that session. */ cds_list_for_each_entry(reg, &usess->buffer_reg_uid_list, lnode) { + struct ust_registry_session *ust_session_reg; struct buffer_reg_channel *reg_chan; struct consumer_socket *socket; @@ -3989,7 +3997,14 @@ int ust_app_stop_trace_all(struct ltt_ust_session *usess) */ (void) consumer_flush_channel(socket, reg_chan->consumer_key); } + + ust_session_reg = reg->registry->reg.ust; + if (!ust_session_reg->metadata_closed) { + /* Push metadata. */ + (void) push_metadata(ust_session_reg, usess->consumer); + } } + break; } case LTTNG_BUFFER_PER_PID: @@ -4043,7 +4058,7 @@ int ust_app_destroy_trace_all(struct ltt_ust_session *usess) void ust_app_global_update(struct ltt_ust_session *usess, int sock) { int ret = 0; - struct lttng_ht_iter iter, uiter, iter_ctx; + struct lttng_ht_iter iter, uiter; struct ust_app *app; struct ust_app_session *ua_sess = NULL; struct ust_app_channel *ua_chan; @@ -4115,8 +4130,11 @@ void ust_app_global_update(struct ltt_ust_session *usess, int sock) } } - cds_lfht_for_each_entry(ua_chan->ctx->ht, &iter_ctx.iter, ua_ctx, - node.node) { + /* + * Add context using the list so they are enabled in the same order the + * user added them. + */ + cds_list_for_each_entry(ua_ctx, &ua_chan->ctx_list, list) { ret = create_ust_channel_context(ua_chan, ua_ctx, app); if (ret < 0) { goto error_unlock; @@ -4646,7 +4664,8 @@ static int add_event_ust_registry(int sock, int sobjd, int cobjd, char *name, */ ret_code = ust_registry_create_event(registry, chan_reg_key, sobjd, cobjd, name, sig, nr_fields, fields, loglevel, - model_emf_uri, ua_sess->buffer_type, &event_id); + model_emf_uri, ua_sess->buffer_type, &event_id, + app); /* * The return value is returned to ustctl so in case of an error, the @@ -4892,68 +4911,135 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess, max_stream_size = output->max_size / nb_streams; } - cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) { - struct consumer_socket *socket; - struct lttng_ht_iter chan_iter; - struct ust_app_channel *ua_chan; - struct ust_app_session *ua_sess; - struct ust_registry_session *registry; + switch (usess->buffer_type) { + case LTTNG_BUFFER_PER_UID: + { + struct buffer_reg_uid *reg; - ua_sess = lookup_session_by_app(usess, app); - if (!ua_sess) { - /* Session not associated with this app. */ - continue; - } + cds_list_for_each_entry(reg, &usess->buffer_reg_uid_list, lnode) { + struct buffer_reg_channel *reg_chan; + struct consumer_socket *socket; - /* Get the right consumer socket for the application. */ - socket = consumer_find_socket_by_bitness(app->bits_per_long, - output->consumer); - if (!socket) { - ret = -EINVAL; - goto error; - } + /* 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; + goto error; + } - /* Add the UST default trace dir to path. */ - memset(pathname, 0, sizeof(pathname)); - ret = snprintf(pathname, sizeof(pathname), DEFAULT_UST_TRACE_DIR "/%s", - ua_sess->path); - if (ret < 0) { - PERROR("snprintf snapshot path"); - goto error; + memset(pathname, 0, sizeof(pathname)); + ret = snprintf(pathname, sizeof(pathname), + DEFAULT_UST_TRACE_DIR "/" DEFAULT_UST_TRACE_UID_PATH, + reg->uid, reg->bits_per_long); + if (ret < 0) { + PERROR("snprintf snapshot path"); + 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) { + + /* + * Make sure the maximum stream size is not lower than the + * subbuffer size or else it's an error since we won't be able to + * snapshot anything. + */ + if (max_stream_size && + reg_chan->subbuf_size > max_stream_size) { + ret = -EINVAL; + DBG3("UST app snapshot record maximum stream size %" PRIu64 + " is smaller than subbuffer size of %zu", + max_stream_size, reg_chan->subbuf_size); + goto error; + } + ret = consumer_snapshot_channel(socket, reg_chan->consumer_key, output, 0, + usess->uid, usess->gid, pathname, wait, + max_stream_size); + if (ret < 0) { + goto error; + } + } + ret = consumer_snapshot_channel(socket, reg->registry->reg.ust->metadata_key, output, + 1, usess->uid, usess->gid, pathname, wait, + max_stream_size); + if (ret < 0) { + goto error; + } } + break; + } + case LTTNG_BUFFER_PER_PID: + { + cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) { + struct consumer_socket *socket; + struct lttng_ht_iter chan_iter; + struct ust_app_channel *ua_chan; + struct ust_app_session *ua_sess; + struct ust_registry_session *registry; - cds_lfht_for_each_entry(ua_sess->channels->ht, &chan_iter.iter, - ua_chan, node.node) { - /* - * Make sure the maximum stream size is not lower than the - * subbuffer size or else it's an error since we won't be able to - * snapshot anything. - */ - if (ua_chan->attr.subbuf_size > max_stream_size) { + ua_sess = lookup_session_by_app(usess, app); + if (!ua_sess) { + /* Session not associated with this app. */ + continue; + } + + /* Get the right consumer socket for the application. */ + socket = consumer_find_socket_by_bitness(app->bits_per_long, + output->consumer); + if (!socket) { ret = -EINVAL; - DBG3("UST app snapshot record maximum stream size %" PRIu64 - " is smaller than subbuffer size of %" PRIu64, - max_stream_size, ua_chan->attr.subbuf_size); goto error; } - ret = consumer_snapshot_channel(socket, ua_chan->key, output, 0, - ua_sess->euid, ua_sess->egid, pathname, wait, - max_stream_size); + /* Add the UST default trace dir to path. */ + memset(pathname, 0, sizeof(pathname)); + ret = snprintf(pathname, sizeof(pathname), DEFAULT_UST_TRACE_DIR "/%s", + ua_sess->path); if (ret < 0) { + PERROR("snprintf snapshot path"); goto error; } - } - registry = get_session_registry(ua_sess); - assert(registry); - ret = consumer_snapshot_channel(socket, registry->metadata_key, output, - 1, ua_sess->euid, ua_sess->egid, pathname, wait, - max_stream_size); - if (ret < 0) { - goto error; - } + cds_lfht_for_each_entry(ua_sess->channels->ht, &chan_iter.iter, + ua_chan, node.node) { + /* + * Make sure the maximum stream size is not lower than the + * subbuffer size or else it's an error since we won't be able to + * snapshot anything. + */ + if (max_stream_size && + ua_chan->attr.subbuf_size > max_stream_size) { + ret = -EINVAL; + DBG3("UST app snapshot record maximum stream size %" PRIu64 + " is smaller than subbuffer size of %" PRIu64, + max_stream_size, ua_chan->attr.subbuf_size); + goto error; + } + + ret = consumer_snapshot_channel(socket, ua_chan->key, output, 0, + ua_sess->euid, ua_sess->egid, pathname, wait, + max_stream_size); + if (ret < 0) { + goto error; + } + } + registry = get_session_registry(ua_sess); + assert(registry); + ret = consumer_snapshot_channel(socket, registry->metadata_key, output, + 1, ua_sess->euid, ua_sess->egid, pathname, wait, + max_stream_size); + if (ret < 0) { + goto error; + } + } + break; + } + default: + assert(0); + break; } error: