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