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.
25 #include <common/common.h>
26 #include <common/defaults.h>
30 #include "kernel-consumer.h"
32 static char *create_channel_path(struct consumer_output
*consumer
,
36 char tmp_path
[PATH_MAX
];
37 char *pathname
= NULL
;
41 /* Get the right path name destination */
42 if (consumer
->type
== CONSUMER_DST_LOCAL
) {
43 /* Set application path to the destination path */
44 ret
= snprintf(tmp_path
, sizeof(tmp_path
), "%s%s",
45 consumer
->dst
.trace_path
, consumer
->subdir
);
47 PERROR("snprintf kernel channel path");
50 pathname
= strndup(tmp_path
, sizeof(tmp_path
));
52 /* Create directory */
53 ret
= run_as_mkdir_recursive(pathname
, S_IRWXU
| S_IRWXG
, uid
, gid
);
56 ERR("Trace directory creation error");
60 DBG3("Kernel local consumer tracefile path: %s", pathname
);
62 ret
= snprintf(tmp_path
, sizeof(tmp_path
), "%s", consumer
->subdir
);
64 PERROR("snprintf kernel metadata path");
67 pathname
= strndup(tmp_path
, sizeof(tmp_path
));
68 DBG3("Kernel network consumer subdir path: %s", pathname
);
79 * Sending a single channel to the consumer with command ADD_CHANNEL.
81 int kernel_consumer_add_channel(struct consumer_socket
*sock
,
82 struct ltt_kernel_channel
*channel
, struct ltt_kernel_session
*session
,
87 struct lttcomm_consumer_msg lkm
;
88 struct consumer_output
*consumer
;
93 assert(session
->consumer
);
95 consumer
= session
->consumer
;
97 DBG("Kernel consumer adding channel %s to kernel consumer",
98 channel
->channel
->name
);
101 pathname
= create_channel_path(consumer
, session
->uid
, session
->gid
);
111 /* Prep channel message structure */
112 consumer_init_channel_comm_msg(&lkm
,
113 LTTNG_CONSUMER_ADD_CHANNEL
,
119 consumer
->net_seq_index
,
120 channel
->channel
->name
,
121 channel
->stream_count
,
122 channel
->channel
->attr
.output
,
123 CONSUMER_CHANNEL_TYPE_DATA
,
124 channel
->channel
->attr
.tracefile_size
,
125 channel
->channel
->attr
.tracefile_count
,
128 health_code_update();
130 ret
= consumer_send_channel(sock
, &lkm
);
135 health_code_update();
142 * Sending metadata to the consumer with command ADD_CHANNEL and ADD_STREAM.
144 int kernel_consumer_add_metadata(struct consumer_socket
*sock
,
145 struct ltt_kernel_session
*session
, unsigned int monitor
)
149 struct lttcomm_consumer_msg lkm
;
150 struct consumer_output
*consumer
;
154 assert(session
->consumer
);
157 DBG("Sending metadata %d to kernel consumer", session
->metadata_stream_fd
);
159 /* Get consumer output pointer */
160 consumer
= session
->consumer
;
163 pathname
= create_channel_path(consumer
, session
->uid
, session
->gid
);
173 /* Prep channel message structure */
174 consumer_init_channel_comm_msg(&lkm
,
175 LTTNG_CONSUMER_ADD_CHANNEL
,
176 session
->metadata
->fd
,
181 consumer
->net_seq_index
,
182 DEFAULT_METADATA_NAME
,
184 DEFAULT_KERNEL_CHANNEL_OUTPUT
,
185 CONSUMER_CHANNEL_TYPE_METADATA
,
189 health_code_update();
191 ret
= consumer_send_channel(sock
, &lkm
);
196 health_code_update();
198 /* Prep stream message structure */
199 consumer_init_stream_comm_msg(&lkm
,
200 LTTNG_CONSUMER_ADD_STREAM
,
201 session
->metadata
->fd
,
202 session
->metadata_stream_fd
,
203 0); /* CPU: 0 for metadata. */
206 * Set the no monitor flag. If set to 1, it indicates the consumer to NOT
207 * monitor the stream but rather add it to a special list in the associated
208 * channel. This is used to handle ephemeral stream used by the snapshot
209 * command or store streams for the flight recorder mode.
211 lkm
.u
.stream
.no_monitor
= no_monitor
;
213 health_code_update();
215 /* Send stream and file descriptor */
216 ret
= consumer_send_stream(sock
, consumer
, &lkm
,
217 &session
->metadata_stream_fd
, 1);
222 health_code_update();
229 * Sending a single stream to the consumer with command ADD_STREAM.
231 int kernel_consumer_add_stream(struct consumer_socket
*sock
,
232 struct ltt_kernel_channel
*channel
, struct ltt_kernel_stream
*stream
,
233 struct ltt_kernel_session
*session
, unsigned int monitor
)
236 struct lttcomm_consumer_msg lkm
;
237 struct consumer_output
*consumer
;
242 assert(session
->consumer
);
245 DBG("Sending stream %d of channel %s to kernel consumer",
246 stream
->fd
, channel
->channel
->name
);
248 /* Get consumer output pointer */
249 consumer
= session
->consumer
;
251 /* Prep stream consumer message */
252 consumer_init_stream_comm_msg(&lkm
,
253 LTTNG_CONSUMER_ADD_STREAM
,
258 health_code_update();
260 /* Send stream and file descriptor */
261 ret
= consumer_send_stream(sock
, consumer
, &lkm
, &stream
->fd
, 1);
266 health_code_update();
273 * Send all stream fds of kernel channel to the consumer.
275 int kernel_consumer_send_channel_stream(struct consumer_socket
*sock
,
276 struct ltt_kernel_channel
*channel
, struct ltt_kernel_session
*session
,
277 unsigned int monitor
)
280 struct ltt_kernel_stream
*stream
;
285 assert(session
->consumer
);
288 /* Bail out if consumer is disabled */
289 if (!session
->consumer
->enabled
) {
294 DBG("Sending streams of channel %s to kernel consumer",
295 channel
->channel
->name
);
297 ret
= kernel_consumer_add_channel(sock
, channel
, session
, monitor
);
303 cds_list_for_each_entry(stream
, &channel
->stream_list
.head
, list
) {
308 /* Add stream on the kernel consumer side. */
309 ret
= kernel_consumer_add_stream(sock
, channel
, stream
, session
,
321 * Send all stream fds of the kernel session to the consumer.
323 int kernel_consumer_send_session(struct consumer_socket
*sock
,
324 struct ltt_kernel_session
*session
)
326 int ret
, monitor
= 0;
327 struct ltt_kernel_channel
*chan
;
331 assert(session
->consumer
);
334 /* Bail out if consumer is disabled */
335 if (!session
->consumer
->enabled
) {
340 /* Don't monitor the streams on the consumer if in flight recorder. */
341 if (session
->output_traces
) {
345 DBG("Sending session stream to kernel consumer");
347 if (session
->metadata_stream_fd
>= 0) {
348 ret
= kernel_consumer_add_metadata(sock
, session
, monitor
);
353 /* Flag that at least the metadata has been sent to the consumer. */
354 session
->consumer_fds_sent
= 1;
357 /* Send channel and streams of it */
358 cds_list_for_each_entry(chan
, &session
->channel_list
.head
, list
) {
359 ret
= kernel_consumer_send_channel_stream(sock
, chan
, session
,
366 DBG("Kernel consumer FDs of metadata and channel streams sent");