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