Fix: consumer should await for initial streams
[lttng-tools.git] / src / common / kernel-consumer / kernel-consumer.c
... / ...
CommitLineData
1/*
2 * Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
3 * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License, version 2 only,
7 * as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#define _GNU_SOURCE
20#include <assert.h>
21#include <poll.h>
22#include <pthread.h>
23#include <stdlib.h>
24#include <string.h>
25#include <sys/mman.h>
26#include <sys/socket.h>
27#include <sys/types.h>
28#include <inttypes.h>
29#include <unistd.h>
30#include <sys/stat.h>
31
32#include <common/common.h>
33#include <common/kernel-ctl/kernel-ctl.h>
34#include <common/sessiond-comm/sessiond-comm.h>
35#include <common/sessiond-comm/relayd.h>
36#include <common/compat/fcntl.h>
37#include <common/relayd/relayd.h>
38
39#include "kernel-consumer.h"
40
41extern struct lttng_consumer_global_data consumer_data;
42extern int consumer_poll_timeout;
43extern volatile int consumer_quit;
44
45/*
46 * Take a snapshot for a specific fd
47 *
48 * Returns 0 on success, < 0 on error
49 */
50int lttng_kconsumer_take_snapshot(struct lttng_consumer_local_data *ctx,
51 struct lttng_consumer_stream *stream)
52{
53 int ret = 0;
54 int infd = stream->wait_fd;
55
56 ret = kernctl_snapshot(infd);
57 if (ret != 0) {
58 errno = -ret;
59 perror("Getting sub-buffer snapshot.");
60 }
61
62 return ret;
63}
64
65/*
66 * Get the produced position
67 *
68 * Returns 0 on success, < 0 on error
69 */
70int lttng_kconsumer_get_produced_snapshot(
71 struct lttng_consumer_local_data *ctx,
72 struct lttng_consumer_stream *stream,
73 unsigned long *pos)
74{
75 int ret;
76 int infd = stream->wait_fd;
77
78 ret = kernctl_snapshot_get_produced(infd, pos);
79 if (ret != 0) {
80 errno = -ret;
81 perror("kernctl_snapshot_get_produced");
82 }
83
84 return ret;
85}
86
87int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
88 int sock, struct pollfd *consumer_sockpoll)
89{
90 ssize_t ret;
91 struct lttcomm_consumer_msg msg;
92
93 ret = lttcomm_recv_unix_sock(sock, &msg, sizeof(msg));
94 if (ret != sizeof(msg)) {
95 lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_ERROR_RECV_CMD);
96 return ret;
97 }
98 if (msg.cmd_type == LTTNG_CONSUMER_STOP) {
99 return -ENOENT;
100 }
101
102 /* relayd needs RCU read-side protection */
103 rcu_read_lock();
104
105 switch (msg.cmd_type) {
106 case LTTNG_CONSUMER_ADD_RELAYD_SOCKET:
107 {
108 ret = consumer_add_relayd_socket(msg.u.relayd_sock.net_index,
109 msg.u.relayd_sock.type, ctx, sock, consumer_sockpoll,
110 &msg.u.relayd_sock.sock);
111 goto end_nosignal;
112 }
113 case LTTNG_CONSUMER_ADD_CHANNEL:
114 {
115 struct lttng_consumer_channel *new_channel;
116
117 DBG("consumer_add_channel %d", msg.u.channel.channel_key);
118 new_channel = consumer_allocate_channel(msg.u.channel.channel_key,
119 -1, -1,
120 msg.u.channel.mmap_len,
121 msg.u.channel.max_sb_size,
122 msg.u.channel.nb_init_streams);
123 if (new_channel == NULL) {
124 lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_OUTFD_ERROR);
125 goto end_nosignal;
126 }
127 if (ctx->on_recv_channel != NULL) {
128 ret = ctx->on_recv_channel(new_channel);
129 if (ret == 0) {
130 consumer_add_channel(new_channel);
131 } else if (ret < 0) {
132 goto end_nosignal;
133 }
134 } else {
135 consumer_add_channel(new_channel);
136 }
137 goto end_nosignal;
138 }
139 case LTTNG_CONSUMER_ADD_STREAM:
140 {
141 int fd;
142 struct consumer_relayd_sock_pair *relayd = NULL;
143 struct lttng_consumer_stream *new_stream;
144
145 /* block */
146 if (lttng_consumer_poll_socket(consumer_sockpoll) < 0) {
147 rcu_read_unlock();
148 return -EINTR;
149 }
150
151 /* Get stream file descriptor from socket */
152 ret = lttcomm_recv_fds_unix_sock(sock, &fd, 1);
153 if (ret != sizeof(fd)) {
154 lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_ERROR_RECV_FD);
155 rcu_read_unlock();
156 return ret;
157 }
158
159 new_stream = consumer_allocate_stream(msg.u.stream.channel_key,
160 msg.u.stream.stream_key,
161 fd, fd,
162 msg.u.stream.state,
163 msg.u.stream.mmap_len,
164 msg.u.stream.output,
165 msg.u.stream.path_name,
166 msg.u.stream.uid,
167 msg.u.stream.gid,
168 msg.u.stream.net_index,
169 msg.u.stream.metadata_flag);
170 if (new_stream == NULL) {
171 lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_OUTFD_ERROR);
172 goto end_nosignal;
173 }
174
175 /*
176 * The buffer flush is done on the session daemon side for the kernel
177 * so no need for the stream "hangup_flush_done" variable to be
178 * tracked. This is important for a kernel stream since we don't rely
179 * on the flush state of the stream to read data. It's not the case for
180 * user space tracing.
181 */
182 new_stream->hangup_flush_done = 0;
183
184 /* The stream is not metadata. Get relayd reference if exists. */
185 relayd = consumer_find_relayd(msg.u.stream.net_index);
186 if (relayd != NULL) {
187 /* Add stream on the relayd */
188 pthread_mutex_lock(&relayd->ctrl_sock_mutex);
189 ret = relayd_add_stream(&relayd->control_sock,
190 msg.u.stream.name, msg.u.stream.path_name,
191 &new_stream->relayd_stream_id);
192 pthread_mutex_unlock(&relayd->ctrl_sock_mutex);
193 if (ret < 0) {
194 goto end_nosignal;
195 }
196 } else if (msg.u.stream.net_index != -1) {
197 ERR("Network sequence index %d unknown. Not adding stream.",
198 msg.u.stream.net_index);
199 free(new_stream);
200 goto end_nosignal;
201 }
202
203 /* Send stream to the metadata thread */
204 if (new_stream->metadata_flag) {
205 if (ctx->on_recv_stream) {
206 ret = ctx->on_recv_stream(new_stream);
207 if (ret < 0) {
208 goto end_nosignal;
209 }
210 }
211
212 do {
213 ret = write(ctx->consumer_metadata_pipe[1], new_stream,
214 sizeof(struct lttng_consumer_stream));
215 } while (ret < 0 && errno == EINTR);
216 if (ret < 0) {
217 PERROR("write metadata pipe");
218 }
219 } else {
220 if (ctx->on_recv_stream) {
221 ret = ctx->on_recv_stream(new_stream);
222 if (ret < 0) {
223 goto end_nosignal;
224 }
225 }
226 consumer_add_stream(new_stream);
227 }
228
229 DBG("Kernel consumer_add_stream (%d)", fd);
230 break;
231 }
232 case LTTNG_CONSUMER_UPDATE_STREAM:
233 {
234 rcu_read_unlock();
235 return -ENOSYS;
236 }
237 case LTTNG_CONSUMER_DESTROY_RELAYD:
238 {
239 uint64_t index = msg.u.destroy_relayd.net_seq_idx;
240 struct consumer_relayd_sock_pair *relayd;
241
242 DBG("Kernel consumer destroying relayd %" PRIu64, index);
243
244 /* Get relayd reference if exists. */
245 relayd = consumer_find_relayd(index);
246 if (relayd == NULL) {
247 ERR("Unable to find relayd %" PRIu64, index);
248 goto end_nosignal;
249 }
250
251 /*
252 * Each relayd socket pair has a refcount of stream attached to it
253 * which tells if the relayd is still active or not depending on the
254 * refcount value.
255 *
256 * This will set the destroy flag of the relayd object and destroy it
257 * if the refcount reaches zero when called.
258 *
259 * The destroy can happen either here or when a stream fd hangs up.
260 */
261 consumer_flag_relayd_for_destroy(relayd);
262
263 goto end_nosignal;
264 }
265 default:
266 goto end_nosignal;
267 }
268
269 /*
270 * Wake-up the other end by writing a null byte in the pipe (non-blocking).
271 * Important note: Because writing into the pipe is non-blocking (and
272 * therefore we allow dropping wakeup data, as long as there is wakeup data
273 * present in the pipe buffer to wake up the other end), the other end
274 * should perform the following sequence for waiting:
275 *
276 * 1) empty the pipe (reads).
277 * 2) perform update operation.
278 * 3) wait on the pipe (poll).
279 */
280 do {
281 ret = write(ctx->consumer_poll_pipe[1], "", 1);
282 } while (ret < 0 && errno == EINTR);
283end_nosignal:
284 rcu_read_unlock();
285
286 /*
287 * Return 1 to indicate success since the 0 value can be a socket
288 * shutdown during the recv() or send() call.
289 */
290 return 1;
291}
292
293/*
294 * Consume data on a file descriptor and write it on a trace file.
295 */
296ssize_t lttng_kconsumer_read_subbuffer(struct lttng_consumer_stream *stream,
297 struct lttng_consumer_local_data *ctx)
298{
299 unsigned long len, subbuf_size, padding;
300 int err;
301 ssize_t ret = 0;
302 int infd = stream->wait_fd;
303
304 DBG("In read_subbuffer (infd : %d)", infd);
305 /* Get the next subbuffer */
306 err = kernctl_get_next_subbuf(infd);
307 if (err != 0) {
308 ret = err;
309 /*
310 * This is a debug message even for single-threaded consumer,
311 * because poll() have more relaxed criterions than get subbuf,
312 * so get_subbuf may fail for short race windows where poll()
313 * would issue wakeups.
314 */
315 DBG("Reserving sub buffer failed (everything is normal, "
316 "it is due to concurrency)");
317 goto end;
318 }
319
320 /* Get the full subbuffer size including padding */
321 err = kernctl_get_padded_subbuf_size(infd, &len);
322 if (err != 0) {
323 errno = -err;
324 perror("Getting sub-buffer len failed.");
325 ret = err;
326 goto end;
327 }
328
329 switch (stream->output) {
330 case LTTNG_EVENT_SPLICE:
331
332 /*
333 * XXX: The lttng-modules splice "actor" does not handle copying
334 * partial pages hence only using the subbuffer size without the
335 * padding makes the splice fail.
336 */
337 subbuf_size = len;
338 padding = 0;
339
340 /* splice the subbuffer to the tracefile */
341 ret = lttng_consumer_on_read_subbuffer_splice(ctx, stream, subbuf_size,
342 padding);
343 /*
344 * XXX: Splice does not support network streaming so the return value
345 * is simply checked against subbuf_size and not like the mmap() op.
346 */
347 if (ret != subbuf_size) {
348 /*
349 * display the error but continue processing to try
350 * to release the subbuffer
351 */
352 ERR("Error splicing to tracefile (ret: %zd != len: %lu)",
353 ret, subbuf_size);
354 }
355 break;
356 case LTTNG_EVENT_MMAP:
357 /* Get subbuffer size without padding */
358 err = kernctl_get_subbuf_size(infd, &subbuf_size);
359 if (err != 0) {
360 errno = -err;
361 perror("Getting sub-buffer len failed.");
362 ret = err;
363 goto end;
364 }
365
366 /* Make sure the tracer is not gone mad on us! */
367 assert(len >= subbuf_size);
368
369 padding = len - subbuf_size;
370
371 /* write the subbuffer to the tracefile */
372 ret = lttng_consumer_on_read_subbuffer_mmap(ctx, stream, subbuf_size,
373 padding);
374 /*
375 * The mmap operation should write subbuf_size amount of data when
376 * network streaming or the full padding (len) size when we are _not_
377 * streaming.
378 */
379 if ((ret != subbuf_size && stream->net_seq_idx != -1) ||
380 (ret != len && stream->net_seq_idx == -1)) {
381 /*
382 * Display the error but continue processing to try to release the
383 * subbuffer
384 */
385 ERR("Error writing to tracefile "
386 "(ret: %zd != len: %lu != subbuf_size: %lu)",
387 ret, len, subbuf_size);
388 }
389 break;
390 default:
391 ERR("Unknown output method");
392 ret = -1;
393 }
394
395 err = kernctl_put_next_subbuf(infd);
396 if (err != 0) {
397 errno = -err;
398 if (errno == EFAULT) {
399 perror("Error in unreserving sub buffer\n");
400 } else if (errno == EIO) {
401 /* Should never happen with newer LTTng versions */
402 perror("Reader has been pushed by the writer, last sub-buffer corrupted.");
403 }
404
405 ret = -err;
406 goto end;
407 }
408
409end:
410 return ret;
411}
412
413int lttng_kconsumer_on_recv_stream(struct lttng_consumer_stream *stream)
414{
415 int ret;
416
417 /* Opening the tracefile in write mode */
418 if (strlen(stream->path_name) > 0 && stream->net_seq_idx == -1) {
419 ret = run_as_open(stream->path_name,
420 O_WRONLY|O_CREAT|O_TRUNC,
421 S_IRWXU|S_IRWXG|S_IRWXO,
422 stream->uid, stream->gid);
423 if (ret < 0) {
424 ERR("Opening %s", stream->path_name);
425 perror("open");
426 goto error;
427 }
428 stream->out_fd = ret;
429 }
430
431 if (stream->output == LTTNG_EVENT_MMAP) {
432 /* get the len of the mmap region */
433 unsigned long mmap_len;
434
435 ret = kernctl_get_mmap_len(stream->wait_fd, &mmap_len);
436 if (ret != 0) {
437 errno = -ret;
438 perror("kernctl_get_mmap_len");
439 goto error_close_fd;
440 }
441 stream->mmap_len = (size_t) mmap_len;
442
443 stream->mmap_base = mmap(NULL, stream->mmap_len,
444 PROT_READ, MAP_PRIVATE, stream->wait_fd, 0);
445 if (stream->mmap_base == MAP_FAILED) {
446 perror("Error mmaping");
447 ret = -1;
448 goto error_close_fd;
449 }
450 }
451
452 /* we return 0 to let the library handle the FD internally */
453 return 0;
454
455error_close_fd:
456 {
457 int err;
458
459 err = close(stream->out_fd);
460 assert(!err);
461 }
462error:
463 return ret;
464}
465
This page took 0.02417 seconds and 4 git commands to generate.