On-disk multiple tracefiles circular buffer
[lttng-tools.git] / src / bin / lttng-sessiond / kernel-consumer.c
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>
27
28 #include "consumer.h"
29 #include "health.h"
30 #include "kernel-consumer.h"
31
32 /*
33 * Sending a single channel to the consumer with command ADD_CHANNEL.
34 */
35 int kernel_consumer_add_channel(struct consumer_socket *sock,
36 struct ltt_kernel_channel *channel, struct ltt_kernel_session *session)
37 {
38 int ret;
39 char tmp_path[PATH_MAX];
40 const char *pathname;
41 struct lttcomm_consumer_msg lkm;
42 struct consumer_output *consumer;
43
44 /* Safety net */
45 assert(channel);
46 assert(session);
47 assert(session->consumer);
48
49 consumer = session->consumer;
50
51 DBG("Kernel consumer adding channel %s to kernel consumer",
52 channel->channel->name);
53
54 /* Get the right path name destination */
55 if (consumer->type == CONSUMER_DST_LOCAL) {
56 /* Set application path to the destination path */
57 ret = snprintf(tmp_path, sizeof(tmp_path), "%s/%s",
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
85 /* Prep channel message structure */
86 consumer_init_channel_comm_msg(&lkm,
87 LTTNG_CONSUMER_ADD_CHANNEL,
88 channel->fd,
89 session->id,
90 pathname,
91 session->uid,
92 session->gid,
93 consumer->net_seq_index,
94 channel->channel->name,
95 channel->stream_count,
96 channel->channel->attr.output,
97 CONSUMER_CHANNEL_TYPE_DATA,
98 channel->channel->attr.tracefile_size,
99 channel->channel->attr.tracefile_count);
100
101 health_code_update();
102
103 ret = consumer_send_channel(sock, &lkm);
104 if (ret < 0) {
105 goto error;
106 }
107
108 health_code_update();
109
110 error:
111 return ret;
112 }
113
114 /*
115 * Sending metadata to the consumer with command ADD_CHANNEL and ADD_STREAM.
116 */
117 int kernel_consumer_add_metadata(struct consumer_socket *sock,
118 struct ltt_kernel_session *session)
119 {
120 int ret;
121 char tmp_path[PATH_MAX];
122 const char *pathname;
123 struct lttcomm_consumer_msg lkm;
124 struct consumer_output *consumer;
125
126 /* Safety net */
127 assert(session);
128 assert(session->consumer);
129 assert(sock);
130
131 DBG("Sending metadata %d to kernel consumer", session->metadata_stream_fd);
132
133 /* Get consumer output pointer */
134 consumer = session->consumer;
135
136 /* Get the right path name destination */
137 if (consumer->type == CONSUMER_DST_LOCAL) {
138 /* Set application path to the destination path */
139 ret = snprintf(tmp_path, sizeof(tmp_path), "%s/%s",
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);
157 } else {
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);
165 }
166
167 /* Prep channel message structure */
168 consumer_init_channel_comm_msg(&lkm,
169 LTTNG_CONSUMER_ADD_CHANNEL,
170 session->metadata->fd,
171 session->id,
172 pathname,
173 session->uid,
174 session->gid,
175 consumer->net_seq_index,
176 DEFAULT_METADATA_NAME,
177 1,
178 DEFAULT_KERNEL_CHANNEL_OUTPUT,
179 CONSUMER_CHANNEL_TYPE_METADATA,
180 0, 0);
181
182 health_code_update();
183
184 ret = consumer_send_channel(sock, &lkm);
185 if (ret < 0) {
186 goto error;
187 }
188
189 health_code_update();
190
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,
196 0); /* CPU: 0 for metadata. */
197
198 health_code_update();
199
200 /* Send stream and file descriptor */
201 ret = consumer_send_stream(sock, consumer, &lkm,
202 &session->metadata_stream_fd, 1);
203 if (ret < 0) {
204 goto error;
205 }
206
207 health_code_update();
208
209 error:
210 return ret;
211 }
212
213 /*
214 * Sending a single stream to the consumer with command ADD_STREAM.
215 */
216 int kernel_consumer_add_stream(struct consumer_socket *sock,
217 struct ltt_kernel_channel *channel, struct ltt_kernel_stream *stream,
218 struct ltt_kernel_session *session)
219 {
220 int ret;
221 struct lttcomm_consumer_msg lkm;
222 struct consumer_output *consumer;
223
224 assert(channel);
225 assert(stream);
226 assert(session);
227 assert(session->consumer);
228 assert(sock);
229
230 DBG("Sending stream %d of channel %s to kernel consumer",
231 stream->fd, channel->channel->name);
232
233 /* Get consumer output pointer */
234 consumer = session->consumer;
235
236 /* Prep stream consumer message */
237 consumer_init_stream_comm_msg(&lkm,
238 LTTNG_CONSUMER_ADD_STREAM,
239 channel->fd,
240 stream->fd,
241 stream->cpu);
242
243 health_code_update();
244
245 /* Send stream and file descriptor */
246 ret = consumer_send_stream(sock, consumer, &lkm, &stream->fd, 1);
247 if (ret < 0) {
248 goto error;
249 }
250
251 health_code_update();
252
253 error:
254 return ret;
255 }
256
257 /*
258 * Send all stream fds of kernel channel to the consumer.
259 */
260 int kernel_consumer_send_channel_stream(struct consumer_socket *sock,
261 struct ltt_kernel_channel *channel, struct ltt_kernel_session *session)
262 {
263 int ret;
264 struct ltt_kernel_stream *stream;
265
266 /* Safety net */
267 assert(channel);
268 assert(session);
269 assert(session->consumer);
270 assert(sock);
271
272 /* Bail out if consumer is disabled */
273 if (!session->consumer->enabled) {
274 ret = LTTNG_OK;
275 goto error;
276 }
277
278 DBG("Sending streams of channel %s to kernel consumer",
279 channel->channel->name);
280
281 ret = kernel_consumer_add_channel(sock, channel, session);
282 if (ret < 0) {
283 goto error;
284 }
285
286 /* Send streams */
287 cds_list_for_each_entry(stream, &channel->stream_list.head, list) {
288 if (!stream->fd) {
289 continue;
290 }
291
292 /* Add stream on the kernel consumer side. */
293 ret = kernel_consumer_add_stream(sock, channel, stream, session);
294 if (ret < 0) {
295 goto error;
296 }
297 }
298
299 error:
300 return ret;
301 }
302
303 /*
304 * Send all stream fds of the kernel session to the consumer.
305 */
306 int kernel_consumer_send_session(struct consumer_socket *sock,
307 struct ltt_kernel_session *session)
308 {
309 int ret;
310 struct ltt_kernel_channel *chan;
311
312 /* Safety net */
313 assert(session);
314 assert(session->consumer);
315 assert(sock);
316
317 /* Bail out if consumer is disabled */
318 if (!session->consumer->enabled) {
319 ret = LTTNG_OK;
320 goto error;
321 }
322
323 DBG("Sending session stream to kernel consumer");
324
325 if (session->metadata_stream_fd >= 0) {
326 ret = kernel_consumer_add_metadata(sock, session);
327 if (ret < 0) {
328 goto error;
329 }
330
331 /* Flag that at least the metadata has been sent to the consumer. */
332 session->consumer_fds_sent = 1;
333 }
334
335 /* Send channel and streams of it */
336 cds_list_for_each_entry(chan, &session->channel_list.head, list) {
337 ret = kernel_consumer_send_channel_stream(sock, chan, session);
338 if (ret < 0) {
339 goto error;
340 }
341 }
342
343 DBG("Kernel consumer FDs of metadata and channel streams sent");
344
345 return 0;
346
347 error:
348 return ret;
349 }
This page took 0.036648 seconds and 5 git commands to generate.