Fix: miscellaneous memory handling fixes
[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"
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 }
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. */
53efb85a 108 pathname = strdup("");
2bba9e53
DG
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 125 channel->channel->attr.tracefile_count,
ecc48a90
JD
126 monitor,
127 channel->channel->attr.live_timer_interval);
00e2e675 128
840cb59c 129 health_code_update();
ca03de58 130
00e2e675
DG
131 ret = consumer_send_channel(sock, &lkm);
132 if (ret < 0) {
133 goto error;
134 }
135
840cb59c 136 health_code_update();
ca03de58 137
00e2e675 138error:
53efb85a 139 free(pathname);
00e2e675
DG
140 return ret;
141}
142
143/*
144 * Sending metadata to the consumer with command ADD_CHANNEL and ADD_STREAM.
145 */
f50f23d9 146int kernel_consumer_add_metadata(struct consumer_socket *sock,
2bba9e53 147 struct ltt_kernel_session *session, unsigned int monitor)
00e2e675
DG
148{
149 int ret;
2bba9e53 150 char *pathname;
00e2e675 151 struct lttcomm_consumer_msg lkm;
a7d9a3e7 152 struct consumer_output *consumer;
00e2e675
DG
153
154 /* Safety net */
155 assert(session);
156 assert(session->consumer);
f50f23d9 157 assert(sock);
00e2e675
DG
158
159 DBG("Sending metadata %d to kernel consumer", session->metadata_stream_fd);
160
161 /* Get consumer output pointer */
a7d9a3e7 162 consumer = session->consumer;
00e2e675 163
2bba9e53
DG
164 if (monitor) {
165 pathname = create_channel_path(consumer, session->uid, session->gid);
166 if (!pathname) {
167 ret = -1;
a7d9a3e7
DG
168 goto error;
169 }
00e2e675 170 } else {
2bba9e53 171 /* Empty path. */
53efb85a 172 pathname = strdup("");
00e2e675
DG
173 }
174
175 /* Prep channel message structure */
176 consumer_init_channel_comm_msg(&lkm,
177 LTTNG_CONSUMER_ADD_CHANNEL,
178 session->metadata->fd,
ffe60014
DG
179 session->id,
180 pathname,
181 session->uid,
182 session->gid,
183 consumer->net_seq_index,
30079b6b 184 DEFAULT_METADATA_NAME,
ffe60014
DG
185 1,
186 DEFAULT_KERNEL_CHANNEL_OUTPUT,
1624d5b7 187 CONSUMER_CHANNEL_TYPE_METADATA,
2bba9e53 188 0, 0,
ecc48a90 189 monitor, 0);
00e2e675 190
840cb59c 191 health_code_update();
ca03de58 192
00e2e675
DG
193 ret = consumer_send_channel(sock, &lkm);
194 if (ret < 0) {
195 goto error;
196 }
197
840cb59c 198 health_code_update();
ca03de58 199
00e2e675
DG
200 /* Prep stream message structure */
201 consumer_init_stream_comm_msg(&lkm,
202 LTTNG_CONSUMER_ADD_STREAM,
203 session->metadata->fd,
204 session->metadata_stream_fd,
1624d5b7 205 0); /* CPU: 0 for metadata. */
00e2e675 206
840cb59c 207 health_code_update();
ca03de58 208
00e2e675 209 /* Send stream and file descriptor */
a7d9a3e7 210 ret = consumer_send_stream(sock, consumer, &lkm,
00e2e675
DG
211 &session->metadata_stream_fd, 1);
212 if (ret < 0) {
213 goto error;
214 }
215
840cb59c 216 health_code_update();
ca03de58 217
00e2e675 218error:
53efb85a 219 free(pathname);
00e2e675
DG
220 return ret;
221}
222
223/*
224 * Sending a single stream to the consumer with command ADD_STREAM.
225 */
f50f23d9
DG
226int kernel_consumer_add_stream(struct consumer_socket *sock,
227 struct ltt_kernel_channel *channel, struct ltt_kernel_stream *stream,
2bba9e53 228 struct ltt_kernel_session *session, unsigned int monitor)
00e2e675
DG
229{
230 int ret;
00e2e675 231 struct lttcomm_consumer_msg lkm;
a7d9a3e7 232 struct consumer_output *consumer;
00e2e675
DG
233
234 assert(channel);
235 assert(stream);
236 assert(session);
237 assert(session->consumer);
f50f23d9 238 assert(sock);
00e2e675
DG
239
240 DBG("Sending stream %d of channel %s to kernel consumer",
241 stream->fd, channel->channel->name);
242
243 /* Get consumer output pointer */
a7d9a3e7 244 consumer = session->consumer;
00e2e675 245
00e2e675 246 /* Prep stream consumer message */
ffe60014
DG
247 consumer_init_stream_comm_msg(&lkm,
248 LTTNG_CONSUMER_ADD_STREAM,
00e2e675
DG
249 channel->fd,
250 stream->fd,
ffe60014 251 stream->cpu);
00e2e675 252
840cb59c 253 health_code_update();
ca03de58 254
00e2e675 255 /* Send stream and file descriptor */
a7d9a3e7 256 ret = consumer_send_stream(sock, consumer, &lkm, &stream->fd, 1);
00e2e675
DG
257 if (ret < 0) {
258 goto error;
259 }
260
840cb59c 261 health_code_update();
ca03de58 262
00e2e675
DG
263error:
264 return ret;
265}
266
a4baae1b
JD
267/*
268 * Sending the notification that all streams were sent with STREAMS_SENT.
269 */
270int kernel_consumer_streams_sent(struct consumer_socket *sock,
271 struct ltt_kernel_session *session, uint64_t channel_key)
272{
273 int ret;
274 struct lttcomm_consumer_msg lkm;
275 struct consumer_output *consumer;
276
277 assert(sock);
278 assert(session);
279
280 DBG("Sending streams_sent");
281 /* Get consumer output pointer */
282 consumer = session->consumer;
283
284 /* Prep stream consumer message */
285 consumer_init_streams_sent_comm_msg(&lkm,
286 LTTNG_CONSUMER_STREAMS_SENT,
287 channel_key, consumer->net_seq_index);
288
289 health_code_update();
290
291 /* Send stream and file descriptor */
292 ret = consumer_send_msg(sock, &lkm);
293 if (ret < 0) {
294 goto error;
295 }
296
297error:
298 return ret;
299}
300
f1e16794
DG
301/*
302 * Send all stream fds of kernel channel to the consumer.
303 */
f50f23d9 304int kernel_consumer_send_channel_stream(struct consumer_socket *sock,
2bba9e53
DG
305 struct ltt_kernel_channel *channel, struct ltt_kernel_session *session,
306 unsigned int monitor)
f1e16794 307{
00e2e675 308 int ret;
f1e16794 309 struct ltt_kernel_stream *stream;
00e2e675
DG
310
311 /* Safety net */
312 assert(channel);
313 assert(session);
314 assert(session->consumer);
f50f23d9 315 assert(sock);
00e2e675
DG
316
317 /* Bail out if consumer is disabled */
318 if (!session->consumer->enabled) {
f73fabfd 319 ret = LTTNG_OK;
00e2e675
DG
320 goto error;
321 }
f1e16794
DG
322
323 DBG("Sending streams of channel %s to kernel consumer",
324 channel->channel->name);
325
2bba9e53 326 ret = kernel_consumer_add_channel(sock, channel, session, monitor);
f1e16794 327 if (ret < 0) {
f1e16794
DG
328 goto error;
329 }
330
331 /* Send streams */
332 cds_list_for_each_entry(stream, &channel->stream_list.head, list) {
333 if (!stream->fd) {
334 continue;
335 }
00e2e675
DG
336
337 /* Add stream on the kernel consumer side. */
2bba9e53
DG
338 ret = kernel_consumer_add_stream(sock, channel, stream, session,
339 monitor);
f1e16794 340 if (ret < 0) {
f1e16794
DG
341 goto error;
342 }
343 }
344
f1e16794
DG
345error:
346 return ret;
347}
348
349/*
350 * Send all stream fds of the kernel session to the consumer.
351 */
f50f23d9
DG
352int kernel_consumer_send_session(struct consumer_socket *sock,
353 struct ltt_kernel_session *session)
f1e16794 354{
2bba9e53 355 int ret, monitor = 0;
f1e16794 356 struct ltt_kernel_channel *chan;
f1e16794 357
00e2e675
DG
358 /* Safety net */
359 assert(session);
360 assert(session->consumer);
f50f23d9 361 assert(sock);
f1e16794 362
00e2e675
DG
363 /* Bail out if consumer is disabled */
364 if (!session->consumer->enabled) {
f73fabfd 365 ret = LTTNG_OK;
00e2e675 366 goto error;
f1e16794
DG
367 }
368
2bba9e53
DG
369 /* Don't monitor the streams on the consumer if in flight recorder. */
370 if (session->output_traces) {
371 monitor = 1;
372 }
373
00e2e675
DG
374 DBG("Sending session stream to kernel consumer");
375
f1e16794 376 if (session->metadata_stream_fd >= 0) {
2bba9e53 377 ret = kernel_consumer_add_metadata(sock, session, monitor);
f1e16794 378 if (ret < 0) {
f1e16794
DG
379 goto error;
380 }
381
00e2e675
DG
382 /* Flag that at least the metadata has been sent to the consumer. */
383 session->consumer_fds_sent = 1;
f1e16794
DG
384 }
385
00e2e675 386 /* Send channel and streams of it */
f1e16794 387 cds_list_for_each_entry(chan, &session->channel_list.head, list) {
2bba9e53
DG
388 ret = kernel_consumer_send_channel_stream(sock, chan, session,
389 monitor);
f1e16794
DG
390 if (ret < 0) {
391 goto error;
392 }
601262d6
JD
393 if (monitor) {
394 /*
395 * Inform the relay that all the streams for the
396 * channel were sent.
397 */
398 ret = kernel_consumer_streams_sent(sock, session, chan->fd);
399 if (ret < 0) {
400 goto error;
401 }
402 }
f1e16794
DG
403 }
404
00e2e675 405 DBG("Kernel consumer FDs of metadata and channel streams sent");
f1e16794
DG
406
407 return 0;
408
409error:
410 return ret;
411}
07b86b52
JD
412
413int kernel_consumer_destroy_channel(struct consumer_socket *socket,
414 struct ltt_kernel_channel *channel)
415{
416 int ret;
417 struct lttcomm_consumer_msg msg;
418
419 assert(channel);
420 assert(socket);
07b86b52
JD
421
422 DBG("Sending kernel consumer destroy channel key %d", channel->fd);
423
53efb85a 424 memset(&msg, 0, sizeof(msg));
07b86b52
JD
425 msg.cmd_type = LTTNG_CONSUMER_DESTROY_CHANNEL;
426 msg.u.destroy_channel.key = channel->fd;
427
428 pthread_mutex_lock(socket->lock);
429 health_code_update();
430
431 ret = consumer_send_msg(socket, &msg);
432 if (ret < 0) {
433 goto error;
434 }
435
436error:
437 health_code_update();
438 pthread_mutex_unlock(socket->lock);
439 return ret;
440}
441
442int kernel_consumer_destroy_metadata(struct consumer_socket *socket,
443 struct ltt_kernel_metadata *metadata)
444{
445 int ret;
446 struct lttcomm_consumer_msg msg;
447
448 assert(metadata);
449 assert(socket);
07b86b52
JD
450
451 DBG("Sending kernel consumer destroy channel key %d", metadata->fd);
452
53efb85a 453 memset(&msg, 0, sizeof(msg));
07b86b52
JD
454 msg.cmd_type = LTTNG_CONSUMER_DESTROY_CHANNEL;
455 msg.u.destroy_channel.key = metadata->fd;
456
457 pthread_mutex_lock(socket->lock);
458 health_code_update();
459
460 ret = consumer_send_msg(socket, &msg);
461 if (ret < 0) {
462 goto error;
463 }
464
465error:
466 health_code_update();
467 pthread_mutex_unlock(socket->lock);
468 return ret;
469}
This page took 0.052868 seconds and 4 git commands to generate.