fix: Unify possible CPU number fallback
[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>
417db92e
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 }
2886e469 115 data->u.channel.wakeup_fd = -1;
ff0f5728 116 }
74d81a6c 117 free(data->u.channel.data);
2886e469 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 }
2886e469 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 }
2886e469 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) {
918 ret = errno;
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) {
954 ret = errno;
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) {
966 ret = errno;
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
b2f3252a
JD
1598static
1599struct lttng_ust_client_lib_ring_buffer_client_cb *get_client_cb(
1600 struct lttng_ust_lib_ring_buffer *buf,
1601 struct lttng_ust_shm_handle *handle)
1602{
1603 struct channel *chan;
1604 const struct lttng_ust_lib_ring_buffer_config *config;
1605 struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
1606
1607 chan = shmp(handle, buf->backend.chan);
34daae3e
MD
1608 if (!chan)
1609 return NULL;
b2f3252a
JD
1610 config = &chan->backend.config;
1611 if (!config->cb_ptr)
1612 return NULL;
1613 client_cb = caa_container_of(config->cb_ptr,
1614 struct lttng_ust_client_lib_ring_buffer_client_cb,
1615 parent);
1616 return client_cb;
1617}
1618
1619int ustctl_get_timestamp_begin(struct ustctl_consumer_stream *stream,
1620 uint64_t *timestamp_begin)
1621{
1622 struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
e1919a41
MD
1623 struct lttng_ust_lib_ring_buffer *buf;
1624 struct lttng_ust_shm_handle *handle;
b2f3252a
JD
1625
1626 if (!stream || !timestamp_begin)
1627 return -EINVAL;
e1919a41
MD
1628 buf = stream->buf;
1629 handle = stream->chan->chan->handle;
b2f3252a
JD
1630 client_cb = get_client_cb(buf, handle);
1631 if (!client_cb)
1632 return -ENOSYS;
1633 return client_cb->timestamp_begin(buf, handle, timestamp_begin);
1634}
1635
1636int ustctl_get_timestamp_end(struct ustctl_consumer_stream *stream,
1637 uint64_t *timestamp_end)
1638{
1639 struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
e1919a41
MD
1640 struct lttng_ust_lib_ring_buffer *buf;
1641 struct lttng_ust_shm_handle *handle;
b2f3252a
JD
1642
1643 if (!stream || !timestamp_end)
1644 return -EINVAL;
e1919a41
MD
1645 buf = stream->buf;
1646 handle = stream->chan->chan->handle;
b2f3252a
JD
1647 client_cb = get_client_cb(buf, handle);
1648 if (!client_cb)
1649 return -ENOSYS;
1650 return client_cb->timestamp_end(buf, handle, timestamp_end);
1651}
1652
1653int ustctl_get_events_discarded(struct ustctl_consumer_stream *stream,
1654 uint64_t *events_discarded)
1655{
1656 struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
e1919a41
MD
1657 struct lttng_ust_lib_ring_buffer *buf;
1658 struct lttng_ust_shm_handle *handle;
b2f3252a
JD
1659
1660 if (!stream || !events_discarded)
1661 return -EINVAL;
e1919a41
MD
1662 buf = stream->buf;
1663 handle = stream->chan->chan->handle;
b2f3252a
JD
1664 client_cb = get_client_cb(buf, handle);
1665 if (!client_cb)
1666 return -ENOSYS;
1667 return client_cb->events_discarded(buf, handle, events_discarded);
1668}
1669
1670int ustctl_get_content_size(struct ustctl_consumer_stream *stream,
1671 uint64_t *content_size)
1672{
1673 struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
e1919a41
MD
1674 struct lttng_ust_lib_ring_buffer *buf;
1675 struct lttng_ust_shm_handle *handle;
b2f3252a
JD
1676
1677 if (!stream || !content_size)
1678 return -EINVAL;
e1919a41
MD
1679 buf = stream->buf;
1680 handle = stream->chan->chan->handle;
b2f3252a
JD
1681 client_cb = get_client_cb(buf, handle);
1682 if (!client_cb)
1683 return -ENOSYS;
1684 return client_cb->content_size(buf, handle, content_size);
1685}
1686
1687int ustctl_get_packet_size(struct ustctl_consumer_stream *stream,
1688 uint64_t *packet_size)
1689{
1690 struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
e1919a41
MD
1691 struct lttng_ust_lib_ring_buffer *buf;
1692 struct lttng_ust_shm_handle *handle;
b2f3252a
JD
1693
1694 if (!stream || !packet_size)
1695 return -EINVAL;
e1919a41
MD
1696 buf = stream->buf;
1697 handle = stream->chan->chan->handle;
b2f3252a
JD
1698 client_cb = get_client_cb(buf, handle);
1699 if (!client_cb)
1700 return -ENOSYS;
1701 return client_cb->packet_size(buf, handle, packet_size);
1702}
1703
1704int ustctl_get_stream_id(struct ustctl_consumer_stream *stream,
1705 uint64_t *stream_id)
1706{
1707 struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
e1919a41
MD
1708 struct lttng_ust_lib_ring_buffer *buf;
1709 struct lttng_ust_shm_handle *handle;
b2f3252a
JD
1710
1711 if (!stream || !stream_id)
1712 return -EINVAL;
e1919a41
MD
1713 buf = stream->buf;
1714 handle = stream->chan->chan->handle;
b2f3252a
JD
1715 client_cb = get_client_cb(buf, handle);
1716 if (!client_cb)
1717 return -ENOSYS;
1718 return client_cb->stream_id(buf, handle, stream_id);
1719}
1720
fca361e8
JD
1721int ustctl_get_current_timestamp(struct ustctl_consumer_stream *stream,
1722 uint64_t *ts)
1723{
1724 struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
e1919a41
MD
1725 struct lttng_ust_lib_ring_buffer *buf;
1726 struct lttng_ust_shm_handle *handle;
fca361e8
JD
1727
1728 if (!stream || !ts)
1729 return -EINVAL;
e1919a41
MD
1730 buf = stream->buf;
1731 handle = stream->chan->chan->handle;
fca361e8
JD
1732 client_cb = get_client_cb(buf, handle);
1733 if (!client_cb || !client_cb->current_timestamp)
1734 return -ENOSYS;
1735 return client_cb->current_timestamp(buf, handle, ts);
1736}
1737
1ff31389
JD
1738int ustctl_get_sequence_number(struct ustctl_consumer_stream *stream,
1739 uint64_t *seq)
1740{
1741 struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
1742 struct lttng_ust_lib_ring_buffer *buf;
1743 struct lttng_ust_shm_handle *handle;
1744
1745 if (!stream || !seq)
1746 return -EINVAL;
1747 buf = stream->buf;
1748 handle = stream->chan->chan->handle;
1749 client_cb = get_client_cb(buf, handle);
1750 if (!client_cb || !client_cb->sequence_number)
1751 return -ENOSYS;
1752 return client_cb->sequence_number(buf, handle, seq);
1753}
1754
45a00b05
JD
1755int ustctl_get_instance_id(struct ustctl_consumer_stream *stream,
1756 uint64_t *id)
1757{
1758 struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
1759 struct lttng_ust_lib_ring_buffer *buf;
1760 struct lttng_ust_shm_handle *handle;
1761
1762 if (!stream || !id)
1763 return -EINVAL;
1764 buf = stream->buf;
1765 handle = stream->chan->chan->handle;
1766 client_cb = get_client_cb(buf, handle);
1767 if (!client_cb)
1768 return -ENOSYS;
1769 return client_cb->instance_id(buf, handle, id);
1770}
1771
c62a3816 1772#ifdef LTTNG_UST_HAVE_PERF_EVENT
57201bb3
MD
1773
1774int ustctl_has_perf_counters(void)
1775{
1776 return 1;
1777}
1778
1779#else
1780
1781int ustctl_has_perf_counters(void)
1782{
1783 return 0;
1784}
1785
1786#endif
1787
417db92e
MD
1788#ifdef __linux__
1789/*
1790 * Override application pid/uid/gid with unix socket credentials. If
1791 * the application announced a pid matching our view, it means it is
1792 * within the same pid namespace, so expose the ppid provided by the
1793 * application.
1794 */
1795static
1796int get_cred(int sock,
1797 const struct ustctl_reg_msg *reg_msg,
1798 uint32_t *pid,
1799 uint32_t *ppid,
1800 uint32_t *uid,
1801 uint32_t *gid)
1802{
1803 struct ucred ucred;
1804 socklen_t ucred_len = sizeof(struct ucred);
1805 int ret;
1806
1807 ret = getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &ucred, &ucred_len);
1808 if (ret) {
1809 return -LTTNG_UST_ERR_PEERCRED;
1810 }
1811 DBG("Unix socket peercred [ pid: %u, uid: %u, gid: %u ], "
1812 "application registered claiming [ pid: %u, ppid: %u, uid: %u, gid: %u ]",
1813 ucred.pid, ucred.uid, ucred.gid,
1814 reg_msg->pid, reg_msg->ppid, reg_msg->uid, reg_msg->gid);
1815 if (!ucred.pid) {
1816 ERR("Unix socket credential pid=0. Refusing application in distinct, non-nested pid namespace.");
1817 return -LTTNG_UST_ERR_PEERCRED_PID;
1818 }
1819 *pid = ucred.pid;
1820 *uid = ucred.uid;
1821 *gid = ucred.gid;
1822 if (ucred.pid == reg_msg->pid) {
1823 *ppid = reg_msg->ppid;
1824 } else {
1825 *ppid = 0;
1826 }
1827 return 0;
1828}
1829#elif defined(__FreeBSD__)
1830#include <sys/ucred.h>
5d519a99 1831#include <sys/un.h>
417db92e
MD
1832
1833/*
1834 * Override application uid/gid with unix socket credentials. Use the
1835 * first group of the cr_groups.
1836 * Use the pid and ppid provided by the application on registration.
1837 */
1838static
1839int get_cred(int sock,
1840 const struct ustctl_reg_msg *reg_msg,
1841 uint32_t *pid,
1842 uint32_t *ppid,
1843 uint32_t *uid,
1844 uint32_t *gid)
1845{
1846 struct xucred xucred;
1847 socklen_t xucred_len = sizeof(struct xucred);
1848 int ret;
1849
1850 ret = getsockopt(sock, SOL_SOCKET, LOCAL_PEERCRED, &xucred, &xucred_len);
1851 if (ret) {
1852 return -LTTNG_UST_ERR_PEERCRED;
1853 }
1854 if (xucred.cr_version != XUCRED_VERSION || xucred.cr_ngroups < 1) {
1855 return -LTTNG_UST_ERR_PEERCRED;
1856 }
1857 DBG("Unix socket peercred [ uid: %u, gid: %u ], "
1858 "application registered claiming [ pid: %d, ppid: %d, uid: %u, gid: %u ]",
5d519a99 1859 xucred.cr_uid, xucred.cr_groups[0],
417db92e
MD
1860 reg_msg->pid, reg_msg->ppid, reg_msg->uid, reg_msg->gid);
1861 *pid = reg_msg->pid;
1862 *ppid = reg_msg->ppid;
5d519a99 1863 *uid = xucred.cr_uid;
417db92e
MD
1864 *gid = xucred.cr_groups[0];
1865 return 0;
1866}
1867#else
1868#warning "Using insecure fallback: trusting user id provided by registered applications. Please consider implementing use of unix socket credentials on your platform."
1869static
1870int get_cred(int sock,
1871 const struct ustctl_reg_msg *reg_msg,
1872 uint32_t *pid,
1873 uint32_t *ppid,
1874 uint32_t *uid,
1875 uint32_t *gid)
1876{
1877 DBG("Application registered claiming [ pid: %u, ppid: %d, uid: %u, gid: %u ]",
1878 reg_msg->pid, reg_msg->ppid, reg_msg->uid, reg_msg->gid);
1879 *pid = reg_msg->pid;
1880 *ppid = reg_msg->ppid;
1881 *uid = reg_msg->uid;
1882 *gid = reg_msg->gid;
1883 return 0;
1884}
1885#endif
1886
32ce8569
MD
1887/*
1888 * Returns 0 on success, negative error value on error.
1889 */
1890int ustctl_recv_reg_msg(int sock,
1891 enum ustctl_socket_type *type,
1892 uint32_t *major,
1893 uint32_t *minor,
1894 uint32_t *pid,
1895 uint32_t *ppid,
1896 uint32_t *uid,
1897 uint32_t *gid,
1898 uint32_t *bits_per_long,
1899 uint32_t *uint8_t_alignment,
1900 uint32_t *uint16_t_alignment,
1901 uint32_t *uint32_t_alignment,
1902 uint32_t *uint64_t_alignment,
1903 uint32_t *long_alignment,
1904 int *byte_order,
1905 char *name)
1906{
1907 ssize_t len;
1908 struct ustctl_reg_msg reg_msg;
1909
1910 len = ustcomm_recv_unix_sock(sock, &reg_msg, sizeof(reg_msg));
1911 if (len > 0 && len != sizeof(reg_msg))
1912 return -EIO;
1913 if (len == 0)
1914 return -EPIPE;
1915 if (len < 0)
1916 return len;
1917
1918 if (reg_msg.magic == LTTNG_UST_COMM_MAGIC) {
1919 *byte_order = BYTE_ORDER == BIG_ENDIAN ?
1920 BIG_ENDIAN : LITTLE_ENDIAN;
1921 } else if (reg_msg.magic == bswap_32(LTTNG_UST_COMM_MAGIC)) {
1922 *byte_order = BYTE_ORDER == BIG_ENDIAN ?
1923 LITTLE_ENDIAN : BIG_ENDIAN;
1924 } else {
1925 return -LTTNG_UST_ERR_INVAL_MAGIC;
1926 }
1927 switch (reg_msg.socket_type) {
1928 case 0: *type = USTCTL_SOCKET_CMD;
1929 break;
1930 case 1: *type = USTCTL_SOCKET_NOTIFY;
1931 break;
1932 default:
1933 return -LTTNG_UST_ERR_INVAL_SOCKET_TYPE;
1934 }
1935 *major = reg_msg.major;
1936 *minor = reg_msg.minor;
32ce8569
MD
1937 *bits_per_long = reg_msg.bits_per_long;
1938 *uint8_t_alignment = reg_msg.uint8_t_alignment;
1939 *uint16_t_alignment = reg_msg.uint16_t_alignment;
1940 *uint32_t_alignment = reg_msg.uint32_t_alignment;
1941 *uint64_t_alignment = reg_msg.uint64_t_alignment;
1942 *long_alignment = reg_msg.long_alignment;
1943 memcpy(name, reg_msg.name, LTTNG_UST_ABI_PROCNAME_LEN);
1944 if (reg_msg.major != LTTNG_UST_ABI_MAJOR_VERSION) {
1945 return -LTTNG_UST_ERR_UNSUP_MAJOR;
1946 }
417db92e 1947 return get_cred(sock, &reg_msg, pid, ppid, uid, gid);
32ce8569
MD
1948}
1949
1950int ustctl_recv_notify(int sock, enum ustctl_notify_cmd *notify_cmd)
1951{
1952 struct ustcomm_notify_hdr header;
1953 ssize_t len;
1954
1955 len = ustcomm_recv_unix_sock(sock, &header, sizeof(header));
1956 if (len > 0 && len != sizeof(header))
1957 return -EIO;
1958 if (len == 0)
1959 return -EPIPE;
1960 if (len < 0)
1961 return len;
1962 switch (header.notify_cmd) {
1963 case 0:
1964 *notify_cmd = USTCTL_NOTIFY_CMD_EVENT;
1965 break;
1966 case 1:
1967 *notify_cmd = USTCTL_NOTIFY_CMD_CHANNEL;
1968 break;
c785c634
MD
1969 case 2:
1970 *notify_cmd = USTCTL_NOTIFY_CMD_ENUM;
1971 break;
32ce8569
MD
1972 default:
1973 return -EINVAL;
1974 }
1975 return 0;
1976}
1977
1978/*
1979 * Returns 0 on success, negative error value on error.
1980 */
1981int ustctl_recv_register_event(int sock,
1982 int *session_objd,
1983 int *channel_objd,
1984 char *event_name,
1985 int *loglevel,
1986 char **signature,
1987 size_t *nr_fields,
1988 struct ustctl_field **fields,
1989 char **model_emf_uri)
1990{
1991 ssize_t len;
1992 struct ustcomm_notify_event_msg msg;
1993 size_t signature_len, fields_len, model_emf_uri_len;
1994 char *a_sign = NULL, *a_model_emf_uri = NULL;
1995 struct ustctl_field *a_fields = NULL;
1996
1997 len = ustcomm_recv_unix_sock(sock, &msg, sizeof(msg));
1998 if (len > 0 && len != sizeof(msg))
1999 return -EIO;
2000 if (len == 0)
2001 return -EPIPE;
2002 if (len < 0)
2003 return len;
2004
2005 *session_objd = msg.session_objd;
2006 *channel_objd = msg.channel_objd;
2007 strncpy(event_name, msg.event_name, LTTNG_UST_SYM_NAME_LEN);
2008 event_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
2009 *loglevel = msg.loglevel;
2010 signature_len = msg.signature_len;
2011 fields_len = msg.fields_len;
2012
2013 if (fields_len % sizeof(*a_fields) != 0) {
2014 return -EINVAL;
2015 }
2016
2017 model_emf_uri_len = msg.model_emf_uri_len;
2018
2019 /* recv signature. contains at least \0. */
2020 a_sign = zmalloc(signature_len);
2021 if (!a_sign)
2022 return -ENOMEM;
2023 len = ustcomm_recv_unix_sock(sock, a_sign, signature_len);
2024 if (len > 0 && len != signature_len) {
2025 len = -EIO;
2026 goto signature_error;
2027 }
2028 if (len == 0) {
2029 len = -EPIPE;
2030 goto signature_error;
2031 }
2032 if (len < 0) {
2033 goto signature_error;
2034 }
2035 /* Enforce end of string */
111198c2 2036 a_sign[signature_len - 1] = '\0';
32ce8569
MD
2037
2038 /* recv fields */
2039 if (fields_len) {
2040 a_fields = zmalloc(fields_len);
2041 if (!a_fields) {
2042 len = -ENOMEM;
2043 goto signature_error;
2044 }
2045 len = ustcomm_recv_unix_sock(sock, a_fields, fields_len);
2046 if (len > 0 && len != fields_len) {
2047 len = -EIO;
2048 goto fields_error;
2049 }
2050 if (len == 0) {
2051 len = -EPIPE;
2052 goto fields_error;
2053 }
2054 if (len < 0) {
2055 goto fields_error;
2056 }
2057 }
2058
2059 if (model_emf_uri_len) {
2060 /* recv model_emf_uri_len */
2061 a_model_emf_uri = zmalloc(model_emf_uri_len);
2062 if (!a_model_emf_uri) {
2063 len = -ENOMEM;
2064 goto fields_error;
2065 }
2066 len = ustcomm_recv_unix_sock(sock, a_model_emf_uri,
2067 model_emf_uri_len);
2068 if (len > 0 && len != model_emf_uri_len) {
2069 len = -EIO;
2070 goto model_error;
2071 }
2072 if (len == 0) {
2073 len = -EPIPE;
2074 goto model_error;
2075 }
2076 if (len < 0) {
2077 goto model_error;
2078 }
2079 /* Enforce end of string */
2080 a_model_emf_uri[model_emf_uri_len - 1] = '\0';
2081 }
2082
2083 *signature = a_sign;
2084 *nr_fields = fields_len / sizeof(*a_fields);
2085 *fields = a_fields;
2086 *model_emf_uri = a_model_emf_uri;
2087
2088 return 0;
2089
2090model_error:
2091 free(a_model_emf_uri);
2092fields_error:
2093 free(a_fields);
2094signature_error:
2095 free(a_sign);
2096 return len;
2097}
2098
2099/*
2100 * Returns 0 on success, negative error value on error.
2101 */
2102int ustctl_reply_register_event(int sock,
2103 uint32_t id,
2104 int ret_code)
2105{
2106 ssize_t len;
2107 struct {
2108 struct ustcomm_notify_hdr header;
2109 struct ustcomm_notify_event_reply r;
2110 } reply;
2111
2112 memset(&reply, 0, sizeof(reply));
2113 reply.header.notify_cmd = USTCTL_NOTIFY_CMD_EVENT;
2114 reply.r.ret_code = ret_code;
2115 reply.r.event_id = id;
2116 len = ustcomm_send_unix_sock(sock, &reply, sizeof(reply));
2117 if (len > 0 && len != sizeof(reply))
2118 return -EIO;
2119 if (len < 0)
2120 return len;
2121 return 0;
2122}
2123
c785c634
MD
2124/*
2125 * Returns 0 on success, negative UST or system error value on error.
2126 */
2127int ustctl_recv_register_enum(int sock,
2128 int *session_objd,
2129 char *enum_name,
2130 struct ustctl_enum_entry **entries,
2131 size_t *nr_entries)
2132{
2133 ssize_t len;
2134 struct ustcomm_notify_enum_msg msg;
2135 size_t entries_len;
2136 struct ustctl_enum_entry *a_entries = NULL;
2137
2138 len = ustcomm_recv_unix_sock(sock, &msg, sizeof(msg));
2139 if (len > 0 && len != sizeof(msg))
2140 return -EIO;
2141 if (len == 0)
2142 return -EPIPE;
2143 if (len < 0)
2144 return len;
2145
2146 *session_objd = msg.session_objd;
2147 strncpy(enum_name, msg.enum_name, LTTNG_UST_SYM_NAME_LEN);
2148 enum_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
2149 entries_len = msg.entries_len;
2150
2151 if (entries_len % sizeof(*a_entries) != 0) {
2152 return -EINVAL;
2153 }
2154
2155 /* recv entries */
2156 if (entries_len) {
2157 a_entries = zmalloc(entries_len);
2158 if (!a_entries)
2159 return -ENOMEM;
2160 len = ustcomm_recv_unix_sock(sock, a_entries, entries_len);
2161 if (len > 0 && len != entries_len) {
2162 len = -EIO;
2163 goto entries_error;
2164 }
2165 if (len == 0) {
2166 len = -EPIPE;
2167 goto entries_error;
2168 }
2169 if (len < 0) {
2170 goto entries_error;
2171 }
2172 }
2173 *nr_entries = entries_len / sizeof(*a_entries);
2174 *entries = a_entries;
2175
2176 return 0;
2177
2178entries_error:
2179 free(a_entries);
2180 return len;
2181}
2182
2183/*
2184 * Returns 0 on success, negative error value on error.
2185 */
2186int ustctl_reply_register_enum(int sock,
2187 uint64_t id,
2188 int ret_code)
2189{
2190 ssize_t len;
2191 struct {
2192 struct ustcomm_notify_hdr header;
2193 struct ustcomm_notify_enum_reply r;
2194 } reply;
2195
2196 memset(&reply, 0, sizeof(reply));
2197 reply.header.notify_cmd = USTCTL_NOTIFY_CMD_ENUM;
2198 reply.r.ret_code = ret_code;
2199 reply.r.enum_id = id;
2200 len = ustcomm_send_unix_sock(sock, &reply, sizeof(reply));
2201 if (len > 0 && len != sizeof(reply))
2202 return -EIO;
2203 if (len < 0)
2204 return len;
2205 return 0;
2206}
2207
32ce8569
MD
2208/*
2209 * Returns 0 on success, negative UST or system error value on error.
2210 */
2211int ustctl_recv_register_channel(int sock,
2212 int *session_objd, /* session descriptor (output) */
2213 int *channel_objd, /* channel descriptor (output) */
2214 size_t *nr_fields,
2215 struct ustctl_field **fields)
2216{
2217 ssize_t len;
2218 struct ustcomm_notify_channel_msg msg;
2219 size_t fields_len;
2220 struct ustctl_field *a_fields;
2221
2222 len = ustcomm_recv_unix_sock(sock, &msg, sizeof(msg));
2223 if (len > 0 && len != sizeof(msg))
2224 return -EIO;
2225 if (len == 0)
2226 return -EPIPE;
2227 if (len < 0)
2228 return len;
2229
2230 *session_objd = msg.session_objd;
2231 *channel_objd = msg.channel_objd;
2232 fields_len = msg.ctx_fields_len;
2233
2234 if (fields_len % sizeof(*a_fields) != 0) {
2235 return -EINVAL;
2236 }
2237
2238 /* recv fields */
2239 if (fields_len) {
2240 a_fields = zmalloc(fields_len);
2241 if (!a_fields) {
2242 len = -ENOMEM;
2243 goto alloc_error;
2244 }
2245 len = ustcomm_recv_unix_sock(sock, a_fields, fields_len);
2246 if (len > 0 && len != fields_len) {
2247 len = -EIO;
2248 goto fields_error;
2249 }
2250 if (len == 0) {
2251 len = -EPIPE;
2252 goto fields_error;
2253 }
2254 if (len < 0) {
2255 goto fields_error;
2256 }
2257 *fields = a_fields;
2258 } else {
2259 *fields = NULL;
2260 }
2261 *nr_fields = fields_len / sizeof(*a_fields);
2262 return 0;
2263
2264fields_error:
2265 free(a_fields);
2266alloc_error:
2267 return len;
2268}
2269
2270/*
2271 * Returns 0 on success, negative error value on error.
2272 */
2273int ustctl_reply_register_channel(int sock,
2274 uint32_t chan_id,
2275 enum ustctl_channel_header header_type,
2276 int ret_code)
2277{
2278 ssize_t len;
2279 struct {
2280 struct ustcomm_notify_hdr header;
2281 struct ustcomm_notify_channel_reply r;
2282 } reply;
2283
2284 memset(&reply, 0, sizeof(reply));
2285 reply.header.notify_cmd = USTCTL_NOTIFY_CMD_CHANNEL;
2286 reply.r.ret_code = ret_code;
2287 reply.r.chan_id = chan_id;
2288 switch (header_type) {
2289 case USTCTL_CHANNEL_HEADER_COMPACT:
2290 reply.r.header_type = 1;
2291 break;
2292 case USTCTL_CHANNEL_HEADER_LARGE:
2293 reply.r.header_type = 2;
2294 break;
2295 default:
2296 reply.r.header_type = 0;
2297 break;
2298 }
2299 len = ustcomm_send_unix_sock(sock, &reply, sizeof(reply));
2300 if (len > 0 && len != sizeof(reply))
2301 return -EIO;
2302 if (len < 0)
2303 return len;
2304 return 0;
2305}
2306
f53329f3
JD
2307/* Regenerate the statedump. */
2308int ustctl_regenerate_statedump(int sock, int handle)
2309{
2310 struct ustcomm_ust_msg lum;
2311 struct ustcomm_ust_reply lur;
2312 int ret;
2313
2314 memset(&lum, 0, sizeof(lum));
2315 lum.handle = handle;
2316 lum.cmd = LTTNG_UST_SESSION_STATEDUMP;
2317 ret = ustcomm_send_app_cmd(sock, &lum, &lur);
2318 if (ret)
2319 return ret;
2320 DBG("Regenerated statedump for handle %u", handle);
2321 return 0;
2322}
2323
74d81a6c
MD
2324static __attribute__((constructor))
2325void ustctl_init(void)
2326{
2327 init_usterr();
6f626d28 2328 lttng_ust_getenv_init(); /* Needs init_usterr() to be completed. */
f9364363 2329 lttng_ust_clock_init();
74d81a6c
MD
2330 lttng_ring_buffer_metadata_client_init();
2331 lttng_ring_buffer_client_overwrite_init();
34a91bdb 2332 lttng_ring_buffer_client_overwrite_rt_init();
74d81a6c 2333 lttng_ring_buffer_client_discard_init();
34a91bdb 2334 lttng_ring_buffer_client_discard_rt_init();
03d2d293 2335 lib_ringbuffer_signal_init();
74d81a6c
MD
2336}
2337
2338static __attribute__((destructor))
2339void ustctl_exit(void)
2340{
34a91bdb 2341 lttng_ring_buffer_client_discard_rt_exit();
74d81a6c 2342 lttng_ring_buffer_client_discard_exit();
34a91bdb 2343 lttng_ring_buffer_client_overwrite_rt_exit();
74d81a6c
MD
2344 lttng_ring_buffer_client_overwrite_exit();
2345 lttng_ring_buffer_metadata_client_exit();
57773204 2346}
This page took 0.133797 seconds and 4 git commands to generate.