sessiond: enforce mmap output type for kernel metadata channel
[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
6c1c0768 18#define _LGPL_SOURCE
f1e16794
DG
19#include <stdio.h>
20#include <stdlib.h>
f1e16794
DG
21#include <sys/stat.h>
22#include <unistd.h>
23
24#include <common/common.h>
25#include <common/defaults.h>
f5436bfc 26#include <common/compat/string.h>
f1e16794 27
00e2e675 28#include "consumer.h"
8782cc74 29#include "health-sessiond.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 }
f5436bfc 50 pathname = lttng_strndup(tmp_path, sizeof(tmp_path));
bb3c4e70 51 if (!pathname) {
f5436bfc 52 PERROR("lttng_strndup");
bb3c4e70
MD
53 goto error;
54 }
ffe60014
DG
55
56 /* Create directory */
2bba9e53 57 ret = run_as_mkdir_recursive(pathname, S_IRWXU | S_IRWXG, uid, gid);
ffe60014 58 if (ret < 0) {
df5b86c8 59 if (errno != EEXIST) {
ffe60014
DG
60 ERR("Trace directory creation error");
61 goto error;
62 }
63 }
64 DBG3("Kernel local consumer tracefile path: %s", pathname);
65 } else {
66 ret = snprintf(tmp_path, sizeof(tmp_path), "%s", consumer->subdir);
67 if (ret < 0) {
2bba9e53 68 PERROR("snprintf kernel metadata path");
ffe60014
DG
69 goto error;
70 }
f5436bfc 71 pathname = lttng_strndup(tmp_path, sizeof(tmp_path));
bb3c4e70 72 if (!pathname) {
f5436bfc 73 PERROR("lttng_strndup");
bb3c4e70
MD
74 goto error;
75 }
ffe60014
DG
76 DBG3("Kernel network consumer subdir path: %s", pathname);
77 }
78
2bba9e53
DG
79 return pathname;
80
81error:
82 free(pathname);
83 return NULL;
84}
85
86/*
87 * Sending a single channel to the consumer with command ADD_CHANNEL.
88 */
89int kernel_consumer_add_channel(struct consumer_socket *sock,
90 struct ltt_kernel_channel *channel, struct ltt_kernel_session *session,
91 unsigned int monitor)
92{
93 int ret;
94 char *pathname;
95 struct lttcomm_consumer_msg lkm;
96 struct consumer_output *consumer;
97
98 /* Safety net */
99 assert(channel);
100 assert(session);
101 assert(session->consumer);
102
103 consumer = session->consumer;
104
105 DBG("Kernel consumer adding channel %s to kernel consumer",
106 channel->channel->name);
107
108 if (monitor) {
109 pathname = create_channel_path(consumer, session->uid, session->gid);
2bba9e53
DG
110 } else {
111 /* Empty path. */
53efb85a 112 pathname = strdup("");
2bba9e53 113 }
bb3c4e70
MD
114 if (!pathname) {
115 ret = -1;
116 goto error;
117 }
2bba9e53 118
00e2e675
DG
119 /* Prep channel message structure */
120 consumer_init_channel_comm_msg(&lkm,
121 LTTNG_CONSUMER_ADD_CHANNEL,
122 channel->fd,
ffe60014
DG
123 session->id,
124 pathname,
125 session->uid,
126 session->gid,
127 consumer->net_seq_index,
c30aaa51 128 channel->channel->name,
ffe60014
DG
129 channel->stream_count,
130 channel->channel->attr.output,
1624d5b7
JD
131 CONSUMER_CHANNEL_TYPE_DATA,
132 channel->channel->attr.tracefile_size,
2bba9e53 133 channel->channel->attr.tracefile_count,
ecc48a90 134 monitor,
11785f65
JG
135 channel->channel->attr.live_timer_interval,
136 session->is_live_session);
00e2e675 137
840cb59c 138 health_code_update();
ca03de58 139
00e2e675
DG
140 ret = consumer_send_channel(sock, &lkm);
141 if (ret < 0) {
142 goto error;
143 }
144
840cb59c 145 health_code_update();
ca03de58 146
00e2e675 147error:
53efb85a 148 free(pathname);
00e2e675
DG
149 return ret;
150}
151
152/*
153 * Sending metadata to the consumer with command ADD_CHANNEL and ADD_STREAM.
ba0fd12e
JG
154 *
155 * The consumer socket lock must be held by the caller.
00e2e675 156 */
f50f23d9 157int kernel_consumer_add_metadata(struct consumer_socket *sock,
2bba9e53 158 struct ltt_kernel_session *session, unsigned int monitor)
00e2e675
DG
159{
160 int ret;
2bba9e53 161 char *pathname;
00e2e675 162 struct lttcomm_consumer_msg lkm;
a7d9a3e7 163 struct consumer_output *consumer;
00e2e675
DG
164
165 /* Safety net */
166 assert(session);
167 assert(session->consumer);
f50f23d9 168 assert(sock);
00e2e675
DG
169
170 DBG("Sending metadata %d to kernel consumer", session->metadata_stream_fd);
171
172 /* Get consumer output pointer */
a7d9a3e7 173 consumer = session->consumer;
00e2e675 174
2bba9e53
DG
175 if (monitor) {
176 pathname = create_channel_path(consumer, session->uid, session->gid);
00e2e675 177 } else {
2bba9e53 178 /* Empty path. */
53efb85a 179 pathname = strdup("");
00e2e675 180 }
bb3c4e70
MD
181 if (!pathname) {
182 ret = -1;
183 goto error;
184 }
00e2e675
DG
185
186 /* Prep channel message structure */
187 consumer_init_channel_comm_msg(&lkm,
188 LTTNG_CONSUMER_ADD_CHANNEL,
189 session->metadata->fd,
ffe60014
DG
190 session->id,
191 pathname,
192 session->uid,
193 session->gid,
194 consumer->net_seq_index,
038abe40 195 session->metadata->conf->name,
ffe60014 196 1,
038abe40 197 session->metadata->conf->attr.output,
1624d5b7 198 CONSUMER_CHANNEL_TYPE_METADATA,
038abe40
JG
199 session->metadata->conf->attr.tracefile_size,
200 session->metadata->conf->attr.tracefile_count,
201 monitor,
202 session->metadata->conf->attr.live_timer_interval,
203 session->is_live_session);
00e2e675 204
840cb59c 205 health_code_update();
ca03de58 206
00e2e675
DG
207 ret = consumer_send_channel(sock, &lkm);
208 if (ret < 0) {
209 goto error;
210 }
211
840cb59c 212 health_code_update();
ca03de58 213
00e2e675
DG
214 /* Prep stream message structure */
215 consumer_init_stream_comm_msg(&lkm,
216 LTTNG_CONSUMER_ADD_STREAM,
217 session->metadata->fd,
218 session->metadata_stream_fd,
1624d5b7 219 0); /* CPU: 0 for metadata. */
00e2e675 220
840cb59c 221 health_code_update();
ca03de58 222
00e2e675 223 /* Send stream and file descriptor */
a7d9a3e7 224 ret = consumer_send_stream(sock, consumer, &lkm,
00e2e675
DG
225 &session->metadata_stream_fd, 1);
226 if (ret < 0) {
227 goto error;
228 }
229
840cb59c 230 health_code_update();
ca03de58 231
00e2e675 232error:
53efb85a 233 free(pathname);
00e2e675
DG
234 return ret;
235}
236
237/*
238 * Sending a single stream to the consumer with command ADD_STREAM.
239 */
f50f23d9
DG
240int kernel_consumer_add_stream(struct consumer_socket *sock,
241 struct ltt_kernel_channel *channel, struct ltt_kernel_stream *stream,
2bba9e53 242 struct ltt_kernel_session *session, unsigned int monitor)
00e2e675
DG
243{
244 int ret;
00e2e675 245 struct lttcomm_consumer_msg lkm;
a7d9a3e7 246 struct consumer_output *consumer;
00e2e675
DG
247
248 assert(channel);
249 assert(stream);
250 assert(session);
251 assert(session->consumer);
f50f23d9 252 assert(sock);
00e2e675
DG
253
254 DBG("Sending stream %d of channel %s to kernel consumer",
255 stream->fd, channel->channel->name);
256
257 /* Get consumer output pointer */
a7d9a3e7 258 consumer = session->consumer;
00e2e675 259
00e2e675 260 /* Prep stream consumer message */
ffe60014
DG
261 consumer_init_stream_comm_msg(&lkm,
262 LTTNG_CONSUMER_ADD_STREAM,
00e2e675
DG
263 channel->fd,
264 stream->fd,
ffe60014 265 stream->cpu);
00e2e675 266
840cb59c 267 health_code_update();
ca03de58 268
00e2e675 269 /* Send stream and file descriptor */
a7d9a3e7 270 ret = consumer_send_stream(sock, consumer, &lkm, &stream->fd, 1);
00e2e675
DG
271 if (ret < 0) {
272 goto error;
273 }
274
840cb59c 275 health_code_update();
ca03de58 276
00e2e675
DG
277error:
278 return ret;
279}
280
a4baae1b
JD
281/*
282 * Sending the notification that all streams were sent with STREAMS_SENT.
283 */
284int kernel_consumer_streams_sent(struct consumer_socket *sock,
285 struct ltt_kernel_session *session, uint64_t channel_key)
286{
287 int ret;
288 struct lttcomm_consumer_msg lkm;
289 struct consumer_output *consumer;
290
291 assert(sock);
292 assert(session);
293
294 DBG("Sending streams_sent");
295 /* Get consumer output pointer */
296 consumer = session->consumer;
297
298 /* Prep stream consumer message */
299 consumer_init_streams_sent_comm_msg(&lkm,
300 LTTNG_CONSUMER_STREAMS_SENT,
301 channel_key, consumer->net_seq_index);
302
303 health_code_update();
304
305 /* Send stream and file descriptor */
306 ret = consumer_send_msg(sock, &lkm);
307 if (ret < 0) {
308 goto error;
309 }
310
311error:
312 return ret;
313}
314
f1e16794
DG
315/*
316 * Send all stream fds of kernel channel to the consumer.
ba0fd12e
JG
317 *
318 * The consumer socket lock must be held by the caller.
f1e16794 319 */
f50f23d9 320int kernel_consumer_send_channel_stream(struct consumer_socket *sock,
2bba9e53
DG
321 struct ltt_kernel_channel *channel, struct ltt_kernel_session *session,
322 unsigned int monitor)
f1e16794 323{
6c598487 324 int ret = LTTNG_OK;
f1e16794 325 struct ltt_kernel_stream *stream;
00e2e675
DG
326
327 /* Safety net */
328 assert(channel);
329 assert(session);
330 assert(session->consumer);
f50f23d9 331 assert(sock);
00e2e675
DG
332
333 /* Bail out if consumer is disabled */
334 if (!session->consumer->enabled) {
f73fabfd 335 ret = LTTNG_OK;
00e2e675
DG
336 goto error;
337 }
f1e16794
DG
338
339 DBG("Sending streams of channel %s to kernel consumer",
340 channel->channel->name);
341
6c598487
MD
342 if (!channel->sent_to_consumer) {
343 ret = kernel_consumer_add_channel(sock, channel, session, monitor);
344 if (ret < 0) {
345 goto error;
346 }
347 channel->sent_to_consumer = true;
f1e16794
DG
348 }
349
350 /* Send streams */
351 cds_list_for_each_entry(stream, &channel->stream_list.head, list) {
b64dd54f 352 if (!stream->fd || stream->sent_to_consumer) {
f1e16794
DG
353 continue;
354 }
00e2e675
DG
355
356 /* Add stream on the kernel consumer side. */
2bba9e53
DG
357 ret = kernel_consumer_add_stream(sock, channel, stream, session,
358 monitor);
f1e16794 359 if (ret < 0) {
f1e16794
DG
360 goto error;
361 }
b64dd54f 362 stream->sent_to_consumer = true;
f1e16794
DG
363 }
364
f1e16794
DG
365error:
366 return ret;
367}
368
369/*
370 * Send all stream fds of the kernel session to the consumer.
ba0fd12e
JG
371 *
372 * The consumer socket lock must be held by the caller.
f1e16794 373 */
f50f23d9
DG
374int kernel_consumer_send_session(struct consumer_socket *sock,
375 struct ltt_kernel_session *session)
f1e16794 376{
2bba9e53 377 int ret, monitor = 0;
f1e16794 378 struct ltt_kernel_channel *chan;
f1e16794 379
00e2e675
DG
380 /* Safety net */
381 assert(session);
382 assert(session->consumer);
f50f23d9 383 assert(sock);
f1e16794 384
00e2e675
DG
385 /* Bail out if consumer is disabled */
386 if (!session->consumer->enabled) {
f73fabfd 387 ret = LTTNG_OK;
00e2e675 388 goto error;
f1e16794
DG
389 }
390
2bba9e53
DG
391 /* Don't monitor the streams on the consumer if in flight recorder. */
392 if (session->output_traces) {
393 monitor = 1;
394 }
395
00e2e675
DG
396 DBG("Sending session stream to kernel consumer");
397
609af759 398 if (session->metadata_stream_fd >= 0 && session->metadata) {
2bba9e53 399 ret = kernel_consumer_add_metadata(sock, session, monitor);
f1e16794 400 if (ret < 0) {
f1e16794
DG
401 goto error;
402 }
f1e16794
DG
403 }
404
00e2e675 405 /* Send channel and streams of it */
f1e16794 406 cds_list_for_each_entry(chan, &session->channel_list.head, list) {
2bba9e53
DG
407 ret = kernel_consumer_send_channel_stream(sock, chan, session,
408 monitor);
f1e16794
DG
409 if (ret < 0) {
410 goto error;
411 }
601262d6
JD
412 if (monitor) {
413 /*
414 * Inform the relay that all the streams for the
415 * channel were sent.
416 */
417 ret = kernel_consumer_streams_sent(sock, session, chan->fd);
418 if (ret < 0) {
419 goto error;
420 }
421 }
f1e16794
DG
422 }
423
00e2e675 424 DBG("Kernel consumer FDs of metadata and channel streams sent");
f1e16794 425
4ce9ff51 426 session->consumer_fds_sent = 1;
f1e16794
DG
427 return 0;
428
429error:
430 return ret;
431}
07b86b52
JD
432
433int kernel_consumer_destroy_channel(struct consumer_socket *socket,
434 struct ltt_kernel_channel *channel)
435{
436 int ret;
437 struct lttcomm_consumer_msg msg;
438
439 assert(channel);
440 assert(socket);
07b86b52
JD
441
442 DBG("Sending kernel consumer destroy channel key %d", channel->fd);
443
53efb85a 444 memset(&msg, 0, sizeof(msg));
07b86b52
JD
445 msg.cmd_type = LTTNG_CONSUMER_DESTROY_CHANNEL;
446 msg.u.destroy_channel.key = channel->fd;
447
448 pthread_mutex_lock(socket->lock);
449 health_code_update();
450
451 ret = consumer_send_msg(socket, &msg);
452 if (ret < 0) {
453 goto error;
454 }
455
456error:
457 health_code_update();
458 pthread_mutex_unlock(socket->lock);
459 return ret;
460}
461
462int kernel_consumer_destroy_metadata(struct consumer_socket *socket,
463 struct ltt_kernel_metadata *metadata)
464{
465 int ret;
466 struct lttcomm_consumer_msg msg;
467
468 assert(metadata);
469 assert(socket);
07b86b52
JD
470
471 DBG("Sending kernel consumer destroy channel key %d", metadata->fd);
472
53efb85a 473 memset(&msg, 0, sizeof(msg));
07b86b52
JD
474 msg.cmd_type = LTTNG_CONSUMER_DESTROY_CHANNEL;
475 msg.u.destroy_channel.key = metadata->fd;
476
477 pthread_mutex_lock(socket->lock);
478 health_code_update();
479
480 ret = consumer_send_msg(socket, &msg);
481 if (ret < 0) {
482 goto error;
483 }
484
485error:
486 health_code_update();
487 pthread_mutex_unlock(socket->lock);
488 return ret;
489}
This page took 0.080692 seconds and 5 git commands to generate.