Support flight recorder mode for a session
[lttng-tools.git] / src / bin / lttng-sessiond / kernel-consumer.c
CommitLineData
f1e16794
DG
1/*
2 * Copyright (C) 2012 - David Goulet <dgoulet@efficios.com>
3 *
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.
7 *
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
11 * more details.
12 *
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.
16 */
17
18#define _GNU_SOURCE
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22#include <sys/stat.h>
23#include <unistd.h>
24
25#include <common/common.h>
26#include <common/defaults.h>
f1e16794 27
00e2e675 28#include "consumer.h"
7972aab2 29#include "health.h"
f1e16794
DG
30#include "kernel-consumer.h"
31
2bba9e53
DG
32static char *create_channel_path(struct consumer_output *consumer,
33 uid_t uid, gid_t gid)
00e2e675
DG
34{
35 int ret;
ffe60014 36 char tmp_path[PATH_MAX];
2bba9e53 37 char *pathname = NULL;
00e2e675 38
2bba9e53 39 assert(consumer);
00e2e675 40
ffe60014
DG
41 /* Get the right path name destination */
42 if (consumer->type == CONSUMER_DST_LOCAL) {
43 /* Set application path to the destination path */
dec56f6c 44 ret = snprintf(tmp_path, sizeof(tmp_path), "%s%s",
ffe60014
DG
45 consumer->dst.trace_path, consumer->subdir);
46 if (ret < 0) {
2bba9e53 47 PERROR("snprintf kernel channel path");
ffe60014
DG
48 goto error;
49 }
2bba9e53 50 pathname = strndup(tmp_path, sizeof(tmp_path));
ffe60014
DG
51
52 /* Create directory */
2bba9e53 53 ret = run_as_mkdir_recursive(pathname, S_IRWXU | S_IRWXG, uid, gid);
ffe60014
DG
54 if (ret < 0) {
55 if (ret != -EEXIST) {
56 ERR("Trace directory creation error");
57 goto error;
58 }
59 }
60 DBG3("Kernel local consumer tracefile path: %s", pathname);
61 } else {
62 ret = snprintf(tmp_path, sizeof(tmp_path), "%s", consumer->subdir);
63 if (ret < 0) {
2bba9e53 64 PERROR("snprintf kernel metadata path");
ffe60014
DG
65 goto error;
66 }
2bba9e53 67 pathname = strndup(tmp_path, sizeof(tmp_path));
ffe60014
DG
68 DBG3("Kernel network consumer subdir path: %s", pathname);
69 }
70
2bba9e53
DG
71 return pathname;
72
73error:
74 free(pathname);
75 return NULL;
76}
77
78/*
79 * Sending a single channel to the consumer with command ADD_CHANNEL.
80 */
81int kernel_consumer_add_channel(struct consumer_socket *sock,
82 struct ltt_kernel_channel *channel, struct ltt_kernel_session *session,
83 unsigned int monitor)
84{
85 int ret;
86 char *pathname;
87 struct lttcomm_consumer_msg lkm;
88 struct consumer_output *consumer;
89
90 /* Safety net */
91 assert(channel);
92 assert(session);
93 assert(session->consumer);
94
95 consumer = session->consumer;
96
97 DBG("Kernel consumer adding channel %s to kernel consumer",
98 channel->channel->name);
99
100 if (monitor) {
101 pathname = create_channel_path(consumer, session->uid, session->gid);
102 if (!pathname) {
103 ret = -1;
104 goto error;
105 }
106 } else {
107 /* Empty path. */
108 pathname = "";
109 }
110
00e2e675
DG
111 /* Prep channel message structure */
112 consumer_init_channel_comm_msg(&lkm,
113 LTTNG_CONSUMER_ADD_CHANNEL,
114 channel->fd,
ffe60014
DG
115 session->id,
116 pathname,
117 session->uid,
118 session->gid,
119 consumer->net_seq_index,
c30aaa51 120 channel->channel->name,
ffe60014
DG
121 channel->stream_count,
122 channel->channel->attr.output,
1624d5b7
JD
123 CONSUMER_CHANNEL_TYPE_DATA,
124 channel->channel->attr.tracefile_size,
2bba9e53
DG
125 channel->channel->attr.tracefile_count,
126 monitor);
00e2e675 127
840cb59c 128 health_code_update();
ca03de58 129
00e2e675
DG
130 ret = consumer_send_channel(sock, &lkm);
131 if (ret < 0) {
132 goto error;
133 }
134
840cb59c 135 health_code_update();
ca03de58 136
00e2e675
DG
137error:
138 return ret;
139}
140
141/*
142 * Sending metadata to the consumer with command ADD_CHANNEL and ADD_STREAM.
143 */
f50f23d9 144int kernel_consumer_add_metadata(struct consumer_socket *sock,
2bba9e53 145 struct ltt_kernel_session *session, unsigned int monitor)
00e2e675
DG
146{
147 int ret;
2bba9e53 148 char *pathname;
00e2e675 149 struct lttcomm_consumer_msg lkm;
a7d9a3e7 150 struct consumer_output *consumer;
00e2e675
DG
151
152 /* Safety net */
153 assert(session);
154 assert(session->consumer);
f50f23d9 155 assert(sock);
00e2e675
DG
156
157 DBG("Sending metadata %d to kernel consumer", session->metadata_stream_fd);
158
159 /* Get consumer output pointer */
a7d9a3e7 160 consumer = session->consumer;
00e2e675 161
2bba9e53
DG
162 if (monitor) {
163 pathname = create_channel_path(consumer, session->uid, session->gid);
164 if (!pathname) {
165 ret = -1;
a7d9a3e7
DG
166 goto error;
167 }
00e2e675 168 } else {
2bba9e53
DG
169 /* Empty path. */
170 pathname = "";
00e2e675
DG
171 }
172
173 /* Prep channel message structure */
174 consumer_init_channel_comm_msg(&lkm,
175 LTTNG_CONSUMER_ADD_CHANNEL,
176 session->metadata->fd,
ffe60014
DG
177 session->id,
178 pathname,
179 session->uid,
180 session->gid,
181 consumer->net_seq_index,
30079b6b 182 DEFAULT_METADATA_NAME,
ffe60014
DG
183 1,
184 DEFAULT_KERNEL_CHANNEL_OUTPUT,
1624d5b7 185 CONSUMER_CHANNEL_TYPE_METADATA,
2bba9e53
DG
186 0, 0,
187 monitor);
00e2e675 188
840cb59c 189 health_code_update();
ca03de58 190
00e2e675
DG
191 ret = consumer_send_channel(sock, &lkm);
192 if (ret < 0) {
193 goto error;
194 }
195
840cb59c 196 health_code_update();
ca03de58 197
00e2e675
DG
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,
1624d5b7 203 0); /* CPU: 0 for metadata. */
00e2e675 204
6dc3064a
DG
205 /*
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.
210 */
211 lkm.u.stream.no_monitor = no_monitor;
212
840cb59c 213 health_code_update();
ca03de58 214
00e2e675 215 /* Send stream and file descriptor */
a7d9a3e7 216 ret = consumer_send_stream(sock, consumer, &lkm,
00e2e675
DG
217 &session->metadata_stream_fd, 1);
218 if (ret < 0) {
219 goto error;
220 }
221
840cb59c 222 health_code_update();
ca03de58 223
00e2e675
DG
224error:
225 return ret;
226}
227
228/*
229 * Sending a single stream to the consumer with command ADD_STREAM.
230 */
f50f23d9
DG
231int kernel_consumer_add_stream(struct consumer_socket *sock,
232 struct ltt_kernel_channel *channel, struct ltt_kernel_stream *stream,
2bba9e53 233 struct ltt_kernel_session *session, unsigned int monitor)
00e2e675
DG
234{
235 int ret;
00e2e675 236 struct lttcomm_consumer_msg lkm;
a7d9a3e7 237 struct consumer_output *consumer;
00e2e675
DG
238
239 assert(channel);
240 assert(stream);
241 assert(session);
242 assert(session->consumer);
f50f23d9 243 assert(sock);
00e2e675
DG
244
245 DBG("Sending stream %d of channel %s to kernel consumer",
246 stream->fd, channel->channel->name);
247
248 /* Get consumer output pointer */
a7d9a3e7 249 consumer = session->consumer;
00e2e675 250
00e2e675 251 /* Prep stream consumer message */
ffe60014
DG
252 consumer_init_stream_comm_msg(&lkm,
253 LTTNG_CONSUMER_ADD_STREAM,
00e2e675
DG
254 channel->fd,
255 stream->fd,
ffe60014 256 stream->cpu);
00e2e675 257
840cb59c 258 health_code_update();
ca03de58 259
00e2e675 260 /* Send stream and file descriptor */
a7d9a3e7 261 ret = consumer_send_stream(sock, consumer, &lkm, &stream->fd, 1);
00e2e675
DG
262 if (ret < 0) {
263 goto error;
264 }
265
840cb59c 266 health_code_update();
ca03de58 267
00e2e675
DG
268error:
269 return ret;
270}
271
f1e16794
DG
272/*
273 * Send all stream fds of kernel channel to the consumer.
274 */
f50f23d9 275int kernel_consumer_send_channel_stream(struct consumer_socket *sock,
2bba9e53
DG
276 struct ltt_kernel_channel *channel, struct ltt_kernel_session *session,
277 unsigned int monitor)
f1e16794 278{
00e2e675 279 int ret;
f1e16794 280 struct ltt_kernel_stream *stream;
00e2e675
DG
281
282 /* Safety net */
283 assert(channel);
284 assert(session);
285 assert(session->consumer);
f50f23d9 286 assert(sock);
00e2e675
DG
287
288 /* Bail out if consumer is disabled */
289 if (!session->consumer->enabled) {
f73fabfd 290 ret = LTTNG_OK;
00e2e675
DG
291 goto error;
292 }
f1e16794
DG
293
294 DBG("Sending streams of channel %s to kernel consumer",
295 channel->channel->name);
296
2bba9e53 297 ret = kernel_consumer_add_channel(sock, channel, session, monitor);
f1e16794 298 if (ret < 0) {
f1e16794
DG
299 goto error;
300 }
301
302 /* Send streams */
303 cds_list_for_each_entry(stream, &channel->stream_list.head, list) {
304 if (!stream->fd) {
305 continue;
306 }
00e2e675
DG
307
308 /* Add stream on the kernel consumer side. */
2bba9e53
DG
309 ret = kernel_consumer_add_stream(sock, channel, stream, session,
310 monitor);
f1e16794 311 if (ret < 0) {
f1e16794
DG
312 goto error;
313 }
314 }
315
f1e16794
DG
316error:
317 return ret;
318}
319
320/*
321 * Send all stream fds of the kernel session to the consumer.
322 */
f50f23d9
DG
323int kernel_consumer_send_session(struct consumer_socket *sock,
324 struct ltt_kernel_session *session)
f1e16794 325{
2bba9e53 326 int ret, monitor = 0;
f1e16794 327 struct ltt_kernel_channel *chan;
f1e16794 328
00e2e675
DG
329 /* Safety net */
330 assert(session);
331 assert(session->consumer);
f50f23d9 332 assert(sock);
f1e16794 333
00e2e675
DG
334 /* Bail out if consumer is disabled */
335 if (!session->consumer->enabled) {
f73fabfd 336 ret = LTTNG_OK;
00e2e675 337 goto error;
f1e16794
DG
338 }
339
2bba9e53
DG
340 /* Don't monitor the streams on the consumer if in flight recorder. */
341 if (session->output_traces) {
342 monitor = 1;
343 }
344
00e2e675
DG
345 DBG("Sending session stream to kernel consumer");
346
f1e16794 347 if (session->metadata_stream_fd >= 0) {
2bba9e53 348 ret = kernel_consumer_add_metadata(sock, session, monitor);
f1e16794 349 if (ret < 0) {
f1e16794
DG
350 goto error;
351 }
352
00e2e675
DG
353 /* Flag that at least the metadata has been sent to the consumer. */
354 session->consumer_fds_sent = 1;
f1e16794
DG
355 }
356
00e2e675 357 /* Send channel and streams of it */
f1e16794 358 cds_list_for_each_entry(chan, &session->channel_list.head, list) {
2bba9e53
DG
359 ret = kernel_consumer_send_channel_stream(sock, chan, session,
360 monitor);
f1e16794
DG
361 if (ret < 0) {
362 goto error;
363 }
364 }
365
00e2e675 366 DBG("Kernel consumer FDs of metadata and channel streams sent");
f1e16794
DG
367
368 return 0;
369
370error:
371 return ret;
372}
This page took 0.049772 seconds and 5 git commands to generate.