Add write metadata API to ust-ctl.h
[lttng-ust.git] / liblttng-ust-ctl / ustctl.c
CommitLineData
57773204
MD
1/*
2 * Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
74d81a6c 3 * Copyright (C) 2011-2013 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
57773204 4 *
e92f3e28
MD
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License only.
57773204
MD
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
e92f3e28
MD
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
57773204
MD
17 */
18
9d335227 19#define _GNU_SOURCE
57773204 20#include <string.h>
4318ae1b
MD
21#include <lttng/ust-ctl.h>
22#include <lttng/ust-abi.h>
c1fca457 23#include <lttng/ust-events.h>
7a784989 24#include <sys/mman.h>
32ce8569 25#include <byteswap.h>
44c72f10
MD
26
27#include <usterr-signal-safe.h>
b728d87e 28#include <ust-comm.h>
74d81a6c 29#include <helper.h>
57773204
MD
30
31#include "../libringbuffer/backend.h"
32#include "../libringbuffer/frontend.h"
c9023c93
MD
33#include "../liblttng-ust/wait.h"
34
35/*
36 * Number of milliseconds to retry before failing metadata writes on
37 * buffer full condition. (10 seconds)
38 */
39#define LTTNG_METADATA_TIMEOUT_MSEC 10000
57773204 40
74d81a6c
MD
41/*
42 * Channel representation within consumer.
43 */
44struct ustctl_consumer_channel {
45 struct lttng_channel *chan; /* lttng channel buffers */
6b120308 46
74d81a6c
MD
47 /* initial attributes */
48 struct ustctl_consumer_channel_attr attr;
49};
50
51/*
52 * Stream representation within consumer.
53 */
54struct 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
63extern void lttng_ring_buffer_client_overwrite_init(void);
64extern void lttng_ring_buffer_client_discard_init(void);
65extern void lttng_ring_buffer_metadata_client_init(void);
66extern void lttng_ring_buffer_client_overwrite_exit(void);
67extern void lttng_ring_buffer_client_discard_exit(void);
68extern void lttng_ring_buffer_metadata_client_exit(void);
69
70volatile enum ust_loglevel ust_loglevel;
57773204 71
2be0e72c
MD
72int ustctl_release_handle(int sock, int handle)
73{
74 struct ustcomm_ust_msg lum;
75 struct ustcomm_ust_reply lur;
2be0e72c 76
74d81a6c
MD
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);
2be0e72c 83}
74d81a6c 84
12388166
MD
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 */
d26228ae 89int ustctl_release_object(int sock, struct lttng_ust_object_data *data)
57773204 90{
57773204
MD
91 int ret;
92
9bfc503d
MD
93 if (!data)
94 return -EINVAL;
95
74d81a6c
MD
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 }
d26228ae 107 }
74d81a6c
MD
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 }
d26228ae 114 }
74d81a6c 115 break;
32ce8569
MD
116 case LTTNG_UST_OBJECT_TYPE_EVENT:
117 case LTTNG_UST_OBJECT_TYPE_CONTEXT:
118 break;
74d81a6c
MD
119 default:
120 assert(0);
d26228ae 121 }
2be0e72c 122 return ustctl_release_handle(sock, data->handle);
57773204
MD
123}
124
1c5e467e
MD
125/*
126 * Send registration done packet to the application.
127 */
128int 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;
1c5e467e 141 return 0;
1c5e467e
MD
142}
143
57773204
MD
144/*
145 * returns session handle.
146 */
147int 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
57773204 165int ustctl_create_event(int sock, struct lttng_ust_event *ev,
61f02aea
MD
166 struct lttng_ust_object_data *channel_data,
167 struct lttng_ust_object_data **_event_data)
57773204
MD
168{
169 struct ustcomm_ust_msg lum;
170 struct ustcomm_ust_reply lur;
61f02aea 171 struct lttng_ust_object_data *event_data;
57773204
MD
172 int ret;
173
9bfc503d
MD
174 if (!channel_data || !_event_data)
175 return -EINVAL;
176
74d81a6c 177 event_data = zmalloc(sizeof(*event_data));
57773204
MD
178 if (!event_data)
179 return -ENOMEM;
32ce8569 180 event_data->type = LTTNG_UST_OBJECT_TYPE_EVENT;
57773204
MD
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;
457a6b58
MD
187 lum.u.event.loglevel_type = ev->loglevel_type;
188 lum.u.event.loglevel = ev->loglevel;
57773204
MD
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
200int ustctl_add_context(int sock, struct lttng_ust_context *ctx,
61f02aea
MD
201 struct lttng_ust_object_data *obj_data,
202 struct lttng_ust_object_data **_context_data)
57773204
MD
203{
204 struct ustcomm_ust_msg lum;
205 struct ustcomm_ust_reply lur;
61f02aea 206 struct lttng_ust_object_data *context_data;
57773204
MD
207 int ret;
208
9bfc503d
MD
209 if (!obj_data || !_context_data)
210 return -EINVAL;
211
74d81a6c 212 context_data = zmalloc(sizeof(*context_data));
57773204
MD
213 if (!context_data)
214 return -ENOMEM;
32ce8569 215 context_data->type = LTTNG_UST_OBJECT_TYPE_CONTEXT;
57773204 216 memset(&lum, 0, sizeof(lum));
3039d8ed 217 lum.handle = obj_data->handle;
57773204
MD
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 }
32ce8569
MD
225 context_data->handle = -1;
226 DBG("Context created successfully");
57773204
MD
227 *_context_data = context_data;
228 return ret;
229}
230
cd54f6d9
MD
231int 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;
e695af51 246 lum.u.filter.seqnum = bytecode->seqnum;
cd54f6d9
MD
247
248 ret = ustcomm_send_app_msg(sock, &lum);
249 if (ret)
250 return ret;
cd54f6d9
MD
251 /* send var len bytecode */
252 ret = ustcomm_send_unix_sock(sock, bytecode->data,
253 bytecode->len);
254 if (ret < 0) {
7bc53e94
MD
255 if (ret == -ECONNRESET)
256 fprintf(stderr, "remote end closed connection\n");
cd54f6d9
MD
257 return ret;
258 }
7bc53e94
MD
259 if (ret != bytecode->len)
260 return -EINVAL;
261 return ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
cd54f6d9
MD
262}
263
57773204 264/* Enable event, channel and session ioctl */
61f02aea 265int ustctl_enable(int sock, struct lttng_ust_object_data *object)
57773204
MD
266{
267 struct ustcomm_ust_msg lum;
268 struct ustcomm_ust_reply lur;
269 int ret;
270
9bfc503d
MD
271 if (!object)
272 return -EINVAL;
273
57773204
MD
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 */
61f02aea 285int ustctl_disable(int sock, struct lttng_ust_object_data *object)
57773204
MD
286{
287 struct ustcomm_ust_msg lum;
288 struct ustcomm_ust_reply lur;
289 int ret;
290
9bfc503d
MD
291 if (!object)
292 return -EINVAL;
293
57773204
MD
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
4a6ca058 304int ustctl_start_session(int sock, int handle)
57773204 305{
61f02aea 306 struct lttng_ust_object_data obj;
4a6ca058
MD
307
308 obj.handle = handle;
309 return ustctl_enable(sock, &obj);
57773204
MD
310}
311
4a6ca058 312int ustctl_stop_session(int sock, int handle)
57773204 313{
61f02aea 314 struct lttng_ust_object_data obj;
4a6ca058
MD
315
316 obj.handle = handle;
317 return ustctl_disable(sock, &obj);
57773204
MD
318}
319
57773204
MD
320int ustctl_tracepoint_list(int sock)
321{
b115631f
MD
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
337int ustctl_tracepoint_list_get(int sock, int tp_list_handle,
cbef6901 338 struct lttng_ust_tracepoint_iter *iter)
b115631f
MD
339{
340 struct ustcomm_ust_msg lum;
341 struct ustcomm_ust_reply lur;
342 int ret;
343
9bfc503d
MD
344 if (!iter)
345 return -EINVAL;
346
b115631f
MD
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;
882a56d7 353 DBG("received tracepoint list entry name %s loglevel %d",
cbef6901 354 lur.u.tracepoint.name,
882a56d7 355 lur.u.tracepoint.loglevel);
cbef6901 356 memcpy(iter, &lur.u.tracepoint, sizeof(*iter));
b115631f 357 return 0;
57773204
MD
358}
359
40003310
MD
360int 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
377int 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
57773204
MD
406int 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
9bfc503d
MD
412 if (!v)
413 return -EINVAL;
414
57773204
MD
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
426int 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
442int ustctl_calibrate(int sock, struct lttng_ust_calibrate *calibrate)
443{
9bfc503d
MD
444 if (!calibrate)
445 return -EINVAL;
446
57773204
MD
447 return -ENOSYS;
448}
449
f1fffc57
MD
450int 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
9bfc503d
MD
456 if (!object)
457 return -EINVAL;
458
f1fffc57
MD
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
74d81a6c
MD
469static
470int 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 }
57773204 506
74d81a6c
MD
507 return 0;
508}
509
510static
511int 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)
57773204 516{
74d81a6c
MD
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
569int 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;
7a784989 574 int ret;
57773204 575
74d81a6c
MD
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 }
9bfc503d 593
74d81a6c
MD
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
624error_recv_data:
625 free(channel_data->u.channel.data);
626error:
627 free(channel_data);
628error_alloc:
629 return ret;
630}
631
632int 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;
57773204 644 }
74d81a6c
MD
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;
0bfe09ec 684 }
0bfe09ec 685 }
74d81a6c
MD
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;
0bfe09ec 690
74d81a6c
MD
691error:
692 free(stream_data);
693error_alloc:
694 return ret;
695}
696
697int 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 }
57773204 728 }
74d81a6c
MD
729 return ret;
730}
731
732int 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
765struct 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 }
c1fca457 780 break;
74d81a6c
MD
781 case LTTNG_UST_CHAN_METADATA:
782 if (attr->output == LTTNG_UST_MMAP)
783 transport_name = "relay-metadata-mmap";
784 else
785 return NULL;
c1fca457
MD
786 break;
787 default:
74d81a6c 788 transport_name = "<unknown>";
c1fca457
MD
789 return NULL;
790 }
74d81a6c
MD
791
792 transport = lttng_transport_find(transport_name);
793 if (!transport) {
794 DBG("LTTng transport %s not found\n",
32ce8569 795 transport_name);
74d81a6c 796 return NULL;
7a784989 797 }
74d81a6c
MD
798
799 chan = zmalloc(sizeof(*chan));
800 if (!chan)
801 return NULL;
802
803 chan->chan = transport->ops.channel_create(transport_name, NULL,
32ce8569 804 attr->subbuf_size, attr->num_subbuf,
74d81a6c 805 attr->switch_timer_interval,
32ce8569 806 attr->read_timer_interval,
74d81a6c
MD
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
815chan_error:
816 free(chan);
817 return NULL;
57773204
MD
818}
819
74d81a6c 820void ustctl_destroy_channel(struct ustctl_consumer_channel *chan)
57773204 821{
74d81a6c
MD
822 chan->chan->ops->channel_destroy(chan->chan);
823 free(chan);
824}
825
826int ustctl_send_channel_to_sessiond(int sock,
827 struct ustctl_consumer_channel *channel)
828{
829 struct shm_object_table *table;
57773204 830
74d81a6c
MD
831 table = channel->chan->handle->table;
832 if (table->size <= 0)
9bfc503d 833 return -EINVAL;
74d81a6c
MD
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}
9bfc503d 840
74d81a6c
MD
841int 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);
57773204
MD
852}
853
c9023c93
MD
854int 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 }
894end:
895 return ret;
896}
897
74d81a6c 898int ustctl_stream_close_wait_fd(struct ustctl_consumer_stream *stream)
5224b5c8
MD
899{
900 struct channel *chan;
901
74d81a6c
MD
902 chan = stream->chan->chan->chan;
903 return ring_buffer_close_wait_fd(&chan->backend.config,
904 chan, stream->handle, stream->cpu);
5224b5c8
MD
905}
906
74d81a6c 907int ustctl_stream_close_wakeup_fd(struct ustctl_consumer_stream *stream)
6e922b24 908{
66bdd22a 909 struct channel *chan;
74d81a6c
MD
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
916struct 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;
4cfec15c 925 struct lttng_ust_lib_ring_buffer *buf;
6e922b24
MD
926 int ret;
927
74d81a6c
MD
928 if (!channel)
929 return NULL;
930 handle = channel->chan->handle;
9bfc503d
MD
931 if (!handle)
932 return NULL;
933
74d81a6c 934 chan = channel->chan->chan;
6e922b24 935 buf = channel_get_ring_buffer(&chan->backend.config,
74d81a6c
MD
936 chan, cpu, handle, &shm_fd, &wait_fd,
937 &wakeup_fd, &memory_map_size);
6e922b24
MD
938 if (!buf)
939 return NULL;
74d81a6c 940 ret = lib_ring_buffer_open_read(buf, handle);
6e922b24
MD
941 if (ret)
942 return NULL;
74d81a6c
MD
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
957alloc_error:
958 return NULL;
959}
960
961void 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);
6e922b24
MD
971}
972
74d81a6c 973int ustctl_get_wait_fd(struct ustctl_consumer_stream *stream)
6e922b24 974{
74d81a6c
MD
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
985int 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);
6e922b24
MD
995}
996
57773204
MD
997/* For mmap mode, readable without "get" operation */
998
74d81a6c 999void *ustctl_get_mmap_base(struct ustctl_consumer_stream *stream)
9095efe9 1000{
74d81a6c
MD
1001 struct lttng_ust_lib_ring_buffer *buf;
1002 struct ustctl_consumer_channel *consumer_chan;
1003
1004 if (!stream)
9bfc503d 1005 return NULL;
74d81a6c
MD
1006 buf = stream->buf;
1007 consumer_chan = stream->chan;
1008 return shmp(consumer_chan->chan->handle, buf->backend.memory_map);
9095efe9
MD
1009}
1010
57773204 1011/* returns the length to mmap. */
74d81a6c 1012int ustctl_get_mmap_len(struct ustctl_consumer_stream *stream,
57773204
MD
1013 unsigned long *len)
1014{
74d81a6c 1015 struct ustctl_consumer_channel *consumer_chan;
57773204 1016 unsigned long mmap_buf_len;
66bdd22a 1017 struct channel *chan;
57773204 1018
74d81a6c 1019 if (!stream)
9bfc503d 1020 return -EINVAL;
74d81a6c
MD
1021 consumer_chan = stream->chan;
1022 chan = consumer_chan->chan->chan;
57773204
MD
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. */
74d81a6c 1035int ustctl_get_max_subbuf_size(struct ustctl_consumer_stream *stream,
57773204
MD
1036 unsigned long *len)
1037{
74d81a6c 1038 struct ustctl_consumer_channel *consumer_chan;
66bdd22a 1039 struct channel *chan;
57773204 1040
74d81a6c 1041 if (!stream)
9bfc503d 1042 return -EINVAL;
74d81a6c
MD
1043 consumer_chan = stream->chan;
1044 chan = consumer_chan->chan->chan;
57773204
MD
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. */
74d81a6c
MD
1055int ustctl_get_mmap_read_offset(struct ustctl_consumer_stream *stream,
1056 unsigned long *off)
57773204 1057{
66bdd22a 1058 struct channel *chan;
57773204 1059 unsigned long sb_bindex;
74d81a6c
MD
1060 struct lttng_ust_lib_ring_buffer *buf;
1061 struct ustctl_consumer_channel *consumer_chan;
57773204 1062
74d81a6c 1063 if (!stream)
9bfc503d 1064 return -EINVAL;
74d81a6c
MD
1065 buf = stream->buf;
1066 consumer_chan = stream->chan;
1067 chan = consumer_chan->chan->chan;
57773204
MD
1068 if (chan->backend.config.output != RING_BUFFER_MMAP)
1069 return -EINVAL;
1070 sb_bindex = subbuffer_id_get_index(&chan->backend.config,
32ce8569 1071 buf->backend.buf_rsb.id);
74d81a6c
MD
1072 *off = shmp(consumer_chan->chan->handle,
1073 shmp_index(consumer_chan->chan->handle, buf->backend.array, sb_bindex)->shmp)->mmap_offset;
57773204
MD
1074 return 0;
1075}
1076
1077/* returns the size of the current sub-buffer, without padding (for mmap). */
74d81a6c
MD
1078int ustctl_get_subbuf_size(struct ustctl_consumer_stream *stream,
1079 unsigned long *len)
57773204 1080{
74d81a6c 1081 struct ustctl_consumer_channel *consumer_chan;
66bdd22a 1082 struct channel *chan;
74d81a6c 1083 struct lttng_ust_lib_ring_buffer *buf;
57773204 1084
74d81a6c 1085 if (!stream)
9bfc503d
MD
1086 return -EINVAL;
1087
74d81a6c
MD
1088 buf = stream->buf;
1089 consumer_chan = stream->chan;
1090 chan = consumer_chan->chan->chan;
57773204 1091 *len = lib_ring_buffer_get_read_data_size(&chan->backend.config, buf,
74d81a6c 1092 consumer_chan->chan->handle);
57773204
MD
1093 return 0;
1094}
1095
1096/* returns the size of the current sub-buffer, without padding (for mmap). */
74d81a6c
MD
1097int ustctl_get_padded_subbuf_size(struct ustctl_consumer_stream *stream,
1098 unsigned long *len)
57773204 1099{
74d81a6c 1100 struct ustctl_consumer_channel *consumer_chan;
66bdd22a 1101 struct channel *chan;
74d81a6c 1102 struct lttng_ust_lib_ring_buffer *buf;
57773204 1103
74d81a6c 1104 if (!stream)
9bfc503d 1105 return -EINVAL;
74d81a6c
MD
1106 buf = stream->buf;
1107 consumer_chan = stream->chan;
1108 chan = consumer_chan->chan->chan;
57773204 1109 *len = lib_ring_buffer_get_read_data_size(&chan->backend.config, buf,
74d81a6c 1110 consumer_chan->chan->handle);
57773204
MD
1111 *len = PAGE_ALIGN(*len);
1112 return 0;
1113}
1114
1115/* Get exclusive read access to the next sub-buffer that can be read. */
74d81a6c 1116int ustctl_get_next_subbuf(struct ustctl_consumer_stream *stream)
57773204 1117{
74d81a6c
MD
1118 struct lttng_ust_lib_ring_buffer *buf;
1119 struct ustctl_consumer_channel *consumer_chan;
9bfc503d 1120
74d81a6c
MD
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);
57773204
MD
1127}
1128
1129
1130/* Release exclusive sub-buffer access, move consumer forward. */
74d81a6c 1131int ustctl_put_next_subbuf(struct ustctl_consumer_stream *stream)
57773204 1132{
74d81a6c
MD
1133 struct lttng_ust_lib_ring_buffer *buf;
1134 struct ustctl_consumer_channel *consumer_chan;
9bfc503d 1135
74d81a6c
MD
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);
57773204
MD
1141 return 0;
1142}
1143
1144/* snapshot */
1145
1146/* Get a snapshot of the current ring buffer producer and consumer positions */
74d81a6c 1147int ustctl_snapshot(struct ustctl_consumer_stream *stream)
57773204 1148{
74d81a6c
MD
1149 struct lttng_ust_lib_ring_buffer *buf;
1150 struct ustctl_consumer_channel *consumer_chan;
9bfc503d 1151
74d81a6c
MD
1152 if (!stream)
1153 return -EINVAL;
1154 buf = stream->buf;
1155 consumer_chan = stream->chan;
57773204 1156 return lib_ring_buffer_snapshot(buf, &buf->cons_snapshot,
74d81a6c 1157 &buf->prod_snapshot, consumer_chan->chan->handle);
57773204
MD
1158}
1159
1160/* Get the consumer position (iteration start) */
74d81a6c
MD
1161int ustctl_snapshot_get_consumed(struct ustctl_consumer_stream *stream,
1162 unsigned long *pos)
57773204 1163{
74d81a6c 1164 struct lttng_ust_lib_ring_buffer *buf;
9bfc503d 1165
74d81a6c
MD
1166 if (!stream)
1167 return -EINVAL;
1168 buf = stream->buf;
57773204
MD
1169 *pos = buf->cons_snapshot;
1170 return 0;
1171}
1172
1173/* Get the producer position (iteration end) */
74d81a6c
MD
1174int ustctl_snapshot_get_produced(struct ustctl_consumer_stream *stream,
1175 unsigned long *pos)
57773204 1176{
74d81a6c 1177 struct lttng_ust_lib_ring_buffer *buf;
9bfc503d 1178
74d81a6c
MD
1179 if (!stream)
1180 return -EINVAL;
1181 buf = stream->buf;
57773204
MD
1182 *pos = buf->prod_snapshot;
1183 return 0;
1184}
1185
1186/* Get exclusive read access to the specified sub-buffer position */
74d81a6c
MD
1187int ustctl_get_subbuf(struct ustctl_consumer_stream *stream,
1188 unsigned long *pos)
57773204 1189{
74d81a6c
MD
1190 struct lttng_ust_lib_ring_buffer *buf;
1191 struct ustctl_consumer_channel *consumer_chan;
9bfc503d 1192
74d81a6c
MD
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);
57773204
MD
1199}
1200
1201/* Release exclusive sub-buffer access */
74d81a6c 1202int ustctl_put_subbuf(struct ustctl_consumer_stream *stream)
57773204 1203{
74d81a6c
MD
1204 struct lttng_ust_lib_ring_buffer *buf;
1205 struct ustctl_consumer_channel *consumer_chan;
9bfc503d 1206
74d81a6c
MD
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);
57773204
MD
1212 return 0;
1213}
1214
74d81a6c 1215void ustctl_flush_buffer(struct ustctl_consumer_stream *stream,
b52190f2 1216 int producer_active)
57773204 1217{
74d81a6c
MD
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;
b52190f2
MD
1224 lib_ring_buffer_switch_slow(buf,
1225 producer_active ? SWITCH_ACTIVE : SWITCH_FLUSH,
74d81a6c
MD
1226 consumer_chan->chan->handle);
1227}
1228
32ce8569
MD
1229/*
1230 * Returns 0 on success, negative error value on error.
1231 */
1232int 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
1297int 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 */
1325int 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
1434model_error:
1435 free(a_model_emf_uri);
1436fields_error:
1437 free(a_fields);
1438signature_error:
1439 free(a_sign);
1440 return len;
1441}
1442
1443/*
1444 * Returns 0 on success, negative error value on error.
1445 */
1446int 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 */
1471int 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
1524fields_error:
1525 free(a_fields);
1526alloc_error:
1527 return len;
1528}
1529
1530/*
1531 * Returns 0 on success, negative error value on error.
1532 */
1533int 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
74d81a6c
MD
1567static __attribute__((constructor))
1568void 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
1576static __attribute__((destructor))
1577void 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();
57773204 1582}
This page took 0.096438 seconds and 5 git commands to generate.