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