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