ua_sess->handle = -1;
ua_sess->channels = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
+ ua_sess->metadata_attr.type = LTTNG_UST_CHAN_METADATA;
pthread_mutex_init(&ua_sess->lock, NULL);
return 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);
+ lttng_ht_add_ulong(ua_chan->ctx, &ua_ctx->node);
cds_list_add_tail(&ua_ctx->list, &ua_chan->ctx_list);
}
ua_sess->consumer = usess->consumer;
ua_sess->output_traces = usess->output_traces;
ua_sess->live_timer_interval = usess->live_timer_interval;
+ copy_channel_attr_to_ustctl(&ua_sess->metadata_attr,
+ &usess->metadata_attr);
switch (ua_sess->buffer_type) {
case LTTNG_BUFFER_PER_PID:
}
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);
+ lttng_ht_add_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);
* Called with UST app session lock held and RCU read side lock.
*/
static int create_ust_app_metadata(struct ust_app_session *ua_sess,
- struct ust_app *app, struct consumer_output *consumer,
- struct ustctl_consumer_channel_attr *attr)
+ struct ust_app *app, struct consumer_output *consumer)
{
int ret = 0;
struct ust_app_channel *metadata;
goto error;
}
- if (!attr) {
- /* Set default attributes for metadata. */
- metadata->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE;
- metadata->attr.subbuf_size = default_get_metadata_subbuf_size();
- metadata->attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM;
- metadata->attr.switch_timer_interval = DEFAULT_METADATA_SWITCH_TIMER;
- metadata->attr.read_timer_interval = DEFAULT_METADATA_READ_TIMER;
- metadata->attr.output = LTTNG_UST_MMAP;
- metadata->attr.type = LTTNG_UST_CHAN_METADATA;
- } else {
- memcpy(&metadata->attr, attr, sizeof(metadata->attr));
- metadata->attr.output = LTTNG_UST_MMAP;
- metadata->attr.type = LTTNG_UST_CHAN_METADATA;
- }
+ memcpy(&metadata->attr, &ua_sess->metadata_attr, sizeof(metadata->attr));
/* Need one fd for the channel. */
ret = lttng_fd_get(LTTNG_FD_APPS, 1);
ret = ustctl_tracer_version(app->sock, &app->version);
if (ret < 0) {
if (ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
- ERR("UST app %d verson failed with ret %d", app->sock, ret);
+ ERR("UST app %d version failed with ret %d", app->sock, ret);
} else {
- DBG3("UST app %d verion failed. Application is dead", app->sock);
+ DBG3("UST app %d version failed. Application is dead", app->sock);
}
}
health_code_update();
if (count >= nbmem) {
/* In case the realloc fails, we free the memory */
- void *ptr;
-
- DBG2("Reallocating event list from %zu to %zu entries", nbmem,
- 2 * nbmem);
- nbmem *= 2;
- ptr = realloc(tmp_event, nbmem * sizeof(struct lttng_event));
- if (ptr == NULL) {
+ struct lttng_event *new_tmp_event;
+ size_t new_nbmem;
+
+ new_nbmem = nbmem << 1;
+ DBG2("Reallocating event list from %zu to %zu entries",
+ nbmem, new_nbmem);
+ new_tmp_event = realloc(tmp_event,
+ new_nbmem * sizeof(struct lttng_event));
+ if (new_tmp_event == NULL) {
PERROR("realloc ust app events");
free(tmp_event);
ret = -ENOMEM;
goto rcu_error;
}
- tmp_event = ptr;
+ /* Zero the new memory */
+ memset(new_tmp_event + nbmem, 0,
+ (new_nbmem - nbmem) * sizeof(struct lttng_event));
+ nbmem = new_nbmem;
+ tmp_event = new_tmp_event;
}
memcpy(tmp_event[count].name, uiter.name, LTTNG_UST_SYM_NAME_LEN);
tmp_event[count].loglevel = uiter.loglevel;
health_code_update();
if (count >= nbmem) {
/* In case the realloc fails, we free the memory */
- void *ptr;
-
- DBG2("Reallocating event field list from %zu to %zu entries", nbmem,
- 2 * nbmem);
- nbmem *= 2;
- ptr = realloc(tmp_event, nbmem * sizeof(struct lttng_event_field));
- if (ptr == NULL) {
+ struct lttng_event_field *new_tmp_event;
+ size_t new_nbmem;
+
+ new_nbmem = nbmem << 1;
+ DBG2("Reallocating event field list from %zu to %zu entries",
+ nbmem, new_nbmem);
+ new_tmp_event = realloc(tmp_event,
+ new_nbmem * sizeof(struct lttng_event_field));
+ if (new_tmp_event == NULL) {
PERROR("realloc ust app event fields");
free(tmp_event);
ret = -ENOMEM;
goto rcu_error;
}
- tmp_event = ptr;
+ /* Zero the new memory */
+ memset(new_tmp_event + nbmem, 0,
+ (new_nbmem - nbmem) * sizeof(struct lttng_event_field));
+ nbmem = new_nbmem;
+ tmp_event = new_tmp_event;
}
memcpy(tmp_event[count].field_name, uiter.field_name, LTTNG_UST_SYM_NAME_LEN);
pthread_mutex_lock(&ua_sess->lock);
if (!strncmp(uchan->name, DEFAULT_METADATA_NAME,
sizeof(uchan->name))) {
- struct ustctl_consumer_channel_attr attr;
- copy_channel_attr_to_ustctl(&attr, &uchan->attr);
- ret = create_ust_app_metadata(ua_sess, app, usess->consumer,
- &attr);
+ copy_channel_attr_to_ustctl(&ua_sess->metadata_attr, &uchan->attr);
+ ret = 0;
} else {
/* Create channel onto application. We don't need the chan ref. */
ret = create_ust_app_channel(ua_sess, uchan, app,
* Create the metadata for the application. This returns gracefully if a
* metadata was already set for the session.
*/
- ret = create_ust_app_metadata(ua_sess, app, usess->consumer, NULL);
+ ret = create_ust_app_metadata(ua_sess, app, usess->consumer);
if (ret < 0) {
goto error_unlock;
}
*/
cds_lfht_for_each_entry(ua_sess->channels->ht, &iter.iter, ua_chan,
node.node) {
- /*
- * For a metadata channel, handle it differently.
- */
- if (!strncmp(ua_chan->name, DEFAULT_METADATA_NAME,
- sizeof(ua_chan->name))) {
- ret = create_ust_app_metadata(ua_sess, app, usess->consumer,
- &ua_chan->attr);
- if (ret < 0) {
- goto error_unlock;
- }
- /* Remove it from the hash table and continue!. */
- ret = lttng_ht_del(ua_sess->channels, &iter);
- assert(!ret);
- delete_ust_app_channel(-1, ua_chan, app);
- continue;
- } else {
- ret = do_create_channel(app, usess, ua_sess, ua_chan);
- if (ret < 0) {
- /*
- * Stop everything. On error, the application failed, no more
- * file descriptor are available or ENOMEM so stopping here is
- * the only thing we can do for now.
- */
- goto error_unlock;
- }
+ ret = do_create_channel(app, usess, ua_sess, ua_chan);
+ if (ret < 0) {
+ /*
+ * Stop everything. On error, the application failed, no more
+ * file descriptor are available or ENOMEM so stopping here is
+ * the only thing we can do for now.
+ */
+ goto error_unlock;
}
/*
pthread_mutex_unlock(&ua_sess->lock);
- if (usess->start_trace) {
+ if (usess->active) {
ret = ust_app_start_trace(usess, app);
if (ret < 0) {
goto error;
* 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, unsigned int nb_streams)
+ struct snapshot_output *output, int wait, uint64_t max_stream_size)
{
int ret = 0;
+ unsigned int snapshot_done = 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;
- }
-
switch (usess->buffer_type) {
case LTTNG_BUFFER_PER_UID:
{
/* 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,
+ 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);
+ 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;
}
+ snapshot_done = 1;
}
break;
}
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,
+ 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;
if (ret < 0) {
goto error;
}
+ snapshot_done = 1;
}
break;
}
break;
}
+ if (!snapshot_done) {
+ /*
+ * If no snapshot was made and we are not in the error path, this means
+ * that there are no buffers thus no (prior) application to snapshot
+ * data from so we have simply NO data.
+ */
+ ret = -ENODATA;
+ }
+
error:
rcu_read_unlock();
return ret;