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