X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fust-app.c;h=223fb77c0c936e0b81d678e4787a2c5f46e80bdc;hp=60b55d25a56e9832a261941ecf34007d6bd752d7;hb=5c786dedd0156b93984f89ba47ec841277ed7dae;hpb=5f4c2d807e49a7d1a5e149615d37ee824f0155a6 diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index 60b55d25a..223fb77c0 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -4871,18 +4871,27 @@ void ust_app_destroy(struct ust_app *app) * Return 0 on success or else a negative value. */ int ust_app_snapshot_record(struct ltt_ust_session *usess, - struct snapshot_output *output, int wait) + struct snapshot_output *output, int wait, unsigned int nb_streams) { int ret = 0; struct lttng_ht_iter iter; struct ust_app *app; char pathname[PATH_MAX]; + uint64_t max_stream_size = 0; assert(usess); assert(output); rcu_read_lock(); + /* + * Compute the maximum size of a single stream if a max size is asked by + * the caller. + */ + if (output->max_size > 0 && nb_streams > 0) { + 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; @@ -4915,8 +4924,22 @@ 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) { + /* + * 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) { + 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); + ua_sess->euid, ua_sess->egid, pathname, wait, + max_stream_size); if (ret < 0) { goto error; } @@ -4925,7 +4948,8 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess, 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); + 1, ua_sess->euid, ua_sess->egid, pathname, wait, + max_stream_size); if (ret < 0) { goto error; } @@ -4936,3 +4960,59 @@ error: rcu_read_unlock(); return ret; } + +/* + * Return the number of streams for a UST session. + */ +unsigned int ust_app_get_nb_stream(struct ltt_ust_session *usess) +{ + unsigned int ret = 0; + struct ust_app *app; + struct lttng_ht_iter iter; + + assert(usess); + + switch (usess->buffer_type) { + case LTTNG_BUFFER_PER_UID: + { + struct buffer_reg_uid *reg; + + cds_list_for_each_entry(reg, &usess->buffer_reg_uid_list, lnode) { + struct buffer_reg_channel *reg_chan; + + cds_lfht_for_each_entry(reg->registry->channels->ht, &iter.iter, + reg_chan, node.node) { + ret += reg_chan->stream_count; + } + } + break; + } + case LTTNG_BUFFER_PER_PID: + { + rcu_read_lock(); + cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) { + struct ust_app_channel *ua_chan; + struct ust_app_session *ua_sess; + struct lttng_ht_iter chan_iter; + + ua_sess = lookup_session_by_app(usess, app); + if (!ua_sess) { + /* Session not associated with this app. */ + continue; + } + + cds_lfht_for_each_entry(ua_sess->channels->ht, &chan_iter.iter, + ua_chan, node.node) { + ret += ua_chan->streams.count; + } + } + rcu_read_unlock(); + break; + } + default: + assert(0); + break; + } + + return ret; +}