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