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