struct ltt_session *session;
assert(name);
-
- /* No URIs is not possible. */
- if (uris == NULL) {
- ret = LTTNG_ERR_SESSION_FAIL;
- goto session_error;
- }
+ assert(creds);
/*
* Verify if the session already exist
goto consumer_error;
}
- ret = cmd_set_consumer_uri(0, session, nb_uri, uris);
- if (ret != LTTNG_OK) {
- goto consumer_error;
+ if (uris) {
+ ret = cmd_set_consumer_uri(0, session, nb_uri, uris);
+ if (ret != LTTNG_OK) {
+ goto consumer_error;
+ }
+ session->output_traces = 1;
+ } else {
+ session->output_traces = 0;
+ DBG2("Session %s created with no output", session->name);
}
session->consumer->enabled = 1;
unsigned char *uuid,
uint32_t chan_id,
uint64_t tracefile_size,
- uint64_t tracefile_count)
+ uint64_t tracefile_count,
+ unsigned int monitor)
{
assert(msg);
msg->u.ask_channel.chan_id = chan_id;
msg->u.ask_channel.tracefile_size = tracefile_size;
msg->u.ask_channel.tracefile_count = tracefile_count;
+ msg->u.ask_channel.monitor = monitor;
memcpy(msg->u.ask_channel.uuid, uuid, sizeof(msg->u.ask_channel.uuid));
enum lttng_event_output output,
int type,
uint64_t tracefile_size,
- uint64_t tracefile_count)
+ uint64_t tracefile_count,
+ unsigned int monitor)
{
assert(msg);
msg->u.channel.type = type;
msg->u.channel.tracefile_size = tracefile_size;
msg->u.channel.tracefile_count = tracefile_count;
+ msg->u.channel.monitor = monitor;
strncpy(msg->u.channel.pathname, pathname,
sizeof(msg->u.channel.pathname));
unsigned char *uuid,
uint32_t chan_id,
uint64_t tracefile_size,
- uint64_t tracefile_count);
+ uint64_t tracefile_count,
+ unsigned int monitor);
void consumer_init_stream_comm_msg(struct lttcomm_consumer_msg *msg,
enum lttng_consumer_command cmd,
uint64_t channel_key,
enum lttng_event_output output,
int type,
uint64_t tracefile_size,
- uint64_t tracefile_count);
+ uint64_t tracefile_count,
+ unsigned int monitor);
int consumer_is_data_pending(uint64_t session_id,
struct consumer_output *consumer);
int consumer_close_metadata(struct consumer_socket *socket,
#include "health.h"
#include "kernel-consumer.h"
-/*
- * Sending a single channel to the consumer with command ADD_CHANNEL.
- */
-int kernel_consumer_add_channel(struct consumer_socket *sock,
- struct ltt_kernel_channel *channel, struct ltt_kernel_session *session)
+static char *create_channel_path(struct consumer_output *consumer,
+ uid_t uid, gid_t gid)
{
int ret;
char tmp_path[PATH_MAX];
- const char *pathname;
- struct lttcomm_consumer_msg lkm;
- struct consumer_output *consumer;
+ char *pathname = NULL;
- /* Safety net */
- assert(channel);
- assert(session);
- assert(session->consumer);
-
- consumer = session->consumer;
-
- DBG("Kernel consumer adding channel %s to kernel consumer",
- channel->channel->name);
+ assert(consumer);
/* Get the right path name destination */
if (consumer->type == CONSUMER_DST_LOCAL) {
ret = snprintf(tmp_path, sizeof(tmp_path), "%s%s",
consumer->dst.trace_path, consumer->subdir);
if (ret < 0) {
- PERROR("snprintf metadata path");
+ PERROR("snprintf kernel channel path");
goto error;
}
- pathname = tmp_path;
+ pathname = strndup(tmp_path, sizeof(tmp_path));
/* Create directory */
- ret = run_as_mkdir_recursive(pathname, S_IRWXU | S_IRWXG,
- session->uid, session->gid);
+ ret = run_as_mkdir_recursive(pathname, S_IRWXU | S_IRWXG, uid, gid);
if (ret < 0) {
if (ret != -EEXIST) {
ERR("Trace directory creation error");
} else {
ret = snprintf(tmp_path, sizeof(tmp_path), "%s", consumer->subdir);
if (ret < 0) {
- PERROR("snprintf metadata path");
+ PERROR("snprintf kernel metadata path");
goto error;
}
- pathname = tmp_path;
+ pathname = strndup(tmp_path, sizeof(tmp_path));
DBG3("Kernel network consumer subdir path: %s", pathname);
}
+ return pathname;
+
+error:
+ free(pathname);
+ return NULL;
+}
+
+/*
+ * Sending a single channel to the consumer with command ADD_CHANNEL.
+ */
+int kernel_consumer_add_channel(struct consumer_socket *sock,
+ struct ltt_kernel_channel *channel, struct ltt_kernel_session *session,
+ unsigned int monitor)
+{
+ int ret;
+ char *pathname;
+ struct lttcomm_consumer_msg lkm;
+ struct consumer_output *consumer;
+
+ /* Safety net */
+ assert(channel);
+ assert(session);
+ assert(session->consumer);
+
+ consumer = session->consumer;
+
+ DBG("Kernel consumer adding channel %s to kernel consumer",
+ channel->channel->name);
+
+ if (monitor) {
+ pathname = create_channel_path(consumer, session->uid, session->gid);
+ if (!pathname) {
+ ret = -1;
+ goto error;
+ }
+ } else {
+ /* Empty path. */
+ pathname = "";
+ }
+
/* Prep channel message structure */
consumer_init_channel_comm_msg(&lkm,
LTTNG_CONSUMER_ADD_CHANNEL,
channel->channel->attr.output,
CONSUMER_CHANNEL_TYPE_DATA,
channel->channel->attr.tracefile_size,
- channel->channel->attr.tracefile_count);
+ channel->channel->attr.tracefile_count,
+ monitor);
health_code_update();
* Sending metadata to the consumer with command ADD_CHANNEL and ADD_STREAM.
*/
int kernel_consumer_add_metadata(struct consumer_socket *sock,
- struct ltt_kernel_session *session, int no_monitor)
+ struct ltt_kernel_session *session, unsigned int monitor)
{
int ret;
- char tmp_path[PATH_MAX];
- const char *pathname;
+ char *pathname;
struct lttcomm_consumer_msg lkm;
struct consumer_output *consumer;
/* Get consumer output pointer */
consumer = session->consumer;
- /* Get the right path name destination */
- if (consumer->type == CONSUMER_DST_LOCAL) {
- /* Set application path to the destination path */
- ret = snprintf(tmp_path, sizeof(tmp_path), "%s%s",
- consumer->dst.trace_path, consumer->subdir);
- if (ret < 0) {
- PERROR("snprintf metadata path");
+ if (monitor) {
+ pathname = create_channel_path(consumer, session->uid, session->gid);
+ if (!pathname) {
+ ret = -1;
goto error;
}
- pathname = tmp_path;
-
- /* Create directory */
- ret = run_as_mkdir_recursive(pathname, S_IRWXU | S_IRWXG,
- session->uid, session->gid);
- if (ret < 0) {
- if (ret != -EEXIST) {
- ERR("Trace directory creation error");
- goto error;
- }
- }
- DBG3("Kernel local consumer tracefile path: %s", pathname);
} else {
- ret = snprintf(tmp_path, sizeof(tmp_path), "%s", consumer->subdir);
- if (ret < 0) {
- PERROR("snprintf metadata path");
- goto error;
- }
- pathname = tmp_path;
- DBG3("Kernel network consumer subdir path: %s", pathname);
+ /* Empty path. */
+ pathname = "";
}
/* Prep channel message structure */
1,
DEFAULT_KERNEL_CHANNEL_OUTPUT,
CONSUMER_CHANNEL_TYPE_METADATA,
- 0, 0);
+ 0, 0,
+ monitor);
health_code_update();
*/
int kernel_consumer_add_stream(struct consumer_socket *sock,
struct ltt_kernel_channel *channel, struct ltt_kernel_stream *stream,
- struct ltt_kernel_session *session)
+ struct ltt_kernel_session *session, unsigned int monitor)
{
int ret;
struct lttcomm_consumer_msg lkm;
* Send all stream fds of kernel channel to the consumer.
*/
int kernel_consumer_send_channel_stream(struct consumer_socket *sock,
- struct ltt_kernel_channel *channel, struct ltt_kernel_session *session)
+ struct ltt_kernel_channel *channel, struct ltt_kernel_session *session,
+ unsigned int monitor)
{
int ret;
struct ltt_kernel_stream *stream;
DBG("Sending streams of channel %s to kernel consumer",
channel->channel->name);
- ret = kernel_consumer_add_channel(sock, channel, session);
+ ret = kernel_consumer_add_channel(sock, channel, session, monitor);
if (ret < 0) {
goto error;
}
}
/* Add stream on the kernel consumer side. */
- ret = kernel_consumer_add_stream(sock, channel, stream, session);
+ ret = kernel_consumer_add_stream(sock, channel, stream, session,
+ monitor);
if (ret < 0) {
goto error;
}
int kernel_consumer_send_session(struct consumer_socket *sock,
struct ltt_kernel_session *session)
{
- int ret;
+ int ret, monitor = 0;
struct ltt_kernel_channel *chan;
/* Safety net */
goto error;
}
+ /* Don't monitor the streams on the consumer if in flight recorder. */
+ if (session->output_traces) {
+ monitor = 1;
+ }
+
DBG("Sending session stream to kernel consumer");
if (session->metadata_stream_fd >= 0) {
- ret = kernel_consumer_add_metadata(sock, session, 0);
+ ret = kernel_consumer_add_metadata(sock, session, monitor);
if (ret < 0) {
goto error;
}
/* Send channel and streams of it */
cds_list_for_each_entry(chan, &session->channel_list.head, list) {
- ret = kernel_consumer_send_channel_stream(sock, chan, session);
+ ret = kernel_consumer_send_channel_stream(sock, chan, session,
+ monitor);
if (ret < 0) {
goto error;
}
#include "trace-kernel.h"
int kernel_consumer_send_channel_stream(struct consumer_socket *sock,
- struct ltt_kernel_channel *channel, struct ltt_kernel_session *session);
+ struct ltt_kernel_channel *channel, struct ltt_kernel_session *session,
+ unsigned int monitor);
int kernel_consumer_send_session(struct consumer_socket *sock,
struct ltt_kernel_session *session);
int kernel_consumer_add_stream(struct consumer_socket *sock,
struct ltt_kernel_channel *channel, struct ltt_kernel_stream *stream,
- struct ltt_kernel_session *session);
+ struct ltt_kernel_session *session, unsigned int monitor);
int kernel_consumer_add_metadata(struct consumer_socket *sock,
- struct ltt_kernel_session *session, int no_monitor);
+ struct ltt_kernel_session *session, unsigned int monitor);
int kernel_consumer_add_channel(struct consumer_socket *sock,
- struct ltt_kernel_channel *channel, struct ltt_kernel_session *session);
+ struct ltt_kernel_channel *channel, struct ltt_kernel_session *session,
+ unsigned int monitor);
pthread_mutex_lock(socket->lock);
ret = kernel_consumer_send_channel_stream(socket,
- channel, ksess);
+ channel, ksess,
+ session->output_traces ? 1 : 0);
pthread_mutex_unlock(socket->lock);
if (ret < 0) {
rcu_read_unlock();
lus->uid = session->uid;
lus->gid = session->gid;
-
+ lus->output_traces = session->output_traces;
session->ust_session = lus;
/* Copy session output to the newly created UST session */
session->kernel_session->uid = session->uid;
session->kernel_session->gid = session->gid;
+ session->kernel_session->output_traces = session->output_traces;
return LTTNG_OK;
unsigned int id;
/* Session is started and active */
unsigned int started;
+ /* Tell or not if the session has to output the traces. */
+ unsigned int output_traces;
};
/*
uint64_t next_channel_id;
/* Once this value reaches UINT32_MAX, no more id can be allocated. */
uint64_t used_channel_id;
+ /* Tell or not if the session has to output the traces. */
+ unsigned int output_traces;
};
/*
ua_sess->bits_per_long = app->bits_per_long;
/* There is only one consumer object per session possible. */
ua_sess->consumer = usess->consumer;
+ ua_sess->output_traces = usess->output_traces;
switch (ua_sess->buffer_type) {
case LTTNG_BUFFER_PER_PID:
uint32_t bits_per_long;
/* For delayed reclaim */
struct rcu_head rcu_head;
+ /* If the channel's streams have to be outputed or not. */
+ unsigned int output_traces;
};
/*
registry->uuid,
chan_id,
ua_chan->tracefile_size,
- ua_chan->tracefile_count);
+ ua_chan->tracefile_count,
+ ua_sess->output_traces);
health_code_update();
static char *opt_ctrl_url;
static char *opt_data_url;
static int opt_no_consumer;
+static int opt_no_output;
static int opt_disable_consumer;
enum {
{"set-url", 'U', POPT_ARG_STRING, &opt_url, 0, 0, 0},
{"ctrl-url", 'C', POPT_ARG_STRING, &opt_ctrl_url, 0, 0, 0},
{"data-url", 'D', POPT_ARG_STRING, &opt_data_url, 0, 0, 0},
- {"no-consumer", 0, POPT_ARG_VAL, &opt_no_consumer, 1, 0, 0},
+ {"no-output", 0, POPT_ARG_VAL, &opt_no_output, 1, 0, 0},
+ {"no-consumer", 0, POPT_ARG_VAL, &opt_no_consumer, 1, 0, 0},
{"disable-consumer", 0, POPT_ARG_VAL, &opt_disable_consumer, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0}
};
fprintf(ofp, " -h, --help Show this help\n");
fprintf(ofp, " --list-options Simple listing of options\n");
fprintf(ofp, " -o, --output PATH Specify output path for traces\n");
+ fprintf(ofp, " --no-output Traces will not be outputed\n");
fprintf(ofp, "\n");
fprintf(ofp, "Extended Options:\n");
fprintf(ofp, "\n");
} else if (opt_url) { /* Handling URL (-U opt) */
url = opt_url;
print_str_url = url;
- } else {
+ } else if (!opt_no_output) {
/* Auto output path */
alloc_path = utils_get_home_dir();
if (alloc_path == NULL) {
if (!opt_data_url && !opt_ctrl_url) {
print_str_url = alloc_url + strlen("file://");
}
+ } else {
+ /* No output means --no-output. */
+ url = NULL;
}
if ((!opt_ctrl_url && opt_data_url) || (opt_ctrl_url && !opt_data_url)) {
}
if (opt_no_consumer) {
- MSG("The option --no-consumer is obsolete.");
+ MSG("The option --no-consumer is obsolete. Use --no-output now.");
ret = CMD_WARNING;
goto end;
}
uint64_t relayd_id,
enum lttng_event_output output,
uint64_t tracefile_size,
- uint64_t tracefile_count)
+ uint64_t tracefile_count,
+ unsigned int monitor)
{
struct lttng_consumer_channel *channel;
channel->output = output;
channel->tracefile_size = tracefile_size;
channel->tracefile_count = tracefile_count;
+ channel->monitor = monitor;
strncpy(channel->pathname, pathname, sizeof(channel->pathname));
channel->pathname[sizeof(channel->pathname) - 1] = '\0';
/* On-disk circular buffer */
uint64_t tracefile_size;
uint64_t tracefile_count;
+ /*
+ * Monitor or not the streams of this channel meaning this indicates if the
+ * streams should be sent to the data/metadata thread or added to the no
+ * monitor list of the channel.
+ */
+ unsigned int monitor;
};
/*
uint64_t relayd_id,
enum lttng_event_output output,
uint64_t tracefile_size,
- uint64_t tracefile_count);
+ uint64_t tracefile_count,
+ unsigned int monitor);
void consumer_del_stream(struct lttng_consumer_stream *stream,
struct lttng_ht *ht);
void consumer_del_metadata_stream(struct lttng_consumer_stream *stream,
msg.u.channel.name, msg.u.channel.uid, msg.u.channel.gid,
msg.u.channel.relayd_id, msg.u.channel.output,
msg.u.channel.tracefile_size,
- msg.u.channel.tracefile_count);
+ msg.u.channel.tracefile_count,
+ msg.u.channel.monitor);
if (new_channel == NULL) {
lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_OUTFD_ERROR);
goto end_nosignal;
}
}
- if (msg.u.stream.no_monitor) {
+ /* Do not monitor this stream. */
+ if (!channel->monitor) {
DBG("Kernel consumer add stream %s in no monitor mode with"
"relayd id %" PRIu64, new_stream->name,
new_stream->relayd_stream_id);
assert(stream);
- /* Don't create anything if this is set for streaming. */
- if (stream->net_seq_idx == (uint64_t) -1ULL) {
+ /*
+ * Don't create anything if this is set for streaming or should not be
+ * monitored.
+ */
+ if (stream->net_seq_idx == (uint64_t) -1ULL && stream->chan->monitor) {
ret = utils_create_stream_file(stream->chan->pathname, stream->name,
stream->chan->tracefile_size, stream->tracefile_count_current,
stream->uid, stream->gid);
int type; /* Per cpu or metadata. */
uint64_t tracefile_size; /* bytes */
uint32_t tracefile_count; /* number of tracefiles */
+ /* If the channel's streams have to be monitored or not. */
+ uint32_t monitor;
} LTTNG_PACKED channel; /* Only used by Kernel. */
struct {
uint64_t stream_key;
uint32_t chan_id; /* Channel ID on the tracer side. */
uint64_t tracefile_size; /* bytes */
uint32_t tracefile_count; /* number of tracefiles */
+ /* Tells the consumer if the stream should be or not monitored. */
+ uint32_t monitor;
} LTTNG_PACKED ask_channel;
struct {
uint64_t key;
static struct lttng_consumer_channel *allocate_channel(uint64_t session_id,
const char *pathname, const char *name, uid_t uid, gid_t gid,
int relayd_id, uint64_t key, enum lttng_event_output output,
- uint64_t tracefile_size, uint64_t tracefile_count)
+ uint64_t tracefile_size, uint64_t tracefile_count,
+ unsigned int monitor)
{
assert(pathname);
assert(name);
return consumer_allocate_channel(key, session_id, pathname, name, uid, gid,
- relayd_id, output, tracefile_size, tracefile_count);
+ relayd_id, output, tracefile_size, tracefile_count, monitor);
}
/*
msg.u.ask_channel.relayd_id, msg.u.ask_channel.key,
(enum lttng_event_output) msg.u.ask_channel.output,
msg.u.ask_channel.tracefile_size,
- msg.u.ask_channel.tracefile_count);
+ msg.u.ask_channel.tracefile_count,
+ msg.u.ask_channel.monitor);
if (!channel) {
goto end_channel_error;
}
struct lttcomm_session_msg lsm;
struct lttng_uri *uris = NULL;
- if (name == NULL || datetime == NULL || url == NULL) {
+ if (name == NULL || datetime == NULL) {
return -LTTNG_ERR_INVALID;
}