2 * Copyright (C) 2012 - David Goulet <dgoulet@efficios.com>
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License, version 2 only, as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 51
15 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include <common/common.h>
25 #include <common/defaults.h>
26 #include <common/compat/string.h>
29 #include "health-sessiond.h"
30 #include "kernel-consumer.h"
31 #include "notification-thread-commands.h"
33 #include "lttng-sessiond.h"
35 static char *create_channel_path(struct consumer_output
*consumer
,
39 char tmp_path
[PATH_MAX
];
40 char *pathname
= NULL
;
44 /* Get the right path name destination */
45 if (consumer
->type
== CONSUMER_DST_LOCAL
) {
46 /* Set application path to the destination path */
47 ret
= snprintf(tmp_path
, sizeof(tmp_path
), "%s%s",
48 consumer
->dst
.trace_path
, consumer
->subdir
);
50 PERROR("snprintf kernel channel path");
53 pathname
= lttng_strndup(tmp_path
, sizeof(tmp_path
));
55 PERROR("lttng_strndup");
59 /* Create directory */
60 ret
= run_as_mkdir_recursive(pathname
, S_IRWXU
| S_IRWXG
, uid
, gid
);
62 if (errno
!= EEXIST
) {
63 ERR("Trace directory creation error");
67 DBG3("Kernel local consumer tracefile path: %s", pathname
);
69 ret
= snprintf(tmp_path
, sizeof(tmp_path
), "%s", consumer
->subdir
);
71 PERROR("snprintf kernel metadata path");
74 pathname
= lttng_strndup(tmp_path
, sizeof(tmp_path
));
76 PERROR("lttng_strndup");
79 DBG3("Kernel network consumer subdir path: %s", pathname
);
90 * Sending a single channel to the consumer with command ADD_CHANNEL.
92 int kernel_consumer_add_channel(struct consumer_socket
*sock
,
93 struct ltt_kernel_channel
*channel
,
94 struct ltt_kernel_session
*ksession
,
99 struct lttcomm_consumer_msg lkm
;
100 struct consumer_output
*consumer
;
101 enum lttng_error_code status
;
102 struct ltt_session
*session
;
103 struct lttng_channel_extended
*channel_attr_extended
;
108 assert(ksession
->consumer
);
110 consumer
= ksession
->consumer
;
111 channel_attr_extended
= (struct lttng_channel_extended
*)
112 channel
->channel
->attr
.extended
.ptr
;
114 DBG("Kernel consumer adding channel %s to kernel consumer",
115 channel
->channel
->name
);
118 pathname
= create_channel_path(consumer
, ksession
->uid
,
122 pathname
= strdup("");
129 /* Prep channel message structure */
130 consumer_init_channel_comm_msg(&lkm
,
131 LTTNG_CONSUMER_ADD_CHANNEL
,
137 consumer
->net_seq_index
,
138 channel
->channel
->name
,
139 channel
->stream_count
,
140 channel
->channel
->attr
.output
,
141 CONSUMER_CHANNEL_TYPE_DATA
,
142 channel
->channel
->attr
.tracefile_size
,
143 channel
->channel
->attr
.tracefile_count
,
145 channel
->channel
->attr
.live_timer_interval
,
146 channel_attr_extended
->monitor_timer_interval
);
148 health_code_update();
150 ret
= consumer_send_channel(sock
, &lkm
);
155 health_code_update();
157 session
= session_find_by_id(ksession
->id
);
160 status
= notification_thread_command_add_channel(
161 notification_thread_handle
, session
->name
,
162 ksession
->uid
, ksession
->gid
,
163 channel
->channel
->name
, channel
->fd
,
165 channel
->channel
->attr
.subbuf_size
* channel
->channel
->attr
.num_subbuf
);
167 if (status
!= LTTNG_OK
) {
172 channel
->published_to_notification_thread
= true;
180 * Sending metadata to the consumer with command ADD_CHANNEL and ADD_STREAM.
182 * The consumer socket lock must be held by the caller.
184 int kernel_consumer_add_metadata(struct consumer_socket
*sock
,
185 struct ltt_kernel_session
*session
, unsigned int monitor
)
189 struct lttcomm_consumer_msg lkm
;
190 struct consumer_output
*consumer
;
194 assert(session
->consumer
);
197 DBG("Sending metadata %d to kernel consumer", session
->metadata_stream_fd
);
199 /* Get consumer output pointer */
200 consumer
= session
->consumer
;
203 pathname
= create_channel_path(consumer
, session
->uid
, session
->gid
);
206 pathname
= strdup("");
213 /* Prep channel message structure */
214 consumer_init_channel_comm_msg(&lkm
,
215 LTTNG_CONSUMER_ADD_CHANNEL
,
216 session
->metadata
->fd
,
221 consumer
->net_seq_index
,
222 DEFAULT_METADATA_NAME
,
224 DEFAULT_KERNEL_CHANNEL_OUTPUT
,
225 CONSUMER_CHANNEL_TYPE_METADATA
,
229 health_code_update();
231 ret
= consumer_send_channel(sock
, &lkm
);
236 health_code_update();
238 /* Prep stream message structure */
239 consumer_init_stream_comm_msg(&lkm
,
240 LTTNG_CONSUMER_ADD_STREAM
,
241 session
->metadata
->fd
,
242 session
->metadata_stream_fd
,
243 0); /* CPU: 0 for metadata. */
245 health_code_update();
247 /* Send stream and file descriptor */
248 ret
= consumer_send_stream(sock
, consumer
, &lkm
,
249 &session
->metadata_stream_fd
, 1);
254 health_code_update();
262 * Sending a single stream to the consumer with command ADD_STREAM.
264 int kernel_consumer_add_stream(struct consumer_socket
*sock
,
265 struct ltt_kernel_channel
*channel
, struct ltt_kernel_stream
*stream
,
266 struct ltt_kernel_session
*session
, unsigned int monitor
)
269 struct lttcomm_consumer_msg lkm
;
270 struct consumer_output
*consumer
;
275 assert(session
->consumer
);
278 DBG("Sending stream %d of channel %s to kernel consumer",
279 stream
->fd
, channel
->channel
->name
);
281 /* Get consumer output pointer */
282 consumer
= session
->consumer
;
284 /* Prep stream consumer message */
285 consumer_init_stream_comm_msg(&lkm
,
286 LTTNG_CONSUMER_ADD_STREAM
,
291 health_code_update();
293 /* Send stream and file descriptor */
294 ret
= consumer_send_stream(sock
, consumer
, &lkm
, &stream
->fd
, 1);
299 health_code_update();
306 * Sending the notification that all streams were sent with STREAMS_SENT.
308 int kernel_consumer_streams_sent(struct consumer_socket
*sock
,
309 struct ltt_kernel_session
*session
, uint64_t channel_key
)
312 struct lttcomm_consumer_msg lkm
;
313 struct consumer_output
*consumer
;
318 DBG("Sending streams_sent");
319 /* Get consumer output pointer */
320 consumer
= session
->consumer
;
322 /* Prep stream consumer message */
323 consumer_init_streams_sent_comm_msg(&lkm
,
324 LTTNG_CONSUMER_STREAMS_SENT
,
325 channel_key
, consumer
->net_seq_index
);
327 health_code_update();
329 /* Send stream and file descriptor */
330 ret
= consumer_send_msg(sock
, &lkm
);
340 * Send all stream fds of kernel channel to the consumer.
342 * The consumer socket lock must be held by the caller.
344 int kernel_consumer_send_channel_stream(struct consumer_socket
*sock
,
345 struct ltt_kernel_channel
*channel
, struct ltt_kernel_session
*session
,
346 unsigned int monitor
)
349 struct ltt_kernel_stream
*stream
;
354 assert(session
->consumer
);
357 /* Bail out if consumer is disabled */
358 if (!session
->consumer
->enabled
) {
363 DBG("Sending streams of channel %s to kernel consumer",
364 channel
->channel
->name
);
366 if (!channel
->sent_to_consumer
) {
367 ret
= kernel_consumer_add_channel(sock
, channel
, session
, monitor
);
371 channel
->sent_to_consumer
= true;
375 cds_list_for_each_entry(stream
, &channel
->stream_list
.head
, list
) {
376 if (!stream
->fd
|| stream
->sent_to_consumer
) {
380 /* Add stream on the kernel consumer side. */
381 ret
= kernel_consumer_add_stream(sock
, channel
, stream
, session
,
386 stream
->sent_to_consumer
= true;
394 * Send all stream fds of the kernel session to the consumer.
396 * The consumer socket lock must be held by the caller.
398 int kernel_consumer_send_session(struct consumer_socket
*sock
,
399 struct ltt_kernel_session
*session
)
401 int ret
, monitor
= 0;
402 struct ltt_kernel_channel
*chan
;
406 assert(session
->consumer
);
409 /* Bail out if consumer is disabled */
410 if (!session
->consumer
->enabled
) {
415 /* Don't monitor the streams on the consumer if in flight recorder. */
416 if (session
->output_traces
) {
420 DBG("Sending session stream to kernel consumer");
422 if (session
->metadata_stream_fd
>= 0 && session
->metadata
) {
423 ret
= kernel_consumer_add_metadata(sock
, session
, monitor
);
429 /* Send channel and streams of it */
430 cds_list_for_each_entry(chan
, &session
->channel_list
.head
, list
) {
431 ret
= kernel_consumer_send_channel_stream(sock
, chan
, session
,
438 * Inform the relay that all the streams for the
441 ret
= kernel_consumer_streams_sent(sock
, session
, chan
->fd
);
448 DBG("Kernel consumer FDs of metadata and channel streams sent");
450 session
->consumer_fds_sent
= 1;
457 int kernel_consumer_destroy_channel(struct consumer_socket
*socket
,
458 struct ltt_kernel_channel
*channel
)
461 struct lttcomm_consumer_msg msg
;
466 DBG("Sending kernel consumer destroy channel key %d", channel
->fd
);
468 memset(&msg
, 0, sizeof(msg
));
469 msg
.cmd_type
= LTTNG_CONSUMER_DESTROY_CHANNEL
;
470 msg
.u
.destroy_channel
.key
= channel
->fd
;
472 pthread_mutex_lock(socket
->lock
);
473 health_code_update();
475 ret
= consumer_send_msg(socket
, &msg
);
481 health_code_update();
482 pthread_mutex_unlock(socket
->lock
);
486 int kernel_consumer_destroy_metadata(struct consumer_socket
*socket
,
487 struct ltt_kernel_metadata
*metadata
)
490 struct lttcomm_consumer_msg msg
;
495 DBG("Sending kernel consumer destroy channel key %d", metadata
->fd
);
497 memset(&msg
, 0, sizeof(msg
));
498 msg
.cmd_type
= LTTNG_CONSUMER_DESTROY_CHANNEL
;
499 msg
.u
.destroy_channel
.key
= metadata
->fd
;
501 pthread_mutex_lock(socket
->lock
);
502 health_code_update();
504 ret
= consumer_send_msg(socket
, &msg
);
510 health_code_update();
511 pthread_mutex_unlock(socket
->lock
);