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