Cleanup: remove unused variables
[lttng-ust.git] / liblttng-ust-ctl / ustctl.c
CommitLineData
57773204
MD
1/*
2 * Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
74d81a6c 3 * Copyright (C) 2011-2013 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
57773204 4 *
e92f3e28
MD
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License only.
57773204
MD
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 *
e92f3e28
MD
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.
57773204
MD
17 */
18
9d335227 19#define _GNU_SOURCE
57773204 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>
32ce8569 25#include <byteswap.h>
44c72f10
MD
26
27#include <usterr-signal-safe.h>
b728d87e 28#include <ust-comm.h>
74d81a6c 29#include <helper.h>
57773204
MD
30
31#include "../libringbuffer/backend.h"
32#include "../libringbuffer/frontend.h"
c9023c93
MD
33#include "../liblttng-ust/wait.h"
34
35/*
36 * Number of milliseconds to retry before failing metadata writes on
37 * buffer full condition. (10 seconds)
38 */
39#define LTTNG_METADATA_TIMEOUT_MSEC 10000
57773204 40
74d81a6c
MD
41/*
42 * Channel representation within consumer.
43 */
44struct ustctl_consumer_channel {
45 struct lttng_channel *chan; /* lttng channel buffers */
6b120308 46
74d81a6c
MD
47 /* initial attributes */
48 struct ustctl_consumer_channel_attr attr;
ff0f5728
MD
49 int wait_fd; /* monitor close() */
50 int wakeup_fd; /* monitor close() */
74d81a6c
MD
51};
52
53/*
54 * Stream representation within consumer.
55 */
56struct ustctl_consumer_stream {
57 struct lttng_ust_shm_handle *handle; /* shared-memory handle */
58 struct lttng_ust_lib_ring_buffer *buf;
59 struct ustctl_consumer_channel *chan;
60 int shm_fd, wait_fd, wakeup_fd;
61 int cpu;
62 uint64_t memory_map_size;
63};
64
65extern void lttng_ring_buffer_client_overwrite_init(void);
66extern void lttng_ring_buffer_client_discard_init(void);
67extern void lttng_ring_buffer_metadata_client_init(void);
68extern void lttng_ring_buffer_client_overwrite_exit(void);
69extern void lttng_ring_buffer_client_discard_exit(void);
70extern void lttng_ring_buffer_metadata_client_exit(void);
71
72volatile enum ust_loglevel ust_loglevel;
57773204 73
2be0e72c
MD
74int ustctl_release_handle(int sock, int handle)
75{
76 struct ustcomm_ust_msg lum;
77 struct ustcomm_ust_reply lur;
2be0e72c 78
74d81a6c
MD
79 if (sock < 0 || handle < 0)
80 return 0;
81 memset(&lum, 0, sizeof(lum));
82 lum.handle = handle;
83 lum.cmd = LTTNG_UST_RELEASE;
84 return ustcomm_send_app_cmd(sock, &lum, &lur);
2be0e72c 85}
74d81a6c 86
12388166
MD
87/*
88 * If sock is negative, it means we don't have to notify the other side
89 * (e.g. application has already vanished).
90 */
d26228ae 91int ustctl_release_object(int sock, struct lttng_ust_object_data *data)
57773204 92{
57773204
MD
93 int ret;
94
9bfc503d
MD
95 if (!data)
96 return -EINVAL;
97
74d81a6c
MD
98 switch (data->type) {
99 case LTTNG_UST_OBJECT_TYPE_CHANNEL:
ff0f5728
MD
100 if (data->u.channel.wakeup_fd >= 0) {
101 ret = close(data->u.channel.wakeup_fd);
102 if (ret < 0) {
103 ret = -errno;
104 return ret;
105 }
106 }
74d81a6c
MD
107 free(data->u.channel.data);
108 break;
109 case LTTNG_UST_OBJECT_TYPE_STREAM:
110 if (data->u.stream.shm_fd >= 0) {
111 ret = close(data->u.stream.shm_fd);
112 if (ret < 0) {
113 ret = -errno;
114 return ret;
115 }
d26228ae 116 }
74d81a6c
MD
117 if (data->u.stream.wakeup_fd >= 0) {
118 ret = close(data->u.stream.wakeup_fd);
119 if (ret < 0) {
120 ret = -errno;
121 return ret;
122 }
d26228ae 123 }
74d81a6c 124 break;
32ce8569
MD
125 case LTTNG_UST_OBJECT_TYPE_EVENT:
126 case LTTNG_UST_OBJECT_TYPE_CONTEXT:
127 break;
74d81a6c
MD
128 default:
129 assert(0);
d26228ae 130 }
2be0e72c 131 return ustctl_release_handle(sock, data->handle);
57773204
MD
132}
133
1c5e467e
MD
134/*
135 * Send registration done packet to the application.
136 */
137int ustctl_register_done(int sock)
138{
139 struct ustcomm_ust_msg lum;
140 struct ustcomm_ust_reply lur;
141 int ret;
142
143 DBG("Sending register done command to %d", sock);
144 memset(&lum, 0, sizeof(lum));
145 lum.handle = LTTNG_UST_ROOT_HANDLE;
146 lum.cmd = LTTNG_UST_REGISTER_DONE;
147 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
148 if (ret)
149 return ret;
1c5e467e 150 return 0;
1c5e467e
MD
151}
152
57773204
MD
153/*
154 * returns session handle.
155 */
156int ustctl_create_session(int sock)
157{
158 struct ustcomm_ust_msg lum;
159 struct ustcomm_ust_reply lur;
160 int ret, session_handle;
161
162 /* Create session */
163 memset(&lum, 0, sizeof(lum));
164 lum.handle = LTTNG_UST_ROOT_HANDLE;
165 lum.cmd = LTTNG_UST_SESSION;
166 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
167 if (ret)
168 return ret;
169 session_handle = lur.ret_val;
170 DBG("received session handle %u", session_handle);
171 return session_handle;
172}
173
57773204 174int ustctl_create_event(int sock, struct lttng_ust_event *ev,
61f02aea
MD
175 struct lttng_ust_object_data *channel_data,
176 struct lttng_ust_object_data **_event_data)
57773204
MD
177{
178 struct ustcomm_ust_msg lum;
179 struct ustcomm_ust_reply lur;
61f02aea 180 struct lttng_ust_object_data *event_data;
57773204
MD
181 int ret;
182
9bfc503d
MD
183 if (!channel_data || !_event_data)
184 return -EINVAL;
185
74d81a6c 186 event_data = zmalloc(sizeof(*event_data));
57773204
MD
187 if (!event_data)
188 return -ENOMEM;
32ce8569 189 event_data->type = LTTNG_UST_OBJECT_TYPE_EVENT;
57773204
MD
190 memset(&lum, 0, sizeof(lum));
191 lum.handle = channel_data->handle;
192 lum.cmd = LTTNG_UST_EVENT;
193 strncpy(lum.u.event.name, ev->name,
194 LTTNG_UST_SYM_NAME_LEN);
195 lum.u.event.instrumentation = ev->instrumentation;
457a6b58
MD
196 lum.u.event.loglevel_type = ev->loglevel_type;
197 lum.u.event.loglevel = ev->loglevel;
57773204
MD
198 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
199 if (ret) {
200 free(event_data);
201 return ret;
202 }
203 event_data->handle = lur.ret_val;
204 DBG("received event handle %u", event_data->handle);
205 *_event_data = event_data;
206 return 0;
207}
208
209int ustctl_add_context(int sock, struct lttng_ust_context *ctx,
61f02aea
MD
210 struct lttng_ust_object_data *obj_data,
211 struct lttng_ust_object_data **_context_data)
57773204
MD
212{
213 struct ustcomm_ust_msg lum;
214 struct ustcomm_ust_reply lur;
61f02aea 215 struct lttng_ust_object_data *context_data;
57773204
MD
216 int ret;
217
9bfc503d
MD
218 if (!obj_data || !_context_data)
219 return -EINVAL;
220
74d81a6c 221 context_data = zmalloc(sizeof(*context_data));
57773204
MD
222 if (!context_data)
223 return -ENOMEM;
32ce8569 224 context_data->type = LTTNG_UST_OBJECT_TYPE_CONTEXT;
57773204 225 memset(&lum, 0, sizeof(lum));
3039d8ed 226 lum.handle = obj_data->handle;
57773204
MD
227 lum.cmd = LTTNG_UST_CONTEXT;
228 lum.u.context.ctx = ctx->ctx;
229 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
230 if (ret) {
231 free(context_data);
232 return ret;
233 }
32ce8569
MD
234 context_data->handle = -1;
235 DBG("Context created successfully");
57773204
MD
236 *_context_data = context_data;
237 return ret;
238}
239
cd54f6d9
MD
240int ustctl_set_filter(int sock, struct lttng_ust_filter_bytecode *bytecode,
241 struct lttng_ust_object_data *obj_data)
242{
243 struct ustcomm_ust_msg lum;
244 struct ustcomm_ust_reply lur;
245 int ret;
246
247 if (!obj_data)
248 return -EINVAL;
249
250 memset(&lum, 0, sizeof(lum));
251 lum.handle = obj_data->handle;
252 lum.cmd = LTTNG_UST_FILTER;
253 lum.u.filter.data_size = bytecode->len;
254 lum.u.filter.reloc_offset = bytecode->reloc_offset;
e695af51 255 lum.u.filter.seqnum = bytecode->seqnum;
cd54f6d9
MD
256
257 ret = ustcomm_send_app_msg(sock, &lum);
258 if (ret)
259 return ret;
cd54f6d9
MD
260 /* send var len bytecode */
261 ret = ustcomm_send_unix_sock(sock, bytecode->data,
262 bytecode->len);
263 if (ret < 0) {
264 return ret;
265 }
7bc53e94
MD
266 if (ret != bytecode->len)
267 return -EINVAL;
268 return ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
cd54f6d9
MD
269}
270
57773204 271/* Enable event, channel and session ioctl */
61f02aea 272int ustctl_enable(int sock, struct lttng_ust_object_data *object)
57773204
MD
273{
274 struct ustcomm_ust_msg lum;
275 struct ustcomm_ust_reply lur;
276 int ret;
277
9bfc503d
MD
278 if (!object)
279 return -EINVAL;
280
57773204
MD
281 memset(&lum, 0, sizeof(lum));
282 lum.handle = object->handle;
283 lum.cmd = LTTNG_UST_ENABLE;
284 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
285 if (ret)
286 return ret;
287 DBG("enabled handle %u", object->handle);
288 return 0;
289}
290
291/* Disable event, channel and session ioctl */
61f02aea 292int ustctl_disable(int sock, struct lttng_ust_object_data *object)
57773204
MD
293{
294 struct ustcomm_ust_msg lum;
295 struct ustcomm_ust_reply lur;
296 int ret;
297
9bfc503d
MD
298 if (!object)
299 return -EINVAL;
300
57773204
MD
301 memset(&lum, 0, sizeof(lum));
302 lum.handle = object->handle;
303 lum.cmd = LTTNG_UST_DISABLE;
304 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
305 if (ret)
306 return ret;
307 DBG("disable handle %u", object->handle);
308 return 0;
309}
310
4a6ca058 311int ustctl_start_session(int sock, int handle)
57773204 312{
61f02aea 313 struct lttng_ust_object_data obj;
4a6ca058
MD
314
315 obj.handle = handle;
316 return ustctl_enable(sock, &obj);
57773204
MD
317}
318
4a6ca058 319int ustctl_stop_session(int sock, int handle)
57773204 320{
61f02aea 321 struct lttng_ust_object_data obj;
4a6ca058
MD
322
323 obj.handle = handle;
324 return ustctl_disable(sock, &obj);
57773204
MD
325}
326
57773204
MD
327int ustctl_tracepoint_list(int sock)
328{
b115631f
MD
329 struct ustcomm_ust_msg lum;
330 struct ustcomm_ust_reply lur;
331 int ret, tp_list_handle;
332
333 memset(&lum, 0, sizeof(lum));
334 lum.handle = LTTNG_UST_ROOT_HANDLE;
335 lum.cmd = LTTNG_UST_TRACEPOINT_LIST;
336 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
337 if (ret)
338 return ret;
339 tp_list_handle = lur.ret_val;
340 DBG("received tracepoint list handle %u", tp_list_handle);
341 return tp_list_handle;
342}
343
344int ustctl_tracepoint_list_get(int sock, int tp_list_handle,
cbef6901 345 struct lttng_ust_tracepoint_iter *iter)
b115631f
MD
346{
347 struct ustcomm_ust_msg lum;
348 struct ustcomm_ust_reply lur;
349 int ret;
350
9bfc503d
MD
351 if (!iter)
352 return -EINVAL;
353
b115631f
MD
354 memset(&lum, 0, sizeof(lum));
355 lum.handle = tp_list_handle;
356 lum.cmd = LTTNG_UST_TRACEPOINT_LIST_GET;
357 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
358 if (ret)
359 return ret;
882a56d7 360 DBG("received tracepoint list entry name %s loglevel %d",
cbef6901 361 lur.u.tracepoint.name,
882a56d7 362 lur.u.tracepoint.loglevel);
cbef6901 363 memcpy(iter, &lur.u.tracepoint, sizeof(*iter));
b115631f 364 return 0;
57773204
MD
365}
366
40003310
MD
367int ustctl_tracepoint_field_list(int sock)
368{
369 struct ustcomm_ust_msg lum;
370 struct ustcomm_ust_reply lur;
371 int ret, tp_field_list_handle;
372
373 memset(&lum, 0, sizeof(lum));
374 lum.handle = LTTNG_UST_ROOT_HANDLE;
375 lum.cmd = LTTNG_UST_TRACEPOINT_FIELD_LIST;
376 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
377 if (ret)
378 return ret;
379 tp_field_list_handle = lur.ret_val;
380 DBG("received tracepoint field list handle %u", tp_field_list_handle);
381 return tp_field_list_handle;
382}
383
384int ustctl_tracepoint_field_list_get(int sock, int tp_field_list_handle,
385 struct lttng_ust_field_iter *iter)
386{
387 struct ustcomm_ust_msg lum;
388 struct ustcomm_ust_reply lur;
389 int ret;
390 ssize_t len;
391
392 if (!iter)
393 return -EINVAL;
394
395 memset(&lum, 0, sizeof(lum));
396 lum.handle = tp_field_list_handle;
397 lum.cmd = LTTNG_UST_TRACEPOINT_FIELD_LIST_GET;
398 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
399 if (ret)
400 return ret;
401 len = ustcomm_recv_unix_sock(sock, iter, sizeof(*iter));
402 if (len != sizeof(*iter)) {
403 return -EINVAL;
404 }
405 DBG("received tracepoint field list entry event_name %s event_loglevel %d field_name %s field_type %d",
406 iter->event_name,
407 iter->loglevel,
408 iter->field_name,
409 iter->type);
410 return 0;
411}
412
57773204
MD
413int ustctl_tracer_version(int sock, struct lttng_ust_tracer_version *v)
414{
415 struct ustcomm_ust_msg lum;
416 struct ustcomm_ust_reply lur;
417 int ret;
418
9bfc503d
MD
419 if (!v)
420 return -EINVAL;
421
57773204
MD
422 memset(&lum, 0, sizeof(lum));
423 lum.handle = LTTNG_UST_ROOT_HANDLE;
424 lum.cmd = LTTNG_UST_TRACER_VERSION;
425 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
426 if (ret)
427 return ret;
428 memcpy(v, &lur.u.version, sizeof(*v));
429 DBG("received tracer version");
430 return 0;
431}
432
433int ustctl_wait_quiescent(int sock)
434{
435 struct ustcomm_ust_msg lum;
436 struct ustcomm_ust_reply lur;
437 int ret;
438
439 memset(&lum, 0, sizeof(lum));
440 lum.handle = LTTNG_UST_ROOT_HANDLE;
441 lum.cmd = LTTNG_UST_WAIT_QUIESCENT;
442 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
443 if (ret)
444 return ret;
445 DBG("waited for quiescent state");
446 return 0;
447}
448
449int ustctl_calibrate(int sock, struct lttng_ust_calibrate *calibrate)
450{
9bfc503d
MD
451 if (!calibrate)
452 return -EINVAL;
453
57773204
MD
454 return -ENOSYS;
455}
456
f1fffc57
MD
457int ustctl_sock_flush_buffer(int sock, struct lttng_ust_object_data *object)
458{
459 struct ustcomm_ust_msg lum;
460 struct ustcomm_ust_reply lur;
461 int ret;
462
9bfc503d
MD
463 if (!object)
464 return -EINVAL;
465
f1fffc57
MD
466 memset(&lum, 0, sizeof(lum));
467 lum.handle = object->handle;
468 lum.cmd = LTTNG_UST_FLUSH_BUFFER;
469 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
470 if (ret)
471 return ret;
472 DBG("flushed buffer handle %u", object->handle);
473 return 0;
474}
475
74d81a6c
MD
476static
477int ustctl_send_channel(int sock,
478 enum lttng_ust_chan_type type,
479 void *data,
480 uint64_t size,
ff0f5728 481 int wakeup_fd,
74d81a6c
MD
482 int send_fd_only)
483{
484 ssize_t len;
485
486 if (!send_fd_only) {
487 /* Send mmap size */
488 len = ustcomm_send_unix_sock(sock, &size, sizeof(size));
489 if (len != sizeof(size)) {
490 if (len < 0)
491 return len;
492 else
493 return -EIO;
494 }
495
496 /* Send channel type */
497 len = ustcomm_send_unix_sock(sock, &type, sizeof(type));
498 if (len != sizeof(type)) {
499 if (len < 0)
500 return len;
501 else
502 return -EIO;
503 }
504 }
505
506 /* Send channel data */
507 len = ustcomm_send_unix_sock(sock, data, size);
508 if (len != size) {
509 if (len < 0)
510 return len;
511 else
512 return -EIO;
513 }
57773204 514
ff0f5728
MD
515 /* Send wakeup fd */
516 len = ustcomm_send_fds_unix_sock(sock, &wakeup_fd, 1);
517 if (len <= 0) {
518 if (len < 0)
519 return len;
520 else
521 return -EIO;
522 }
74d81a6c
MD
523 return 0;
524}
525
526static
527int ustctl_send_stream(int sock,
528 uint32_t stream_nr,
529 uint64_t memory_map_size,
530 int shm_fd, int wakeup_fd,
531 int send_fd_only)
57773204 532{
74d81a6c
MD
533 ssize_t len;
534 int fds[2];
535
536 if (!send_fd_only) {
537 if (shm_fd < 0) {
538 /* finish iteration */
539 uint64_t v = -1;
540
541 len = ustcomm_send_unix_sock(sock, &v, sizeof(v));
542 if (len != sizeof(v)) {
543 if (len < 0)
544 return len;
545 else
546 return -EIO;
547 }
548 return 0;
549 }
550
551 /* Send mmap size */
552 len = ustcomm_send_unix_sock(sock, &memory_map_size,
553 sizeof(memory_map_size));
554 if (len != sizeof(memory_map_size)) {
555 if (len < 0)
556 return len;
557 else
558 return -EIO;
559 }
560
561 /* Send stream nr */
562 len = ustcomm_send_unix_sock(sock, &stream_nr,
563 sizeof(stream_nr));
564 if (len != sizeof(stream_nr)) {
565 if (len < 0)
566 return len;
567 else
568 return -EIO;
569 }
570 }
571
572 /* Send shm fd and wakeup fd */
573 fds[0] = shm_fd;
574 fds[1] = wakeup_fd;
575 len = ustcomm_send_fds_unix_sock(sock, fds, 2);
576 if (len <= 0) {
577 if (len < 0)
578 return len;
579 else
580 return -EIO;
581 }
582 return 0;
583}
584
585int ustctl_recv_channel_from_consumer(int sock,
586 struct lttng_ust_object_data **_channel_data)
587{
588 struct lttng_ust_object_data *channel_data;
589 ssize_t len;
ff0f5728 590 int wakeup_fd;
7a784989 591 int ret;
57773204 592
74d81a6c
MD
593 channel_data = zmalloc(sizeof(*channel_data));
594 if (!channel_data) {
595 ret = -ENOMEM;
596 goto error_alloc;
597 }
598 channel_data->type = LTTNG_UST_OBJECT_TYPE_CHANNEL;
12f3dabc 599 channel_data->handle = -1;
74d81a6c
MD
600
601 /* recv mmap size */
602 len = ustcomm_recv_unix_sock(sock, &channel_data->size,
603 sizeof(channel_data->size));
604 if (len != sizeof(channel_data->size)) {
605 if (len < 0)
606 ret = len;
607 else
608 ret = -EINVAL;
609 goto error;
610 }
9bfc503d 611
74d81a6c
MD
612 /* recv channel type */
613 len = ustcomm_recv_unix_sock(sock, &channel_data->u.channel.type,
614 sizeof(channel_data->u.channel.type));
615 if (len != sizeof(channel_data->u.channel.type)) {
616 if (len < 0)
617 ret = len;
618 else
619 ret = -EINVAL;
620 goto error;
621 }
622
623 /* recv channel data */
624 channel_data->u.channel.data = zmalloc(channel_data->size);
625 if (!channel_data->u.channel.data) {
626 ret = -ENOMEM;
627 goto error;
628 }
629 len = ustcomm_recv_unix_sock(sock, channel_data->u.channel.data,
630 channel_data->size);
631 if (len != channel_data->size) {
632 if (len < 0)
633 ret = len;
634 else
635 ret = -EINVAL;
636 goto error_recv_data;
637 }
ff0f5728
MD
638 /* recv wakeup fd */
639 len = ustcomm_recv_fds_unix_sock(sock, &wakeup_fd, 1);
640 if (len <= 0) {
641 if (len < 0) {
642 ret = len;
643 goto error_recv_data;
644 } else {
645 ret = -EIO;
646 goto error_recv_data;
647 }
648 }
649 channel_data->u.channel.wakeup_fd = wakeup_fd;
74d81a6c
MD
650 *_channel_data = channel_data;
651 return 0;
652
653error_recv_data:
654 free(channel_data->u.channel.data);
655error:
656 free(channel_data);
657error_alloc:
658 return ret;
659}
660
661int ustctl_recv_stream_from_consumer(int sock,
662 struct lttng_ust_object_data **_stream_data)
663{
664 struct lttng_ust_object_data *stream_data;
665 ssize_t len;
666 int ret;
667 int fds[2];
668
669 stream_data = zmalloc(sizeof(*stream_data));
670 if (!stream_data) {
671 ret = -ENOMEM;
672 goto error_alloc;
57773204 673 }
74d81a6c
MD
674
675 stream_data->type = LTTNG_UST_OBJECT_TYPE_STREAM;
676 stream_data->handle = -1;
677
678 /* recv mmap size */
679 len = ustcomm_recv_unix_sock(sock, &stream_data->size,
680 sizeof(stream_data->size));
681 if (len != sizeof(stream_data->size)) {
682 if (len < 0)
683 ret = len;
684 else
685 ret = -EINVAL;
686 goto error;
687 }
688 if (stream_data->size == -1) {
689 ret = -LTTNG_UST_ERR_NOENT;
690 goto error;
691 }
692
693 /* recv stream nr */
694 len = ustcomm_recv_unix_sock(sock, &stream_data->u.stream.stream_nr,
695 sizeof(stream_data->u.stream.stream_nr));
696 if (len != sizeof(stream_data->u.stream.stream_nr)) {
697 if (len < 0)
698 ret = len;
699 else
700 ret = -EINVAL;
701 goto error;
702 }
703
704 /* recv shm fd and wakeup fd */
705 len = ustcomm_recv_fds_unix_sock(sock, fds, 2);
706 if (len <= 0) {
707 if (len < 0) {
708 ret = len;
709 goto error;
710 } else {
711 ret = -EIO;
712 goto error;
0bfe09ec 713 }
0bfe09ec 714 }
74d81a6c
MD
715 stream_data->u.stream.shm_fd = fds[0];
716 stream_data->u.stream.wakeup_fd = fds[1];
717 *_stream_data = stream_data;
718 return 0;
0bfe09ec 719
74d81a6c
MD
720error:
721 free(stream_data);
722error_alloc:
723 return ret;
724}
725
726int ustctl_send_channel_to_ust(int sock, int session_handle,
727 struct lttng_ust_object_data *channel_data)
728{
729 struct ustcomm_ust_msg lum;
730 struct ustcomm_ust_reply lur;
731 int ret;
732
733 if (!channel_data)
734 return -EINVAL;
735
736 memset(&lum, 0, sizeof(lum));
737 lum.handle = session_handle;
738 lum.cmd = LTTNG_UST_CHANNEL;
739 lum.u.channel.len = channel_data->size;
740 lum.u.channel.type = channel_data->u.channel.type;
741 ret = ustcomm_send_app_msg(sock, &lum);
742 if (ret)
743 return ret;
744
745 ret = ustctl_send_channel(sock,
746 channel_data->u.channel.type,
747 channel_data->u.channel.data,
748 channel_data->size,
ff0f5728 749 channel_data->u.channel.wakeup_fd,
74d81a6c
MD
750 1);
751 if (ret)
752 return ret;
753 ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
754 if (!ret) {
755 if (lur.ret_val >= 0) {
756 channel_data->handle = lur.ret_val;
757 }
57773204 758 }
74d81a6c
MD
759 return ret;
760}
761
762int ustctl_send_stream_to_ust(int sock,
763 struct lttng_ust_object_data *channel_data,
764 struct lttng_ust_object_data *stream_data)
765{
766 struct ustcomm_ust_msg lum;
767 struct ustcomm_ust_reply lur;
768 int ret;
769
770 memset(&lum, 0, sizeof(lum));
771 lum.handle = channel_data->handle;
772 lum.cmd = LTTNG_UST_STREAM;
773 lum.u.stream.len = stream_data->size;
774 lum.u.stream.stream_nr = stream_data->u.stream.stream_nr;
775 ret = ustcomm_send_app_msg(sock, &lum);
776 if (ret)
777 return ret;
778
779 assert(stream_data);
780 assert(stream_data->type == LTTNG_UST_OBJECT_TYPE_STREAM);
781
782 ret = ustctl_send_stream(sock,
783 stream_data->u.stream.stream_nr,
784 stream_data->size,
785 stream_data->u.stream.shm_fd,
786 stream_data->u.stream.wakeup_fd, 1);
787 if (ret)
788 return ret;
789 return ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
790}
791
12f3dabc
MD
792int ustctl_duplicate_ust_object_data(struct lttng_ust_object_data **dest,
793 struct lttng_ust_object_data *src)
794{
795 struct lttng_ust_object_data *obj;
796 int ret;
797
798 if (src->handle != -1) {
799 ret = -EINVAL;
800 goto error;
801 }
802
803 obj = zmalloc(sizeof(*obj));
804 if (!obj) {
805 ret = -ENOMEM;
806 goto error;
807 }
808
809 obj->type = src->type;
810 obj->handle = src->handle;
811 obj->size = src->size;
812
813 switch (obj->type) {
814 case LTTNG_UST_OBJECT_TYPE_CHANNEL:
815 {
816 obj->u.channel.type = src->u.channel.type;
817 if (src->u.channel.wakeup_fd >= 0) {
818 obj->u.channel.wakeup_fd =
819 dup(src->u.channel.wakeup_fd);
820 if (obj->u.channel.wakeup_fd < 0) {
821 ret = errno;
822 goto chan_error_wakeup_fd;
823 }
824 } else {
825 obj->u.channel.wakeup_fd =
826 src->u.channel.wakeup_fd;
827 }
828 obj->u.channel.data = zmalloc(obj->size);
829 if (!obj->u.channel.data) {
830 ret = -ENOMEM;
831 goto chan_error_alloc;
832 }
833 memcpy(obj->u.channel.data, src->u.channel.data, obj->size);
834 break;
835
836 chan_error_alloc:
837 if (src->u.channel.wakeup_fd >= 0) {
838 int closeret;
839
840 closeret = close(obj->u.channel.wakeup_fd);
841 if (closeret) {
842 PERROR("close");
843 }
844 }
845 chan_error_wakeup_fd:
846 goto error_type;
847
848 }
849
850 case LTTNG_UST_OBJECT_TYPE_STREAM:
851 {
852 obj->u.stream.stream_nr = src->u.stream.stream_nr;
853 if (src->u.stream.wakeup_fd >= 0) {
854 obj->u.stream.wakeup_fd =
855 dup(src->u.stream.wakeup_fd);
856 if (obj->u.stream.wakeup_fd < 0) {
857 ret = errno;
858 goto stream_error_wakeup_fd;
859 }
860 } else {
861 obj->u.stream.wakeup_fd =
862 src->u.stream.wakeup_fd;
863 }
864
865 if (src->u.stream.shm_fd >= 0) {
866 obj->u.stream.shm_fd =
867 dup(src->u.stream.shm_fd);
868 if (obj->u.stream.shm_fd < 0) {
869 ret = errno;
870 goto stream_error_shm_fd;
871 }
872 } else {
873 obj->u.stream.shm_fd =
874 src->u.stream.shm_fd;
875 }
876 break;
877
878 stream_error_shm_fd:
879 if (src->u.stream.wakeup_fd >= 0) {
880 int closeret;
881
882 closeret = close(obj->u.stream.wakeup_fd);
883 if (closeret) {
884 PERROR("close");
885 }
886 }
887 stream_error_wakeup_fd:
888 goto error_type;
889 }
890
891 default:
892 ret = -EINVAL;
893 goto error_type;
894 }
895
896 *dest = obj;
897 return 0;
898
899error_type:
900 free(obj);
901error:
902 return ret;
903}
904
74d81a6c
MD
905
906/* Buffer operations */
907
908struct ustctl_consumer_channel *
909 ustctl_create_channel(struct ustctl_consumer_channel_attr *attr)
910{
911 struct ustctl_consumer_channel *chan;
912 const char *transport_name;
913 struct lttng_transport *transport;
914
915 switch (attr->type) {
916 case LTTNG_UST_CHAN_PER_CPU:
917 if (attr->output == LTTNG_UST_MMAP) {
34a91bdb
MD
918 if (attr->overwrite) {
919 if (attr->read_timer_interval == 0) {
920 transport_name = "relay-overwrite-mmap";
921 } else {
922 transport_name = "relay-overwrite-rt-mmap";
923 }
924 } else {
925 if (attr->read_timer_interval == 0) {
926 transport_name = "relay-discard-mmap";
927 } else {
928 transport_name = "relay-discard-rt-mmap";
929 }
930 }
74d81a6c
MD
931 } else {
932 return NULL;
933 }
c1fca457 934 break;
74d81a6c
MD
935 case LTTNG_UST_CHAN_METADATA:
936 if (attr->output == LTTNG_UST_MMAP)
937 transport_name = "relay-metadata-mmap";
938 else
939 return NULL;
c1fca457
MD
940 break;
941 default:
74d81a6c 942 transport_name = "<unknown>";
c1fca457
MD
943 return NULL;
944 }
74d81a6c
MD
945
946 transport = lttng_transport_find(transport_name);
947 if (!transport) {
948 DBG("LTTng transport %s not found\n",
32ce8569 949 transport_name);
74d81a6c 950 return NULL;
7a784989 951 }
74d81a6c
MD
952
953 chan = zmalloc(sizeof(*chan));
954 if (!chan)
955 return NULL;
956
957 chan->chan = transport->ops.channel_create(transport_name, NULL,
32ce8569 958 attr->subbuf_size, attr->num_subbuf,
74d81a6c 959 attr->switch_timer_interval,
32ce8569 960 attr->read_timer_interval,
74d81a6c
MD
961 attr->uuid);
962 if (!chan->chan) {
963 goto chan_error;
964 }
965 chan->chan->ops = &transport->ops;
966 memcpy(&chan->attr, attr, sizeof(chan->attr));
cb7378b3
MD
967 chan->wait_fd = ustctl_channel_get_wait_fd(chan);
968 chan->wakeup_fd = ustctl_channel_get_wakeup_fd(chan);
74d81a6c
MD
969 return chan;
970
971chan_error:
972 free(chan);
973 return NULL;
57773204
MD
974}
975
74d81a6c 976void ustctl_destroy_channel(struct ustctl_consumer_channel *chan)
57773204 977{
74d81a6c
MD
978 chan->chan->ops->channel_destroy(chan->chan);
979 free(chan);
980}
981
982int ustctl_send_channel_to_sessiond(int sock,
983 struct ustctl_consumer_channel *channel)
984{
985 struct shm_object_table *table;
57773204 986
74d81a6c
MD
987 table = channel->chan->handle->table;
988 if (table->size <= 0)
9bfc503d 989 return -EINVAL;
74d81a6c
MD
990 return ustctl_send_channel(sock,
991 channel->attr.type,
992 table->objects[0].memory_map,
993 table->objects[0].memory_map_size,
ff0f5728 994 channel->wakeup_fd,
74d81a6c
MD
995 0);
996}
9bfc503d 997
74d81a6c
MD
998int ustctl_send_stream_to_sessiond(int sock,
999 struct ustctl_consumer_stream *stream)
1000{
1001 if (!stream)
1002 return ustctl_send_stream(sock, -1U, -1U, -1, -1, 0);
1003
1004 return ustctl_send_stream(sock,
1005 stream->cpu,
1006 stream->memory_map_size,
1007 stream->shm_fd, stream->wakeup_fd,
1008 0);
57773204
MD
1009}
1010
c9023c93
MD
1011int ustctl_write_metadata_to_channel(
1012 struct ustctl_consumer_channel *channel,
1013 const char *metadata_str, /* NOT null-terminated */
1014 size_t len) /* metadata length */
1015{
1016 struct lttng_ust_lib_ring_buffer_ctx ctx;
1017 struct lttng_channel *chan = channel->chan;
1018 const char *str = metadata_str;
1019 int ret = 0, waitret;
1020 size_t reserve_len, pos;
1021
1022 for (pos = 0; pos < len; pos += reserve_len) {
1023 reserve_len = min_t(size_t,
1024 chan->ops->packet_avail_size(chan->chan, chan->handle),
1025 len - pos);
1026 lib_ring_buffer_ctx_init(&ctx, chan->chan, NULL, reserve_len,
1027 sizeof(char), -1, chan->handle);
1028 /*
1029 * We don't care about metadata buffer's records lost
1030 * count, because we always retry here. Report error if
1031 * we need to bail out after timeout or being
1032 * interrupted.
1033 */
1034 waitret = wait_cond_interruptible_timeout(
1035 ({
1036 ret = chan->ops->event_reserve(&ctx, 0);
1037 ret != -ENOBUFS || !ret;
1038 }),
1039 LTTNG_METADATA_TIMEOUT_MSEC);
1040 if (waitret == -ETIMEDOUT || waitret == -EINTR || ret) {
1041 DBG("LTTng: Failure to write metadata to buffers (%s)\n",
1042 waitret == -EINTR ? "interrupted" :
1043 (ret == -ENOBUFS ? "timeout" : "I/O error"));
1044 if (waitret == -EINTR)
1045 ret = waitret;
1046 goto end;
1047 }
1048 chan->ops->event_write(&ctx, &str[pos], reserve_len);
1049 chan->ops->event_commit(&ctx);
1050 }
1051end:
1052 return ret;
1053}
1054
ff0f5728
MD
1055int ustctl_channel_close_wait_fd(struct ustctl_consumer_channel *consumer_chan)
1056{
1057 struct channel *chan;
cb7378b3 1058 int ret;
ff0f5728
MD
1059
1060 chan = consumer_chan->chan->chan;
cb7378b3 1061 ret = ring_buffer_channel_close_wait_fd(&chan->backend.config,
ff0f5728 1062 chan, chan->handle);
cb7378b3
MD
1063 if (!ret)
1064 consumer_chan->wait_fd = -1;
1065 return ret;
ff0f5728
MD
1066}
1067
1068int ustctl_channel_close_wakeup_fd(struct ustctl_consumer_channel *consumer_chan)
1069{
1070 struct channel *chan;
cb7378b3 1071 int ret;
ff0f5728
MD
1072
1073 chan = consumer_chan->chan->chan;
cb7378b3 1074 ret = ring_buffer_channel_close_wakeup_fd(&chan->backend.config,
ff0f5728 1075 chan, chan->handle);
cb7378b3
MD
1076 if (!ret)
1077 consumer_chan->wakeup_fd = -1;
1078 return ret;
ff0f5728
MD
1079}
1080
74d81a6c 1081int ustctl_stream_close_wait_fd(struct ustctl_consumer_stream *stream)
5224b5c8
MD
1082{
1083 struct channel *chan;
1084
74d81a6c 1085 chan = stream->chan->chan->chan;
ff0f5728 1086 return ring_buffer_stream_close_wait_fd(&chan->backend.config,
74d81a6c 1087 chan, stream->handle, stream->cpu);
5224b5c8
MD
1088}
1089
74d81a6c 1090int ustctl_stream_close_wakeup_fd(struct ustctl_consumer_stream *stream)
6e922b24 1091{
66bdd22a 1092 struct channel *chan;
74d81a6c
MD
1093
1094 chan = stream->chan->chan->chan;
ff0f5728 1095 return ring_buffer_stream_close_wakeup_fd(&chan->backend.config,
74d81a6c
MD
1096 chan, stream->handle, stream->cpu);
1097}
1098
1099struct ustctl_consumer_stream *
1100 ustctl_create_stream(struct ustctl_consumer_channel *channel,
1101 int cpu)
1102{
1103 struct ustctl_consumer_stream *stream;
1104 struct lttng_ust_shm_handle *handle;
1105 struct channel *chan;
1106 int shm_fd, wait_fd, wakeup_fd;
1107 uint64_t memory_map_size;
4cfec15c 1108 struct lttng_ust_lib_ring_buffer *buf;
6e922b24
MD
1109 int ret;
1110
74d81a6c
MD
1111 if (!channel)
1112 return NULL;
1113 handle = channel->chan->handle;
9bfc503d
MD
1114 if (!handle)
1115 return NULL;
1116
74d81a6c 1117 chan = channel->chan->chan;
6e922b24 1118 buf = channel_get_ring_buffer(&chan->backend.config,
74d81a6c
MD
1119 chan, cpu, handle, &shm_fd, &wait_fd,
1120 &wakeup_fd, &memory_map_size);
6e922b24
MD
1121 if (!buf)
1122 return NULL;
74d81a6c 1123 ret = lib_ring_buffer_open_read(buf, handle);
6e922b24
MD
1124 if (ret)
1125 return NULL;
74d81a6c
MD
1126
1127 stream = zmalloc(sizeof(*stream));
1128 if (!stream)
1129 goto alloc_error;
1130 stream->handle = handle;
1131 stream->buf = buf;
1132 stream->chan = channel;
1133 stream->shm_fd = shm_fd;
1134 stream->wait_fd = wait_fd;
1135 stream->wakeup_fd = wakeup_fd;
1136 stream->memory_map_size = memory_map_size;
1137 stream->cpu = cpu;
1138 return stream;
1139
1140alloc_error:
1141 return NULL;
1142}
1143
1144void ustctl_destroy_stream(struct ustctl_consumer_stream *stream)
1145{
1146 struct lttng_ust_lib_ring_buffer *buf;
1147 struct ustctl_consumer_channel *consumer_chan;
1148
1149 assert(stream);
1150 buf = stream->buf;
1151 consumer_chan = stream->chan;
1152 lib_ring_buffer_release_read(buf, consumer_chan->chan->handle);
1153 free(stream);
6e922b24
MD
1154}
1155
ff0f5728
MD
1156int ustctl_channel_get_wait_fd(struct ustctl_consumer_channel *chan)
1157{
1158 if (!chan)
1159 return -EINVAL;
1160 return shm_get_wait_fd(chan->chan->handle,
1161 &chan->chan->handle->chan._ref);
1162}
1163
1164int ustctl_channel_get_wakeup_fd(struct ustctl_consumer_channel *chan)
1165{
1166 if (!chan)
1167 return -EINVAL;
1168 return shm_get_wakeup_fd(chan->chan->handle,
1169 &chan->chan->handle->chan._ref);
1170}
1171
1172int ustctl_stream_get_wait_fd(struct ustctl_consumer_stream *stream)
6e922b24 1173{
74d81a6c
MD
1174 struct lttng_ust_lib_ring_buffer *buf;
1175 struct ustctl_consumer_channel *consumer_chan;
1176
1177 if (!stream)
1178 return -EINVAL;
1179 buf = stream->buf;
1180 consumer_chan = stream->chan;
1181 return shm_get_wait_fd(consumer_chan->chan->handle, &buf->self._ref);
1182}
1183
ff0f5728 1184int ustctl_stream_get_wakeup_fd(struct ustctl_consumer_stream *stream)
74d81a6c
MD
1185{
1186 struct lttng_ust_lib_ring_buffer *buf;
1187 struct ustctl_consumer_channel *consumer_chan;
1188
1189 if (!stream)
1190 return -EINVAL;
1191 buf = stream->buf;
1192 consumer_chan = stream->chan;
1193 return shm_get_wakeup_fd(consumer_chan->chan->handle, &buf->self._ref);
6e922b24
MD
1194}
1195
57773204
MD
1196/* For mmap mode, readable without "get" operation */
1197
74d81a6c 1198void *ustctl_get_mmap_base(struct ustctl_consumer_stream *stream)
9095efe9 1199{
74d81a6c
MD
1200 struct lttng_ust_lib_ring_buffer *buf;
1201 struct ustctl_consumer_channel *consumer_chan;
1202
1203 if (!stream)
9bfc503d 1204 return NULL;
74d81a6c
MD
1205 buf = stream->buf;
1206 consumer_chan = stream->chan;
1207 return shmp(consumer_chan->chan->handle, buf->backend.memory_map);
9095efe9
MD
1208}
1209
57773204 1210/* returns the length to mmap. */
74d81a6c 1211int ustctl_get_mmap_len(struct ustctl_consumer_stream *stream,
57773204
MD
1212 unsigned long *len)
1213{
74d81a6c 1214 struct ustctl_consumer_channel *consumer_chan;
57773204 1215 unsigned long mmap_buf_len;
66bdd22a 1216 struct channel *chan;
57773204 1217
74d81a6c 1218 if (!stream)
9bfc503d 1219 return -EINVAL;
74d81a6c
MD
1220 consumer_chan = stream->chan;
1221 chan = consumer_chan->chan->chan;
57773204
MD
1222 if (chan->backend.config.output != RING_BUFFER_MMAP)
1223 return -EINVAL;
1224 mmap_buf_len = chan->backend.buf_size;
1225 if (chan->backend.extra_reader_sb)
1226 mmap_buf_len += chan->backend.subbuf_size;
1227 if (mmap_buf_len > INT_MAX)
1228 return -EFBIG;
1229 *len = mmap_buf_len;
1230 return 0;
1231}
1232
1233/* returns the maximum size for sub-buffers. */
74d81a6c 1234int ustctl_get_max_subbuf_size(struct ustctl_consumer_stream *stream,
57773204
MD
1235 unsigned long *len)
1236{
74d81a6c 1237 struct ustctl_consumer_channel *consumer_chan;
66bdd22a 1238 struct channel *chan;
57773204 1239
74d81a6c 1240 if (!stream)
9bfc503d 1241 return -EINVAL;
74d81a6c
MD
1242 consumer_chan = stream->chan;
1243 chan = consumer_chan->chan->chan;
57773204
MD
1244 *len = chan->backend.subbuf_size;
1245 return 0;
1246}
1247
1248/*
1249 * For mmap mode, operate on the current packet (between get/put or
1250 * get_next/put_next).
1251 */
1252
1253/* returns the offset of the subbuffer belonging to the mmap reader. */
74d81a6c
MD
1254int ustctl_get_mmap_read_offset(struct ustctl_consumer_stream *stream,
1255 unsigned long *off)
57773204 1256{
66bdd22a 1257 struct channel *chan;
57773204 1258 unsigned long sb_bindex;
74d81a6c
MD
1259 struct lttng_ust_lib_ring_buffer *buf;
1260 struct ustctl_consumer_channel *consumer_chan;
57773204 1261
74d81a6c 1262 if (!stream)
9bfc503d 1263 return -EINVAL;
74d81a6c
MD
1264 buf = stream->buf;
1265 consumer_chan = stream->chan;
1266 chan = consumer_chan->chan->chan;
57773204
MD
1267 if (chan->backend.config.output != RING_BUFFER_MMAP)
1268 return -EINVAL;
1269 sb_bindex = subbuffer_id_get_index(&chan->backend.config,
32ce8569 1270 buf->backend.buf_rsb.id);
74d81a6c
MD
1271 *off = shmp(consumer_chan->chan->handle,
1272 shmp_index(consumer_chan->chan->handle, buf->backend.array, sb_bindex)->shmp)->mmap_offset;
57773204
MD
1273 return 0;
1274}
1275
1276/* returns the size of the current sub-buffer, without padding (for mmap). */
74d81a6c
MD
1277int ustctl_get_subbuf_size(struct ustctl_consumer_stream *stream,
1278 unsigned long *len)
57773204 1279{
74d81a6c 1280 struct ustctl_consumer_channel *consumer_chan;
66bdd22a 1281 struct channel *chan;
74d81a6c 1282 struct lttng_ust_lib_ring_buffer *buf;
57773204 1283
74d81a6c 1284 if (!stream)
9bfc503d
MD
1285 return -EINVAL;
1286
74d81a6c
MD
1287 buf = stream->buf;
1288 consumer_chan = stream->chan;
1289 chan = consumer_chan->chan->chan;
57773204 1290 *len = lib_ring_buffer_get_read_data_size(&chan->backend.config, buf,
74d81a6c 1291 consumer_chan->chan->handle);
57773204
MD
1292 return 0;
1293}
1294
1295/* returns the size of the current sub-buffer, without padding (for mmap). */
74d81a6c
MD
1296int ustctl_get_padded_subbuf_size(struct ustctl_consumer_stream *stream,
1297 unsigned long *len)
57773204 1298{
74d81a6c 1299 struct ustctl_consumer_channel *consumer_chan;
66bdd22a 1300 struct channel *chan;
74d81a6c 1301 struct lttng_ust_lib_ring_buffer *buf;
57773204 1302
74d81a6c 1303 if (!stream)
9bfc503d 1304 return -EINVAL;
74d81a6c
MD
1305 buf = stream->buf;
1306 consumer_chan = stream->chan;
1307 chan = consumer_chan->chan->chan;
57773204 1308 *len = lib_ring_buffer_get_read_data_size(&chan->backend.config, buf,
74d81a6c 1309 consumer_chan->chan->handle);
57773204
MD
1310 *len = PAGE_ALIGN(*len);
1311 return 0;
1312}
1313
1314/* Get exclusive read access to the next sub-buffer that can be read. */
74d81a6c 1315int ustctl_get_next_subbuf(struct ustctl_consumer_stream *stream)
57773204 1316{
74d81a6c
MD
1317 struct lttng_ust_lib_ring_buffer *buf;
1318 struct ustctl_consumer_channel *consumer_chan;
9bfc503d 1319
74d81a6c
MD
1320 if (!stream)
1321 return -EINVAL;
1322 buf = stream->buf;
1323 consumer_chan = stream->chan;
1324 return lib_ring_buffer_get_next_subbuf(buf,
1325 consumer_chan->chan->handle);
57773204
MD
1326}
1327
1328
1329/* Release exclusive sub-buffer access, move consumer forward. */
74d81a6c 1330int ustctl_put_next_subbuf(struct ustctl_consumer_stream *stream)
57773204 1331{
74d81a6c
MD
1332 struct lttng_ust_lib_ring_buffer *buf;
1333 struct ustctl_consumer_channel *consumer_chan;
9bfc503d 1334
74d81a6c
MD
1335 if (!stream)
1336 return -EINVAL;
1337 buf = stream->buf;
1338 consumer_chan = stream->chan;
1339 lib_ring_buffer_put_next_subbuf(buf, consumer_chan->chan->handle);
57773204
MD
1340 return 0;
1341}
1342
1343/* snapshot */
1344
1345/* Get a snapshot of the current ring buffer producer and consumer positions */
74d81a6c 1346int ustctl_snapshot(struct ustctl_consumer_stream *stream)
57773204 1347{
74d81a6c
MD
1348 struct lttng_ust_lib_ring_buffer *buf;
1349 struct ustctl_consumer_channel *consumer_chan;
9bfc503d 1350
74d81a6c
MD
1351 if (!stream)
1352 return -EINVAL;
1353 buf = stream->buf;
1354 consumer_chan = stream->chan;
57773204 1355 return lib_ring_buffer_snapshot(buf, &buf->cons_snapshot,
74d81a6c 1356 &buf->prod_snapshot, consumer_chan->chan->handle);
57773204
MD
1357}
1358
1359/* Get the consumer position (iteration start) */
74d81a6c
MD
1360int ustctl_snapshot_get_consumed(struct ustctl_consumer_stream *stream,
1361 unsigned long *pos)
57773204 1362{
74d81a6c 1363 struct lttng_ust_lib_ring_buffer *buf;
9bfc503d 1364
74d81a6c
MD
1365 if (!stream)
1366 return -EINVAL;
1367 buf = stream->buf;
57773204
MD
1368 *pos = buf->cons_snapshot;
1369 return 0;
1370}
1371
1372/* Get the producer position (iteration end) */
74d81a6c
MD
1373int ustctl_snapshot_get_produced(struct ustctl_consumer_stream *stream,
1374 unsigned long *pos)
57773204 1375{
74d81a6c 1376 struct lttng_ust_lib_ring_buffer *buf;
9bfc503d 1377
74d81a6c
MD
1378 if (!stream)
1379 return -EINVAL;
1380 buf = stream->buf;
57773204
MD
1381 *pos = buf->prod_snapshot;
1382 return 0;
1383}
1384
1385/* Get exclusive read access to the specified sub-buffer position */
74d81a6c
MD
1386int ustctl_get_subbuf(struct ustctl_consumer_stream *stream,
1387 unsigned long *pos)
57773204 1388{
74d81a6c
MD
1389 struct lttng_ust_lib_ring_buffer *buf;
1390 struct ustctl_consumer_channel *consumer_chan;
9bfc503d 1391
74d81a6c
MD
1392 if (!stream)
1393 return -EINVAL;
1394 buf = stream->buf;
1395 consumer_chan = stream->chan;
1396 return lib_ring_buffer_get_subbuf(buf, *pos,
1397 consumer_chan->chan->handle);
57773204
MD
1398}
1399
1400/* Release exclusive sub-buffer access */
74d81a6c 1401int ustctl_put_subbuf(struct ustctl_consumer_stream *stream)
57773204 1402{
74d81a6c
MD
1403 struct lttng_ust_lib_ring_buffer *buf;
1404 struct ustctl_consumer_channel *consumer_chan;
9bfc503d 1405
74d81a6c
MD
1406 if (!stream)
1407 return -EINVAL;
1408 buf = stream->buf;
1409 consumer_chan = stream->chan;
1410 lib_ring_buffer_put_subbuf(buf, consumer_chan->chan->handle);
57773204
MD
1411 return 0;
1412}
1413
74d81a6c 1414void ustctl_flush_buffer(struct ustctl_consumer_stream *stream,
b52190f2 1415 int producer_active)
57773204 1416{
74d81a6c
MD
1417 struct lttng_ust_lib_ring_buffer *buf;
1418 struct ustctl_consumer_channel *consumer_chan;
1419
1420 assert(stream);
1421 buf = stream->buf;
1422 consumer_chan = stream->chan;
b52190f2
MD
1423 lib_ring_buffer_switch_slow(buf,
1424 producer_active ? SWITCH_ACTIVE : SWITCH_FLUSH,
74d81a6c
MD
1425 consumer_chan->chan->handle);
1426}
1427
32ce8569
MD
1428/*
1429 * Returns 0 on success, negative error value on error.
1430 */
1431int ustctl_recv_reg_msg(int sock,
1432 enum ustctl_socket_type *type,
1433 uint32_t *major,
1434 uint32_t *minor,
1435 uint32_t *pid,
1436 uint32_t *ppid,
1437 uint32_t *uid,
1438 uint32_t *gid,
1439 uint32_t *bits_per_long,
1440 uint32_t *uint8_t_alignment,
1441 uint32_t *uint16_t_alignment,
1442 uint32_t *uint32_t_alignment,
1443 uint32_t *uint64_t_alignment,
1444 uint32_t *long_alignment,
1445 int *byte_order,
1446 char *name)
1447{
1448 ssize_t len;
1449 struct ustctl_reg_msg reg_msg;
1450
1451 len = ustcomm_recv_unix_sock(sock, &reg_msg, sizeof(reg_msg));
1452 if (len > 0 && len != sizeof(reg_msg))
1453 return -EIO;
1454 if (len == 0)
1455 return -EPIPE;
1456 if (len < 0)
1457 return len;
1458
1459 if (reg_msg.magic == LTTNG_UST_COMM_MAGIC) {
1460 *byte_order = BYTE_ORDER == BIG_ENDIAN ?
1461 BIG_ENDIAN : LITTLE_ENDIAN;
1462 } else if (reg_msg.magic == bswap_32(LTTNG_UST_COMM_MAGIC)) {
1463 *byte_order = BYTE_ORDER == BIG_ENDIAN ?
1464 LITTLE_ENDIAN : BIG_ENDIAN;
1465 } else {
1466 return -LTTNG_UST_ERR_INVAL_MAGIC;
1467 }
1468 switch (reg_msg.socket_type) {
1469 case 0: *type = USTCTL_SOCKET_CMD;
1470 break;
1471 case 1: *type = USTCTL_SOCKET_NOTIFY;
1472 break;
1473 default:
1474 return -LTTNG_UST_ERR_INVAL_SOCKET_TYPE;
1475 }
1476 *major = reg_msg.major;
1477 *minor = reg_msg.minor;
1478 *pid = reg_msg.pid;
1479 *ppid = reg_msg.ppid;
1480 *uid = reg_msg.uid;
1481 *gid = reg_msg.gid;
1482 *bits_per_long = reg_msg.bits_per_long;
1483 *uint8_t_alignment = reg_msg.uint8_t_alignment;
1484 *uint16_t_alignment = reg_msg.uint16_t_alignment;
1485 *uint32_t_alignment = reg_msg.uint32_t_alignment;
1486 *uint64_t_alignment = reg_msg.uint64_t_alignment;
1487 *long_alignment = reg_msg.long_alignment;
1488 memcpy(name, reg_msg.name, LTTNG_UST_ABI_PROCNAME_LEN);
1489 if (reg_msg.major != LTTNG_UST_ABI_MAJOR_VERSION) {
1490 return -LTTNG_UST_ERR_UNSUP_MAJOR;
1491 }
1492
1493 return 0;
1494}
1495
1496int ustctl_recv_notify(int sock, enum ustctl_notify_cmd *notify_cmd)
1497{
1498 struct ustcomm_notify_hdr header;
1499 ssize_t len;
1500
1501 len = ustcomm_recv_unix_sock(sock, &header, sizeof(header));
1502 if (len > 0 && len != sizeof(header))
1503 return -EIO;
1504 if (len == 0)
1505 return -EPIPE;
1506 if (len < 0)
1507 return len;
1508 switch (header.notify_cmd) {
1509 case 0:
1510 *notify_cmd = USTCTL_NOTIFY_CMD_EVENT;
1511 break;
1512 case 1:
1513 *notify_cmd = USTCTL_NOTIFY_CMD_CHANNEL;
1514 break;
1515 default:
1516 return -EINVAL;
1517 }
1518 return 0;
1519}
1520
1521/*
1522 * Returns 0 on success, negative error value on error.
1523 */
1524int ustctl_recv_register_event(int sock,
1525 int *session_objd,
1526 int *channel_objd,
1527 char *event_name,
1528 int *loglevel,
1529 char **signature,
1530 size_t *nr_fields,
1531 struct ustctl_field **fields,
1532 char **model_emf_uri)
1533{
1534 ssize_t len;
1535 struct ustcomm_notify_event_msg msg;
1536 size_t signature_len, fields_len, model_emf_uri_len;
1537 char *a_sign = NULL, *a_model_emf_uri = NULL;
1538 struct ustctl_field *a_fields = NULL;
1539
1540 len = ustcomm_recv_unix_sock(sock, &msg, sizeof(msg));
1541 if (len > 0 && len != sizeof(msg))
1542 return -EIO;
1543 if (len == 0)
1544 return -EPIPE;
1545 if (len < 0)
1546 return len;
1547
1548 *session_objd = msg.session_objd;
1549 *channel_objd = msg.channel_objd;
1550 strncpy(event_name, msg.event_name, LTTNG_UST_SYM_NAME_LEN);
1551 event_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
1552 *loglevel = msg.loglevel;
1553 signature_len = msg.signature_len;
1554 fields_len = msg.fields_len;
1555
1556 if (fields_len % sizeof(*a_fields) != 0) {
1557 return -EINVAL;
1558 }
1559
1560 model_emf_uri_len = msg.model_emf_uri_len;
1561
1562 /* recv signature. contains at least \0. */
1563 a_sign = zmalloc(signature_len);
1564 if (!a_sign)
1565 return -ENOMEM;
1566 len = ustcomm_recv_unix_sock(sock, a_sign, signature_len);
1567 if (len > 0 && len != signature_len) {
1568 len = -EIO;
1569 goto signature_error;
1570 }
1571 if (len == 0) {
1572 len = -EPIPE;
1573 goto signature_error;
1574 }
1575 if (len < 0) {
1576 goto signature_error;
1577 }
1578 /* Enforce end of string */
1579 signature[signature_len - 1] = '\0';
1580
1581 /* recv fields */
1582 if (fields_len) {
1583 a_fields = zmalloc(fields_len);
1584 if (!a_fields) {
1585 len = -ENOMEM;
1586 goto signature_error;
1587 }
1588 len = ustcomm_recv_unix_sock(sock, a_fields, fields_len);
1589 if (len > 0 && len != fields_len) {
1590 len = -EIO;
1591 goto fields_error;
1592 }
1593 if (len == 0) {
1594 len = -EPIPE;
1595 goto fields_error;
1596 }
1597 if (len < 0) {
1598 goto fields_error;
1599 }
1600 }
1601
1602 if (model_emf_uri_len) {
1603 /* recv model_emf_uri_len */
1604 a_model_emf_uri = zmalloc(model_emf_uri_len);
1605 if (!a_model_emf_uri) {
1606 len = -ENOMEM;
1607 goto fields_error;
1608 }
1609 len = ustcomm_recv_unix_sock(sock, a_model_emf_uri,
1610 model_emf_uri_len);
1611 if (len > 0 && len != model_emf_uri_len) {
1612 len = -EIO;
1613 goto model_error;
1614 }
1615 if (len == 0) {
1616 len = -EPIPE;
1617 goto model_error;
1618 }
1619 if (len < 0) {
1620 goto model_error;
1621 }
1622 /* Enforce end of string */
1623 a_model_emf_uri[model_emf_uri_len - 1] = '\0';
1624 }
1625
1626 *signature = a_sign;
1627 *nr_fields = fields_len / sizeof(*a_fields);
1628 *fields = a_fields;
1629 *model_emf_uri = a_model_emf_uri;
1630
1631 return 0;
1632
1633model_error:
1634 free(a_model_emf_uri);
1635fields_error:
1636 free(a_fields);
1637signature_error:
1638 free(a_sign);
1639 return len;
1640}
1641
1642/*
1643 * Returns 0 on success, negative error value on error.
1644 */
1645int ustctl_reply_register_event(int sock,
1646 uint32_t id,
1647 int ret_code)
1648{
1649 ssize_t len;
1650 struct {
1651 struct ustcomm_notify_hdr header;
1652 struct ustcomm_notify_event_reply r;
1653 } reply;
1654
1655 memset(&reply, 0, sizeof(reply));
1656 reply.header.notify_cmd = USTCTL_NOTIFY_CMD_EVENT;
1657 reply.r.ret_code = ret_code;
1658 reply.r.event_id = id;
1659 len = ustcomm_send_unix_sock(sock, &reply, sizeof(reply));
1660 if (len > 0 && len != sizeof(reply))
1661 return -EIO;
1662 if (len < 0)
1663 return len;
1664 return 0;
1665}
1666
1667/*
1668 * Returns 0 on success, negative UST or system error value on error.
1669 */
1670int ustctl_recv_register_channel(int sock,
1671 int *session_objd, /* session descriptor (output) */
1672 int *channel_objd, /* channel descriptor (output) */
1673 size_t *nr_fields,
1674 struct ustctl_field **fields)
1675{
1676 ssize_t len;
1677 struct ustcomm_notify_channel_msg msg;
1678 size_t fields_len;
1679 struct ustctl_field *a_fields;
1680
1681 len = ustcomm_recv_unix_sock(sock, &msg, sizeof(msg));
1682 if (len > 0 && len != sizeof(msg))
1683 return -EIO;
1684 if (len == 0)
1685 return -EPIPE;
1686 if (len < 0)
1687 return len;
1688
1689 *session_objd = msg.session_objd;
1690 *channel_objd = msg.channel_objd;
1691 fields_len = msg.ctx_fields_len;
1692
1693 if (fields_len % sizeof(*a_fields) != 0) {
1694 return -EINVAL;
1695 }
1696
1697 /* recv fields */
1698 if (fields_len) {
1699 a_fields = zmalloc(fields_len);
1700 if (!a_fields) {
1701 len = -ENOMEM;
1702 goto alloc_error;
1703 }
1704 len = ustcomm_recv_unix_sock(sock, a_fields, fields_len);
1705 if (len > 0 && len != fields_len) {
1706 len = -EIO;
1707 goto fields_error;
1708 }
1709 if (len == 0) {
1710 len = -EPIPE;
1711 goto fields_error;
1712 }
1713 if (len < 0) {
1714 goto fields_error;
1715 }
1716 *fields = a_fields;
1717 } else {
1718 *fields = NULL;
1719 }
1720 *nr_fields = fields_len / sizeof(*a_fields);
1721 return 0;
1722
1723fields_error:
1724 free(a_fields);
1725alloc_error:
1726 return len;
1727}
1728
1729/*
1730 * Returns 0 on success, negative error value on error.
1731 */
1732int ustctl_reply_register_channel(int sock,
1733 uint32_t chan_id,
1734 enum ustctl_channel_header header_type,
1735 int ret_code)
1736{
1737 ssize_t len;
1738 struct {
1739 struct ustcomm_notify_hdr header;
1740 struct ustcomm_notify_channel_reply r;
1741 } reply;
1742
1743 memset(&reply, 0, sizeof(reply));
1744 reply.header.notify_cmd = USTCTL_NOTIFY_CMD_CHANNEL;
1745 reply.r.ret_code = ret_code;
1746 reply.r.chan_id = chan_id;
1747 switch (header_type) {
1748 case USTCTL_CHANNEL_HEADER_COMPACT:
1749 reply.r.header_type = 1;
1750 break;
1751 case USTCTL_CHANNEL_HEADER_LARGE:
1752 reply.r.header_type = 2;
1753 break;
1754 default:
1755 reply.r.header_type = 0;
1756 break;
1757 }
1758 len = ustcomm_send_unix_sock(sock, &reply, sizeof(reply));
1759 if (len > 0 && len != sizeof(reply))
1760 return -EIO;
1761 if (len < 0)
1762 return len;
1763 return 0;
1764}
1765
74d81a6c
MD
1766static __attribute__((constructor))
1767void ustctl_init(void)
1768{
1769 init_usterr();
1770 lttng_ring_buffer_metadata_client_init();
1771 lttng_ring_buffer_client_overwrite_init();
34a91bdb 1772 lttng_ring_buffer_client_overwrite_rt_init();
74d81a6c 1773 lttng_ring_buffer_client_discard_init();
34a91bdb 1774 lttng_ring_buffer_client_discard_rt_init();
03d2d293 1775 lib_ringbuffer_signal_init();
74d81a6c
MD
1776}
1777
1778static __attribute__((destructor))
1779void ustctl_exit(void)
1780{
34a91bdb 1781 lttng_ring_buffer_client_discard_rt_exit();
74d81a6c 1782 lttng_ring_buffer_client_discard_exit();
34a91bdb 1783 lttng_ring_buffer_client_overwrite_rt_exit();
74d81a6c
MD
1784 lttng_ring_buffer_client_overwrite_exit();
1785 lttng_ring_buffer_metadata_client_exit();
57773204 1786}
This page took 0.106267 seconds and 4 git commands to generate.