fix: ust comm error handling segfault
[lttng-ust.git] / liblttng-ust-ctl / ustctl.c
CommitLineData
57773204
MD
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
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; only version 2
8 * of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
9d335227 20#define _GNU_SOURCE
57773204 21#include <string.h>
4318ae1b
MD
22#include <lttng/ust-ctl.h>
23#include <lttng/ust-abi.h>
c1fca457 24#include <lttng/ust-events.h>
7a784989 25#include <sys/mman.h>
44c72f10
MD
26
27#include <usterr-signal-safe.h>
b728d87e 28#include <ust-comm.h>
57773204
MD
29
30#include "../libringbuffer/backend.h"
31#include "../libringbuffer/frontend.h"
32
6b120308
MD
33volatile enum ust_loglevel ust_loglevel;
34
57773204 35static
61f02aea 36void init_object(struct lttng_ust_object_data *data)
57773204
MD
37{
38 data->handle = -1;
39 data->shm_fd = -1;
40 data->wait_fd = -1;
41 data->memory_map_size = 0;
42}
43
2be0e72c
MD
44int ustctl_release_handle(int sock, int handle)
45{
46 struct ustcomm_ust_msg lum;
47 struct ustcomm_ust_reply lur;
48 int ret;
49
50 if (sock >= 0) {
51 memset(&lum, 0, sizeof(lum));
52 lum.handle = handle;
53 lum.cmd = LTTNG_UST_RELEASE;
54 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
55 if (ret < 0) {
56 return ret;
57 }
58 }
59 return 0;
60}
12388166
MD
61/*
62 * If sock is negative, it means we don't have to notify the other side
63 * (e.g. application has already vanished).
64 */
d26228ae 65int ustctl_release_object(int sock, struct lttng_ust_object_data *data)
57773204 66{
57773204
MD
67 int ret;
68
d26228ae
MD
69 if (data->shm_fd >= 0) {
70 ret = close(data->shm_fd);
71 if (ret < 0) {
72 return ret;
73 }
74 }
75 if (data->wait_fd >= 0) {
76 ret = close(data->wait_fd);
77 if (ret < 0) {
78 return ret;
79 }
80 }
2be0e72c 81 return ustctl_release_handle(sock, data->handle);
57773204
MD
82}
83
1c5e467e
MD
84/*
85 * Send registration done packet to the application.
86 */
87int ustctl_register_done(int sock)
88{
89 struct ustcomm_ust_msg lum;
90 struct ustcomm_ust_reply lur;
91 int ret;
92
93 DBG("Sending register done command to %d", sock);
94 memset(&lum, 0, sizeof(lum));
95 lum.handle = LTTNG_UST_ROOT_HANDLE;
96 lum.cmd = LTTNG_UST_REGISTER_DONE;
97 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
98 if (ret)
99 return ret;
100 if (lur.ret_code != USTCOMM_OK) {
101 DBG("Return code: %s", ustcomm_get_readable_code(lur.ret_code));
102 goto error;
103 }
104 return 0;
105
106error:
107 return -1;
108}
109
57773204
MD
110/*
111 * returns session handle.
112 */
113int ustctl_create_session(int sock)
114{
115 struct ustcomm_ust_msg lum;
116 struct ustcomm_ust_reply lur;
117 int ret, session_handle;
118
119 /* Create session */
120 memset(&lum, 0, sizeof(lum));
121 lum.handle = LTTNG_UST_ROOT_HANDLE;
122 lum.cmd = LTTNG_UST_SESSION;
123 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
124 if (ret)
125 return ret;
126 session_handle = lur.ret_val;
127 DBG("received session handle %u", session_handle);
128 return session_handle;
129}
130
131/* open the metadata global channel */
132int ustctl_open_metadata(int sock, int session_handle,
133 struct lttng_ust_channel_attr *chops,
61f02aea 134 struct lttng_ust_object_data **_metadata_data)
57773204
MD
135{
136 struct ustcomm_ust_msg lum;
137 struct ustcomm_ust_reply lur;
61f02aea 138 struct lttng_ust_object_data *metadata_data;
eeee05f3 139 int ret, err = 0;
57773204
MD
140
141 metadata_data = malloc(sizeof(*metadata_data));
142 if (!metadata_data)
143 return -ENOMEM;
144 init_object(metadata_data);
145 /* Create metadata channel */
146 memset(&lum, 0, sizeof(lum));
147 lum.handle = session_handle;
148 lum.cmd = LTTNG_UST_METADATA;
149 lum.u.channel.overwrite = chops->overwrite;
150 lum.u.channel.subbuf_size = chops->subbuf_size;
151 lum.u.channel.num_subbuf = chops->num_subbuf;
152 lum.u.channel.switch_timer_interval = chops->switch_timer_interval;
153 lum.u.channel.read_timer_interval = chops->read_timer_interval;
154 lum.u.channel.output = chops->output;
155 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
156 if (ret) {
157 free(metadata_data);
158 return ret;
159 }
160 if (lur.ret_code != USTCOMM_OK) {
161 free(metadata_data);
162 return lur.ret_code;
163 }
164 metadata_data->handle = lur.ret_val;
165 DBG("received metadata handle %u", metadata_data->handle);
166 metadata_data->memory_map_size = lur.u.channel.memory_map_size;
167 /* get shm fd */
168 ret = ustcomm_recv_fd(sock);
169 if (ret < 0)
eeee05f3
MD
170 err = 1;
171 else
172 metadata_data->shm_fd = ret;
173 /*
174 * We need to get the second FD even if the first fails, because
175 * libust expects us to read the two FDs.
176 */
57773204
MD
177 /* get wait fd */
178 ret = ustcomm_recv_fd(sock);
179 if (ret < 0)
eeee05f3
MD
180 err = 1;
181 else
182 metadata_data->wait_fd = ret;
183 if (err)
57773204 184 goto error;
57773204
MD
185 *_metadata_data = metadata_data;
186 return 0;
187
188error:
d26228ae 189 (void) ustctl_release_object(sock, metadata_data);
38970582 190 free(metadata_data);
57773204
MD
191 return -EINVAL;
192}
193
194int ustctl_create_channel(int sock, int session_handle,
195 struct lttng_ust_channel_attr *chops,
61f02aea 196 struct lttng_ust_object_data **_channel_data)
57773204
MD
197{
198 struct ustcomm_ust_msg lum;
199 struct ustcomm_ust_reply lur;
61f02aea 200 struct lttng_ust_object_data *channel_data;
eeee05f3 201 int ret, err = 0;
57773204
MD
202
203 channel_data = malloc(sizeof(*channel_data));
204 if (!channel_data)
205 return -ENOMEM;
206 init_object(channel_data);
207 /* Create metadata channel */
208 memset(&lum, 0, sizeof(lum));
209 lum.handle = session_handle;
210 lum.cmd = LTTNG_UST_CHANNEL;
211 lum.u.channel.overwrite = chops->overwrite;
212 lum.u.channel.subbuf_size = chops->subbuf_size;
213 lum.u.channel.num_subbuf = chops->num_subbuf;
214 lum.u.channel.switch_timer_interval = chops->switch_timer_interval;
215 lum.u.channel.read_timer_interval = chops->read_timer_interval;
216 lum.u.channel.output = chops->output;
217 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
218 if (ret) {
219 free(channel_data);
220 return ret;
221 }
222 if (lur.ret_code != USTCOMM_OK) {
223 free(channel_data);
224 return lur.ret_code;
225 }
226 channel_data->handle = lur.ret_val;
227 DBG("received channel handle %u", channel_data->handle);
228 channel_data->memory_map_size = lur.u.channel.memory_map_size;
229 /* get shm fd */
230 ret = ustcomm_recv_fd(sock);
231 if (ret < 0)
eeee05f3
MD
232 err = 1;
233 else
234 channel_data->shm_fd = ret;
235 /*
236 * We need to get the second FD even if the first fails, because
237 * libust expects us to read the two FDs.
238 */
57773204
MD
239 /* get wait fd */
240 ret = ustcomm_recv_fd(sock);
241 if (ret < 0)
eeee05f3
MD
242 err = 1;
243 else
244 channel_data->wait_fd = ret;
245 if (err)
57773204 246 goto error;
57773204
MD
247 *_channel_data = channel_data;
248 return 0;
249
250error:
d26228ae 251 (void) ustctl_release_object(sock, channel_data);
38970582 252 free(channel_data);
57773204
MD
253 return -EINVAL;
254}
255
256/*
257 * Return -ENOENT if no more stream is available for creation.
258 * Return 0 on success.
259 * Return negative error value on error.
260 */
61f02aea
MD
261int ustctl_create_stream(int sock, struct lttng_ust_object_data *channel_data,
262 struct lttng_ust_object_data **_stream_data)
57773204
MD
263{
264 struct ustcomm_ust_msg lum;
265 struct ustcomm_ust_reply lur;
61f02aea 266 struct lttng_ust_object_data *stream_data;
eeee05f3 267 int ret, fd, err = 0;
57773204
MD
268
269 stream_data = malloc(sizeof(*stream_data));
270 if (!stream_data)
271 return -ENOMEM;
272 init_object(stream_data);
273 memset(&lum, 0, sizeof(lum));
274 lum.handle = channel_data->handle;
275 lum.cmd = LTTNG_UST_STREAM;
276 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
277 if (ret) {
278 free(stream_data);
279 return ret;
280 }
281 if (lur.ret_code != USTCOMM_OK) {
282 free(stream_data);
283 return lur.ret_code;
284 }
285
286 stream_data->handle = lur.ret_val;
287 DBG("received stream handle %u", stream_data->handle);
288 stream_data->memory_map_size = lur.u.stream.memory_map_size;
289 /* get shm fd */
290 fd = ustcomm_recv_fd(sock);
291 if (fd < 0)
eeee05f3
MD
292 err = 1;
293 else
294 stream_data->shm_fd = fd;
295 /*
296 * We need to get the second FD even if the first fails, because
297 * libust expects us to read the two FDs.
298 */
57773204
MD
299 /* get wait fd */
300 fd = ustcomm_recv_fd(sock);
301 if (fd < 0)
eeee05f3
MD
302 err = 1;
303 else
304 stream_data->wait_fd = fd;
305 if (err)
57773204 306 goto error;
57773204
MD
307 *_stream_data = stream_data;
308 return ret;
309
310error:
d26228ae 311 (void) ustctl_release_object(sock, stream_data);
38970582 312 free(stream_data);
57773204
MD
313 return -EINVAL;
314}
315
316int ustctl_create_event(int sock, struct lttng_ust_event *ev,
61f02aea
MD
317 struct lttng_ust_object_data *channel_data,
318 struct lttng_ust_object_data **_event_data)
57773204
MD
319{
320 struct ustcomm_ust_msg lum;
321 struct ustcomm_ust_reply lur;
61f02aea 322 struct lttng_ust_object_data *event_data;
57773204
MD
323 int ret;
324
325 event_data = malloc(sizeof(*event_data));
326 if (!event_data)
327 return -ENOMEM;
328 init_object(event_data);
329 memset(&lum, 0, sizeof(lum));
330 lum.handle = channel_data->handle;
331 lum.cmd = LTTNG_UST_EVENT;
332 strncpy(lum.u.event.name, ev->name,
333 LTTNG_UST_SYM_NAME_LEN);
334 lum.u.event.instrumentation = ev->instrumentation;
457a6b58
MD
335 lum.u.event.loglevel_type = ev->loglevel_type;
336 lum.u.event.loglevel = ev->loglevel;
57773204
MD
337 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
338 if (ret) {
339 free(event_data);
340 return ret;
341 }
342 event_data->handle = lur.ret_val;
343 DBG("received event handle %u", event_data->handle);
344 *_event_data = event_data;
345 return 0;
346}
347
348int ustctl_add_context(int sock, struct lttng_ust_context *ctx,
61f02aea
MD
349 struct lttng_ust_object_data *obj_data,
350 struct lttng_ust_object_data **_context_data)
57773204
MD
351{
352 struct ustcomm_ust_msg lum;
353 struct ustcomm_ust_reply lur;
61f02aea 354 struct lttng_ust_object_data *context_data;
57773204
MD
355 int ret;
356
357 context_data = malloc(sizeof(*context_data));
358 if (!context_data)
359 return -ENOMEM;
360 init_object(context_data);
361 memset(&lum, 0, sizeof(lum));
3039d8ed 362 lum.handle = obj_data->handle;
57773204
MD
363 lum.cmd = LTTNG_UST_CONTEXT;
364 lum.u.context.ctx = ctx->ctx;
365 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
366 if (ret) {
367 free(context_data);
368 return ret;
369 }
370 context_data->handle = lur.ret_val;
371 DBG("received context handle %u", context_data->handle);
372 *_context_data = context_data;
373 return ret;
374}
375
376/* Enable event, channel and session ioctl */
61f02aea 377int ustctl_enable(int sock, struct lttng_ust_object_data *object)
57773204
MD
378{
379 struct ustcomm_ust_msg lum;
380 struct ustcomm_ust_reply lur;
381 int ret;
382
383 memset(&lum, 0, sizeof(lum));
384 lum.handle = object->handle;
385 lum.cmd = LTTNG_UST_ENABLE;
386 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
387 if (ret)
388 return ret;
389 DBG("enabled handle %u", object->handle);
390 return 0;
391}
392
393/* Disable event, channel and session ioctl */
61f02aea 394int ustctl_disable(int sock, struct lttng_ust_object_data *object)
57773204
MD
395{
396 struct ustcomm_ust_msg lum;
397 struct ustcomm_ust_reply lur;
398 int ret;
399
400 memset(&lum, 0, sizeof(lum));
401 lum.handle = object->handle;
402 lum.cmd = LTTNG_UST_DISABLE;
403 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
404 if (ret)
405 return ret;
406 DBG("disable handle %u", object->handle);
407 return 0;
408}
409
4a6ca058 410int ustctl_start_session(int sock, int handle)
57773204 411{
61f02aea 412 struct lttng_ust_object_data obj;
4a6ca058
MD
413
414 obj.handle = handle;
415 return ustctl_enable(sock, &obj);
57773204
MD
416}
417
4a6ca058 418int ustctl_stop_session(int sock, int handle)
57773204 419{
61f02aea 420 struct lttng_ust_object_data obj;
4a6ca058
MD
421
422 obj.handle = handle;
423 return ustctl_disable(sock, &obj);
57773204
MD
424}
425
57773204
MD
426int ustctl_tracepoint_list(int sock)
427{
b115631f
MD
428 struct ustcomm_ust_msg lum;
429 struct ustcomm_ust_reply lur;
430 int ret, tp_list_handle;
431
432 memset(&lum, 0, sizeof(lum));
433 lum.handle = LTTNG_UST_ROOT_HANDLE;
434 lum.cmd = LTTNG_UST_TRACEPOINT_LIST;
435 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
436 if (ret)
437 return ret;
438 tp_list_handle = lur.ret_val;
439 DBG("received tracepoint list handle %u", tp_list_handle);
440 return tp_list_handle;
441}
442
443int ustctl_tracepoint_list_get(int sock, int tp_list_handle,
cbef6901 444 struct lttng_ust_tracepoint_iter *iter)
b115631f
MD
445{
446 struct ustcomm_ust_msg lum;
447 struct ustcomm_ust_reply lur;
448 int ret;
449
450 memset(&lum, 0, sizeof(lum));
451 lum.handle = tp_list_handle;
452 lum.cmd = LTTNG_UST_TRACEPOINT_LIST_GET;
453 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
454 if (ret)
455 return ret;
882a56d7 456 DBG("received tracepoint list entry name %s loglevel %d",
cbef6901 457 lur.u.tracepoint.name,
882a56d7 458 lur.u.tracepoint.loglevel);
cbef6901 459 memcpy(iter, &lur.u.tracepoint, sizeof(*iter));
b115631f 460 return 0;
57773204
MD
461}
462
463int ustctl_tracer_version(int sock, struct lttng_ust_tracer_version *v)
464{
465 struct ustcomm_ust_msg lum;
466 struct ustcomm_ust_reply lur;
467 int ret;
468
469 memset(&lum, 0, sizeof(lum));
470 lum.handle = LTTNG_UST_ROOT_HANDLE;
471 lum.cmd = LTTNG_UST_TRACER_VERSION;
472 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
473 if (ret)
474 return ret;
475 memcpy(v, &lur.u.version, sizeof(*v));
476 DBG("received tracer version");
477 return 0;
478}
479
480int ustctl_wait_quiescent(int sock)
481{
482 struct ustcomm_ust_msg lum;
483 struct ustcomm_ust_reply lur;
484 int ret;
485
486 memset(&lum, 0, sizeof(lum));
487 lum.handle = LTTNG_UST_ROOT_HANDLE;
488 lum.cmd = LTTNG_UST_WAIT_QUIESCENT;
489 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
490 if (ret)
491 return ret;
492 DBG("waited for quiescent state");
493 return 0;
494}
495
496int ustctl_calibrate(int sock, struct lttng_ust_calibrate *calibrate)
497{
498 return -ENOSYS;
499}
500
f1fffc57
MD
501int ustctl_sock_flush_buffer(int sock, struct lttng_ust_object_data *object)
502{
503 struct ustcomm_ust_msg lum;
504 struct ustcomm_ust_reply lur;
505 int ret;
506
507 memset(&lum, 0, sizeof(lum));
508 lum.handle = object->handle;
509 lum.cmd = LTTNG_UST_FLUSH_BUFFER;
510 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
511 if (ret)
512 return ret;
513 DBG("flushed buffer handle %u", object->handle);
514 return 0;
515}
516
57773204
MD
517/* Buffer operations */
518
519/* Map channel shm into process memory */
38fae1d3 520struct lttng_ust_shm_handle *ustctl_map_channel(struct lttng_ust_object_data *chan_data)
57773204 521{
38fae1d3 522 struct lttng_ust_shm_handle *handle;
57773204
MD
523 struct channel *chan;
524 size_t chan_size;
c1fca457 525 struct lttng_ust_lib_ring_buffer_config *config;
7a784989 526 int ret;
57773204
MD
527
528 handle = channel_handle_create(chan_data->shm_fd,
529 chan_data->wait_fd,
530 chan_data->memory_map_size);
531 if (!handle) {
532 ERR("create handle error");
533 return NULL;
534 }
535 /*
0bfe09ec
MD
536 * Set to -1, and then close the shm fd, and set the handle shm
537 * fd to -1 too. We don't need the shm fds after they have been
538 * mapped.
539 * The wait_fd is set to -1 in chan_data because it is now owned
540 * by the handle.
57773204
MD
541 */
542 chan_data->shm_fd = -1;
543 chan_data->wait_fd = -1;
544
0bfe09ec
MD
545 /* chan is object 0. This is hardcoded. */
546 if (handle->table->objects[0].shm_fd >= 0) {
547 ret = close(handle->table->objects[0].shm_fd);
548 if (ret) {
549 perror("Error closing shm_fd");
550 }
551 handle->table->objects[0].shm_fd = -1;
552 }
553
57773204
MD
554 /*
555 * TODO: add consistency checks to be resilient if the
556 * application try to feed us with incoherent channel structure
557 * values.
558 */
559 chan = shmp(handle, handle->chan);
560 /* chan is object 0. This is hardcoded. */
561 chan_size = handle->table->objects[0].allocated_len;
562 handle->shadow_chan = malloc(chan_size);
563 if (!handle->shadow_chan) {
564 channel_destroy(chan, handle, 1);
565 return NULL;
566 }
567 memcpy(handle->shadow_chan, chan, chan_size);
bbc70d1b
MD
568 /*
569 * The callback pointers in the producer are invalid in the
c1fca457 570 * consumer. We need to look them up here.
bbc70d1b 571 */
c1fca457
MD
572 config = &handle->shadow_chan->backend.config;
573 switch (config->client_type) {
574 case LTTNG_CLIENT_METADATA:
575 memcpy(&config->cb, lttng_client_callbacks_metadata,
576 sizeof(config->cb));
577 break;
578 case LTTNG_CLIENT_DISCARD:
579 memcpy(&config->cb, lttng_client_callbacks_discard,
580 sizeof(config->cb));
581 break;
582 case LTTNG_CLIENT_OVERWRITE:
583 memcpy(&config->cb, lttng_client_callbacks_overwrite,
584 sizeof(config->cb));
585 break;
586 default:
587 ERR("Unknown client type %d", config->client_type);
588 channel_destroy(chan, handle, 1);
589 return NULL;
590 }
7a784989
MD
591 /* Replace the object table pointer. */
592 ret = munmap(handle->table->objects[0].memory_map,
593 handle->table->objects[0].memory_map_size);
594 if (ret) {
595 perror("munmap");
596 assert(0);
597 }
598 handle->table->objects[0].memory_map = (char *) handle->shadow_chan;
599 handle->table->objects[0].is_shadow = 1;
57773204
MD
600 return handle;
601}
602
603/* Add stream to channel shm and map its shm into process memory */
38fae1d3 604int ustctl_add_stream(struct lttng_ust_shm_handle *handle,
61f02aea 605 struct lttng_ust_object_data *stream_data)
57773204
MD
606{
607 int ret;
608
609 if (!stream_data->handle)
610 return -ENOENT;
611 /* map stream */
612 ret = channel_handle_add_stream(handle,
613 stream_data->shm_fd,
614 stream_data->wait_fd,
615 stream_data->memory_map_size);
616 if (ret) {
617 ERR("add stream error\n");
618 return ret;
619 }
620 /*
38fae1d3 621 * Set to -1 because the lttng_ust_shm_handle destruction will take care
57773204
MD
622 * of closing shm_fd and wait_fd.
623 */
624 stream_data->shm_fd = -1;
625 stream_data->wait_fd = -1;
626 return 0;
627}
628
38fae1d3 629void ustctl_unmap_channel(struct lttng_ust_shm_handle *handle)
5224b5c8
MD
630{
631 struct channel *chan;
632
633 chan = shmp(handle, handle->chan);
634 channel_destroy(chan, handle, 1);
635}
636
0bfe09ec
MD
637/*
638 * ustctl closes the shm_fd fds after mapping it.
639 */
4cfec15c 640struct lttng_ust_lib_ring_buffer *ustctl_open_stream_read(struct lttng_ust_shm_handle *handle,
6e922b24
MD
641 int cpu)
642{
643 struct channel *chan = handle->shadow_chan;
ef9ff354
MD
644 int *shm_fd, *wait_fd;
645 uint64_t *memory_map_size;
4cfec15c 646 struct lttng_ust_lib_ring_buffer *buf;
6e922b24
MD
647 int ret;
648
649 buf = channel_get_ring_buffer(&chan->backend.config,
650 chan, cpu, handle, &shm_fd, &wait_fd, &memory_map_size);
651 if (!buf)
652 return NULL;
653 ret = lib_ring_buffer_open_read(buf, handle, 1);
654 if (ret)
655 return NULL;
0bfe09ec
MD
656 /*
657 * We can close shm_fd early, right after is has been mapped.
658 */
659 if (*shm_fd >= 0) {
660 ret = close(*shm_fd);
661 if (ret) {
662 perror("Error closing shm_fd");
663 }
664 *shm_fd = -1;
665 }
6e922b24
MD
666 return buf;
667}
668
38fae1d3 669void ustctl_close_stream_read(struct lttng_ust_shm_handle *handle,
4cfec15c 670 struct lttng_ust_lib_ring_buffer *buf)
6e922b24
MD
671{
672 lib_ring_buffer_release_read(buf, handle, 1);
673}
674
57773204
MD
675/* For mmap mode, readable without "get" operation */
676
38fae1d3 677void *ustctl_get_mmap_base(struct lttng_ust_shm_handle *handle,
4cfec15c 678 struct lttng_ust_lib_ring_buffer *buf)
9095efe9
MD
679{
680 return shmp(handle, buf->backend.memory_map);
681}
682
57773204 683/* returns the length to mmap. */
38fae1d3 684int ustctl_get_mmap_len(struct lttng_ust_shm_handle *handle,
4cfec15c 685 struct lttng_ust_lib_ring_buffer *buf,
57773204
MD
686 unsigned long *len)
687{
688 unsigned long mmap_buf_len;
689 struct channel *chan = handle->shadow_chan;
690
691 if (chan->backend.config.output != RING_BUFFER_MMAP)
692 return -EINVAL;
693 mmap_buf_len = chan->backend.buf_size;
694 if (chan->backend.extra_reader_sb)
695 mmap_buf_len += chan->backend.subbuf_size;
696 if (mmap_buf_len > INT_MAX)
697 return -EFBIG;
698 *len = mmap_buf_len;
699 return 0;
700}
701
702/* returns the maximum size for sub-buffers. */
38fae1d3 703int ustctl_get_max_subbuf_size(struct lttng_ust_shm_handle *handle,
4cfec15c 704 struct lttng_ust_lib_ring_buffer *buf,
57773204
MD
705 unsigned long *len)
706{
707 struct channel *chan = handle->shadow_chan;
708
709 *len = chan->backend.subbuf_size;
710 return 0;
711}
712
713/*
714 * For mmap mode, operate on the current packet (between get/put or
715 * get_next/put_next).
716 */
717
718/* returns the offset of the subbuffer belonging to the mmap reader. */
38fae1d3 719int ustctl_get_mmap_read_offset(struct lttng_ust_shm_handle *handle,
4cfec15c 720 struct lttng_ust_lib_ring_buffer *buf, unsigned long *off)
57773204
MD
721{
722 struct channel *chan = handle->shadow_chan;
723 unsigned long sb_bindex;
724
725 if (chan->backend.config.output != RING_BUFFER_MMAP)
726 return -EINVAL;
727 sb_bindex = subbuffer_id_get_index(&chan->backend.config,
728 buf->backend.buf_rsb.id);
729 *off = shmp(handle, shmp_index(handle, buf->backend.array, sb_bindex)->shmp)->mmap_offset;
730 return 0;
731}
732
733/* returns the size of the current sub-buffer, without padding (for mmap). */
38fae1d3 734int ustctl_get_subbuf_size(struct lttng_ust_shm_handle *handle,
4cfec15c 735 struct lttng_ust_lib_ring_buffer *buf, unsigned long *len)
57773204
MD
736{
737 struct channel *chan = handle->shadow_chan;
738
739 *len = lib_ring_buffer_get_read_data_size(&chan->backend.config, buf,
740 handle);
741 return 0;
742}
743
744/* returns the size of the current sub-buffer, without padding (for mmap). */
38fae1d3 745int ustctl_get_padded_subbuf_size(struct lttng_ust_shm_handle *handle,
4cfec15c 746 struct lttng_ust_lib_ring_buffer *buf, unsigned long *len)
57773204
MD
747{
748 struct channel *chan = handle->shadow_chan;
749
750 *len = lib_ring_buffer_get_read_data_size(&chan->backend.config, buf,
751 handle);
752 *len = PAGE_ALIGN(*len);
753 return 0;
754}
755
756/* Get exclusive read access to the next sub-buffer that can be read. */
38fae1d3 757int ustctl_get_next_subbuf(struct lttng_ust_shm_handle *handle,
4cfec15c 758 struct lttng_ust_lib_ring_buffer *buf)
57773204
MD
759{
760 return lib_ring_buffer_get_next_subbuf(buf, handle);
761}
762
763
764/* Release exclusive sub-buffer access, move consumer forward. */
38fae1d3 765int ustctl_put_next_subbuf(struct lttng_ust_shm_handle *handle,
4cfec15c 766 struct lttng_ust_lib_ring_buffer *buf)
57773204
MD
767{
768 lib_ring_buffer_put_next_subbuf(buf, handle);
769 return 0;
770}
771
772/* snapshot */
773
774/* Get a snapshot of the current ring buffer producer and consumer positions */
38fae1d3 775int ustctl_snapshot(struct lttng_ust_shm_handle *handle,
4cfec15c 776 struct lttng_ust_lib_ring_buffer *buf)
57773204
MD
777{
778 return lib_ring_buffer_snapshot(buf, &buf->cons_snapshot,
779 &buf->prod_snapshot, handle);
780}
781
782/* Get the consumer position (iteration start) */
38fae1d3 783int ustctl_snapshot_get_consumed(struct lttng_ust_shm_handle *handle,
4cfec15c 784 struct lttng_ust_lib_ring_buffer *buf, unsigned long *pos)
57773204
MD
785{
786 *pos = buf->cons_snapshot;
787 return 0;
788}
789
790/* Get the producer position (iteration end) */
38fae1d3 791int ustctl_snapshot_get_produced(struct lttng_ust_shm_handle *handle,
4cfec15c 792 struct lttng_ust_lib_ring_buffer *buf, unsigned long *pos)
57773204
MD
793{
794 *pos = buf->prod_snapshot;
795 return 0;
796}
797
798/* Get exclusive read access to the specified sub-buffer position */
38fae1d3 799int ustctl_get_subbuf(struct lttng_ust_shm_handle *handle,
4cfec15c 800 struct lttng_ust_lib_ring_buffer *buf, unsigned long *pos)
57773204
MD
801{
802 return lib_ring_buffer_get_subbuf(buf, *pos, handle);
803}
804
805/* Release exclusive sub-buffer access */
38fae1d3 806int ustctl_put_subbuf(struct lttng_ust_shm_handle *handle,
4cfec15c 807 struct lttng_ust_lib_ring_buffer *buf)
57773204
MD
808{
809 lib_ring_buffer_put_subbuf(buf, handle);
810 return 0;
811}
812
02a15cfb 813void ustctl_flush_buffer(struct lttng_ust_shm_handle *handle,
b52190f2
MD
814 struct lttng_ust_lib_ring_buffer *buf,
815 int producer_active)
57773204 816{
b52190f2
MD
817 lib_ring_buffer_switch_slow(buf,
818 producer_active ? SWITCH_ACTIVE : SWITCH_FLUSH,
819 handle);
57773204 820}
This page took 0.058266 seconds and 4 git commands to generate.