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