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