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