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