X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fkernel-consumer.c;h=6244963cc688746b575719ee09fad3e217db5025;hp=49adabb72336b11d0255e3a1f1d2462b0a70601a;hb=d42266a417afa6e8ca6024590b8282002aebca07;hpb=5b0e3ccb033e701a4c4005d6859757652ca8897c diff --git a/src/bin/lttng-sessiond/kernel-consumer.c b/src/bin/lttng-sessiond/kernel-consumer.c index 49adabb72..6244963cc 100644 --- a/src/bin/lttng-sessiond/kernel-consumer.c +++ b/src/bin/lttng-sessiond/kernel-consumer.c @@ -1,18 +1,8 @@ /* - * Copyright (C) 2012 - David Goulet + * Copyright (C) 2012 David Goulet * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License, version 2 only, as - * published by the Free Software Foundation. + * SPDX-License-Identifier: GPL-2.0-only * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _LGPL_SOURCE @@ -34,7 +24,7 @@ #include "lttng-sessiond.h" static char *create_channel_path(struct consumer_output *consumer, - uid_t uid, gid_t gid) + size_t *consumer_path_offset) { int ret; char tmp_path[PATH_MAX]; @@ -43,42 +33,24 @@ static char *create_channel_path(struct consumer_output *consumer, assert(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%s", - consumer->dst.session_root_path, - consumer->chunk_path, - consumer->subdir); - if (ret < 0) { - PERROR("snprintf kernel channel path"); - goto error; - } else if (ret >= sizeof(tmp_path)) { - ERR("Kernel channel path exceeds the maximal allowed length of of %zu bytes (%i bytes required) with path \"%s%s%s\"", - sizeof(tmp_path), ret, - consumer->dst.session_root_path, - consumer->chunk_path, - consumer->subdir); - goto error; - } - pathname = lttng_strndup(tmp_path, sizeof(tmp_path)); + if (consumer->type == CONSUMER_DST_LOCAL || + (consumer->type == CONSUMER_DST_NET && + consumer->relay_major_version == 2 && + consumer->relay_minor_version >= 11)) { + pathname = strdup(consumer->domain_subdir); if (!pathname) { - PERROR("lttng_strndup"); + PERROR("Failed to copy domain subdirectory string %s", + consumer->domain_subdir); goto error; } - - /* Create directory */ - ret = run_as_mkdir_recursive(pathname, S_IRWXU | S_IRWXG, uid, gid); - if (ret < 0) { - if (errno != EEXIST) { - ERR("Trace directory creation error"); - goto error; - } - } - DBG3("Kernel local consumer tracefile path: %s", pathname); + *consumer_path_offset = strlen(consumer->domain_subdir); + DBG3("Kernel local consumer trace path relative to current trace chunk: \"%s\"", + pathname); } else { + /* Network output, relayd < 2.11. */ ret = snprintf(tmp_path, sizeof(tmp_path), "%s%s", consumer->dst.net.base_dir, - consumer->subdir); + consumer->domain_subdir); if (ret < 0) { PERROR("snprintf kernel metadata path"); goto error; @@ -86,7 +58,7 @@ static char *create_channel_path(struct consumer_output *consumer, ERR("Kernel channel path exceeds the maximal allowed length of of %zu bytes (%i bytes required) with path \"%s%s\"", sizeof(tmp_path), ret, consumer->dst.net.base_dir, - consumer->subdir); + consumer->domain_subdir); goto error; } pathname = lttng_strndup(tmp_path, sizeof(tmp_path)); @@ -94,6 +66,7 @@ static char *create_channel_path(struct consumer_output *consumer, PERROR("lttng_strndup"); goto error; } + *consumer_path_offset = 0; DBG3("Kernel network consumer subdir path: %s", pathname); } @@ -107,18 +80,21 @@ error: /* * Sending a single channel to the consumer with command ADD_CHANNEL. */ +static int kernel_consumer_add_channel(struct consumer_socket *sock, struct ltt_kernel_channel *channel, struct ltt_kernel_session *ksession, unsigned int monitor) { int ret; - char *pathname; + char *pathname = NULL; struct lttcomm_consumer_msg lkm; struct consumer_output *consumer; enum lttng_error_code status; - struct ltt_session *session; + struct ltt_session *session = NULL; struct lttng_channel_extended *channel_attr_extended; + bool is_local_trace; + size_t consumer_path_offset = 0; /* Safety net */ assert(channel); @@ -131,24 +107,44 @@ int kernel_consumer_add_channel(struct consumer_socket *sock, DBG("Kernel consumer adding channel %s to kernel consumer", channel->channel->name); + is_local_trace = consumer->net_seq_index == -1ULL; - if (monitor) { - pathname = create_channel_path(consumer, ksession->uid, - ksession->gid); - } else { - /* Empty path. */ - pathname = strdup(""); - } + pathname = create_channel_path(consumer, &consumer_path_offset); if (!pathname) { ret = -1; goto error; } + if (is_local_trace && ksession->current_trace_chunk) { + enum lttng_trace_chunk_status chunk_status; + char *pathname_index; + + ret = asprintf(&pathname_index, "%s/" DEFAULT_INDEX_DIR, + pathname); + if (ret < 0) { + ERR("Failed to format channel index directory"); + ret = -1; + goto error; + } + + /* + * Create the index subdirectory which will take care + * of implicitly creating the channel's path. + */ + chunk_status = lttng_trace_chunk_create_subdirectory( + ksession->current_trace_chunk, pathname_index); + free(pathname_index); + if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { + ret = -1; + goto error; + } + } + /* Prep channel message structure */ consumer_init_add_channel_comm_msg(&lkm, channel->key, ksession->id, - pathname, + &pathname[consumer_path_offset], ksession->uid, ksession->gid, consumer->net_seq_index, @@ -160,7 +156,9 @@ int kernel_consumer_add_channel(struct consumer_socket *sock, channel->channel->attr.tracefile_count, monitor, channel->channel->attr.live_timer_interval, - channel_attr_extended->monitor_timer_interval); + ksession->is_live_session, + channel_attr_extended->monitor_timer_interval, + ksession->current_trace_chunk); health_code_update(); @@ -173,6 +171,8 @@ int kernel_consumer_add_channel(struct consumer_socket *sock, rcu_read_lock(); session = session_find_by_id(ksession->id); assert(session); + assert(pthread_mutex_trylock(&session->lock)); + assert(session_trylock_list()); status = notification_thread_command_add_channel( notification_thread_handle, session->name, @@ -189,6 +189,9 @@ int kernel_consumer_add_channel(struct consumer_socket *sock, channel->published_to_notification_thread = true; error: + if (session) { + session_put(session); + } free(pathname); return ret; } @@ -199,48 +202,44 @@ error: * The consumer socket lock must be held by the caller. */ int kernel_consumer_add_metadata(struct consumer_socket *sock, - struct ltt_kernel_session *session, unsigned int monitor) + struct ltt_kernel_session *ksession, unsigned int monitor) { int ret; - char *pathname; struct lttcomm_consumer_msg lkm; struct consumer_output *consumer; + rcu_read_lock(); + /* Safety net */ - assert(session); - assert(session->consumer); + assert(ksession); + assert(ksession->consumer); assert(sock); - DBG("Sending metadata %d to kernel consumer", session->metadata_stream_fd); + DBG("Sending metadata %d to kernel consumer", + ksession->metadata_stream_fd); /* Get consumer output pointer */ - consumer = session->consumer; - - if (monitor) { - pathname = create_channel_path(consumer, session->uid, session->gid); - } else { - /* Empty path. */ - pathname = strdup(""); - } - if (!pathname) { - ret = -1; - goto error; - } + consumer = ksession->consumer; /* Prep channel message structure */ consumer_init_add_channel_comm_msg(&lkm, - session->metadata->key, - session->id, - pathname, - session->uid, - session->gid, + ksession->metadata->key, + ksession->id, + "", + ksession->uid, + ksession->gid, consumer->net_seq_index, - DEFAULT_METADATA_NAME, + ksession->metadata->conf->name, 1, - DEFAULT_KERNEL_CHANNEL_OUTPUT, + ksession->metadata->conf->attr.output, CONSUMER_CHANNEL_TYPE_METADATA, - 0, 0, - monitor, 0, 0); + ksession->metadata->conf->attr.tracefile_size, + ksession->metadata->conf->attr.tracefile_count, + monitor, + ksession->metadata->conf->attr.live_timer_interval, + ksession->is_live_session, + 0, + ksession->current_trace_chunk); health_code_update(); @@ -252,17 +251,16 @@ int kernel_consumer_add_metadata(struct consumer_socket *sock, health_code_update(); /* Prep stream message structure */ - consumer_init_stream_comm_msg(&lkm, - LTTNG_CONSUMER_ADD_STREAM, - session->metadata->key, - session->metadata_stream_fd, - 0); /* CPU: 0 for metadata. */ + consumer_init_add_stream_comm_msg(&lkm, + ksession->metadata->key, + ksession->metadata_stream_fd, + 0 /* CPU: 0 for metadata. */); health_code_update(); /* Send stream and file descriptor */ ret = consumer_send_stream(sock, consumer, &lkm, - &session->metadata_stream_fd, 1); + &ksession->metadata_stream_fd, 1); if (ret < 0) { goto error; } @@ -270,7 +268,7 @@ int kernel_consumer_add_metadata(struct consumer_socket *sock, health_code_update(); error: - free(pathname); + rcu_read_unlock(); return ret; } @@ -279,7 +277,8 @@ error: */ static int kernel_consumer_add_stream(struct consumer_socket *sock, - struct ltt_kernel_channel *channel, struct ltt_kernel_stream *stream, + struct ltt_kernel_channel *channel, + struct ltt_kernel_stream *stream, struct ltt_kernel_session *session, unsigned int monitor) { int ret; @@ -299,8 +298,7 @@ int kernel_consumer_add_stream(struct consumer_socket *sock, consumer = session->consumer; /* Prep stream consumer message */ - consumer_init_stream_comm_msg(&lkm, - LTTNG_CONSUMER_ADD_STREAM, + consumer_init_add_stream_comm_msg(&lkm, channel->key, stream->fd, stream->cpu); @@ -359,7 +357,7 @@ error: * The consumer socket lock must be held by the caller. */ int kernel_consumer_send_channel_streams(struct consumer_socket *sock, - struct ltt_kernel_channel *channel, struct ltt_kernel_session *session, + struct ltt_kernel_channel *channel, struct ltt_kernel_session *ksession, unsigned int monitor) { int ret = LTTNG_OK; @@ -367,12 +365,14 @@ int kernel_consumer_send_channel_streams(struct consumer_socket *sock, /* Safety net */ assert(channel); - assert(session); - assert(session->consumer); + assert(ksession); + assert(ksession->consumer); assert(sock); + rcu_read_lock(); + /* Bail out if consumer is disabled */ - if (!session->consumer->enabled) { + if (!ksession->consumer->enabled) { ret = LTTNG_OK; goto error; } @@ -381,7 +381,7 @@ int kernel_consumer_send_channel_streams(struct consumer_socket *sock, channel->channel->name); if (!channel->sent_to_consumer) { - ret = kernel_consumer_add_channel(sock, channel, session, monitor); + ret = kernel_consumer_add_channel(sock, channel, ksession, monitor); if (ret < 0) { goto error; } @@ -395,8 +395,8 @@ int kernel_consumer_send_channel_streams(struct consumer_socket *sock, } /* Add stream on the kernel consumer side. */ - ret = kernel_consumer_add_stream(sock, channel, stream, session, - monitor); + ret = kernel_consumer_add_stream(sock, channel, stream, + ksession, monitor); if (ret < 0) { goto error; } @@ -404,6 +404,7 @@ int kernel_consumer_send_channel_streams(struct consumer_socket *sock, } error: + rcu_read_unlock(); return ret; }