static int send_consumer_relayd_sockets(int domain,
struct ltt_session *session, struct consumer_output *consumer, int fd)
{
- int ret;
+ int ret = LTTNG_OK;
assert(session);
assert(consumer);
assert(socket->fd >= 0);
pthread_mutex_lock(socket->lock);
- send_consumer_relayd_sockets(LTTNG_DOMAIN_UST, session,
+ ret = send_consumer_relayd_sockets(LTTNG_DOMAIN_UST, session,
usess->consumer, socket->fd);
pthread_mutex_unlock(socket->lock);
if (ret != LTTNG_OK) {
assert(socket->fd >= 0);
pthread_mutex_lock(socket->lock);
- send_consumer_relayd_sockets(LTTNG_DOMAIN_KERNEL, session,
+ ret = send_consumer_relayd_sockets(LTTNG_DOMAIN_KERNEL, session,
ksess->consumer, socket->fd);
pthread_mutex_unlock(socket->lock);
if (ret != LTTNG_OK) {
* Command LTTNG_ADD_CONTEXT processed by the client thread.
*/
int cmd_add_context(struct ltt_session *session, int domain,
- char *channel_name, char *event_name, struct lttng_event_context *ctx)
+ char *channel_name, char *event_name, struct lttng_event_context *ctx,
+ int kwpipe)
{
int ret;
switch (domain) {
case LTTNG_DOMAIN_KERNEL:
+ assert(session->kernel_session);
+
+ if (session->kernel_session->channel_count == 0) {
+ /* Create default channel */
+ ret = channel_kernel_create(session->kernel_session, NULL, kwpipe);
+ if (ret != LTTNG_OK) {
+ goto error;
+ }
+ }
+
/* Add kernel context to kernel tracer */
ret = context_kernel_add(session->kernel_session, ctx,
event_name, channel_name);
case LTTNG_DOMAIN_UST:
{
struct ltt_ust_session *usess = session->ust_session;
-
assert(usess);
+ unsigned int chan_count =
+ lttng_ht_get_count(usess->domain_global.channels);
+ if (chan_count == 0) {
+ struct lttng_channel *attr;
+ /* Create default channel */
+ attr = channel_new_default_attr(domain);
+ if (attr == NULL) {
+ ret = LTTNG_ERR_FATAL;
+ goto error;
+ }
+
+ ret = channel_ust_create(usess, domain, attr);
+ if (ret != LTTNG_OK) {
+ free(attr);
+ goto error;
+ }
+ free(attr);
+ }
+
+
ret = context_ust_add(usess, domain, ctx, event_name, channel_name);
if (ret != LTTNG_OK) {
goto error;
goto error;
}
- if (!session->start_consumer) {
- ret = LTTNG_ERR_NO_CONSUMER;
- goto error;
- }
-
/*
* This case switch makes sure the domain session has a temporary consumer
* so the URL can be set.
goto error;
}
- if (!session->start_consumer) {
- ret = LTTNG_ERR_NO_CONSUMER;
- goto error;
- }
-
switch (domain) {
case 0:
assert(session->consumer);
break;
}
- /* Append default kernel trace dir to subdir */
- strncat(ksess->consumer->subdir, DEFAULT_KERNEL_TRACE_DIR,
- sizeof(ksess->consumer->subdir) -
- strlen(ksess->consumer->subdir) - 1);
-
/*
* @session-lock
* This is race free for now since the session lock is acquired before
* is valid.
*/
rcu_read_lock();
+ /* Destroy current consumer. We are about to replace it */
consumer_destroy_output(ksess->consumer);
rcu_read_unlock();
ksess->consumer = consumer;
break;
}
- /* Append default kernel trace dir to subdir */
- strncat(usess->consumer->subdir, DEFAULT_UST_TRACE_DIR,
- sizeof(usess->consumer->subdir) -
- strlen(usess->consumer->subdir) - 1);
-
/*
* @session-lock
* This is race free for now since the session lock is acquired before
* is valid.
*/
rcu_read_lock();
+ /* Destroy current consumer. We are about to replace it */
consumer_destroy_output(usess->consumer);
rcu_read_unlock();
usess->consumer = consumer;
break;
}
+ session->start_consumer = 1;
+
/* Enable it */
if (consumer) {
consumer->enabled = 1;
return ret;
}
+/*
+ * Command LTTNG_DATA_PENDING returning 0 if the data is NOT pending meaning
+ * ready for trace analysis (or anykind of reader) or else 1 for pending data.
+ */
+int cmd_data_pending(struct ltt_session *session)
+{
+ int ret;
+ struct ltt_kernel_session *ksess = session->kernel_session;
+ struct ltt_ust_session *usess = session->ust_session;
+
+ assert(session);
+
+ /* Session MUST be stopped to ask for data availability. */
+ if (session->enabled) {
+ ret = LTTNG_ERR_SESSION_STARTED;
+ goto error;
+ }
+
+ if (ksess && ksess->consumer) {
+ ret = consumer_is_data_pending(ksess->id, ksess->consumer);
+ if (ret == 1) {
+ /* Data is still being extracted for the kernel. */
+ goto error;
+ }
+ }
+
+ if (usess && usess->consumer) {
+ ret = consumer_is_data_pending(usess->id, usess->consumer);
+ if (ret == 1) {
+ /* Data is still being extracted for the kernel. */
+ goto error;
+ }
+ }
+
+ /* Data is ready to be read by a viewer */
+ ret = 0;
+
+error:
+ return ret;
+}
+
/*
* Init command subsystem.
*/