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