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