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