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