Add missing #define _GNU_SOURCE for sched_getcpu()
[lttng-ust.git] / liblttng-ust-ctl / ustctl.c
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
20 #define _GNU_SOURCE
21 #include <string.h>
22 #include <lttng/ust-ctl.h>
23 #include <lttng/ust-abi.h>
24 #include <lttng/ust-events.h>
25 #include <sys/mman.h>
26
27 #include <usterr-signal-safe.h>
28 #include <ust-comm.h>
29
30 #include "../libringbuffer/backend.h"
31 #include "../libringbuffer/frontend.h"
32
33 volatile enum ust_loglevel ust_loglevel;
34
35 static
36 void init_object(struct lttng_ust_object_data *data)
37 {
38 data->handle = -1;
39 data->shm_fd = -1;
40 data->wait_fd = -1;
41 data->memory_map_size = 0;
42 }
43
44 int 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 }
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 */
65 int ustctl_release_object(int sock, struct lttng_ust_object_data *data)
66 {
67 int ret;
68
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 }
81 return ustctl_release_handle(sock, data->handle);
82 }
83
84 /*
85 * Send registration done packet to the application.
86 */
87 int 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
106 error:
107 return -1;
108 }
109
110 /*
111 * returns session handle.
112 */
113 int 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 */
132 int ustctl_open_metadata(int sock, int session_handle,
133 struct lttng_ust_channel_attr *chops,
134 struct lttng_ust_object_data **_metadata_data)
135 {
136 struct ustcomm_ust_msg lum;
137 struct ustcomm_ust_reply lur;
138 struct lttng_ust_object_data *metadata_data;
139 int ret, err = 0;
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)
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 */
177 /* get wait fd */
178 ret = ustcomm_recv_fd(sock);
179 if (ret < 0)
180 err = 1;
181 else
182 metadata_data->wait_fd = ret;
183 if (err)
184 goto error;
185 *_metadata_data = metadata_data;
186 return 0;
187
188 error:
189 (void) ustctl_release_object(sock, metadata_data);
190 free(metadata_data);
191 return -EINVAL;
192 }
193
194 int ustctl_create_channel(int sock, int session_handle,
195 struct lttng_ust_channel_attr *chops,
196 struct lttng_ust_object_data **_channel_data)
197 {
198 struct ustcomm_ust_msg lum;
199 struct ustcomm_ust_reply lur;
200 struct lttng_ust_object_data *channel_data;
201 int ret, err = 0;
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)
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 */
239 /* get wait fd */
240 ret = ustcomm_recv_fd(sock);
241 if (ret < 0)
242 err = 1;
243 else
244 channel_data->wait_fd = ret;
245 if (err)
246 goto error;
247 *_channel_data = channel_data;
248 return 0;
249
250 error:
251 (void) ustctl_release_object(sock, channel_data);
252 free(channel_data);
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 */
261 int ustctl_create_stream(int sock, struct lttng_ust_object_data *channel_data,
262 struct lttng_ust_object_data **_stream_data)
263 {
264 struct ustcomm_ust_msg lum;
265 struct ustcomm_ust_reply lur;
266 struct lttng_ust_object_data *stream_data;
267 int ret, fd, err = 0;
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)
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 */
299 /* get wait fd */
300 fd = ustcomm_recv_fd(sock);
301 if (fd < 0)
302 err = 1;
303 else
304 stream_data->wait_fd = fd;
305 if (err)
306 goto error;
307 *_stream_data = stream_data;
308 return ret;
309
310 error:
311 (void) ustctl_release_object(sock, stream_data);
312 free(stream_data);
313 return -EINVAL;
314 }
315
316 int ustctl_create_event(int sock, struct lttng_ust_event *ev,
317 struct lttng_ust_object_data *channel_data,
318 struct lttng_ust_object_data **_event_data)
319 {
320 struct ustcomm_ust_msg lum;
321 struct ustcomm_ust_reply lur;
322 struct lttng_ust_object_data *event_data;
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;
335 lum.u.event.loglevel_type = ev->loglevel_type;
336 lum.u.event.loglevel = ev->loglevel;
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
348 int ustctl_add_context(int sock, struct lttng_ust_context *ctx,
349 struct lttng_ust_object_data *obj_data,
350 struct lttng_ust_object_data **_context_data)
351 {
352 struct ustcomm_ust_msg lum;
353 struct ustcomm_ust_reply lur;
354 struct lttng_ust_object_data *context_data;
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));
362 lum.handle = obj_data->handle;
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 */
377 int ustctl_enable(int sock, struct lttng_ust_object_data *object)
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 */
394 int ustctl_disable(int sock, struct lttng_ust_object_data *object)
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
410 int ustctl_start_session(int sock, int handle)
411 {
412 struct lttng_ust_object_data obj;
413
414 obj.handle = handle;
415 return ustctl_enable(sock, &obj);
416 }
417
418 int ustctl_stop_session(int sock, int handle)
419 {
420 struct lttng_ust_object_data obj;
421
422 obj.handle = handle;
423 return ustctl_disable(sock, &obj);
424 }
425
426 int ustctl_tracepoint_list(int sock)
427 {
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
443 int ustctl_tracepoint_list_get(int sock, int tp_list_handle,
444 struct lttng_ust_tracepoint_iter *iter)
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;
456 DBG("received tracepoint list entry name %s loglevel %d",
457 lur.u.tracepoint.name,
458 lur.u.tracepoint.loglevel);
459 memcpy(iter, &lur.u.tracepoint, sizeof(*iter));
460 return 0;
461 }
462
463 int 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
480 int 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
496 int ustctl_calibrate(int sock, struct lttng_ust_calibrate *calibrate)
497 {
498 return -ENOSYS;
499 }
500
501 int 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
517 /* Buffer operations */
518
519 /* Map channel shm into process memory */
520 struct lttng_ust_shm_handle *ustctl_map_channel(struct lttng_ust_object_data *chan_data)
521 {
522 struct lttng_ust_shm_handle *handle;
523 struct channel *chan;
524 size_t chan_size;
525 struct lttng_ust_lib_ring_buffer_config *config;
526 int ret;
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 /*
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.
541 */
542 chan_data->shm_fd = -1;
543 chan_data->wait_fd = -1;
544
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
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);
568 /*
569 * The callback pointers in the producer are invalid in the
570 * consumer. We need to look them up here.
571 */
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 }
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;
600 return handle;
601 }
602
603 /* Add stream to channel shm and map its shm into process memory */
604 int ustctl_add_stream(struct lttng_ust_shm_handle *handle,
605 struct lttng_ust_object_data *stream_data)
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 /*
621 * Set to -1 because the lttng_ust_shm_handle destruction will take care
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
629 void ustctl_unmap_channel(struct lttng_ust_shm_handle *handle)
630 {
631 struct channel *chan;
632
633 chan = shmp(handle, handle->chan);
634 channel_destroy(chan, handle, 1);
635 }
636
637 /*
638 * ustctl closes the shm_fd fds after mapping it.
639 */
640 struct lttng_ust_lib_ring_buffer *ustctl_open_stream_read(struct lttng_ust_shm_handle *handle,
641 int cpu)
642 {
643 struct channel *chan = handle->shadow_chan;
644 int *shm_fd, *wait_fd;
645 uint64_t *memory_map_size;
646 struct lttng_ust_lib_ring_buffer *buf;
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;
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 }
666 return buf;
667 }
668
669 void ustctl_close_stream_read(struct lttng_ust_shm_handle *handle,
670 struct lttng_ust_lib_ring_buffer *buf)
671 {
672 lib_ring_buffer_release_read(buf, handle, 1);
673 }
674
675 /* For mmap mode, readable without "get" operation */
676
677 void *ustctl_get_mmap_base(struct lttng_ust_shm_handle *handle,
678 struct lttng_ust_lib_ring_buffer *buf)
679 {
680 return shmp(handle, buf->backend.memory_map);
681 }
682
683 /* returns the length to mmap. */
684 int ustctl_get_mmap_len(struct lttng_ust_shm_handle *handle,
685 struct lttng_ust_lib_ring_buffer *buf,
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. */
703 int ustctl_get_max_subbuf_size(struct lttng_ust_shm_handle *handle,
704 struct lttng_ust_lib_ring_buffer *buf,
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. */
719 int ustctl_get_mmap_read_offset(struct lttng_ust_shm_handle *handle,
720 struct lttng_ust_lib_ring_buffer *buf, unsigned long *off)
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). */
734 int ustctl_get_subbuf_size(struct lttng_ust_shm_handle *handle,
735 struct lttng_ust_lib_ring_buffer *buf, unsigned long *len)
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). */
745 int ustctl_get_padded_subbuf_size(struct lttng_ust_shm_handle *handle,
746 struct lttng_ust_lib_ring_buffer *buf, unsigned long *len)
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. */
757 int ustctl_get_next_subbuf(struct lttng_ust_shm_handle *handle,
758 struct lttng_ust_lib_ring_buffer *buf)
759 {
760 return lib_ring_buffer_get_next_subbuf(buf, handle);
761 }
762
763
764 /* Release exclusive sub-buffer access, move consumer forward. */
765 int ustctl_put_next_subbuf(struct lttng_ust_shm_handle *handle,
766 struct lttng_ust_lib_ring_buffer *buf)
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 */
775 int ustctl_snapshot(struct lttng_ust_shm_handle *handle,
776 struct lttng_ust_lib_ring_buffer *buf)
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) */
783 int ustctl_snapshot_get_consumed(struct lttng_ust_shm_handle *handle,
784 struct lttng_ust_lib_ring_buffer *buf, unsigned long *pos)
785 {
786 *pos = buf->cons_snapshot;
787 return 0;
788 }
789
790 /* Get the producer position (iteration end) */
791 int ustctl_snapshot_get_produced(struct lttng_ust_shm_handle *handle,
792 struct lttng_ust_lib_ring_buffer *buf, unsigned long *pos)
793 {
794 *pos = buf->prod_snapshot;
795 return 0;
796 }
797
798 /* Get exclusive read access to the specified sub-buffer position */
799 int ustctl_get_subbuf(struct lttng_ust_shm_handle *handle,
800 struct lttng_ust_lib_ring_buffer *buf, unsigned long *pos)
801 {
802 return lib_ring_buffer_get_subbuf(buf, *pos, handle);
803 }
804
805 /* Release exclusive sub-buffer access */
806 int ustctl_put_subbuf(struct lttng_ust_shm_handle *handle,
807 struct lttng_ust_lib_ring_buffer *buf)
808 {
809 lib_ring_buffer_put_subbuf(buf, handle);
810 return 0;
811 }
812
813 void ustctl_flush_buffer(struct lttng_ust_shm_handle *handle,
814 struct lttng_ust_lib_ring_buffer *buf,
815 int producer_active)
816 {
817 lib_ring_buffer_switch_slow(buf,
818 producer_active ? SWITCH_ACTIVE : SWITCH_FLUSH,
819 handle);
820 }
This page took 0.046697 seconds and 5 git commands to generate.