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