* this function.
*/
static
-void delete_ust_app_stream(int sock, struct ltt_ust_stream *stream)
+void delete_ust_app_stream(int sock, struct ust_app_stream *stream)
{
if (stream->obj) {
ustctl_release_object(sock, stream->obj);
struct lttng_ht_iter iter;
struct ust_app_event *ua_event;
struct ust_app_ctx *ua_ctx;
- struct ltt_ust_stream *stream, *stmp;
+ struct ust_app_stream *stream, *stmp;
/* Wipe stream */
cds_list_for_each_entry_safe(stream, stmp, &ua_chan->streams.head, list) {
return NULL;
}
+/*
+ * Allocate and initialize a UST app stream.
+ *
+ * Return newly allocated stream pointer or NULL on error.
+ */
+static struct ust_app_stream *alloc_ust_app_stream(void)
+{
+ struct ust_app_stream *stream = NULL;
+
+ stream = zmalloc(sizeof(*stream));
+ if (stream == NULL) {
+ PERROR("zmalloc ust app stream");
+ goto error;
+ }
+
+ /* Zero could be a valid value for a handle so flag it to -1. */
+ stream->handle = -1;
+
+error:
+ return stream;
+}
+
/*
* Alloc new UST app event.
*/
}
/*
- * Create stream onto the UST tracer for a UST session.
+ * Create metadata stream onto the UST tracer for a given session.
*/
-static int create_ust_stream(struct ust_app *app,
+static int create_ust_metadata_stream(struct ust_app *app,
struct ust_app_session *ua_sess)
{
int ret;
ret = ustctl_create_stream(app->sock, ua_sess->metadata->obj,
&ua_sess->metadata->stream_obj);
if (ret < 0) {
+ lttng_fd_put(LTTNG_FD_APPS, 2);
ERR("UST create metadata stream failed");
goto error;
}
return ret;
}
+/*
+ * Create stream onto the UST tracer for a given channel.
+ *
+ * Return -ENOENT if no more stream is available for this channel.
+ * On success, return 0.
+ * On error, return a negative value.
+ */
+static int create_ust_stream(struct ust_app *app,
+ struct ust_app_channel *ua_chan, struct ust_app_stream *stream)
+{
+ int ret;
+
+ assert(app);
+ assert(ua_chan);
+ assert(ua_chan->obj);
+ assert(stream);
+
+ health_code_update(&health_thread_cmd);
+
+ /* We are going to receive 2 fds, we need to reserve them. */
+ ret = lttng_fd_get(LTTNG_FD_APPS, 2);
+ if (ret < 0) {
+ ERR("Exhausted number of available FD on stream creation");
+ /* Just to make sure we never return -ENOENT. */
+ ret = -1;
+ goto error;
+ }
+
+ /*
+ * Set the stream name before creating it. On error, we don't have to
+ * delete it on the tracer side.
+ */
+ ret = snprintf(stream->name, sizeof(stream->name), "%s_%u",
+ ua_chan->name, ua_chan->streams.count);
+ if (ret < 0) {
+ /* Without the stream name we can't continue using it. */
+ PERROR("snprintf UST create stream");
+ /* Just to make sure we never return -ENOENT. */
+ ret = -1;
+ goto error;
+ }
+
+ ret = ustctl_create_stream(app->sock, ua_chan->obj, &stream->obj);
+ if (ret < 0) {
+ lttng_fd_put(LTTNG_FD_APPS, 2);
+ /* Indicates that there is no more stream for that channel. */
+ if (ret != -LTTNG_UST_ERR_NOENT) {
+ ERR("UST create metadata stream failed (ret: %d)", ret);
+ }
+ goto error;
+ }
+
+ /* Set stream handle with the returned value. */
+ stream->handle = stream->obj->handle;
+
+error:
+ health_code_update(&health_thread_cmd);
+ return ret;
+}
+
/*
* Create the specified channel onto the UST tracer for a UST session.
*/
/* Open UST metadata stream */
if (ua_sess->metadata->stream_obj == NULL) {
- ret = create_ust_stream(app, ua_sess);
+ ret = create_ust_metadata_stream(app, ua_sess);
if (ret < 0) {
goto error;
}
struct lttng_ht_iter iter;
struct ust_app_session *ua_sess;
struct ust_app_channel *ua_chan;
- struct ltt_ust_stream *ustream;
+ struct ust_app_stream *ustream;
struct consumer_socket *socket;
DBG("Starting tracing for ust app pid %d", app->pid);
/* Create all streams */
while (1) {
/* Create UST stream */
- ustream = zmalloc(sizeof(*ustream));
+ ustream = alloc_ust_app_stream();
if (ustream == NULL) {
- PERROR("zmalloc ust stream");
- goto error_rcu_unlock;
- }
-
- /* We are going to receive 2 fds, we need to reserve them. */
- ret = lttng_fd_get(LTTNG_FD_APPS, 2);
- if (ret < 0) {
- ERR("Exhausted number of available FD upon stream create");
- free(ustream);
goto error_rcu_unlock;
}
health_code_update(&health_thread_cmd);
- ret = ustctl_create_stream(app->sock, ua_chan->obj,
- &ustream->obj);
+ ret = create_ust_stream(app, ua_chan, ustream);
if (ret < 0) {
- /* Got all streams */
- lttng_fd_put(LTTNG_FD_APPS, 2);
+ /* Free unused memory after this point. */
free(ustream);
+ if (ret == -LTTNG_UST_ERR_NOENT) {
+ /* Got all streams. Continue normal execution. */
+ break;
+ }
+ /* Error at this point. Stop everything. */
ret = LTTNG_ERR_UST_STREAM_FAIL;
- break;
+ goto error_rcu_unlock;
}
- ustream->handle = ustream->obj->handle;
health_code_update(&health_thread_cmd);
- /* Order is important */
+ /* Order is important this is why a list is used. */
cds_list_add_tail(&ustream->list, &ua_chan->streams.head);
- ret = snprintf(ustream->name, sizeof(ustream->name), "%s_%u",
- ua_chan->name, ua_chan->streams.count);
ua_chan->streams.count++;
- if (ret < 0) {
- PERROR("asprintf UST create stream");
- /*
- * XXX what should we do here with the
- * stream ?
- */
- continue;
- }
+
DBG2("UST stream %d ready (handle: %d)", ua_chan->streams.count,
ustream->handle);
}