Move UST registry into sessiond and implement notifiers
[lttng-ust.git] / liblttng-ust-ctl / ustctl.c
1 /*
2 * Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
3 * Copyright (C) 2011-2013 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 *
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.
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 *
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.
17 */
18
19 #define _GNU_SOURCE
20 #include <string.h>
21 #include <lttng/ust-ctl.h>
22 #include <lttng/ust-abi.h>
23 #include <lttng/ust-events.h>
24 #include <sys/mman.h>
25 #include <byteswap.h>
26
27 #include <usterr-signal-safe.h>
28 #include <ust-comm.h>
29 #include <helper.h>
30
31 #include "../libringbuffer/backend.h"
32 #include "../libringbuffer/frontend.h"
33
34 /*
35 * Channel representation within consumer.
36 */
37 struct ustctl_consumer_channel {
38 struct lttng_channel *chan; /* lttng channel buffers */
39
40 /* initial attributes */
41 struct ustctl_consumer_channel_attr attr;
42 };
43
44 /*
45 * Stream representation within consumer.
46 */
47 struct 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
56 extern void lttng_ring_buffer_client_overwrite_init(void);
57 extern void lttng_ring_buffer_client_discard_init(void);
58 extern void lttng_ring_buffer_metadata_client_init(void);
59 extern void lttng_ring_buffer_client_overwrite_exit(void);
60 extern void lttng_ring_buffer_client_discard_exit(void);
61 extern void lttng_ring_buffer_metadata_client_exit(void);
62
63 volatile enum ust_loglevel ust_loglevel;
64
65 int ustctl_release_handle(int sock, int handle)
66 {
67 struct ustcomm_ust_msg lum;
68 struct ustcomm_ust_reply lur;
69
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);
76 }
77
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 */
82 int ustctl_release_object(int sock, struct lttng_ust_object_data *data)
83 {
84 int ret;
85
86 if (!data)
87 return -EINVAL;
88
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 }
100 }
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 }
107 }
108 break;
109 case LTTNG_UST_OBJECT_TYPE_EVENT:
110 case LTTNG_UST_OBJECT_TYPE_CONTEXT:
111 break;
112 default:
113 assert(0);
114 }
115 return ustctl_release_handle(sock, data->handle);
116 }
117
118 /*
119 * Send registration done packet to the application.
120 */
121 int 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;
134 return 0;
135 }
136
137 /*
138 * returns session handle.
139 */
140 int 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
158 int ustctl_create_event(int sock, struct lttng_ust_event *ev,
159 struct lttng_ust_object_data *channel_data,
160 struct lttng_ust_object_data **_event_data)
161 {
162 struct ustcomm_ust_msg lum;
163 struct ustcomm_ust_reply lur;
164 struct lttng_ust_object_data *event_data;
165 int ret;
166
167 if (!channel_data || !_event_data)
168 return -EINVAL;
169
170 event_data = zmalloc(sizeof(*event_data));
171 if (!event_data)
172 return -ENOMEM;
173 event_data->type = LTTNG_UST_OBJECT_TYPE_EVENT;
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;
180 lum.u.event.loglevel_type = ev->loglevel_type;
181 lum.u.event.loglevel = ev->loglevel;
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
193 int ustctl_add_context(int sock, struct lttng_ust_context *ctx,
194 struct lttng_ust_object_data *obj_data,
195 struct lttng_ust_object_data **_context_data)
196 {
197 struct ustcomm_ust_msg lum;
198 struct ustcomm_ust_reply lur;
199 struct lttng_ust_object_data *context_data;
200 int ret;
201
202 if (!obj_data || !_context_data)
203 return -EINVAL;
204
205 context_data = zmalloc(sizeof(*context_data));
206 if (!context_data)
207 return -ENOMEM;
208 context_data->type = LTTNG_UST_OBJECT_TYPE_CONTEXT;
209 memset(&lum, 0, sizeof(lum));
210 lum.handle = obj_data->handle;
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 }
218 context_data->handle = -1;
219 DBG("Context created successfully");
220 *_context_data = context_data;
221 return ret;
222 }
223
224 int 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;
239 lum.u.filter.seqnum = bytecode->seqnum;
240
241 ret = ustcomm_send_app_msg(sock, &lum);
242 if (ret)
243 return ret;
244 /* send var len bytecode */
245 ret = ustcomm_send_unix_sock(sock, bytecode->data,
246 bytecode->len);
247 if (ret < 0) {
248 if (ret == -ECONNRESET)
249 fprintf(stderr, "remote end closed connection\n");
250 return ret;
251 }
252 if (ret != bytecode->len)
253 return -EINVAL;
254 return ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
255 }
256
257 /* Enable event, channel and session ioctl */
258 int ustctl_enable(int sock, struct lttng_ust_object_data *object)
259 {
260 struct ustcomm_ust_msg lum;
261 struct ustcomm_ust_reply lur;
262 int ret;
263
264 if (!object)
265 return -EINVAL;
266
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 */
278 int ustctl_disable(int sock, struct lttng_ust_object_data *object)
279 {
280 struct ustcomm_ust_msg lum;
281 struct ustcomm_ust_reply lur;
282 int ret;
283
284 if (!object)
285 return -EINVAL;
286
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
297 int ustctl_start_session(int sock, int handle)
298 {
299 struct lttng_ust_object_data obj;
300
301 obj.handle = handle;
302 return ustctl_enable(sock, &obj);
303 }
304
305 int ustctl_stop_session(int sock, int handle)
306 {
307 struct lttng_ust_object_data obj;
308
309 obj.handle = handle;
310 return ustctl_disable(sock, &obj);
311 }
312
313 int ustctl_tracepoint_list(int sock)
314 {
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
330 int ustctl_tracepoint_list_get(int sock, int tp_list_handle,
331 struct lttng_ust_tracepoint_iter *iter)
332 {
333 struct ustcomm_ust_msg lum;
334 struct ustcomm_ust_reply lur;
335 int ret;
336
337 if (!iter)
338 return -EINVAL;
339
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;
346 DBG("received tracepoint list entry name %s loglevel %d",
347 lur.u.tracepoint.name,
348 lur.u.tracepoint.loglevel);
349 memcpy(iter, &lur.u.tracepoint, sizeof(*iter));
350 return 0;
351 }
352
353 int 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
370 int 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
399 int 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
405 if (!v)
406 return -EINVAL;
407
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
419 int 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
435 int ustctl_calibrate(int sock, struct lttng_ust_calibrate *calibrate)
436 {
437 if (!calibrate)
438 return -EINVAL;
439
440 return -ENOSYS;
441 }
442
443 int 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
449 if (!object)
450 return -EINVAL;
451
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
462 static
463 int 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 }
499
500 return 0;
501 }
502
503 static
504 int 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)
509 {
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
562 int 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;
567 int ret;
568
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 }
586
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
617 error_recv_data:
618 free(channel_data->u.channel.data);
619 error:
620 free(channel_data);
621 error_alloc:
622 return ret;
623 }
624
625 int 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;
637 }
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;
677 }
678 }
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;
683
684 error:
685 free(stream_data);
686 error_alloc:
687 return ret;
688 }
689
690 int 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 }
721 }
722 return ret;
723 }
724
725 int 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
758 struct 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 }
773 break;
774 case LTTNG_UST_CHAN_METADATA:
775 if (attr->output == LTTNG_UST_MMAP)
776 transport_name = "relay-metadata-mmap";
777 else
778 return NULL;
779 break;
780 default:
781 transport_name = "<unknown>";
782 return NULL;
783 }
784
785 transport = lttng_transport_find(transport_name);
786 if (!transport) {
787 DBG("LTTng transport %s not found\n",
788 transport_name);
789 return NULL;
790 }
791
792 chan = zmalloc(sizeof(*chan));
793 if (!chan)
794 return NULL;
795
796 chan->chan = transport->ops.channel_create(transport_name, NULL,
797 attr->subbuf_size, attr->num_subbuf,
798 attr->switch_timer_interval,
799 attr->read_timer_interval,
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
808 chan_error:
809 free(chan);
810 return NULL;
811 }
812
813 void ustctl_destroy_channel(struct ustctl_consumer_channel *chan)
814 {
815 chan->chan->ops->channel_destroy(chan->chan);
816 free(chan);
817 }
818
819 int ustctl_send_channel_to_sessiond(int sock,
820 struct ustctl_consumer_channel *channel)
821 {
822 struct shm_object_table *table;
823
824 table = channel->chan->handle->table;
825 if (table->size <= 0)
826 return -EINVAL;
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 }
833
834 int 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);
845 }
846
847 int ustctl_stream_close_wait_fd(struct ustctl_consumer_stream *stream)
848 {
849 struct channel *chan;
850
851 chan = stream->chan->chan->chan;
852 return ring_buffer_close_wait_fd(&chan->backend.config,
853 chan, stream->handle, stream->cpu);
854 }
855
856 int ustctl_stream_close_wakeup_fd(struct ustctl_consumer_stream *stream)
857 {
858 struct channel *chan;
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
865 struct 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;
874 struct lttng_ust_lib_ring_buffer *buf;
875 int ret;
876
877 if (!channel)
878 return NULL;
879 handle = channel->chan->handle;
880 if (!handle)
881 return NULL;
882
883 chan = channel->chan->chan;
884 buf = channel_get_ring_buffer(&chan->backend.config,
885 chan, cpu, handle, &shm_fd, &wait_fd,
886 &wakeup_fd, &memory_map_size);
887 if (!buf)
888 return NULL;
889 ret = lib_ring_buffer_open_read(buf, handle);
890 if (ret)
891 return NULL;
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
906 alloc_error:
907 return NULL;
908 }
909
910 void 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);
920 }
921
922 int ustctl_get_wait_fd(struct ustctl_consumer_stream *stream)
923 {
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
934 int 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);
944 }
945
946 /* For mmap mode, readable without "get" operation */
947
948 void *ustctl_get_mmap_base(struct ustctl_consumer_stream *stream)
949 {
950 struct lttng_ust_lib_ring_buffer *buf;
951 struct ustctl_consumer_channel *consumer_chan;
952
953 if (!stream)
954 return NULL;
955 buf = stream->buf;
956 consumer_chan = stream->chan;
957 return shmp(consumer_chan->chan->handle, buf->backend.memory_map);
958 }
959
960 /* returns the length to mmap. */
961 int ustctl_get_mmap_len(struct ustctl_consumer_stream *stream,
962 unsigned long *len)
963 {
964 struct ustctl_consumer_channel *consumer_chan;
965 unsigned long mmap_buf_len;
966 struct channel *chan;
967
968 if (!stream)
969 return -EINVAL;
970 consumer_chan = stream->chan;
971 chan = consumer_chan->chan->chan;
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. */
984 int ustctl_get_max_subbuf_size(struct ustctl_consumer_stream *stream,
985 unsigned long *len)
986 {
987 struct ustctl_consumer_channel *consumer_chan;
988 struct channel *chan;
989
990 if (!stream)
991 return -EINVAL;
992 consumer_chan = stream->chan;
993 chan = consumer_chan->chan->chan;
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. */
1004 int ustctl_get_mmap_read_offset(struct ustctl_consumer_stream *stream,
1005 unsigned long *off)
1006 {
1007 struct channel *chan;
1008 unsigned long sb_bindex;
1009 struct lttng_ust_lib_ring_buffer *buf;
1010 struct ustctl_consumer_channel *consumer_chan;
1011
1012 if (!stream)
1013 return -EINVAL;
1014 buf = stream->buf;
1015 consumer_chan = stream->chan;
1016 chan = consumer_chan->chan->chan;
1017 if (chan->backend.config.output != RING_BUFFER_MMAP)
1018 return -EINVAL;
1019 sb_bindex = subbuffer_id_get_index(&chan->backend.config,
1020 buf->backend.buf_rsb.id);
1021 *off = shmp(consumer_chan->chan->handle,
1022 shmp_index(consumer_chan->chan->handle, buf->backend.array, sb_bindex)->shmp)->mmap_offset;
1023 return 0;
1024 }
1025
1026 /* returns the size of the current sub-buffer, without padding (for mmap). */
1027 int ustctl_get_subbuf_size(struct ustctl_consumer_stream *stream,
1028 unsigned long *len)
1029 {
1030 struct ustctl_consumer_channel *consumer_chan;
1031 struct channel *chan;
1032 struct lttng_ust_lib_ring_buffer *buf;
1033
1034 if (!stream)
1035 return -EINVAL;
1036
1037 buf = stream->buf;
1038 consumer_chan = stream->chan;
1039 chan = consumer_chan->chan->chan;
1040 *len = lib_ring_buffer_get_read_data_size(&chan->backend.config, buf,
1041 consumer_chan->chan->handle);
1042 return 0;
1043 }
1044
1045 /* returns the size of the current sub-buffer, without padding (for mmap). */
1046 int ustctl_get_padded_subbuf_size(struct ustctl_consumer_stream *stream,
1047 unsigned long *len)
1048 {
1049 struct ustctl_consumer_channel *consumer_chan;
1050 struct channel *chan;
1051 struct lttng_ust_lib_ring_buffer *buf;
1052
1053 if (!stream)
1054 return -EINVAL;
1055 buf = stream->buf;
1056 consumer_chan = stream->chan;
1057 chan = consumer_chan->chan->chan;
1058 *len = lib_ring_buffer_get_read_data_size(&chan->backend.config, buf,
1059 consumer_chan->chan->handle);
1060 *len = PAGE_ALIGN(*len);
1061 return 0;
1062 }
1063
1064 /* Get exclusive read access to the next sub-buffer that can be read. */
1065 int ustctl_get_next_subbuf(struct ustctl_consumer_stream *stream)
1066 {
1067 struct lttng_ust_lib_ring_buffer *buf;
1068 struct ustctl_consumer_channel *consumer_chan;
1069
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);
1076 }
1077
1078
1079 /* Release exclusive sub-buffer access, move consumer forward. */
1080 int ustctl_put_next_subbuf(struct ustctl_consumer_stream *stream)
1081 {
1082 struct lttng_ust_lib_ring_buffer *buf;
1083 struct ustctl_consumer_channel *consumer_chan;
1084
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);
1090 return 0;
1091 }
1092
1093 /* snapshot */
1094
1095 /* Get a snapshot of the current ring buffer producer and consumer positions */
1096 int ustctl_snapshot(struct ustctl_consumer_stream *stream)
1097 {
1098 struct lttng_ust_lib_ring_buffer *buf;
1099 struct ustctl_consumer_channel *consumer_chan;
1100
1101 if (!stream)
1102 return -EINVAL;
1103 buf = stream->buf;
1104 consumer_chan = stream->chan;
1105 return lib_ring_buffer_snapshot(buf, &buf->cons_snapshot,
1106 &buf->prod_snapshot, consumer_chan->chan->handle);
1107 }
1108
1109 /* Get the consumer position (iteration start) */
1110 int ustctl_snapshot_get_consumed(struct ustctl_consumer_stream *stream,
1111 unsigned long *pos)
1112 {
1113 struct lttng_ust_lib_ring_buffer *buf;
1114
1115 if (!stream)
1116 return -EINVAL;
1117 buf = stream->buf;
1118 *pos = buf->cons_snapshot;
1119 return 0;
1120 }
1121
1122 /* Get the producer position (iteration end) */
1123 int ustctl_snapshot_get_produced(struct ustctl_consumer_stream *stream,
1124 unsigned long *pos)
1125 {
1126 struct lttng_ust_lib_ring_buffer *buf;
1127
1128 if (!stream)
1129 return -EINVAL;
1130 buf = stream->buf;
1131 *pos = buf->prod_snapshot;
1132 return 0;
1133 }
1134
1135 /* Get exclusive read access to the specified sub-buffer position */
1136 int ustctl_get_subbuf(struct ustctl_consumer_stream *stream,
1137 unsigned long *pos)
1138 {
1139 struct lttng_ust_lib_ring_buffer *buf;
1140 struct ustctl_consumer_channel *consumer_chan;
1141
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);
1148 }
1149
1150 /* Release exclusive sub-buffer access */
1151 int ustctl_put_subbuf(struct ustctl_consumer_stream *stream)
1152 {
1153 struct lttng_ust_lib_ring_buffer *buf;
1154 struct ustctl_consumer_channel *consumer_chan;
1155
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);
1161 return 0;
1162 }
1163
1164 void ustctl_flush_buffer(struct ustctl_consumer_stream *stream,
1165 int producer_active)
1166 {
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;
1173 lib_ring_buffer_switch_slow(buf,
1174 producer_active ? SWITCH_ACTIVE : SWITCH_FLUSH,
1175 consumer_chan->chan->handle);
1176 }
1177
1178 /*
1179 * Returns 0 on success, negative error value on error.
1180 */
1181 int 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
1246 int 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 */
1274 int 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
1383 model_error:
1384 free(a_model_emf_uri);
1385 fields_error:
1386 free(a_fields);
1387 signature_error:
1388 free(a_sign);
1389 return len;
1390 }
1391
1392 /*
1393 * Returns 0 on success, negative error value on error.
1394 */
1395 int 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 */
1420 int 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
1473 fields_error:
1474 free(a_fields);
1475 alloc_error:
1476 return len;
1477 }
1478
1479 /*
1480 * Returns 0 on success, negative error value on error.
1481 */
1482 int 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
1516 static __attribute__((constructor))
1517 void 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
1525 static __attribute__((destructor))
1526 void 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();
1531 }
This page took 0.061238 seconds and 5 git commands to generate.