Fix: Use negative value for error code of lttng_ust_ctl_duplicate_ust_object_data
[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>
4a07ff75
MD
21#include <sys/types.h>
22#include <sys/socket.h>
23
c62a3816 24#include <lttng/ust-config.h>
4318ae1b
MD
25#include <lttng/ust-ctl.h>
26#include <lttng/ust-abi.h>
c1fca457 27#include <lttng/ust-events.h>
7a784989 28#include <sys/mman.h>
32ce8569 29#include <byteswap.h>
44c72f10
MD
30
31#include <usterr-signal-safe.h>
b728d87e 32#include <ust-comm.h>
74d81a6c 33#include <helper.h>
57773204
MD
34
35#include "../libringbuffer/backend.h"
36#include "../libringbuffer/frontend.h"
c9023c93 37#include "../liblttng-ust/wait.h"
b2f3252a 38#include "../liblttng-ust/lttng-rb-clients.h"
f9364363 39#include "../liblttng-ust/clock.h"
92ce256d 40#include "../liblttng-ust/getenv.h"
c9023c93
MD
41
42/*
43 * Number of milliseconds to retry before failing metadata writes on
44 * buffer full condition. (10 seconds)
45 */
46#define LTTNG_METADATA_TIMEOUT_MSEC 10000
57773204 47
74d81a6c
MD
48/*
49 * Channel representation within consumer.
50 */
51struct ustctl_consumer_channel {
52 struct lttng_channel *chan; /* lttng channel buffers */
6b120308 53
74d81a6c
MD
54 /* initial attributes */
55 struct ustctl_consumer_channel_attr attr;
ff0f5728
MD
56 int wait_fd; /* monitor close() */
57 int wakeup_fd; /* monitor close() */
74d81a6c
MD
58};
59
60/*
61 * Stream representation within consumer.
62 */
63struct ustctl_consumer_stream {
64 struct lttng_ust_shm_handle *handle; /* shared-memory handle */
65 struct lttng_ust_lib_ring_buffer *buf;
66 struct ustctl_consumer_channel *chan;
67 int shm_fd, wait_fd, wakeup_fd;
68 int cpu;
69 uint64_t memory_map_size;
70};
71
72extern void lttng_ring_buffer_client_overwrite_init(void);
08a3170c 73extern void lttng_ring_buffer_client_overwrite_rt_init(void);
74d81a6c 74extern void lttng_ring_buffer_client_discard_init(void);
08a3170c 75extern void lttng_ring_buffer_client_discard_rt_init(void);
74d81a6c
MD
76extern void lttng_ring_buffer_metadata_client_init(void);
77extern void lttng_ring_buffer_client_overwrite_exit(void);
08a3170c 78extern void lttng_ring_buffer_client_overwrite_rt_exit(void);
74d81a6c 79extern void lttng_ring_buffer_client_discard_exit(void);
08a3170c 80extern void lttng_ring_buffer_client_discard_rt_exit(void);
74d81a6c
MD
81extern void lttng_ring_buffer_metadata_client_exit(void);
82
2be0e72c
MD
83int ustctl_release_handle(int sock, int handle)
84{
85 struct ustcomm_ust_msg lum;
86 struct ustcomm_ust_reply lur;
2be0e72c 87
74d81a6c
MD
88 if (sock < 0 || handle < 0)
89 return 0;
90 memset(&lum, 0, sizeof(lum));
91 lum.handle = handle;
92 lum.cmd = LTTNG_UST_RELEASE;
93 return ustcomm_send_app_cmd(sock, &lum, &lur);
2be0e72c 94}
74d81a6c 95
12388166
MD
96/*
97 * If sock is negative, it means we don't have to notify the other side
98 * (e.g. application has already vanished).
99 */
d26228ae 100int ustctl_release_object(int sock, struct lttng_ust_object_data *data)
57773204 101{
57773204
MD
102 int ret;
103
9bfc503d
MD
104 if (!data)
105 return -EINVAL;
106
74d81a6c
MD
107 switch (data->type) {
108 case LTTNG_UST_OBJECT_TYPE_CHANNEL:
ff0f5728
MD
109 if (data->u.channel.wakeup_fd >= 0) {
110 ret = close(data->u.channel.wakeup_fd);
111 if (ret < 0) {
112 ret = -errno;
113 return ret;
114 }
bad4193f 115 data->u.channel.wakeup_fd = -1;
ff0f5728 116 }
74d81a6c 117 free(data->u.channel.data);
bad4193f 118 data->u.channel.data = NULL;
74d81a6c
MD
119 break;
120 case LTTNG_UST_OBJECT_TYPE_STREAM:
121 if (data->u.stream.shm_fd >= 0) {
122 ret = close(data->u.stream.shm_fd);
123 if (ret < 0) {
124 ret = -errno;
125 return ret;
126 }
bad4193f 127 data->u.stream.shm_fd = -1;
d26228ae 128 }
74d81a6c
MD
129 if (data->u.stream.wakeup_fd >= 0) {
130 ret = close(data->u.stream.wakeup_fd);
131 if (ret < 0) {
132 ret = -errno;
133 return ret;
134 }
bad4193f 135 data->u.stream.wakeup_fd = -1;
d26228ae 136 }
74d81a6c 137 break;
32ce8569
MD
138 case LTTNG_UST_OBJECT_TYPE_EVENT:
139 case LTTNG_UST_OBJECT_TYPE_CONTEXT:
140 break;
74d81a6c
MD
141 default:
142 assert(0);
d26228ae 143 }
2be0e72c 144 return ustctl_release_handle(sock, data->handle);
57773204
MD
145}
146
1c5e467e
MD
147/*
148 * Send registration done packet to the application.
149 */
150int ustctl_register_done(int sock)
151{
152 struct ustcomm_ust_msg lum;
153 struct ustcomm_ust_reply lur;
154 int ret;
155
156 DBG("Sending register done command to %d", sock);
157 memset(&lum, 0, sizeof(lum));
158 lum.handle = LTTNG_UST_ROOT_HANDLE;
159 lum.cmd = LTTNG_UST_REGISTER_DONE;
160 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
161 if (ret)
162 return ret;
1c5e467e 163 return 0;
1c5e467e
MD
164}
165
57773204
MD
166/*
167 * returns session handle.
168 */
169int ustctl_create_session(int sock)
170{
171 struct ustcomm_ust_msg lum;
172 struct ustcomm_ust_reply lur;
173 int ret, session_handle;
174
175 /* Create session */
176 memset(&lum, 0, sizeof(lum));
177 lum.handle = LTTNG_UST_ROOT_HANDLE;
178 lum.cmd = LTTNG_UST_SESSION;
179 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
180 if (ret)
181 return ret;
182 session_handle = lur.ret_val;
183 DBG("received session handle %u", session_handle);
184 return session_handle;
185}
186
57773204 187int ustctl_create_event(int sock, struct lttng_ust_event *ev,
61f02aea
MD
188 struct lttng_ust_object_data *channel_data,
189 struct lttng_ust_object_data **_event_data)
57773204
MD
190{
191 struct ustcomm_ust_msg lum;
192 struct ustcomm_ust_reply lur;
61f02aea 193 struct lttng_ust_object_data *event_data;
57773204
MD
194 int ret;
195
9bfc503d
MD
196 if (!channel_data || !_event_data)
197 return -EINVAL;
198
74d81a6c 199 event_data = zmalloc(sizeof(*event_data));
57773204
MD
200 if (!event_data)
201 return -ENOMEM;
32ce8569 202 event_data->type = LTTNG_UST_OBJECT_TYPE_EVENT;
57773204
MD
203 memset(&lum, 0, sizeof(lum));
204 lum.handle = channel_data->handle;
205 lum.cmd = LTTNG_UST_EVENT;
206 strncpy(lum.u.event.name, ev->name,
207 LTTNG_UST_SYM_NAME_LEN);
208 lum.u.event.instrumentation = ev->instrumentation;
457a6b58
MD
209 lum.u.event.loglevel_type = ev->loglevel_type;
210 lum.u.event.loglevel = ev->loglevel;
57773204
MD
211 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
212 if (ret) {
213 free(event_data);
214 return ret;
215 }
216 event_data->handle = lur.ret_val;
217 DBG("received event handle %u", event_data->handle);
218 *_event_data = event_data;
219 return 0;
220}
221
53f0df51 222int ustctl_add_context(int sock, struct lttng_ust_context_attr *ctx,
61f02aea
MD
223 struct lttng_ust_object_data *obj_data,
224 struct lttng_ust_object_data **_context_data)
57773204
MD
225{
226 struct ustcomm_ust_msg lum;
227 struct ustcomm_ust_reply lur;
53f0df51
JG
228 struct lttng_ust_object_data *context_data = NULL;
229 char *buf = NULL;
230 size_t len;
57773204
MD
231 int ret;
232
53f0df51
JG
233 if (!obj_data || !_context_data) {
234 ret = -EINVAL;
235 goto end;
236 }
9bfc503d 237
74d81a6c 238 context_data = zmalloc(sizeof(*context_data));
53f0df51
JG
239 if (!context_data) {
240 ret = -ENOMEM;
241 goto end;
242 }
32ce8569 243 context_data->type = LTTNG_UST_OBJECT_TYPE_CONTEXT;
57773204 244 memset(&lum, 0, sizeof(lum));
3039d8ed 245 lum.handle = obj_data->handle;
57773204 246 lum.cmd = LTTNG_UST_CONTEXT;
53f0df51
JG
247
248 lum.u.context.ctx = ctx->ctx;
249 switch (ctx->ctx) {
250 case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER:
251 lum.u.context.u.perf_counter = ctx->u.perf_counter;
252 break;
253 case LTTNG_UST_CONTEXT_APP_CONTEXT:
254 {
255 size_t provider_name_len = strlen(
256 ctx->u.app_ctx.provider_name) + 1;
257 size_t ctx_name_len = strlen(ctx->u.app_ctx.ctx_name) + 1;
258
259 lum.u.context.u.app_ctx.provider_name_len = provider_name_len;
260 lum.u.context.u.app_ctx.ctx_name_len = ctx_name_len;
261
262 len = provider_name_len + ctx_name_len;
263 buf = zmalloc(len);
264 if (!buf) {
265 ret = -ENOMEM;
266 goto end;
267 }
268 memcpy(buf, ctx->u.app_ctx.provider_name,
269 provider_name_len);
270 memcpy(buf + provider_name_len, ctx->u.app_ctx.ctx_name,
271 ctx_name_len);
272 break;
273 }
274 default:
275 break;
276 }
277 ret = ustcomm_send_app_msg(sock, &lum);
278 if (ret)
279 goto end;
280 if (buf) {
281 /* send var len ctx_name */
282 ret = ustcomm_send_unix_sock(sock, buf, len);
283 if (ret < 0) {
284 goto end;
285 }
286 if (ret != len) {
287 ret = -EINVAL;
288 goto end;
289 }
290 }
291 ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
292 if (ret < 0) {
293 goto end;
57773204 294 }
32ce8569
MD
295 context_data->handle = -1;
296 DBG("Context created successfully");
57773204 297 *_context_data = context_data;
53f0df51
JG
298 context_data = NULL;
299end:
300 free(context_data);
301 free(buf);
57773204
MD
302 return ret;
303}
304
cd54f6d9
MD
305int ustctl_set_filter(int sock, struct lttng_ust_filter_bytecode *bytecode,
306 struct lttng_ust_object_data *obj_data)
307{
308 struct ustcomm_ust_msg lum;
309 struct ustcomm_ust_reply lur;
310 int ret;
311
312 if (!obj_data)
313 return -EINVAL;
314
315 memset(&lum, 0, sizeof(lum));
316 lum.handle = obj_data->handle;
317 lum.cmd = LTTNG_UST_FILTER;
318 lum.u.filter.data_size = bytecode->len;
319 lum.u.filter.reloc_offset = bytecode->reloc_offset;
e695af51 320 lum.u.filter.seqnum = bytecode->seqnum;
cd54f6d9
MD
321
322 ret = ustcomm_send_app_msg(sock, &lum);
323 if (ret)
324 return ret;
cd54f6d9
MD
325 /* send var len bytecode */
326 ret = ustcomm_send_unix_sock(sock, bytecode->data,
327 bytecode->len);
328 if (ret < 0) {
329 return ret;
330 }
7bc53e94
MD
331 if (ret != bytecode->len)
332 return -EINVAL;
333 return ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
cd54f6d9
MD
334}
335
da57c034
JI
336int ustctl_set_exclusion(int sock, struct lttng_ust_event_exclusion *exclusion,
337 struct lttng_ust_object_data *obj_data)
338{
339 struct ustcomm_ust_msg lum;
340 struct ustcomm_ust_reply lur;
341 int ret;
342
343 if (!obj_data) {
344 return -EINVAL;
345 }
346
347 memset(&lum, 0, sizeof(lum));
348 lum.handle = obj_data->handle;
349 lum.cmd = LTTNG_UST_EXCLUSION;
350 lum.u.exclusion.count = exclusion->count;
351
352 ret = ustcomm_send_app_msg(sock, &lum);
353 if (ret) {
354 return ret;
355 }
356
1628366f 357 /* send var len exclusion names */
da57c034
JI
358 ret = ustcomm_send_unix_sock(sock,
359 exclusion->names,
360 exclusion->count * LTTNG_UST_SYM_NAME_LEN);
361 if (ret < 0) {
362 return ret;
363 }
364 if (ret != exclusion->count * LTTNG_UST_SYM_NAME_LEN) {
365 return -EINVAL;
366 }
367 return ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
368}
369
57773204 370/* Enable event, channel and session ioctl */
61f02aea 371int ustctl_enable(int sock, struct lttng_ust_object_data *object)
57773204
MD
372{
373 struct ustcomm_ust_msg lum;
374 struct ustcomm_ust_reply lur;
375 int ret;
376
9bfc503d
MD
377 if (!object)
378 return -EINVAL;
379
57773204
MD
380 memset(&lum, 0, sizeof(lum));
381 lum.handle = object->handle;
382 lum.cmd = LTTNG_UST_ENABLE;
383 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
384 if (ret)
385 return ret;
386 DBG("enabled handle %u", object->handle);
387 return 0;
388}
389
390/* Disable event, channel and session ioctl */
61f02aea 391int ustctl_disable(int sock, struct lttng_ust_object_data *object)
57773204
MD
392{
393 struct ustcomm_ust_msg lum;
394 struct ustcomm_ust_reply lur;
395 int ret;
396
9bfc503d
MD
397 if (!object)
398 return -EINVAL;
399
57773204
MD
400 memset(&lum, 0, sizeof(lum));
401 lum.handle = object->handle;
402 lum.cmd = LTTNG_UST_DISABLE;
403 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
404 if (ret)
405 return ret;
406 DBG("disable handle %u", object->handle);
407 return 0;
408}
409
4a6ca058 410int ustctl_start_session(int sock, int handle)
57773204 411{
61f02aea 412 struct lttng_ust_object_data obj;
4a6ca058
MD
413
414 obj.handle = handle;
415 return ustctl_enable(sock, &obj);
57773204
MD
416}
417
4a6ca058 418int ustctl_stop_session(int sock, int handle)
57773204 419{
61f02aea 420 struct lttng_ust_object_data obj;
4a6ca058
MD
421
422 obj.handle = handle;
423 return ustctl_disable(sock, &obj);
57773204
MD
424}
425
57773204
MD
426int ustctl_tracepoint_list(int sock)
427{
b115631f
MD
428 struct ustcomm_ust_msg lum;
429 struct ustcomm_ust_reply lur;
430 int ret, tp_list_handle;
431
432 memset(&lum, 0, sizeof(lum));
433 lum.handle = LTTNG_UST_ROOT_HANDLE;
434 lum.cmd = LTTNG_UST_TRACEPOINT_LIST;
435 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
436 if (ret)
437 return ret;
438 tp_list_handle = lur.ret_val;
439 DBG("received tracepoint list handle %u", tp_list_handle);
440 return tp_list_handle;
441}
442
443int ustctl_tracepoint_list_get(int sock, int tp_list_handle,
cbef6901 444 struct lttng_ust_tracepoint_iter *iter)
b115631f
MD
445{
446 struct ustcomm_ust_msg lum;
447 struct ustcomm_ust_reply lur;
448 int ret;
449
9bfc503d
MD
450 if (!iter)
451 return -EINVAL;
452
b115631f
MD
453 memset(&lum, 0, sizeof(lum));
454 lum.handle = tp_list_handle;
455 lum.cmd = LTTNG_UST_TRACEPOINT_LIST_GET;
456 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
457 if (ret)
458 return ret;
882a56d7 459 DBG("received tracepoint list entry name %s loglevel %d",
cbef6901 460 lur.u.tracepoint.name,
882a56d7 461 lur.u.tracepoint.loglevel);
cbef6901 462 memcpy(iter, &lur.u.tracepoint, sizeof(*iter));
b115631f 463 return 0;
57773204
MD
464}
465
40003310
MD
466int ustctl_tracepoint_field_list(int sock)
467{
468 struct ustcomm_ust_msg lum;
469 struct ustcomm_ust_reply lur;
470 int ret, tp_field_list_handle;
471
472 memset(&lum, 0, sizeof(lum));
473 lum.handle = LTTNG_UST_ROOT_HANDLE;
474 lum.cmd = LTTNG_UST_TRACEPOINT_FIELD_LIST;
475 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
476 if (ret)
477 return ret;
478 tp_field_list_handle = lur.ret_val;
479 DBG("received tracepoint field list handle %u", tp_field_list_handle);
480 return tp_field_list_handle;
481}
482
483int ustctl_tracepoint_field_list_get(int sock, int tp_field_list_handle,
484 struct lttng_ust_field_iter *iter)
485{
486 struct ustcomm_ust_msg lum;
487 struct ustcomm_ust_reply lur;
488 int ret;
489 ssize_t len;
490
491 if (!iter)
492 return -EINVAL;
493
494 memset(&lum, 0, sizeof(lum));
495 lum.handle = tp_field_list_handle;
496 lum.cmd = LTTNG_UST_TRACEPOINT_FIELD_LIST_GET;
497 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
498 if (ret)
499 return ret;
500 len = ustcomm_recv_unix_sock(sock, iter, sizeof(*iter));
501 if (len != sizeof(*iter)) {
502 return -EINVAL;
503 }
504 DBG("received tracepoint field list entry event_name %s event_loglevel %d field_name %s field_type %d",
505 iter->event_name,
506 iter->loglevel,
507 iter->field_name,
508 iter->type);
509 return 0;
510}
511
57773204
MD
512int ustctl_tracer_version(int sock, struct lttng_ust_tracer_version *v)
513{
514 struct ustcomm_ust_msg lum;
515 struct ustcomm_ust_reply lur;
516 int ret;
517
9bfc503d
MD
518 if (!v)
519 return -EINVAL;
520
57773204
MD
521 memset(&lum, 0, sizeof(lum));
522 lum.handle = LTTNG_UST_ROOT_HANDLE;
523 lum.cmd = LTTNG_UST_TRACER_VERSION;
524 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
525 if (ret)
526 return ret;
527 memcpy(v, &lur.u.version, sizeof(*v));
528 DBG("received tracer version");
529 return 0;
530}
531
532int ustctl_wait_quiescent(int sock)
533{
534 struct ustcomm_ust_msg lum;
535 struct ustcomm_ust_reply lur;
536 int ret;
537
538 memset(&lum, 0, sizeof(lum));
539 lum.handle = LTTNG_UST_ROOT_HANDLE;
540 lum.cmd = LTTNG_UST_WAIT_QUIESCENT;
541 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
542 if (ret)
543 return ret;
544 DBG("waited for quiescent state");
545 return 0;
546}
547
548int ustctl_calibrate(int sock, struct lttng_ust_calibrate *calibrate)
549{
9bfc503d
MD
550 if (!calibrate)
551 return -EINVAL;
552
57773204
MD
553 return -ENOSYS;
554}
555
f1fffc57
MD
556int ustctl_sock_flush_buffer(int sock, struct lttng_ust_object_data *object)
557{
558 struct ustcomm_ust_msg lum;
559 struct ustcomm_ust_reply lur;
560 int ret;
561
9bfc503d
MD
562 if (!object)
563 return -EINVAL;
564
f1fffc57
MD
565 memset(&lum, 0, sizeof(lum));
566 lum.handle = object->handle;
567 lum.cmd = LTTNG_UST_FLUSH_BUFFER;
568 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
569 if (ret)
570 return ret;
571 DBG("flushed buffer handle %u", object->handle);
572 return 0;
573}
574
74d81a6c
MD
575static
576int ustctl_send_channel(int sock,
577 enum lttng_ust_chan_type type,
578 void *data,
579 uint64_t size,
ff0f5728 580 int wakeup_fd,
74d81a6c
MD
581 int send_fd_only)
582{
583 ssize_t len;
584
585 if (!send_fd_only) {
586 /* Send mmap size */
587 len = ustcomm_send_unix_sock(sock, &size, sizeof(size));
588 if (len != sizeof(size)) {
589 if (len < 0)
590 return len;
591 else
592 return -EIO;
593 }
594
595 /* Send channel type */
596 len = ustcomm_send_unix_sock(sock, &type, sizeof(type));
597 if (len != sizeof(type)) {
598 if (len < 0)
599 return len;
600 else
601 return -EIO;
602 }
603 }
604
605 /* Send channel data */
606 len = ustcomm_send_unix_sock(sock, data, size);
607 if (len != size) {
608 if (len < 0)
609 return len;
610 else
611 return -EIO;
612 }
57773204 613
ff0f5728
MD
614 /* Send wakeup fd */
615 len = ustcomm_send_fds_unix_sock(sock, &wakeup_fd, 1);
616 if (len <= 0) {
617 if (len < 0)
618 return len;
619 else
620 return -EIO;
621 }
74d81a6c
MD
622 return 0;
623}
624
625static
626int ustctl_send_stream(int sock,
627 uint32_t stream_nr,
628 uint64_t memory_map_size,
629 int shm_fd, int wakeup_fd,
630 int send_fd_only)
57773204 631{
74d81a6c
MD
632 ssize_t len;
633 int fds[2];
634
635 if (!send_fd_only) {
636 if (shm_fd < 0) {
637 /* finish iteration */
638 uint64_t v = -1;
639
640 len = ustcomm_send_unix_sock(sock, &v, sizeof(v));
641 if (len != sizeof(v)) {
642 if (len < 0)
643 return len;
644 else
645 return -EIO;
646 }
647 return 0;
648 }
649
650 /* Send mmap size */
651 len = ustcomm_send_unix_sock(sock, &memory_map_size,
652 sizeof(memory_map_size));
653 if (len != sizeof(memory_map_size)) {
654 if (len < 0)
655 return len;
656 else
657 return -EIO;
658 }
659
660 /* Send stream nr */
661 len = ustcomm_send_unix_sock(sock, &stream_nr,
662 sizeof(stream_nr));
663 if (len != sizeof(stream_nr)) {
664 if (len < 0)
665 return len;
666 else
667 return -EIO;
668 }
669 }
670
671 /* Send shm fd and wakeup fd */
672 fds[0] = shm_fd;
673 fds[1] = wakeup_fd;
674 len = ustcomm_send_fds_unix_sock(sock, fds, 2);
675 if (len <= 0) {
676 if (len < 0)
677 return len;
678 else
679 return -EIO;
680 }
681 return 0;
682}
683
684int ustctl_recv_channel_from_consumer(int sock,
685 struct lttng_ust_object_data **_channel_data)
686{
687 struct lttng_ust_object_data *channel_data;
688 ssize_t len;
ff0f5728 689 int wakeup_fd;
7a784989 690 int ret;
57773204 691
74d81a6c
MD
692 channel_data = zmalloc(sizeof(*channel_data));
693 if (!channel_data) {
694 ret = -ENOMEM;
695 goto error_alloc;
696 }
697 channel_data->type = LTTNG_UST_OBJECT_TYPE_CHANNEL;
12f3dabc 698 channel_data->handle = -1;
74d81a6c
MD
699
700 /* recv mmap size */
701 len = ustcomm_recv_unix_sock(sock, &channel_data->size,
702 sizeof(channel_data->size));
703 if (len != sizeof(channel_data->size)) {
704 if (len < 0)
705 ret = len;
706 else
707 ret = -EINVAL;
708 goto error;
709 }
9bfc503d 710
74d81a6c
MD
711 /* recv channel type */
712 len = ustcomm_recv_unix_sock(sock, &channel_data->u.channel.type,
713 sizeof(channel_data->u.channel.type));
714 if (len != sizeof(channel_data->u.channel.type)) {
715 if (len < 0)
716 ret = len;
717 else
718 ret = -EINVAL;
719 goto error;
720 }
721
722 /* recv channel data */
723 channel_data->u.channel.data = zmalloc(channel_data->size);
724 if (!channel_data->u.channel.data) {
725 ret = -ENOMEM;
726 goto error;
727 }
728 len = ustcomm_recv_unix_sock(sock, channel_data->u.channel.data,
729 channel_data->size);
730 if (len != channel_data->size) {
731 if (len < 0)
732 ret = len;
733 else
734 ret = -EINVAL;
735 goto error_recv_data;
736 }
ff0f5728
MD
737 /* recv wakeup fd */
738 len = ustcomm_recv_fds_unix_sock(sock, &wakeup_fd, 1);
739 if (len <= 0) {
740 if (len < 0) {
741 ret = len;
742 goto error_recv_data;
743 } else {
744 ret = -EIO;
745 goto error_recv_data;
746 }
747 }
748 channel_data->u.channel.wakeup_fd = wakeup_fd;
74d81a6c
MD
749 *_channel_data = channel_data;
750 return 0;
751
752error_recv_data:
753 free(channel_data->u.channel.data);
754error:
755 free(channel_data);
756error_alloc:
757 return ret;
758}
759
760int ustctl_recv_stream_from_consumer(int sock,
761 struct lttng_ust_object_data **_stream_data)
762{
763 struct lttng_ust_object_data *stream_data;
764 ssize_t len;
765 int ret;
766 int fds[2];
767
768 stream_data = zmalloc(sizeof(*stream_data));
769 if (!stream_data) {
770 ret = -ENOMEM;
771 goto error_alloc;
57773204 772 }
74d81a6c
MD
773
774 stream_data->type = LTTNG_UST_OBJECT_TYPE_STREAM;
775 stream_data->handle = -1;
776
777 /* recv mmap size */
778 len = ustcomm_recv_unix_sock(sock, &stream_data->size,
779 sizeof(stream_data->size));
780 if (len != sizeof(stream_data->size)) {
781 if (len < 0)
782 ret = len;
783 else
784 ret = -EINVAL;
785 goto error;
786 }
787 if (stream_data->size == -1) {
788 ret = -LTTNG_UST_ERR_NOENT;
789 goto error;
790 }
791
792 /* recv stream nr */
793 len = ustcomm_recv_unix_sock(sock, &stream_data->u.stream.stream_nr,
794 sizeof(stream_data->u.stream.stream_nr));
795 if (len != sizeof(stream_data->u.stream.stream_nr)) {
796 if (len < 0)
797 ret = len;
798 else
799 ret = -EINVAL;
800 goto error;
801 }
802
803 /* recv shm fd and wakeup fd */
804 len = ustcomm_recv_fds_unix_sock(sock, fds, 2);
805 if (len <= 0) {
806 if (len < 0) {
807 ret = len;
808 goto error;
809 } else {
810 ret = -EIO;
811 goto error;
0bfe09ec 812 }
0bfe09ec 813 }
74d81a6c
MD
814 stream_data->u.stream.shm_fd = fds[0];
815 stream_data->u.stream.wakeup_fd = fds[1];
816 *_stream_data = stream_data;
817 return 0;
0bfe09ec 818
74d81a6c
MD
819error:
820 free(stream_data);
821error_alloc:
822 return ret;
823}
824
825int ustctl_send_channel_to_ust(int sock, int session_handle,
826 struct lttng_ust_object_data *channel_data)
827{
828 struct ustcomm_ust_msg lum;
829 struct ustcomm_ust_reply lur;
830 int ret;
831
832 if (!channel_data)
833 return -EINVAL;
834
835 memset(&lum, 0, sizeof(lum));
836 lum.handle = session_handle;
837 lum.cmd = LTTNG_UST_CHANNEL;
838 lum.u.channel.len = channel_data->size;
839 lum.u.channel.type = channel_data->u.channel.type;
840 ret = ustcomm_send_app_msg(sock, &lum);
841 if (ret)
842 return ret;
843
844 ret = ustctl_send_channel(sock,
845 channel_data->u.channel.type,
846 channel_data->u.channel.data,
847 channel_data->size,
ff0f5728 848 channel_data->u.channel.wakeup_fd,
74d81a6c
MD
849 1);
850 if (ret)
851 return ret;
852 ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
853 if (!ret) {
7f2348b8 854 channel_data->handle = lur.ret_val;
57773204 855 }
74d81a6c
MD
856 return ret;
857}
858
859int ustctl_send_stream_to_ust(int sock,
860 struct lttng_ust_object_data *channel_data,
861 struct lttng_ust_object_data *stream_data)
862{
863 struct ustcomm_ust_msg lum;
864 struct ustcomm_ust_reply lur;
865 int ret;
866
867 memset(&lum, 0, sizeof(lum));
868 lum.handle = channel_data->handle;
869 lum.cmd = LTTNG_UST_STREAM;
870 lum.u.stream.len = stream_data->size;
871 lum.u.stream.stream_nr = stream_data->u.stream.stream_nr;
872 ret = ustcomm_send_app_msg(sock, &lum);
873 if (ret)
874 return ret;
875
876 assert(stream_data);
877 assert(stream_data->type == LTTNG_UST_OBJECT_TYPE_STREAM);
878
879 ret = ustctl_send_stream(sock,
880 stream_data->u.stream.stream_nr,
881 stream_data->size,
882 stream_data->u.stream.shm_fd,
883 stream_data->u.stream.wakeup_fd, 1);
884 if (ret)
885 return ret;
886 return ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
887}
888
12f3dabc
MD
889int ustctl_duplicate_ust_object_data(struct lttng_ust_object_data **dest,
890 struct lttng_ust_object_data *src)
891{
892 struct lttng_ust_object_data *obj;
893 int ret;
894
895 if (src->handle != -1) {
896 ret = -EINVAL;
897 goto error;
898 }
899
900 obj = zmalloc(sizeof(*obj));
901 if (!obj) {
902 ret = -ENOMEM;
903 goto error;
904 }
905
906 obj->type = src->type;
907 obj->handle = src->handle;
908 obj->size = src->size;
909
910 switch (obj->type) {
911 case LTTNG_UST_OBJECT_TYPE_CHANNEL:
912 {
913 obj->u.channel.type = src->u.channel.type;
914 if (src->u.channel.wakeup_fd >= 0) {
915 obj->u.channel.wakeup_fd =
916 dup(src->u.channel.wakeup_fd);
917 if (obj->u.channel.wakeup_fd < 0) {
2a2febe2 918 ret = -errno;
12f3dabc
MD
919 goto chan_error_wakeup_fd;
920 }
921 } else {
922 obj->u.channel.wakeup_fd =
923 src->u.channel.wakeup_fd;
924 }
925 obj->u.channel.data = zmalloc(obj->size);
926 if (!obj->u.channel.data) {
927 ret = -ENOMEM;
928 goto chan_error_alloc;
929 }
930 memcpy(obj->u.channel.data, src->u.channel.data, obj->size);
931 break;
932
933 chan_error_alloc:
934 if (src->u.channel.wakeup_fd >= 0) {
935 int closeret;
936
937 closeret = close(obj->u.channel.wakeup_fd);
938 if (closeret) {
939 PERROR("close");
940 }
941 }
942 chan_error_wakeup_fd:
943 goto error_type;
944
945 }
946
947 case LTTNG_UST_OBJECT_TYPE_STREAM:
948 {
949 obj->u.stream.stream_nr = src->u.stream.stream_nr;
950 if (src->u.stream.wakeup_fd >= 0) {
951 obj->u.stream.wakeup_fd =
952 dup(src->u.stream.wakeup_fd);
953 if (obj->u.stream.wakeup_fd < 0) {
2a2febe2 954 ret = -errno;
12f3dabc
MD
955 goto stream_error_wakeup_fd;
956 }
957 } else {
958 obj->u.stream.wakeup_fd =
959 src->u.stream.wakeup_fd;
960 }
961
962 if (src->u.stream.shm_fd >= 0) {
963 obj->u.stream.shm_fd =
964 dup(src->u.stream.shm_fd);
965 if (obj->u.stream.shm_fd < 0) {
2a2febe2 966 ret = -errno;
12f3dabc
MD
967 goto stream_error_shm_fd;
968 }
969 } else {
970 obj->u.stream.shm_fd =
971 src->u.stream.shm_fd;
972 }
973 break;
974
975 stream_error_shm_fd:
976 if (src->u.stream.wakeup_fd >= 0) {
977 int closeret;
978
979 closeret = close(obj->u.stream.wakeup_fd);
980 if (closeret) {
981 PERROR("close");
982 }
983 }
984 stream_error_wakeup_fd:
985 goto error_type;
986 }
987
988 default:
989 ret = -EINVAL;
990 goto error_type;
991 }
992
993 *dest = obj;
994 return 0;
995
996error_type:
997 free(obj);
998error:
999 return ret;
1000}
1001
74d81a6c
MD
1002
1003/* Buffer operations */
1004
5ea386c3
MD
1005int ustctl_get_nr_stream_per_channel(void)
1006{
1007 return num_possible_cpus();
1008}
1009
74d81a6c 1010struct ustctl_consumer_channel *
5ea386c3
MD
1011 ustctl_create_channel(struct ustctl_consumer_channel_attr *attr,
1012 const int *stream_fds, int nr_stream_fds)
74d81a6c
MD
1013{
1014 struct ustctl_consumer_channel *chan;
1015 const char *transport_name;
1016 struct lttng_transport *transport;
1017
1018 switch (attr->type) {
1019 case LTTNG_UST_CHAN_PER_CPU:
1020 if (attr->output == LTTNG_UST_MMAP) {
34a91bdb
MD
1021 if (attr->overwrite) {
1022 if (attr->read_timer_interval == 0) {
1023 transport_name = "relay-overwrite-mmap";
1024 } else {
1025 transport_name = "relay-overwrite-rt-mmap";
1026 }
1027 } else {
1028 if (attr->read_timer_interval == 0) {
1029 transport_name = "relay-discard-mmap";
1030 } else {
1031 transport_name = "relay-discard-rt-mmap";
1032 }
1033 }
74d81a6c
MD
1034 } else {
1035 return NULL;
1036 }
c1fca457 1037 break;
74d81a6c
MD
1038 case LTTNG_UST_CHAN_METADATA:
1039 if (attr->output == LTTNG_UST_MMAP)
1040 transport_name = "relay-metadata-mmap";
1041 else
1042 return NULL;
c1fca457
MD
1043 break;
1044 default:
74d81a6c 1045 transport_name = "<unknown>";
c1fca457
MD
1046 return NULL;
1047 }
74d81a6c
MD
1048
1049 transport = lttng_transport_find(transport_name);
1050 if (!transport) {
1051 DBG("LTTng transport %s not found\n",
32ce8569 1052 transport_name);
74d81a6c 1053 return NULL;
7a784989 1054 }
74d81a6c
MD
1055
1056 chan = zmalloc(sizeof(*chan));
1057 if (!chan)
1058 return NULL;
1059
1060 chan->chan = transport->ops.channel_create(transport_name, NULL,
32ce8569 1061 attr->subbuf_size, attr->num_subbuf,
74d81a6c 1062 attr->switch_timer_interval,
32ce8569 1063 attr->read_timer_interval,
a9ff648c 1064 attr->uuid, attr->chan_id,
b2c5f61a
MD
1065 stream_fds, nr_stream_fds,
1066 attr->blocking_timeout);
74d81a6c
MD
1067 if (!chan->chan) {
1068 goto chan_error;
1069 }
1070 chan->chan->ops = &transport->ops;
1071 memcpy(&chan->attr, attr, sizeof(chan->attr));
cb7378b3
MD
1072 chan->wait_fd = ustctl_channel_get_wait_fd(chan);
1073 chan->wakeup_fd = ustctl_channel_get_wakeup_fd(chan);
74d81a6c
MD
1074 return chan;
1075
1076chan_error:
1077 free(chan);
1078 return NULL;
57773204
MD
1079}
1080
74d81a6c 1081void ustctl_destroy_channel(struct ustctl_consumer_channel *chan)
57773204 1082{
b24e4e91
MD
1083 (void) ustctl_channel_close_wait_fd(chan);
1084 (void) ustctl_channel_close_wakeup_fd(chan);
74d81a6c
MD
1085 chan->chan->ops->channel_destroy(chan->chan);
1086 free(chan);
1087}
1088
1089int ustctl_send_channel_to_sessiond(int sock,
1090 struct ustctl_consumer_channel *channel)
1091{
1092 struct shm_object_table *table;
57773204 1093
74d81a6c
MD
1094 table = channel->chan->handle->table;
1095 if (table->size <= 0)
9bfc503d 1096 return -EINVAL;
74d81a6c
MD
1097 return ustctl_send_channel(sock,
1098 channel->attr.type,
1099 table->objects[0].memory_map,
1100 table->objects[0].memory_map_size,
ff0f5728 1101 channel->wakeup_fd,
74d81a6c
MD
1102 0);
1103}
9bfc503d 1104
74d81a6c
MD
1105int ustctl_send_stream_to_sessiond(int sock,
1106 struct ustctl_consumer_stream *stream)
1107{
1108 if (!stream)
1109 return ustctl_send_stream(sock, -1U, -1U, -1, -1, 0);
1110
1111 return ustctl_send_stream(sock,
1112 stream->cpu,
1113 stream->memory_map_size,
1114 stream->shm_fd, stream->wakeup_fd,
1115 0);
57773204
MD
1116}
1117
c9023c93
MD
1118int ustctl_write_metadata_to_channel(
1119 struct ustctl_consumer_channel *channel,
1120 const char *metadata_str, /* NOT null-terminated */
1121 size_t len) /* metadata length */
1122{
1123 struct lttng_ust_lib_ring_buffer_ctx ctx;
1124 struct lttng_channel *chan = channel->chan;
1125 const char *str = metadata_str;
1126 int ret = 0, waitret;
1127 size_t reserve_len, pos;
1128
1129 for (pos = 0; pos < len; pos += reserve_len) {
1130 reserve_len = min_t(size_t,
1131 chan->ops->packet_avail_size(chan->chan, chan->handle),
1132 len - pos);
1133 lib_ring_buffer_ctx_init(&ctx, chan->chan, NULL, reserve_len,
53569322 1134 sizeof(char), -1, chan->handle, NULL);
c9023c93
MD
1135 /*
1136 * We don't care about metadata buffer's records lost
1137 * count, because we always retry here. Report error if
1138 * we need to bail out after timeout or being
1139 * interrupted.
1140 */
1141 waitret = wait_cond_interruptible_timeout(
1142 ({
1143 ret = chan->ops->event_reserve(&ctx, 0);
1144 ret != -ENOBUFS || !ret;
1145 }),
1146 LTTNG_METADATA_TIMEOUT_MSEC);
1147 if (waitret == -ETIMEDOUT || waitret == -EINTR || ret) {
1148 DBG("LTTng: Failure to write metadata to buffers (%s)\n",
1149 waitret == -EINTR ? "interrupted" :
1150 (ret == -ENOBUFS ? "timeout" : "I/O error"));
1151 if (waitret == -EINTR)
1152 ret = waitret;
1153 goto end;
1154 }
1155 chan->ops->event_write(&ctx, &str[pos], reserve_len);
1156 chan->ops->event_commit(&ctx);
1157 }
1158end:
1159 return ret;
1160}
1161
3ef94b0e
JD
1162/*
1163 * Write at most one packet in the channel.
1164 * Returns the number of bytes written on success, < 0 on error.
1165 */
1166ssize_t ustctl_write_one_packet_to_channel(
1167 struct ustctl_consumer_channel *channel,
1168 const char *metadata_str, /* NOT null-terminated */
1169 size_t len) /* metadata length */
1170{
1171 struct lttng_ust_lib_ring_buffer_ctx ctx;
1172 struct lttng_channel *chan = channel->chan;
1173 const char *str = metadata_str;
1174 ssize_t reserve_len;
1175 int ret;
1176
1177 reserve_len = min_t(ssize_t,
1178 chan->ops->packet_avail_size(chan->chan, chan->handle),
1179 len);
1180 lib_ring_buffer_ctx_init(&ctx, chan->chan, NULL, reserve_len,
53569322 1181 sizeof(char), -1, chan->handle, NULL);
3ef94b0e
JD
1182 ret = chan->ops->event_reserve(&ctx, 0);
1183 if (ret != 0) {
1184 DBG("LTTng: event reservation failed");
1185 assert(ret < 0);
1186 reserve_len = ret;
1187 goto end;
1188 }
1189 chan->ops->event_write(&ctx, str, reserve_len);
1190 chan->ops->event_commit(&ctx);
1191
1192end:
1193 return reserve_len;
1194}
1195
ff0f5728
MD
1196int ustctl_channel_close_wait_fd(struct ustctl_consumer_channel *consumer_chan)
1197{
1198 struct channel *chan;
cb7378b3 1199 int ret;
ff0f5728
MD
1200
1201 chan = consumer_chan->chan->chan;
cb7378b3 1202 ret = ring_buffer_channel_close_wait_fd(&chan->backend.config,
ff0f5728 1203 chan, chan->handle);
cb7378b3
MD
1204 if (!ret)
1205 consumer_chan->wait_fd = -1;
1206 return ret;
ff0f5728
MD
1207}
1208
1209int ustctl_channel_close_wakeup_fd(struct ustctl_consumer_channel *consumer_chan)
1210{
1211 struct channel *chan;
cb7378b3 1212 int ret;
ff0f5728
MD
1213
1214 chan = consumer_chan->chan->chan;
cb7378b3 1215 ret = ring_buffer_channel_close_wakeup_fd(&chan->backend.config,
ff0f5728 1216 chan, chan->handle);
cb7378b3
MD
1217 if (!ret)
1218 consumer_chan->wakeup_fd = -1;
1219 return ret;
ff0f5728
MD
1220}
1221
74d81a6c 1222int ustctl_stream_close_wait_fd(struct ustctl_consumer_stream *stream)
5224b5c8
MD
1223{
1224 struct channel *chan;
1225
74d81a6c 1226 chan = stream->chan->chan->chan;
ff0f5728 1227 return ring_buffer_stream_close_wait_fd(&chan->backend.config,
74d81a6c 1228 chan, stream->handle, stream->cpu);
5224b5c8
MD
1229}
1230
74d81a6c 1231int ustctl_stream_close_wakeup_fd(struct ustctl_consumer_stream *stream)
6e922b24 1232{
66bdd22a 1233 struct channel *chan;
74d81a6c
MD
1234
1235 chan = stream->chan->chan->chan;
ff0f5728 1236 return ring_buffer_stream_close_wakeup_fd(&chan->backend.config,
74d81a6c
MD
1237 chan, stream->handle, stream->cpu);
1238}
1239
1240struct ustctl_consumer_stream *
1241 ustctl_create_stream(struct ustctl_consumer_channel *channel,
1242 int cpu)
1243{
1244 struct ustctl_consumer_stream *stream;
1245 struct lttng_ust_shm_handle *handle;
1246 struct channel *chan;
1247 int shm_fd, wait_fd, wakeup_fd;
1248 uint64_t memory_map_size;
4cfec15c 1249 struct lttng_ust_lib_ring_buffer *buf;
6e922b24
MD
1250 int ret;
1251
74d81a6c
MD
1252 if (!channel)
1253 return NULL;
1254 handle = channel->chan->handle;
9bfc503d
MD
1255 if (!handle)
1256 return NULL;
1257
74d81a6c 1258 chan = channel->chan->chan;
6e922b24 1259 buf = channel_get_ring_buffer(&chan->backend.config,
74d81a6c
MD
1260 chan, cpu, handle, &shm_fd, &wait_fd,
1261 &wakeup_fd, &memory_map_size);
6e922b24
MD
1262 if (!buf)
1263 return NULL;
74d81a6c 1264 ret = lib_ring_buffer_open_read(buf, handle);
6e922b24
MD
1265 if (ret)
1266 return NULL;
74d81a6c
MD
1267
1268 stream = zmalloc(sizeof(*stream));
1269 if (!stream)
1270 goto alloc_error;
1271 stream->handle = handle;
1272 stream->buf = buf;
1273 stream->chan = channel;
1274 stream->shm_fd = shm_fd;
1275 stream->wait_fd = wait_fd;
1276 stream->wakeup_fd = wakeup_fd;
1277 stream->memory_map_size = memory_map_size;
1278 stream->cpu = cpu;
1279 return stream;
1280
1281alloc_error:
1282 return NULL;
1283}
1284
1285void ustctl_destroy_stream(struct ustctl_consumer_stream *stream)
1286{
1287 struct lttng_ust_lib_ring_buffer *buf;
1288 struct ustctl_consumer_channel *consumer_chan;
1289
1290 assert(stream);
1291 buf = stream->buf;
1292 consumer_chan = stream->chan;
b24e4e91
MD
1293 (void) ustctl_stream_close_wait_fd(stream);
1294 (void) ustctl_stream_close_wakeup_fd(stream);
74d81a6c
MD
1295 lib_ring_buffer_release_read(buf, consumer_chan->chan->handle);
1296 free(stream);
6e922b24
MD
1297}
1298
ff0f5728
MD
1299int ustctl_channel_get_wait_fd(struct ustctl_consumer_channel *chan)
1300{
1301 if (!chan)
1302 return -EINVAL;
1303 return shm_get_wait_fd(chan->chan->handle,
1304 &chan->chan->handle->chan._ref);
1305}
1306
1307int ustctl_channel_get_wakeup_fd(struct ustctl_consumer_channel *chan)
1308{
1309 if (!chan)
1310 return -EINVAL;
1311 return shm_get_wakeup_fd(chan->chan->handle,
1312 &chan->chan->handle->chan._ref);
1313}
1314
1315int ustctl_stream_get_wait_fd(struct ustctl_consumer_stream *stream)
6e922b24 1316{
74d81a6c
MD
1317 struct lttng_ust_lib_ring_buffer *buf;
1318 struct ustctl_consumer_channel *consumer_chan;
1319
1320 if (!stream)
1321 return -EINVAL;
1322 buf = stream->buf;
1323 consumer_chan = stream->chan;
1324 return shm_get_wait_fd(consumer_chan->chan->handle, &buf->self._ref);
1325}
1326
ff0f5728 1327int ustctl_stream_get_wakeup_fd(struct ustctl_consumer_stream *stream)
74d81a6c
MD
1328{
1329 struct lttng_ust_lib_ring_buffer *buf;
1330 struct ustctl_consumer_channel *consumer_chan;
1331
1332 if (!stream)
1333 return -EINVAL;
1334 buf = stream->buf;
1335 consumer_chan = stream->chan;
1336 return shm_get_wakeup_fd(consumer_chan->chan->handle, &buf->self._ref);
6e922b24
MD
1337}
1338
57773204
MD
1339/* For mmap mode, readable without "get" operation */
1340
74d81a6c 1341void *ustctl_get_mmap_base(struct ustctl_consumer_stream *stream)
9095efe9 1342{
74d81a6c
MD
1343 struct lttng_ust_lib_ring_buffer *buf;
1344 struct ustctl_consumer_channel *consumer_chan;
1345
1346 if (!stream)
9bfc503d 1347 return NULL;
74d81a6c
MD
1348 buf = stream->buf;
1349 consumer_chan = stream->chan;
1350 return shmp(consumer_chan->chan->handle, buf->backend.memory_map);
9095efe9
MD
1351}
1352
57773204 1353/* returns the length to mmap. */
74d81a6c 1354int ustctl_get_mmap_len(struct ustctl_consumer_stream *stream,
57773204
MD
1355 unsigned long *len)
1356{
74d81a6c 1357 struct ustctl_consumer_channel *consumer_chan;
57773204 1358 unsigned long mmap_buf_len;
66bdd22a 1359 struct channel *chan;
57773204 1360
74d81a6c 1361 if (!stream)
9bfc503d 1362 return -EINVAL;
74d81a6c
MD
1363 consumer_chan = stream->chan;
1364 chan = consumer_chan->chan->chan;
57773204
MD
1365 if (chan->backend.config.output != RING_BUFFER_MMAP)
1366 return -EINVAL;
1367 mmap_buf_len = chan->backend.buf_size;
1368 if (chan->backend.extra_reader_sb)
1369 mmap_buf_len += chan->backend.subbuf_size;
1370 if (mmap_buf_len > INT_MAX)
1371 return -EFBIG;
1372 *len = mmap_buf_len;
1373 return 0;
1374}
1375
1376/* returns the maximum size for sub-buffers. */
74d81a6c 1377int ustctl_get_max_subbuf_size(struct ustctl_consumer_stream *stream,
57773204
MD
1378 unsigned long *len)
1379{
74d81a6c 1380 struct ustctl_consumer_channel *consumer_chan;
66bdd22a 1381 struct channel *chan;
57773204 1382
74d81a6c 1383 if (!stream)
9bfc503d 1384 return -EINVAL;
74d81a6c
MD
1385 consumer_chan = stream->chan;
1386 chan = consumer_chan->chan->chan;
57773204
MD
1387 *len = chan->backend.subbuf_size;
1388 return 0;
1389}
1390
1391/*
1392 * For mmap mode, operate on the current packet (between get/put or
1393 * get_next/put_next).
1394 */
1395
1396/* returns the offset of the subbuffer belonging to the mmap reader. */
74d81a6c
MD
1397int ustctl_get_mmap_read_offset(struct ustctl_consumer_stream *stream,
1398 unsigned long *off)
57773204 1399{
66bdd22a 1400 struct channel *chan;
57773204 1401 unsigned long sb_bindex;
74d81a6c
MD
1402 struct lttng_ust_lib_ring_buffer *buf;
1403 struct ustctl_consumer_channel *consumer_chan;
34daae3e
MD
1404 struct lttng_ust_lib_ring_buffer_backend_pages_shmp *barray_idx;
1405 struct lttng_ust_lib_ring_buffer_backend_pages *pages;
57773204 1406
74d81a6c 1407 if (!stream)
9bfc503d 1408 return -EINVAL;
74d81a6c
MD
1409 buf = stream->buf;
1410 consumer_chan = stream->chan;
1411 chan = consumer_chan->chan->chan;
57773204
MD
1412 if (chan->backend.config.output != RING_BUFFER_MMAP)
1413 return -EINVAL;
1414 sb_bindex = subbuffer_id_get_index(&chan->backend.config,
32ce8569 1415 buf->backend.buf_rsb.id);
34daae3e
MD
1416 barray_idx = shmp_index(consumer_chan->chan->handle, buf->backend.array,
1417 sb_bindex);
1418 if (!barray_idx)
1419 return -EINVAL;
1420 pages = shmp(consumer_chan->chan->handle, barray_idx->shmp);
1421 if (!pages)
1422 return -EINVAL;
1423 *off = pages->mmap_offset;
57773204
MD
1424 return 0;
1425}
1426
1427/* returns the size of the current sub-buffer, without padding (for mmap). */
74d81a6c
MD
1428int ustctl_get_subbuf_size(struct ustctl_consumer_stream *stream,
1429 unsigned long *len)
57773204 1430{
74d81a6c 1431 struct ustctl_consumer_channel *consumer_chan;
66bdd22a 1432 struct channel *chan;
74d81a6c 1433 struct lttng_ust_lib_ring_buffer *buf;
57773204 1434
74d81a6c 1435 if (!stream)
9bfc503d
MD
1436 return -EINVAL;
1437
74d81a6c
MD
1438 buf = stream->buf;
1439 consumer_chan = stream->chan;
1440 chan = consumer_chan->chan->chan;
57773204 1441 *len = lib_ring_buffer_get_read_data_size(&chan->backend.config, buf,
74d81a6c 1442 consumer_chan->chan->handle);
57773204
MD
1443 return 0;
1444}
1445
1446/* returns the size of the current sub-buffer, without padding (for mmap). */
74d81a6c
MD
1447int ustctl_get_padded_subbuf_size(struct ustctl_consumer_stream *stream,
1448 unsigned long *len)
57773204 1449{
74d81a6c 1450 struct ustctl_consumer_channel *consumer_chan;
66bdd22a 1451 struct channel *chan;
74d81a6c 1452 struct lttng_ust_lib_ring_buffer *buf;
57773204 1453
74d81a6c 1454 if (!stream)
9bfc503d 1455 return -EINVAL;
74d81a6c
MD
1456 buf = stream->buf;
1457 consumer_chan = stream->chan;
1458 chan = consumer_chan->chan->chan;
57773204 1459 *len = lib_ring_buffer_get_read_data_size(&chan->backend.config, buf,
74d81a6c 1460 consumer_chan->chan->handle);
57773204
MD
1461 *len = PAGE_ALIGN(*len);
1462 return 0;
1463}
1464
1465/* Get exclusive read access to the next sub-buffer that can be read. */
74d81a6c 1466int ustctl_get_next_subbuf(struct ustctl_consumer_stream *stream)
57773204 1467{
74d81a6c
MD
1468 struct lttng_ust_lib_ring_buffer *buf;
1469 struct ustctl_consumer_channel *consumer_chan;
9bfc503d 1470
74d81a6c
MD
1471 if (!stream)
1472 return -EINVAL;
1473 buf = stream->buf;
1474 consumer_chan = stream->chan;
1475 return lib_ring_buffer_get_next_subbuf(buf,
1476 consumer_chan->chan->handle);
57773204
MD
1477}
1478
1479
1480/* Release exclusive sub-buffer access, move consumer forward. */
74d81a6c 1481int ustctl_put_next_subbuf(struct ustctl_consumer_stream *stream)
57773204 1482{
74d81a6c
MD
1483 struct lttng_ust_lib_ring_buffer *buf;
1484 struct ustctl_consumer_channel *consumer_chan;
9bfc503d 1485
74d81a6c
MD
1486 if (!stream)
1487 return -EINVAL;
1488 buf = stream->buf;
1489 consumer_chan = stream->chan;
1490 lib_ring_buffer_put_next_subbuf(buf, consumer_chan->chan->handle);
57773204
MD
1491 return 0;
1492}
1493
1494/* snapshot */
1495
1496/* Get a snapshot of the current ring buffer producer and consumer positions */
74d81a6c 1497int ustctl_snapshot(struct ustctl_consumer_stream *stream)
57773204 1498{
74d81a6c
MD
1499 struct lttng_ust_lib_ring_buffer *buf;
1500 struct ustctl_consumer_channel *consumer_chan;
9bfc503d 1501
74d81a6c
MD
1502 if (!stream)
1503 return -EINVAL;
1504 buf = stream->buf;
1505 consumer_chan = stream->chan;
57773204 1506 return lib_ring_buffer_snapshot(buf, &buf->cons_snapshot,
74d81a6c 1507 &buf->prod_snapshot, consumer_chan->chan->handle);
57773204
MD
1508}
1509
f45930b7
JG
1510/*
1511 * Get a snapshot of the current ring buffer producer and consumer positions
1512 * even if the consumed and produced positions are contained within the same
1513 * subbuffer.
1514 */
1515int ustctl_snapshot_sample_positions(struct ustctl_consumer_stream *stream)
1516{
1517 struct lttng_ust_lib_ring_buffer *buf;
1518 struct ustctl_consumer_channel *consumer_chan;
1519
1520 if (!stream)
1521 return -EINVAL;
1522 buf = stream->buf;
1523 consumer_chan = stream->chan;
1524 return lib_ring_buffer_snapshot_sample_positions(buf,
1525 &buf->cons_snapshot, &buf->prod_snapshot,
1526 consumer_chan->chan->handle);
1527}
1528
57773204 1529/* Get the consumer position (iteration start) */
74d81a6c
MD
1530int ustctl_snapshot_get_consumed(struct ustctl_consumer_stream *stream,
1531 unsigned long *pos)
57773204 1532{
74d81a6c 1533 struct lttng_ust_lib_ring_buffer *buf;
9bfc503d 1534
74d81a6c
MD
1535 if (!stream)
1536 return -EINVAL;
1537 buf = stream->buf;
57773204
MD
1538 *pos = buf->cons_snapshot;
1539 return 0;
1540}
1541
1542/* Get the producer position (iteration end) */
74d81a6c
MD
1543int ustctl_snapshot_get_produced(struct ustctl_consumer_stream *stream,
1544 unsigned long *pos)
57773204 1545{
74d81a6c 1546 struct lttng_ust_lib_ring_buffer *buf;
9bfc503d 1547
74d81a6c
MD
1548 if (!stream)
1549 return -EINVAL;
1550 buf = stream->buf;
57773204
MD
1551 *pos = buf->prod_snapshot;
1552 return 0;
1553}
1554
1555/* Get exclusive read access to the specified sub-buffer position */
74d81a6c
MD
1556int ustctl_get_subbuf(struct ustctl_consumer_stream *stream,
1557 unsigned long *pos)
57773204 1558{
74d81a6c
MD
1559 struct lttng_ust_lib_ring_buffer *buf;
1560 struct ustctl_consumer_channel *consumer_chan;
9bfc503d 1561
74d81a6c
MD
1562 if (!stream)
1563 return -EINVAL;
1564 buf = stream->buf;
1565 consumer_chan = stream->chan;
1566 return lib_ring_buffer_get_subbuf(buf, *pos,
1567 consumer_chan->chan->handle);
57773204
MD
1568}
1569
1570/* Release exclusive sub-buffer access */
74d81a6c 1571int ustctl_put_subbuf(struct ustctl_consumer_stream *stream)
57773204 1572{
74d81a6c
MD
1573 struct lttng_ust_lib_ring_buffer *buf;
1574 struct ustctl_consumer_channel *consumer_chan;
9bfc503d 1575
74d81a6c
MD
1576 if (!stream)
1577 return -EINVAL;
1578 buf = stream->buf;
1579 consumer_chan = stream->chan;
1580 lib_ring_buffer_put_subbuf(buf, consumer_chan->chan->handle);
57773204
MD
1581 return 0;
1582}
1583
74d81a6c 1584void ustctl_flush_buffer(struct ustctl_consumer_stream *stream,
b52190f2 1585 int producer_active)
57773204 1586{
74d81a6c
MD
1587 struct lttng_ust_lib_ring_buffer *buf;
1588 struct ustctl_consumer_channel *consumer_chan;
1589
1590 assert(stream);
1591 buf = stream->buf;
1592 consumer_chan = stream->chan;
b52190f2
MD
1593 lib_ring_buffer_switch_slow(buf,
1594 producer_active ? SWITCH_ACTIVE : SWITCH_FLUSH,
74d81a6c
MD
1595 consumer_chan->chan->handle);
1596}
1597
beca55a1
MD
1598void ustctl_clear_buffer(struct ustctl_consumer_stream *stream)
1599{
1600 struct lttng_ust_lib_ring_buffer *buf;
1601 struct ustctl_consumer_channel *consumer_chan;
1602
1603 assert(stream);
1604 buf = stream->buf;
1605 consumer_chan = stream->chan;
1606 lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE,
1607 consumer_chan->chan->handle);
1608 lib_ring_buffer_clear_reader(buf, consumer_chan->chan->handle);
1609}
1610
b2f3252a
JD
1611static
1612struct lttng_ust_client_lib_ring_buffer_client_cb *get_client_cb(
1613 struct lttng_ust_lib_ring_buffer *buf,
1614 struct lttng_ust_shm_handle *handle)
1615{
1616 struct channel *chan;
1617 const struct lttng_ust_lib_ring_buffer_config *config;
1618 struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
1619
1620 chan = shmp(handle, buf->backend.chan);
34daae3e
MD
1621 if (!chan)
1622 return NULL;
b2f3252a
JD
1623 config = &chan->backend.config;
1624 if (!config->cb_ptr)
1625 return NULL;
1626 client_cb = caa_container_of(config->cb_ptr,
1627 struct lttng_ust_client_lib_ring_buffer_client_cb,
1628 parent);
1629 return client_cb;
1630}
1631
1632int ustctl_get_timestamp_begin(struct ustctl_consumer_stream *stream,
1633 uint64_t *timestamp_begin)
1634{
1635 struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
e1919a41
MD
1636 struct lttng_ust_lib_ring_buffer *buf;
1637 struct lttng_ust_shm_handle *handle;
b2f3252a
JD
1638
1639 if (!stream || !timestamp_begin)
1640 return -EINVAL;
e1919a41
MD
1641 buf = stream->buf;
1642 handle = stream->chan->chan->handle;
b2f3252a
JD
1643 client_cb = get_client_cb(buf, handle);
1644 if (!client_cb)
1645 return -ENOSYS;
1646 return client_cb->timestamp_begin(buf, handle, timestamp_begin);
1647}
1648
1649int ustctl_get_timestamp_end(struct ustctl_consumer_stream *stream,
1650 uint64_t *timestamp_end)
1651{
1652 struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
e1919a41
MD
1653 struct lttng_ust_lib_ring_buffer *buf;
1654 struct lttng_ust_shm_handle *handle;
b2f3252a
JD
1655
1656 if (!stream || !timestamp_end)
1657 return -EINVAL;
e1919a41
MD
1658 buf = stream->buf;
1659 handle = stream->chan->chan->handle;
b2f3252a
JD
1660 client_cb = get_client_cb(buf, handle);
1661 if (!client_cb)
1662 return -ENOSYS;
1663 return client_cb->timestamp_end(buf, handle, timestamp_end);
1664}
1665
1666int ustctl_get_events_discarded(struct ustctl_consumer_stream *stream,
1667 uint64_t *events_discarded)
1668{
1669 struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
e1919a41
MD
1670 struct lttng_ust_lib_ring_buffer *buf;
1671 struct lttng_ust_shm_handle *handle;
b2f3252a
JD
1672
1673 if (!stream || !events_discarded)
1674 return -EINVAL;
e1919a41
MD
1675 buf = stream->buf;
1676 handle = stream->chan->chan->handle;
b2f3252a
JD
1677 client_cb = get_client_cb(buf, handle);
1678 if (!client_cb)
1679 return -ENOSYS;
1680 return client_cb->events_discarded(buf, handle, events_discarded);
1681}
1682
1683int ustctl_get_content_size(struct ustctl_consumer_stream *stream,
1684 uint64_t *content_size)
1685{
1686 struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
e1919a41
MD
1687 struct lttng_ust_lib_ring_buffer *buf;
1688 struct lttng_ust_shm_handle *handle;
b2f3252a
JD
1689
1690 if (!stream || !content_size)
1691 return -EINVAL;
e1919a41
MD
1692 buf = stream->buf;
1693 handle = stream->chan->chan->handle;
b2f3252a
JD
1694 client_cb = get_client_cb(buf, handle);
1695 if (!client_cb)
1696 return -ENOSYS;
1697 return client_cb->content_size(buf, handle, content_size);
1698}
1699
1700int ustctl_get_packet_size(struct ustctl_consumer_stream *stream,
1701 uint64_t *packet_size)
1702{
1703 struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
e1919a41
MD
1704 struct lttng_ust_lib_ring_buffer *buf;
1705 struct lttng_ust_shm_handle *handle;
b2f3252a
JD
1706
1707 if (!stream || !packet_size)
1708 return -EINVAL;
e1919a41
MD
1709 buf = stream->buf;
1710 handle = stream->chan->chan->handle;
b2f3252a
JD
1711 client_cb = get_client_cb(buf, handle);
1712 if (!client_cb)
1713 return -ENOSYS;
1714 return client_cb->packet_size(buf, handle, packet_size);
1715}
1716
1717int ustctl_get_stream_id(struct ustctl_consumer_stream *stream,
1718 uint64_t *stream_id)
1719{
1720 struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
e1919a41
MD
1721 struct lttng_ust_lib_ring_buffer *buf;
1722 struct lttng_ust_shm_handle *handle;
b2f3252a
JD
1723
1724 if (!stream || !stream_id)
1725 return -EINVAL;
e1919a41
MD
1726 buf = stream->buf;
1727 handle = stream->chan->chan->handle;
b2f3252a
JD
1728 client_cb = get_client_cb(buf, handle);
1729 if (!client_cb)
1730 return -ENOSYS;
1731 return client_cb->stream_id(buf, handle, stream_id);
1732}
1733
fca361e8
JD
1734int ustctl_get_current_timestamp(struct ustctl_consumer_stream *stream,
1735 uint64_t *ts)
1736{
1737 struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
e1919a41
MD
1738 struct lttng_ust_lib_ring_buffer *buf;
1739 struct lttng_ust_shm_handle *handle;
fca361e8
JD
1740
1741 if (!stream || !ts)
1742 return -EINVAL;
e1919a41
MD
1743 buf = stream->buf;
1744 handle = stream->chan->chan->handle;
fca361e8
JD
1745 client_cb = get_client_cb(buf, handle);
1746 if (!client_cb || !client_cb->current_timestamp)
1747 return -ENOSYS;
1748 return client_cb->current_timestamp(buf, handle, ts);
1749}
1750
1ff31389
JD
1751int ustctl_get_sequence_number(struct ustctl_consumer_stream *stream,
1752 uint64_t *seq)
1753{
1754 struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
1755 struct lttng_ust_lib_ring_buffer *buf;
1756 struct lttng_ust_shm_handle *handle;
1757
1758 if (!stream || !seq)
1759 return -EINVAL;
1760 buf = stream->buf;
1761 handle = stream->chan->chan->handle;
1762 client_cb = get_client_cb(buf, handle);
1763 if (!client_cb || !client_cb->sequence_number)
1764 return -ENOSYS;
1765 return client_cb->sequence_number(buf, handle, seq);
1766}
1767
45a00b05
JD
1768int ustctl_get_instance_id(struct ustctl_consumer_stream *stream,
1769 uint64_t *id)
1770{
1771 struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
1772 struct lttng_ust_lib_ring_buffer *buf;
1773 struct lttng_ust_shm_handle *handle;
1774
1775 if (!stream || !id)
1776 return -EINVAL;
1777 buf = stream->buf;
1778 handle = stream->chan->chan->handle;
1779 client_cb = get_client_cb(buf, handle);
1780 if (!client_cb)
1781 return -ENOSYS;
1782 return client_cb->instance_id(buf, handle, id);
1783}
1784
c62a3816 1785#ifdef LTTNG_UST_HAVE_PERF_EVENT
57201bb3
MD
1786
1787int ustctl_has_perf_counters(void)
1788{
1789 return 1;
1790}
1791
1792#else
1793
1794int ustctl_has_perf_counters(void)
1795{
1796 return 0;
1797}
1798
1799#endif
1800
4a07ff75
MD
1801#ifdef __linux__
1802/*
1803 * Override application pid/uid/gid with unix socket credentials. If
1804 * the application announced a pid matching our view, it means it is
1805 * within the same pid namespace, so expose the ppid provided by the
1806 * application.
1807 */
1808static
1809int get_cred(int sock,
1810 const struct ustctl_reg_msg *reg_msg,
1811 uint32_t *pid,
1812 uint32_t *ppid,
1813 uint32_t *uid,
1814 uint32_t *gid)
1815{
1816 struct ucred ucred;
1817 socklen_t ucred_len = sizeof(struct ucred);
1818 int ret;
1819
1820 ret = getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &ucred, &ucred_len);
1821 if (ret) {
1822 return -LTTNG_UST_ERR_PEERCRED;
1823 }
1824 DBG("Unix socket peercred [ pid: %u, uid: %u, gid: %u ], "
1825 "application registered claiming [ pid: %u, ppid: %u, uid: %u, gid: %u ]",
1826 ucred.pid, ucred.uid, ucred.gid,
1827 reg_msg->pid, reg_msg->ppid, reg_msg->uid, reg_msg->gid);
1828 if (!ucred.pid) {
1829 ERR("Unix socket credential pid=0. Refusing application in distinct, non-nested pid namespace.");
1830 return -LTTNG_UST_ERR_PEERCRED_PID;
1831 }
1832 *pid = ucred.pid;
1833 *uid = ucred.uid;
1834 *gid = ucred.gid;
1835 if (ucred.pid == reg_msg->pid) {
1836 *ppid = reg_msg->ppid;
1837 } else {
1838 *ppid = 0;
1839 }
1840 return 0;
1841}
1842#elif defined(__FreeBSD__)
1843#include <sys/ucred.h>
9f327dfe 1844#include <sys/un.h>
4a07ff75
MD
1845
1846/*
1847 * Override application uid/gid with unix socket credentials. Use the
1848 * first group of the cr_groups.
1849 * Use the pid and ppid provided by the application on registration.
1850 */
1851static
1852int get_cred(int sock,
1853 const struct ustctl_reg_msg *reg_msg,
1854 uint32_t *pid,
1855 uint32_t *ppid,
1856 uint32_t *uid,
1857 uint32_t *gid)
1858{
1859 struct xucred xucred;
1860 socklen_t xucred_len = sizeof(struct xucred);
1861 int ret;
1862
1863 ret = getsockopt(sock, SOL_SOCKET, LOCAL_PEERCRED, &xucred, &xucred_len);
1864 if (ret) {
1865 return -LTTNG_UST_ERR_PEERCRED;
1866 }
1867 if (xucred.cr_version != XUCRED_VERSION || xucred.cr_ngroups < 1) {
1868 return -LTTNG_UST_ERR_PEERCRED;
1869 }
1870 DBG("Unix socket peercred [ uid: %u, gid: %u ], "
1871 "application registered claiming [ pid: %d, ppid: %d, uid: %u, gid: %u ]",
9f327dfe 1872 xucred.cr_uid, xucred.cr_groups[0],
4a07ff75
MD
1873 reg_msg->pid, reg_msg->ppid, reg_msg->uid, reg_msg->gid);
1874 *pid = reg_msg->pid;
1875 *ppid = reg_msg->ppid;
9f327dfe 1876 *uid = xucred.cr_uid;
4a07ff75
MD
1877 *gid = xucred.cr_groups[0];
1878 return 0;
1879}
1880#else
1881#warning "Using insecure fallback: trusting user id provided by registered applications. Please consider implementing use of unix socket credentials on your platform."
1882static
1883int get_cred(int sock,
1884 const struct ustctl_reg_msg *reg_msg,
1885 uint32_t *pid,
1886 uint32_t *ppid,
1887 uint32_t *uid,
1888 uint32_t *gid)
1889{
1890 DBG("Application registered claiming [ pid: %u, ppid: %d, uid: %u, gid: %u ]",
1891 reg_msg->pid, reg_msg->ppid, reg_msg->uid, reg_msg->gid);
1892 *pid = reg_msg->pid;
1893 *ppid = reg_msg->ppid;
1894 *uid = reg_msg->uid;
1895 *gid = reg_msg->gid;
1896 return 0;
1897}
1898#endif
1899
32ce8569
MD
1900/*
1901 * Returns 0 on success, negative error value on error.
1902 */
1903int ustctl_recv_reg_msg(int sock,
1904 enum ustctl_socket_type *type,
1905 uint32_t *major,
1906 uint32_t *minor,
1907 uint32_t *pid,
1908 uint32_t *ppid,
1909 uint32_t *uid,
1910 uint32_t *gid,
1911 uint32_t *bits_per_long,
1912 uint32_t *uint8_t_alignment,
1913 uint32_t *uint16_t_alignment,
1914 uint32_t *uint32_t_alignment,
1915 uint32_t *uint64_t_alignment,
1916 uint32_t *long_alignment,
1917 int *byte_order,
1918 char *name)
1919{
1920 ssize_t len;
1921 struct ustctl_reg_msg reg_msg;
1922
1923 len = ustcomm_recv_unix_sock(sock, &reg_msg, sizeof(reg_msg));
1924 if (len > 0 && len != sizeof(reg_msg))
1925 return -EIO;
1926 if (len == 0)
1927 return -EPIPE;
1928 if (len < 0)
1929 return len;
1930
1931 if (reg_msg.magic == LTTNG_UST_COMM_MAGIC) {
1932 *byte_order = BYTE_ORDER == BIG_ENDIAN ?
1933 BIG_ENDIAN : LITTLE_ENDIAN;
1934 } else if (reg_msg.magic == bswap_32(LTTNG_UST_COMM_MAGIC)) {
1935 *byte_order = BYTE_ORDER == BIG_ENDIAN ?
1936 LITTLE_ENDIAN : BIG_ENDIAN;
1937 } else {
1938 return -LTTNG_UST_ERR_INVAL_MAGIC;
1939 }
1940 switch (reg_msg.socket_type) {
1941 case 0: *type = USTCTL_SOCKET_CMD;
1942 break;
1943 case 1: *type = USTCTL_SOCKET_NOTIFY;
1944 break;
1945 default:
1946 return -LTTNG_UST_ERR_INVAL_SOCKET_TYPE;
1947 }
1948 *major = reg_msg.major;
1949 *minor = reg_msg.minor;
32ce8569
MD
1950 *bits_per_long = reg_msg.bits_per_long;
1951 *uint8_t_alignment = reg_msg.uint8_t_alignment;
1952 *uint16_t_alignment = reg_msg.uint16_t_alignment;
1953 *uint32_t_alignment = reg_msg.uint32_t_alignment;
1954 *uint64_t_alignment = reg_msg.uint64_t_alignment;
1955 *long_alignment = reg_msg.long_alignment;
1956 memcpy(name, reg_msg.name, LTTNG_UST_ABI_PROCNAME_LEN);
1957 if (reg_msg.major != LTTNG_UST_ABI_MAJOR_VERSION) {
1958 return -LTTNG_UST_ERR_UNSUP_MAJOR;
1959 }
4a07ff75 1960 return get_cred(sock, &reg_msg, pid, ppid, uid, gid);
32ce8569
MD
1961}
1962
1963int ustctl_recv_notify(int sock, enum ustctl_notify_cmd *notify_cmd)
1964{
1965 struct ustcomm_notify_hdr header;
1966 ssize_t len;
1967
1968 len = ustcomm_recv_unix_sock(sock, &header, sizeof(header));
1969 if (len > 0 && len != sizeof(header))
1970 return -EIO;
1971 if (len == 0)
1972 return -EPIPE;
1973 if (len < 0)
1974 return len;
1975 switch (header.notify_cmd) {
1976 case 0:
1977 *notify_cmd = USTCTL_NOTIFY_CMD_EVENT;
1978 break;
1979 case 1:
1980 *notify_cmd = USTCTL_NOTIFY_CMD_CHANNEL;
1981 break;
c785c634
MD
1982 case 2:
1983 *notify_cmd = USTCTL_NOTIFY_CMD_ENUM;
1984 break;
32ce8569
MD
1985 default:
1986 return -EINVAL;
1987 }
1988 return 0;
1989}
1990
1991/*
1992 * Returns 0 on success, negative error value on error.
1993 */
1994int ustctl_recv_register_event(int sock,
1995 int *session_objd,
1996 int *channel_objd,
1997 char *event_name,
1998 int *loglevel,
1999 char **signature,
2000 size_t *nr_fields,
2001 struct ustctl_field **fields,
2002 char **model_emf_uri)
2003{
2004 ssize_t len;
2005 struct ustcomm_notify_event_msg msg;
2006 size_t signature_len, fields_len, model_emf_uri_len;
2007 char *a_sign = NULL, *a_model_emf_uri = NULL;
2008 struct ustctl_field *a_fields = NULL;
2009
2010 len = ustcomm_recv_unix_sock(sock, &msg, sizeof(msg));
2011 if (len > 0 && len != sizeof(msg))
2012 return -EIO;
2013 if (len == 0)
2014 return -EPIPE;
2015 if (len < 0)
2016 return len;
2017
2018 *session_objd = msg.session_objd;
2019 *channel_objd = msg.channel_objd;
2020 strncpy(event_name, msg.event_name, LTTNG_UST_SYM_NAME_LEN);
2021 event_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
2022 *loglevel = msg.loglevel;
2023 signature_len = msg.signature_len;
2024 fields_len = msg.fields_len;
2025
2026 if (fields_len % sizeof(*a_fields) != 0) {
2027 return -EINVAL;
2028 }
2029
2030 model_emf_uri_len = msg.model_emf_uri_len;
2031
2032 /* recv signature. contains at least \0. */
2033 a_sign = zmalloc(signature_len);
2034 if (!a_sign)
2035 return -ENOMEM;
2036 len = ustcomm_recv_unix_sock(sock, a_sign, signature_len);
2037 if (len > 0 && len != signature_len) {
2038 len = -EIO;
2039 goto signature_error;
2040 }
2041 if (len == 0) {
2042 len = -EPIPE;
2043 goto signature_error;
2044 }
2045 if (len < 0) {
2046 goto signature_error;
2047 }
2048 /* Enforce end of string */
111198c2 2049 a_sign[signature_len - 1] = '\0';
32ce8569
MD
2050
2051 /* recv fields */
2052 if (fields_len) {
2053 a_fields = zmalloc(fields_len);
2054 if (!a_fields) {
2055 len = -ENOMEM;
2056 goto signature_error;
2057 }
2058 len = ustcomm_recv_unix_sock(sock, a_fields, fields_len);
2059 if (len > 0 && len != fields_len) {
2060 len = -EIO;
2061 goto fields_error;
2062 }
2063 if (len == 0) {
2064 len = -EPIPE;
2065 goto fields_error;
2066 }
2067 if (len < 0) {
2068 goto fields_error;
2069 }
2070 }
2071
2072 if (model_emf_uri_len) {
2073 /* recv model_emf_uri_len */
2074 a_model_emf_uri = zmalloc(model_emf_uri_len);
2075 if (!a_model_emf_uri) {
2076 len = -ENOMEM;
2077 goto fields_error;
2078 }
2079 len = ustcomm_recv_unix_sock(sock, a_model_emf_uri,
2080 model_emf_uri_len);
2081 if (len > 0 && len != model_emf_uri_len) {
2082 len = -EIO;
2083 goto model_error;
2084 }
2085 if (len == 0) {
2086 len = -EPIPE;
2087 goto model_error;
2088 }
2089 if (len < 0) {
2090 goto model_error;
2091 }
2092 /* Enforce end of string */
2093 a_model_emf_uri[model_emf_uri_len - 1] = '\0';
2094 }
2095
2096 *signature = a_sign;
2097 *nr_fields = fields_len / sizeof(*a_fields);
2098 *fields = a_fields;
2099 *model_emf_uri = a_model_emf_uri;
2100
2101 return 0;
2102
2103model_error:
2104 free(a_model_emf_uri);
2105fields_error:
2106 free(a_fields);
2107signature_error:
2108 free(a_sign);
2109 return len;
2110}
2111
2112/*
2113 * Returns 0 on success, negative error value on error.
2114 */
2115int ustctl_reply_register_event(int sock,
2116 uint32_t id,
2117 int ret_code)
2118{
2119 ssize_t len;
2120 struct {
2121 struct ustcomm_notify_hdr header;
2122 struct ustcomm_notify_event_reply r;
2123 } reply;
2124
2125 memset(&reply, 0, sizeof(reply));
2126 reply.header.notify_cmd = USTCTL_NOTIFY_CMD_EVENT;
2127 reply.r.ret_code = ret_code;
2128 reply.r.event_id = id;
2129 len = ustcomm_send_unix_sock(sock, &reply, sizeof(reply));
2130 if (len > 0 && len != sizeof(reply))
2131 return -EIO;
2132 if (len < 0)
2133 return len;
2134 return 0;
2135}
2136
c785c634
MD
2137/*
2138 * Returns 0 on success, negative UST or system error value on error.
2139 */
2140int ustctl_recv_register_enum(int sock,
2141 int *session_objd,
2142 char *enum_name,
2143 struct ustctl_enum_entry **entries,
2144 size_t *nr_entries)
2145{
2146 ssize_t len;
2147 struct ustcomm_notify_enum_msg msg;
2148 size_t entries_len;
2149 struct ustctl_enum_entry *a_entries = NULL;
2150
2151 len = ustcomm_recv_unix_sock(sock, &msg, sizeof(msg));
2152 if (len > 0 && len != sizeof(msg))
2153 return -EIO;
2154 if (len == 0)
2155 return -EPIPE;
2156 if (len < 0)
2157 return len;
2158
2159 *session_objd = msg.session_objd;
2160 strncpy(enum_name, msg.enum_name, LTTNG_UST_SYM_NAME_LEN);
2161 enum_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
2162 entries_len = msg.entries_len;
2163
2164 if (entries_len % sizeof(*a_entries) != 0) {
2165 return -EINVAL;
2166 }
2167
2168 /* recv entries */
2169 if (entries_len) {
2170 a_entries = zmalloc(entries_len);
2171 if (!a_entries)
2172 return -ENOMEM;
2173 len = ustcomm_recv_unix_sock(sock, a_entries, entries_len);
2174 if (len > 0 && len != entries_len) {
2175 len = -EIO;
2176 goto entries_error;
2177 }
2178 if (len == 0) {
2179 len = -EPIPE;
2180 goto entries_error;
2181 }
2182 if (len < 0) {
2183 goto entries_error;
2184 }
2185 }
2186 *nr_entries = entries_len / sizeof(*a_entries);
2187 *entries = a_entries;
2188
2189 return 0;
2190
2191entries_error:
2192 free(a_entries);
2193 return len;
2194}
2195
2196/*
2197 * Returns 0 on success, negative error value on error.
2198 */
2199int ustctl_reply_register_enum(int sock,
2200 uint64_t id,
2201 int ret_code)
2202{
2203 ssize_t len;
2204 struct {
2205 struct ustcomm_notify_hdr header;
2206 struct ustcomm_notify_enum_reply r;
2207 } reply;
2208
2209 memset(&reply, 0, sizeof(reply));
2210 reply.header.notify_cmd = USTCTL_NOTIFY_CMD_ENUM;
2211 reply.r.ret_code = ret_code;
2212 reply.r.enum_id = id;
2213 len = ustcomm_send_unix_sock(sock, &reply, sizeof(reply));
2214 if (len > 0 && len != sizeof(reply))
2215 return -EIO;
2216 if (len < 0)
2217 return len;
2218 return 0;
2219}
2220
32ce8569
MD
2221/*
2222 * Returns 0 on success, negative UST or system error value on error.
2223 */
2224int ustctl_recv_register_channel(int sock,
2225 int *session_objd, /* session descriptor (output) */
2226 int *channel_objd, /* channel descriptor (output) */
2227 size_t *nr_fields,
2228 struct ustctl_field **fields)
2229{
2230 ssize_t len;
2231 struct ustcomm_notify_channel_msg msg;
2232 size_t fields_len;
2233 struct ustctl_field *a_fields;
2234
2235 len = ustcomm_recv_unix_sock(sock, &msg, sizeof(msg));
2236 if (len > 0 && len != sizeof(msg))
2237 return -EIO;
2238 if (len == 0)
2239 return -EPIPE;
2240 if (len < 0)
2241 return len;
2242
2243 *session_objd = msg.session_objd;
2244 *channel_objd = msg.channel_objd;
2245 fields_len = msg.ctx_fields_len;
2246
2247 if (fields_len % sizeof(*a_fields) != 0) {
2248 return -EINVAL;
2249 }
2250
2251 /* recv fields */
2252 if (fields_len) {
2253 a_fields = zmalloc(fields_len);
2254 if (!a_fields) {
2255 len = -ENOMEM;
2256 goto alloc_error;
2257 }
2258 len = ustcomm_recv_unix_sock(sock, a_fields, fields_len);
2259 if (len > 0 && len != fields_len) {
2260 len = -EIO;
2261 goto fields_error;
2262 }
2263 if (len == 0) {
2264 len = -EPIPE;
2265 goto fields_error;
2266 }
2267 if (len < 0) {
2268 goto fields_error;
2269 }
2270 *fields = a_fields;
2271 } else {
2272 *fields = NULL;
2273 }
2274 *nr_fields = fields_len / sizeof(*a_fields);
2275 return 0;
2276
2277fields_error:
2278 free(a_fields);
2279alloc_error:
2280 return len;
2281}
2282
2283/*
2284 * Returns 0 on success, negative error value on error.
2285 */
2286int ustctl_reply_register_channel(int sock,
2287 uint32_t chan_id,
2288 enum ustctl_channel_header header_type,
2289 int ret_code)
2290{
2291 ssize_t len;
2292 struct {
2293 struct ustcomm_notify_hdr header;
2294 struct ustcomm_notify_channel_reply r;
2295 } reply;
2296
2297 memset(&reply, 0, sizeof(reply));
2298 reply.header.notify_cmd = USTCTL_NOTIFY_CMD_CHANNEL;
2299 reply.r.ret_code = ret_code;
2300 reply.r.chan_id = chan_id;
2301 switch (header_type) {
2302 case USTCTL_CHANNEL_HEADER_COMPACT:
2303 reply.r.header_type = 1;
2304 break;
2305 case USTCTL_CHANNEL_HEADER_LARGE:
2306 reply.r.header_type = 2;
2307 break;
2308 default:
2309 reply.r.header_type = 0;
2310 break;
2311 }
2312 len = ustcomm_send_unix_sock(sock, &reply, sizeof(reply));
2313 if (len > 0 && len != sizeof(reply))
2314 return -EIO;
2315 if (len < 0)
2316 return len;
2317 return 0;
2318}
2319
f53329f3
JD
2320/* Regenerate the statedump. */
2321int ustctl_regenerate_statedump(int sock, int handle)
2322{
2323 struct ustcomm_ust_msg lum;
2324 struct ustcomm_ust_reply lur;
2325 int ret;
2326
2327 memset(&lum, 0, sizeof(lum));
2328 lum.handle = handle;
2329 lum.cmd = LTTNG_UST_SESSION_STATEDUMP;
2330 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
2331 if (ret)
2332 return ret;
2333 DBG("Regenerated statedump for handle %u", handle);
2334 return 0;
2335}
2336
74d81a6c
MD
2337static __attribute__((constructor))
2338void ustctl_init(void)
2339{
2340 init_usterr();
6f626d28 2341 lttng_ust_getenv_init(); /* Needs init_usterr() to be completed. */
f9364363 2342 lttng_ust_clock_init();
74d81a6c
MD
2343 lttng_ring_buffer_metadata_client_init();
2344 lttng_ring_buffer_client_overwrite_init();
34a91bdb 2345 lttng_ring_buffer_client_overwrite_rt_init();
74d81a6c 2346 lttng_ring_buffer_client_discard_init();
34a91bdb 2347 lttng_ring_buffer_client_discard_rt_init();
03d2d293 2348 lib_ringbuffer_signal_init();
74d81a6c
MD
2349}
2350
2351static __attribute__((destructor))
2352void ustctl_exit(void)
2353{
34a91bdb 2354 lttng_ring_buffer_client_discard_rt_exit();
74d81a6c 2355 lttng_ring_buffer_client_discard_exit();
34a91bdb 2356 lttng_ring_buffer_client_overwrite_rt_exit();
74d81a6c
MD
2357 lttng_ring_buffer_client_overwrite_exit();
2358 lttng_ring_buffer_metadata_client_exit();
57773204 2359}
This page took 0.148139 seconds and 4 git commands to generate.