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