2adb127ee96d07cafba669055c01b3fc9e2e5b0e
[lttng-ust.git] / src / lib / lttng-ust / lttng-ust-abi.c
1 /*
2 * SPDX-License-Identifier: LGPL-2.1-only
3 *
4 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 *
6 * LTTng UST ABI
7 *
8 * Mimic system calls for:
9 * - session creation, returns an object descriptor or failure.
10 * - channel creation, returns an object descriptor or failure.
11 * - Operates on a session object descriptor
12 * - Takes all channel options as parameters.
13 * - stream get, returns an object descriptor or failure.
14 * - Operates on a channel object descriptor.
15 * - stream notifier get, returns an object descriptor or failure.
16 * - Operates on a channel object descriptor.
17 * - event creation, returns an object descriptor or failure.
18 * - Operates on a channel object descriptor
19 * - Takes an event name as parameter
20 * - Takes an instrumentation source as parameter
21 * - e.g. tracepoints, dynamic_probes...
22 * - Takes instrumentation source specific arguments.
23 */
24
25 #define _LGPL_SOURCE
26 #include <fcntl.h>
27 #include <stdint.h>
28 #include <unistd.h>
29
30 #include <urcu/compiler.h>
31 #include <urcu/list.h>
32
33 #include <lttng/tracepoint.h>
34 #include <lttng/ust-abi.h>
35 #include <lttng/ust-error.h>
36 #include <lttng/ust-events.h>
37 #include <lttng/ust-version.h>
38
39 #include "common/ust-fd.h"
40 #include "common/logging.h"
41 #include "common/align.h"
42
43 #include "common/ringbuffer/frontend_types.h"
44 #include "common/ringbuffer/frontend.h"
45 #include "common/ringbuffer/shm.h"
46 #include "common/counter/counter.h"
47 #include "common/tracepoint.h"
48 #include "common/tracer.h"
49 #include "common/strutils.h"
50 #include "lib/lttng-ust/events.h"
51 #include "lib/lttng-ust/lttng-tracer-core.h"
52 #include "context-internal.h"
53 #include "common/macros.h"
54
55 #define OBJ_NAME_LEN 16
56
57 static int lttng_ust_abi_close_in_progress;
58
59 static
60 int lttng_abi_tracepoint_list(void *owner);
61 static
62 int lttng_abi_tracepoint_field_list(void *owner);
63
64 /*
65 * Object descriptor table. Should be protected from concurrent access
66 * by the caller.
67 */
68
69 struct lttng_ust_abi_obj {
70 union {
71 struct {
72 void *private_data;
73 const struct lttng_ust_abi_objd_ops *ops;
74 int f_count;
75 int owner_ref; /* has ref from owner */
76 void *owner;
77 char name[OBJ_NAME_LEN];
78 } s;
79 int freelist_next; /* offset freelist. end is -1. */
80 } u;
81 };
82
83 struct lttng_ust_abi_objd_table {
84 struct lttng_ust_abi_obj *array;
85 unsigned int len, allocated_len;
86 int freelist_head; /* offset freelist head. end is -1 */
87 };
88
89 static struct lttng_ust_abi_objd_table objd_table = {
90 .freelist_head = -1,
91 };
92
93 static
94 int objd_alloc(void *private_data, const struct lttng_ust_abi_objd_ops *ops,
95 void *owner, const char *name)
96 {
97 struct lttng_ust_abi_obj *obj;
98
99 if (objd_table.freelist_head != -1) {
100 obj = &objd_table.array[objd_table.freelist_head];
101 objd_table.freelist_head = obj->u.freelist_next;
102 goto end;
103 }
104
105 if (objd_table.len >= objd_table.allocated_len) {
106 unsigned int new_allocated_len, old_allocated_len;
107 struct lttng_ust_abi_obj *new_table, *old_table;
108
109 old_allocated_len = objd_table.allocated_len;
110 old_table = objd_table.array;
111 if (!old_allocated_len)
112 new_allocated_len = 1;
113 else
114 new_allocated_len = old_allocated_len << 1;
115 new_table = zmalloc(sizeof(struct lttng_ust_abi_obj) * new_allocated_len);
116 if (!new_table)
117 return -ENOMEM;
118 memcpy(new_table, old_table,
119 sizeof(struct lttng_ust_abi_obj) * old_allocated_len);
120 free(old_table);
121 objd_table.array = new_table;
122 objd_table.allocated_len = new_allocated_len;
123 }
124 obj = &objd_table.array[objd_table.len];
125 objd_table.len++;
126 end:
127 obj->u.s.private_data = private_data;
128 obj->u.s.ops = ops;
129 obj->u.s.f_count = 2; /* count == 1 : object is allocated */
130 /* count == 2 : allocated + hold ref */
131 obj->u.s.owner_ref = 1; /* One owner reference */
132 obj->u.s.owner = owner;
133 strncpy(obj->u.s.name, name, OBJ_NAME_LEN);
134 obj->u.s.name[OBJ_NAME_LEN - 1] = '\0';
135 return obj - objd_table.array;
136 }
137
138 static
139 struct lttng_ust_abi_obj *_objd_get(int id)
140 {
141 if (id >= objd_table.len)
142 return NULL;
143 if (!objd_table.array[id].u.s.f_count)
144 return NULL;
145 return &objd_table.array[id];
146 }
147
148 static
149 void *objd_private(int id)
150 {
151 struct lttng_ust_abi_obj *obj = _objd_get(id);
152 assert(obj);
153 return obj->u.s.private_data;
154 }
155
156 static
157 void objd_set_private(int id, void *private_data)
158 {
159 struct lttng_ust_abi_obj *obj = _objd_get(id);
160 assert(obj);
161 obj->u.s.private_data = private_data;
162 }
163
164 const struct lttng_ust_abi_objd_ops *lttng_ust_abi_objd_ops(int id)
165 {
166 struct lttng_ust_abi_obj *obj = _objd_get(id);
167
168 if (!obj)
169 return NULL;
170 return obj->u.s.ops;
171 }
172
173 static
174 void objd_free(int id)
175 {
176 struct lttng_ust_abi_obj *obj = _objd_get(id);
177
178 assert(obj);
179 obj->u.freelist_next = objd_table.freelist_head;
180 objd_table.freelist_head = obj - objd_table.array;
181 assert(obj->u.s.f_count == 1);
182 obj->u.s.f_count = 0; /* deallocated */
183 }
184
185 static
186 void objd_ref(int id)
187 {
188 struct lttng_ust_abi_obj *obj = _objd_get(id);
189 assert(obj != NULL);
190 obj->u.s.f_count++;
191 }
192
193 int lttng_ust_abi_objd_unref(int id, int is_owner)
194 {
195 struct lttng_ust_abi_obj *obj = _objd_get(id);
196
197 if (!obj)
198 return -EINVAL;
199 if (obj->u.s.f_count == 1) {
200 ERR("Reference counting error\n");
201 return -EINVAL;
202 }
203 if (is_owner) {
204 if (!obj->u.s.owner_ref) {
205 ERR("Error decrementing owner reference");
206 return -EINVAL;
207 }
208 obj->u.s.owner_ref--;
209 }
210 if ((--obj->u.s.f_count) == 1) {
211 const struct lttng_ust_abi_objd_ops *ops = lttng_ust_abi_objd_ops(id);
212
213 if (ops->release)
214 ops->release(id);
215 objd_free(id);
216 }
217 return 0;
218 }
219
220 static
221 void objd_table_destroy(void)
222 {
223 int i;
224
225 for (i = 0; i < objd_table.allocated_len; i++) {
226 struct lttng_ust_abi_obj *obj;
227
228 obj = _objd_get(i);
229 if (!obj)
230 continue;
231 if (!obj->u.s.owner_ref)
232 continue; /* only unref owner ref. */
233 (void) lttng_ust_abi_objd_unref(i, 1);
234 }
235 free(objd_table.array);
236 objd_table.array = NULL;
237 objd_table.len = 0;
238 objd_table.allocated_len = 0;
239 objd_table.freelist_head = -1;
240 }
241
242 const char *lttng_ust_obj_get_name(int id)
243 {
244 struct lttng_ust_abi_obj *obj = _objd_get(id);
245
246 if (!obj)
247 return NULL;
248 return obj->u.s.name;
249 }
250
251 void lttng_ust_abi_objd_table_owner_cleanup(void *owner)
252 {
253 int i;
254
255 for (i = 0; i < objd_table.allocated_len; i++) {
256 struct lttng_ust_abi_obj *obj;
257
258 obj = _objd_get(i);
259 if (!obj)
260 continue;
261 if (!obj->u.s.owner)
262 continue; /* skip root handles */
263 if (!obj->u.s.owner_ref)
264 continue; /* only unref owner ref. */
265 if (obj->u.s.owner == owner)
266 (void) lttng_ust_abi_objd_unref(i, 1);
267 }
268 }
269
270 /*
271 * This is LTTng's own personal way to create an ABI for sessiond.
272 * We send commands over a socket.
273 */
274
275 static const struct lttng_ust_abi_objd_ops lttng_ops;
276 static const struct lttng_ust_abi_objd_ops lttng_event_notifier_group_ops;
277 static const struct lttng_ust_abi_objd_ops lttng_session_ops;
278 static const struct lttng_ust_abi_objd_ops lttng_channel_ops;
279 static const struct lttng_ust_abi_objd_ops lttng_counter_ops;
280 static const struct lttng_ust_abi_objd_ops lttng_event_enabler_ops;
281 static const struct lttng_ust_abi_objd_ops lttng_event_notifier_enabler_ops;
282 static const struct lttng_ust_abi_objd_ops lttng_tracepoint_list_ops;
283 static const struct lttng_ust_abi_objd_ops lttng_tracepoint_field_list_ops;
284
285 int lttng_abi_create_root_handle(void)
286 {
287 int root_handle;
288
289 /* root handles have NULL owners */
290 root_handle = objd_alloc(NULL, &lttng_ops, NULL, "root");
291 return root_handle;
292 }
293
294 static
295 int lttng_is_channel_ready(struct lttng_ust_channel_buffer *lttng_chan)
296 {
297 struct lttng_ust_ring_buffer_channel *chan;
298 unsigned int nr_streams, exp_streams;
299
300 chan = lttng_chan->priv->rb_chan;
301 nr_streams = channel_handle_get_nr_streams(lttng_chan->priv->rb_chan->handle);
302 exp_streams = chan->nr_streams;
303 return nr_streams == exp_streams;
304 }
305
306 static
307 int lttng_abi_create_session(void *owner)
308 {
309 struct lttng_ust_session *session;
310 int session_objd, ret;
311
312 session = lttng_session_create();
313 if (!session)
314 return -ENOMEM;
315 session_objd = objd_alloc(session, &lttng_session_ops, owner, "session");
316 if (session_objd < 0) {
317 ret = session_objd;
318 goto objd_error;
319 }
320 session->priv->objd = session_objd;
321 session->priv->owner = owner;
322 return session_objd;
323
324 objd_error:
325 lttng_session_destroy(session);
326 return ret;
327 }
328
329 static
330 long lttng_abi_tracer_version(int objd __attribute__((unused)),
331 struct lttng_ust_abi_tracer_version *v)
332 {
333 v->major = LTTNG_UST_MAJOR_VERSION;
334 v->minor = LTTNG_UST_MINOR_VERSION;
335 v->patchlevel = LTTNG_UST_PATCHLEVEL_VERSION;
336 return 0;
337 }
338
339 static
340 int lttng_abi_event_notifier_send_fd(void *owner, int *event_notifier_notif_fd)
341 {
342 struct lttng_event_notifier_group *event_notifier_group;
343 int event_notifier_group_objd, ret, fd_flag;
344
345 event_notifier_group = lttng_event_notifier_group_create();
346 if (!event_notifier_group)
347 return -ENOMEM;
348
349 /*
350 * Set this file descriptor as NON-BLOCKING.
351 */
352 fd_flag = fcntl(*event_notifier_notif_fd, F_GETFL);
353
354 fd_flag |= O_NONBLOCK;
355
356 ret = fcntl(*event_notifier_notif_fd, F_SETFL, fd_flag);
357 if (ret) {
358 ret = -errno;
359 goto fd_error;
360 }
361
362 event_notifier_group_objd = objd_alloc(event_notifier_group,
363 &lttng_event_notifier_group_ops, owner, "event_notifier_group");
364 if (event_notifier_group_objd < 0) {
365 ret = event_notifier_group_objd;
366 goto objd_error;
367 }
368
369 event_notifier_group->objd = event_notifier_group_objd;
370 event_notifier_group->owner = owner;
371 event_notifier_group->notification_fd = *event_notifier_notif_fd;
372 /* Object descriptor takes ownership of notification fd. */
373 *event_notifier_notif_fd = -1;
374
375 return event_notifier_group_objd;
376
377 objd_error:
378 lttng_event_notifier_group_destroy(event_notifier_group);
379 fd_error:
380 return ret;
381 }
382
383 static
384 long lttng_abi_add_context(int objd __attribute__((unused)),
385 struct lttng_ust_abi_context *context_param,
386 union lttng_ust_abi_args *uargs,
387 struct lttng_ust_ctx **ctx, struct lttng_ust_session *session)
388 {
389 return lttng_attach_context(context_param, uargs, ctx, session);
390 }
391
392 /**
393 * lttng_cmd - lttng control through socket commands
394 *
395 * @objd: the object descriptor
396 * @cmd: the command
397 * @arg: command arg
398 * @uargs: UST arguments (internal)
399 * @owner: objd owner
400 *
401 * This descriptor implements lttng commands:
402 * LTTNG_UST_ABI_SESSION
403 * Returns a LTTng trace session object descriptor
404 * LTTNG_UST_ABI_TRACER_VERSION
405 * Returns the LTTng kernel tracer version
406 * LTTNG_UST_ABI_TRACEPOINT_LIST
407 * Returns a file descriptor listing available tracepoints
408 * LTTNG_UST_ABI_TRACEPOINT_FIELD_LIST
409 * Returns a file descriptor listing available tracepoint fields
410 * LTTNG_UST_ABI_WAIT_QUIESCENT
411 * Returns after all previously running probes have completed
412 *
413 * The returned session will be deleted when its file descriptor is closed.
414 */
415 static
416 long lttng_cmd(int objd, unsigned int cmd, unsigned long arg,
417 union lttng_ust_abi_args *uargs, void *owner)
418 {
419 switch (cmd) {
420 case LTTNG_UST_ABI_SESSION:
421 return lttng_abi_create_session(owner);
422 case LTTNG_UST_ABI_TRACER_VERSION:
423 return lttng_abi_tracer_version(objd,
424 (struct lttng_ust_abi_tracer_version *) arg);
425 case LTTNG_UST_ABI_TRACEPOINT_LIST:
426 return lttng_abi_tracepoint_list(owner);
427 case LTTNG_UST_ABI_TRACEPOINT_FIELD_LIST:
428 return lttng_abi_tracepoint_field_list(owner);
429 case LTTNG_UST_ABI_WAIT_QUIESCENT:
430 lttng_ust_urcu_synchronize_rcu();
431 return 0;
432 case LTTNG_UST_ABI_EVENT_NOTIFIER_GROUP_CREATE:
433 return lttng_abi_event_notifier_send_fd(owner,
434 &uargs->event_notifier_handle.event_notifier_notif_fd);
435 default:
436 return -EINVAL;
437 }
438 }
439
440 static const struct lttng_ust_abi_objd_ops lttng_ops = {
441 .cmd = lttng_cmd,
442 };
443
444 static
445 int lttng_abi_map_channel(int session_objd,
446 struct lttng_ust_abi_channel *ust_chan,
447 union lttng_ust_abi_args *uargs,
448 void *owner)
449 {
450 struct lttng_ust_session *session = objd_private(session_objd);
451 const char *transport_name;
452 struct lttng_transport *transport;
453 const char *chan_name;
454 int chan_objd;
455 struct lttng_ust_shm_handle *channel_handle;
456 struct lttng_ust_abi_channel_config *lttng_chan_config;
457 struct lttng_ust_channel_buffer *lttng_chan_buf;
458 struct lttng_ust_ring_buffer_channel *chan;
459 struct lttng_ust_ring_buffer_config *config;
460 void *chan_data;
461 int wakeup_fd;
462 uint64_t len;
463 int ret;
464 enum lttng_ust_abi_chan_type type;
465
466 chan_data = uargs->channel.chan_data;
467 wakeup_fd = uargs->channel.wakeup_fd;
468 len = ust_chan->len;
469 type = ust_chan->type;
470
471 switch (type) {
472 case LTTNG_UST_ABI_CHAN_PER_CPU:
473 break;
474 default:
475 ret = -EINVAL;
476 goto invalid;
477 }
478
479 if (session->priv->been_active) {
480 ret = -EBUSY;
481 goto active; /* Refuse to add channel to active session */
482 }
483
484 lttng_chan_buf = lttng_ust_alloc_channel_buffer();
485 if (!lttng_chan_buf) {
486 ret = -ENOMEM;
487 goto lttng_chan_buf_error;
488 }
489
490 channel_handle = channel_handle_create(chan_data, len, wakeup_fd);
491 if (!channel_handle) {
492 ret = -EINVAL;
493 goto handle_error;
494 }
495
496 /* Ownership of chan_data and wakeup_fd taken by channel handle. */
497 uargs->channel.chan_data = NULL;
498 uargs->channel.wakeup_fd = -1;
499
500 chan = shmp(channel_handle, channel_handle->chan);
501 assert(chan);
502 chan->handle = channel_handle;
503 config = &chan->backend.config;
504 lttng_chan_config = channel_get_private_config(chan);
505 if (!lttng_chan_config) {
506 ret = -EINVAL;
507 goto alloc_error;
508 }
509
510 if (lttng_ust_session_uuid_validate(session, lttng_chan_config->uuid)) {
511 ret = -EINVAL;
512 goto uuid_error;
513 }
514
515 /* Lookup transport name */
516 switch (type) {
517 case LTTNG_UST_ABI_CHAN_PER_CPU:
518 if (config->output == RING_BUFFER_MMAP) {
519 if (config->mode == RING_BUFFER_OVERWRITE) {
520 if (config->wakeup == RING_BUFFER_WAKEUP_BY_WRITER) {
521 transport_name = "relay-overwrite-mmap";
522 } else {
523 transport_name = "relay-overwrite-rt-mmap";
524 }
525 } else {
526 if (config->wakeup == RING_BUFFER_WAKEUP_BY_WRITER) {
527 transport_name = "relay-discard-mmap";
528 } else {
529 transport_name = "relay-discard-rt-mmap";
530 }
531 }
532 } else {
533 ret = -EINVAL;
534 goto notransport;
535 }
536 chan_name = "channel";
537 break;
538 default:
539 ret = -EINVAL;
540 goto notransport;
541 }
542 transport = lttng_ust_transport_find(transport_name);
543 if (!transport) {
544 DBG("LTTng transport %s not found\n",
545 transport_name);
546 ret = -EINVAL;
547 goto notransport;
548 }
549
550 chan_objd = objd_alloc(NULL, &lttng_channel_ops, owner, chan_name);
551 if (chan_objd < 0) {
552 ret = chan_objd;
553 goto objd_error;
554 }
555
556 /* Initialize our lttng chan */
557 lttng_chan_buf->parent->enabled = 1;
558 lttng_chan_buf->parent->session = session;
559
560 lttng_chan_buf->priv->parent.tstate = 1;
561 lttng_chan_buf->priv->ctx = NULL;
562 lttng_chan_buf->priv->rb_chan = chan;
563
564 lttng_chan_buf->ops = &transport->ops;
565
566 memcpy(&chan->backend.config,
567 transport->client_config,
568 sizeof(chan->backend.config));
569 cds_list_add(&lttng_chan_buf->priv->node, &session->priv->chan_head);
570 lttng_chan_buf->priv->header_type = 0;
571 lttng_chan_buf->priv->type = type;
572 /* Copy fields from lttng ust chan config. */
573 lttng_chan_buf->priv->id = lttng_chan_config->id;
574 memcpy(lttng_chan_buf->priv->uuid, lttng_chan_config->uuid, LTTNG_UST_UUID_LEN);
575 channel_set_private(chan, lttng_chan_buf);
576
577 /*
578 * We tolerate no failure path after channel creation. It will stay
579 * invariant for the rest of the session.
580 */
581 objd_set_private(chan_objd, lttng_chan_buf);
582 lttng_chan_buf->priv->parent.objd = chan_objd;
583 /* The channel created holds a reference on the session */
584 objd_ref(session_objd);
585 return chan_objd;
586
587 /* error path after channel was created */
588 objd_error:
589 notransport:
590 uuid_error:
591 alloc_error:
592 channel_destroy(chan, channel_handle, 0);
593 lttng_ust_free_channel_common(lttng_chan_buf->parent);
594 return ret;
595
596 handle_error:
597 lttng_ust_free_channel_common(lttng_chan_buf->parent);
598 lttng_chan_buf_error:
599 active:
600 invalid:
601 return ret;
602 }
603
604 static
605 bool check_zero(const char *p, size_t len)
606 {
607 size_t i;
608
609 for (i = 0; i < len; i++) {
610 if (p[i] != 0)
611 return false;
612 }
613 return true;
614 }
615
616 static
617 int copy_abi_struct(void *dst_struct, size_t dst_struct_len,
618 const void *src_struct, size_t src_struct_len)
619 {
620 if (dst_struct_len >= src_struct_len) {
621 memcpy(dst_struct, src_struct, src_struct_len);
622 if (dst_struct_len > src_struct_len)
623 memset(dst_struct + src_struct_len, 0, dst_struct_len - src_struct_len);
624 } else { /* dst_struct_len < src_struct_len */
625 /* Validate zero-padding. */
626 if (!check_zero(src_struct + dst_struct_len, src_struct_len - dst_struct_len))
627 return -E2BIG;
628 memcpy(dst_struct, src_struct, dst_struct_len);
629 }
630 return 0;
631 }
632
633 static
634 long lttng_session_create_counter(
635 int session_objd,
636 const struct lttng_ust_abi_counter_conf *abi_counter_conf,
637 union lttng_ust_abi_args *uargs,
638 void *owner)
639 {
640 struct lttng_ust_session *session = objd_private(session_objd);
641 int counter_objd, ret;
642 const char *counter_transport_name;
643 struct lttng_ust_channel_counter *counter = NULL;
644 struct lttng_counter_dimension dimensions[1] = {};
645 size_t number_dimensions = 1;
646 struct lttng_ust_abi_counter_conf counter_conf;
647 uint32_t min_expected_len = lttng_ust_offsetofend(struct lttng_ust_abi_counter_conf, elem_len);
648 const struct lttng_ust_abi_counter_dimension *abi_dimension;
649 struct lttng_ust_abi_counter_dimension dimension;
650
651 if (uargs->counter.len < min_expected_len) {
652 ERR("LTTng: Map: Counter configuration of wrong size.");
653 return -EINVAL;
654 }
655 if (abi_counter_conf->len > uargs->counter.len || abi_counter_conf->len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_conf, elem_len)) {
656 return -EINVAL;
657 }
658 ret = copy_abi_struct(&counter_conf, sizeof(counter_conf), abi_counter_conf, abi_counter_conf->len);
659 if (ret) {
660 ERR("Unexpected counter configuration structure content");
661 return ret;
662 }
663 if (counter_conf.number_dimensions != 1) {
664 ERR("LTTng: Map: Unsupprted number of dimensions %u.", counter_conf.number_dimensions);
665 return -EINVAL;
666 }
667 if (counter_conf.elem_len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_dimension, overflow_index)) {
668 ERR("Unexpected dimension array element length %u.", counter_conf.elem_len);
669 return -EINVAL;
670 }
671 if (counter_conf.len + counter_conf.elem_len > uargs->counter.len) {
672 return -EINVAL;
673 }
674 abi_dimension = (const struct lttng_ust_abi_counter_dimension *)(((char *)abi_counter_conf) + counter_conf.len);
675 ret = copy_abi_struct(&dimension, sizeof(dimension), abi_dimension, counter_conf.elem_len);
676 if (ret) {
677 ERR("Unexpected dimension structure content");
678 return ret;
679 }
680 if (counter_conf.arithmetic != LTTNG_UST_ABI_COUNTER_ARITHMETIC_MODULAR) {
681 ERR("LTTng: Map: Counter of the wrong type.");
682 return -EINVAL;
683 }
684 if (counter_conf.global_sum_step) {
685 /* Unsupported. */
686 return -EINVAL;
687 }
688 switch (counter_conf.bitness) {
689 case LTTNG_UST_ABI_COUNTER_BITNESS_64:
690 counter_transport_name = "counter-per-cpu-64-modular";
691 break;
692 case LTTNG_UST_ABI_COUNTER_BITNESS_32:
693 counter_transport_name = "counter-per-cpu-32-modular";
694 break;
695 default:
696 return -EINVAL;
697 }
698
699 dimensions[0].size = dimension.size;
700 dimensions[0].underflow_index = dimension.underflow_index;
701 dimensions[0].overflow_index = dimension.overflow_index;
702 dimensions[0].has_underflow = dimension.flags & LTTNG_UST_ABI_COUNTER_DIMENSION_FLAG_UNDERFLOW;
703 dimensions[0].has_overflow = dimension.flags & LTTNG_UST_ABI_COUNTER_DIMENSION_FLAG_OVERFLOW;
704 switch (dimension.key_type) {
705 case LTTNG_UST_ABI_KEY_TYPE_TOKENS:
706 dimensions[0].key_type = LTTNG_KEY_TYPE_TOKENS;
707 break;
708 case LTTNG_UST_ABI_KEY_TYPE_INTEGER: /* Fall-through */
709 default:
710 return -EINVAL;
711 }
712
713 counter_objd = objd_alloc(NULL, &lttng_counter_ops, owner, "counter");
714 if (counter_objd < 0) {
715 ret = counter_objd;
716 goto objd_error;
717 }
718
719 counter = lttng_ust_counter_create(counter_transport_name,
720 number_dimensions, dimensions,
721 0, counter_conf.flags & LTTNG_UST_ABI_COUNTER_CONF_FLAG_COALESCE_HITS);
722 if (!counter) {
723 ret = -EINVAL;
724 goto counter_error;
725 }
726 counter->parent->session = session;
727 cds_list_add(&counter->priv->node, &session->priv->counters_head);
728 objd_set_private(counter_objd, counter);
729 counter->priv->parent.objd = counter_objd;
730 counter->priv->parent.tstate = 1;
731 counter->parent->enabled = 1;
732 /* The channel created holds a reference on the session */
733 objd_ref(session_objd);
734 return counter_objd;
735
736 counter_error:
737 {
738 int err;
739
740 err = lttng_ust_abi_objd_unref(counter_objd, 1);
741 assert(!err);
742 }
743 objd_error:
744 return ret;
745 }
746
747 /**
748 * lttng_session_cmd - lttng session object command
749 *
750 * @obj: the object
751 * @cmd: the command
752 * @arg: command arg
753 * @uargs: UST arguments (internal)
754 * @owner: objd owner
755 *
756 * This descriptor implements lttng commands:
757 * LTTNG_UST_ABI_CHANNEL
758 * Returns a LTTng channel object descriptor
759 * LTTNG_UST_ABI_ENABLE
760 * Enables tracing for a session (weak enable)
761 * LTTNG_UST_ABI_DISABLE
762 * Disables tracing for a session (strong disable)
763 *
764 * The returned channel will be deleted when its file descriptor is closed.
765 */
766 static
767 long lttng_session_cmd(int objd, unsigned int cmd, unsigned long arg,
768 union lttng_ust_abi_args *uargs, void *owner)
769 {
770 struct lttng_ust_session *session = objd_private(objd);
771
772 switch (cmd) {
773 case LTTNG_UST_ABI_CHANNEL:
774 return lttng_abi_map_channel(objd,
775 (struct lttng_ust_abi_channel *) arg,
776 uargs, owner);
777 case LTTNG_UST_ABI_SESSION_START:
778 case LTTNG_UST_ABI_ENABLE:
779 return lttng_session_enable(session);
780 case LTTNG_UST_ABI_SESSION_STOP:
781 case LTTNG_UST_ABI_DISABLE:
782 return lttng_session_disable(session);
783 case LTTNG_UST_ABI_SESSION_STATEDUMP:
784 return lttng_session_statedump(session);
785 case LTTNG_UST_ABI_COUNTER:
786 return lttng_session_create_counter(objd,
787 (struct lttng_ust_abi_counter_conf *)arg,
788 uargs, owner);
789 default:
790 return -EINVAL;
791 }
792 }
793
794 /*
795 * Called when the last file reference is dropped.
796 *
797 * Big fat note: channels and events are invariant for the whole session after
798 * their creation. So this session destruction also destroys all channel and
799 * event structures specific to this session (they are not destroyed when their
800 * individual file is released).
801 */
802 static
803 int lttng_release_session(int objd)
804 {
805 struct lttng_ust_session *session = objd_private(objd);
806
807 if (session) {
808 lttng_session_destroy(session);
809 return 0;
810 } else {
811 return -EINVAL;
812 }
813 }
814
815 static const struct lttng_ust_abi_objd_ops lttng_session_ops = {
816 .release = lttng_release_session,
817 .cmd = lttng_session_cmd,
818 };
819
820 static int lttng_ust_event_notifier_enabler_create(int event_notifier_group_obj,
821 void *owner, struct lttng_ust_abi_event_notifier *event_notifier_param,
822 enum lttng_enabler_format_type type)
823 {
824 struct lttng_event_notifier_group *event_notifier_group =
825 objd_private(event_notifier_group_obj);
826 struct lttng_event_notifier_enabler *event_notifier_enabler;
827 int event_notifier_objd, ret;
828
829 event_notifier_param->event.name[LTTNG_UST_ABI_SYM_NAME_LEN - 1] = '\0';
830 event_notifier_objd = objd_alloc(NULL, &lttng_event_notifier_enabler_ops, owner,
831 "event_notifier enabler");
832 if (event_notifier_objd < 0) {
833 ret = event_notifier_objd;
834 goto objd_error;
835 }
836
837 event_notifier_enabler = lttng_event_notifier_enabler_create(
838 event_notifier_group, type, event_notifier_param);
839 if (!event_notifier_enabler) {
840 ret = -ENOMEM;
841 goto event_notifier_error;
842 }
843
844 objd_set_private(event_notifier_objd, event_notifier_enabler);
845 /* The event_notifier holds a reference on the event_notifier group. */
846 objd_ref(event_notifier_enabler->group->objd);
847
848 return event_notifier_objd;
849
850 event_notifier_error:
851 {
852 int err;
853
854 err = lttng_ust_abi_objd_unref(event_notifier_objd, 1);
855 assert(!err);
856 }
857 objd_error:
858 return ret;
859 }
860
861 static
862 long lttng_event_notifier_enabler_cmd(int objd, unsigned int cmd, unsigned long arg,
863 union lttng_ust_abi_args *uargs __attribute__((unused)),
864 void *owner __attribute__((unused)))
865 {
866 struct lttng_event_notifier_enabler *event_notifier_enabler = objd_private(objd);
867 switch (cmd) {
868 case LTTNG_UST_ABI_FILTER:
869 return lttng_event_enabler_attach_filter_bytecode(
870 &event_notifier_enabler->parent,
871 (struct lttng_ust_bytecode_node **) arg);
872 case LTTNG_UST_ABI_EXCLUSION:
873 return lttng_event_enabler_attach_exclusion(&event_notifier_enabler->parent,
874 (struct lttng_ust_excluder_node **) arg);
875 case LTTNG_UST_ABI_CAPTURE:
876 return lttng_event_notifier_enabler_attach_capture_bytecode(
877 event_notifier_enabler,
878 (struct lttng_ust_bytecode_node **) arg);
879 case LTTNG_UST_ABI_ENABLE:
880 return lttng_event_enabler_enable(&event_notifier_enabler->parent);
881 case LTTNG_UST_ABI_DISABLE:
882 return lttng_event_enabler_disable(&event_notifier_enabler->parent);
883 default:
884 return -EINVAL;
885 }
886 }
887
888 /**
889 * lttng_event_notifier_group_error_counter_cmd - lttng event_notifier group error counter object command
890 *
891 * @obj: the object
892 * @cmd: the command
893 * @arg: command arg
894 * @uargs: UST arguments (internal)
895 * @owner: objd owner
896 *
897 * This descriptor implements lttng commands:
898 * LTTNG_UST_ABI_COUNTER_GLOBAL
899 * Return negative error code on error, 0 on success.
900 * LTTNG_UST_ABI_COUNTER_CPU
901 * Return negative error code on error, 0 on success.
902 */
903 static
904 long lttng_event_notifier_group_error_counter_cmd(int objd, unsigned int cmd, unsigned long arg,
905 union lttng_ust_abi_args *uargs, void *owner __attribute__((unused)))
906 {
907 int ret;
908 struct lttng_ust_channel_counter *counter = objd_private(objd);
909
910 switch (cmd) {
911 case LTTNG_UST_ABI_COUNTER_GLOBAL:
912 ret = -EINVAL; /* Unimplemented. */
913 break;
914 case LTTNG_UST_ABI_COUNTER_CPU:
915 {
916 struct lttng_ust_abi_counter_cpu *abi_counter_cpu =
917 (struct lttng_ust_abi_counter_cpu *) arg;
918 struct lttng_ust_abi_counter_cpu counter_cpu;
919
920 if (abi_counter_cpu->len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_cpu, cpu_nr)) {
921 return -EINVAL;
922 }
923 ret = copy_abi_struct(&counter_cpu, sizeof(counter_cpu),
924 abi_counter_cpu, abi_counter_cpu->len);
925 if (ret)
926 return ret;
927 ret = lttng_counter_set_cpu_shm(counter->priv->counter,
928 counter_cpu.cpu_nr, uargs->counter_shm.shm_fd);
929 if (!ret) {
930 /* Take ownership of the shm_fd. */
931 uargs->counter_shm.shm_fd = -1;
932 }
933 break;
934 }
935 default:
936 ret = -EINVAL;
937 break;
938 }
939
940 return ret;
941 }
942
943 int lttng_release_event_notifier_group_error_counter(int objd)
944 __attribute__((visibility("hidden")));
945 int lttng_release_event_notifier_group_error_counter(int objd)
946 {
947 struct lttng_ust_channel_counter *counter = objd_private(objd);
948
949 if (counter) {
950 return lttng_ust_abi_objd_unref(counter->priv->event_notifier_group->objd, 0);
951 } else {
952 return -EINVAL;
953 }
954 }
955
956 static const struct lttng_ust_abi_objd_ops lttng_event_notifier_group_error_counter_ops = {
957 .release = lttng_release_event_notifier_group_error_counter,
958 .cmd = lttng_event_notifier_group_error_counter_cmd,
959 };
960
961 static
962 int lttng_ust_event_notifier_group_create_error_counter(int event_notifier_group_objd,
963 struct lttng_ust_abi_counter_conf *abi_counter_conf,
964 union lttng_ust_abi_args *uargs,
965 void *owner)
966 {
967 const char *counter_transport_name;
968 struct lttng_event_notifier_group *event_notifier_group =
969 objd_private(event_notifier_group_objd);
970 struct lttng_ust_channel_counter *counter;
971 int counter_objd, ret;
972 size_t counter_len;
973 struct lttng_counter_dimension dimensions[1] = {};
974 struct lttng_ust_abi_counter_conf counter_conf;
975 uint32_t min_expected_len = lttng_ust_offsetofend(struct lttng_ust_abi_counter_conf, elem_len);
976 const struct lttng_ust_abi_counter_dimension *abi_dimension;
977 struct lttng_ust_abi_counter_dimension dimension;
978
979 if (event_notifier_group->error_counter)
980 return -EBUSY;
981
982 if (uargs->counter.len < min_expected_len) {
983 ERR("LTTng: Counter configuration of wrong size.");
984 return -EINVAL;
985 }
986 if (abi_counter_conf->len > uargs->counter.len || abi_counter_conf->len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_conf, elem_len)) {
987 return -EINVAL;
988 }
989 ret = copy_abi_struct(&counter_conf, sizeof(counter_conf), abi_counter_conf, abi_counter_conf->len);
990 if (ret) {
991 ERR("Unexpected counter configuration structure content");
992 return ret;
993 }
994 if (counter_conf.number_dimensions != 1) {
995 ERR("LTTng: Map: Unsupprted number of dimensions %u.", counter_conf.number_dimensions);
996 return -EINVAL;
997 }
998 if (counter_conf.elem_len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_dimension, overflow_index)) {
999 ERR("Unexpected dimension array element length %u.", counter_conf.elem_len);
1000 return -EINVAL;
1001 }
1002 if (counter_conf.len + counter_conf.elem_len > uargs->counter.len) {
1003 return -EINVAL;
1004 }
1005 abi_dimension = (const struct lttng_ust_abi_counter_dimension *)(((char *)abi_counter_conf) + counter_conf.len);
1006 ret = copy_abi_struct(&dimension, sizeof(dimension), abi_dimension, counter_conf.elem_len);
1007 if (ret) {
1008 ERR("Unexpected dimension structure content");
1009 return ret;
1010 }
1011 if (counter_conf.arithmetic != LTTNG_UST_ABI_COUNTER_ARITHMETIC_MODULAR) {
1012 ERR("LTTng: Counter of the wrong type.");
1013 return -EINVAL;
1014 }
1015 if (counter_conf.global_sum_step) {
1016 /* Unsupported. */
1017 return -EINVAL;
1018 }
1019 switch (counter_conf.bitness) {
1020 case LTTNG_UST_ABI_COUNTER_BITNESS_64:
1021 counter_transport_name = "counter-per-cpu-64-modular";
1022 break;
1023 case LTTNG_UST_ABI_COUNTER_BITNESS_32:
1024 counter_transport_name = "counter-per-cpu-32-modular";
1025 break;
1026 default:
1027 return -EINVAL;
1028 }
1029
1030 counter_len = dimension.size;
1031 dimensions[0].size = counter_len;
1032 dimensions[0].underflow_index = dimension.underflow_index;
1033 dimensions[0].overflow_index = dimension.overflow_index;
1034 dimensions[0].has_underflow = dimension.flags & LTTNG_UST_ABI_COUNTER_DIMENSION_FLAG_UNDERFLOW;
1035 dimensions[0].has_overflow = dimension.flags & LTTNG_UST_ABI_COUNTER_DIMENSION_FLAG_OVERFLOW;
1036
1037 counter_objd = objd_alloc(NULL, &lttng_event_notifier_group_error_counter_ops, owner,
1038 "event_notifier group error counter");
1039 if (counter_objd < 0) {
1040 ret = counter_objd;
1041 goto objd_error;
1042 }
1043
1044 counter = lttng_ust_counter_create(counter_transport_name, 1, dimensions, 0, false);
1045 if (!counter) {
1046 ret = -EINVAL;
1047 goto create_error;
1048 }
1049
1050 event_notifier_group->error_counter_len = counter_len;
1051 /*
1052 * store-release to publish error counter matches load-acquire
1053 * in record_error. Ensures the counter is created and the
1054 * error_counter_len is set before they are used.
1055 * Currently a full memory barrier is used, which could be
1056 * turned into acquire-release barriers.
1057 */
1058 cmm_smp_mb();
1059 CMM_STORE_SHARED(event_notifier_group->error_counter, counter);
1060
1061 counter->priv->parent.objd = counter_objd;
1062 counter->priv->event_notifier_group = event_notifier_group; /* owner */
1063
1064 objd_set_private(counter_objd, counter);
1065 /* The error counter holds a reference on the event_notifier group. */
1066 objd_ref(event_notifier_group->objd);
1067
1068 return counter_objd;
1069
1070 create_error:
1071 {
1072 int err;
1073
1074 err = lttng_ust_abi_objd_unref(counter_objd, 1);
1075 assert(!err);
1076 }
1077 objd_error:
1078 return ret;
1079 }
1080
1081 static
1082 long lttng_event_notifier_group_cmd(int objd, unsigned int cmd, unsigned long arg,
1083 union lttng_ust_abi_args *uargs, void *owner)
1084 {
1085 int ret;
1086
1087 switch (cmd) {
1088 case LTTNG_UST_ABI_EVENT_NOTIFIER_CREATE:
1089 {
1090 struct lttng_ust_abi_event_notifier *abi_event_notifier =
1091 (struct lttng_ust_abi_event_notifier *) arg;
1092 struct lttng_ust_abi_event_notifier event_notifier = {};
1093
1094 if (uargs->event_notifier.len < lttng_ust_offsetofend(struct lttng_ust_abi_event_notifier, error_counter_index))
1095 return -EINVAL;
1096 ret = copy_abi_struct(&event_notifier, sizeof(event_notifier),
1097 abi_event_notifier, uargs->event_notifier.len);
1098 if (ret)
1099 return ret;
1100 event_notifier.event.name[LTTNG_UST_ABI_SYM_NAME_LEN - 1] = '\0';
1101 if (strutils_is_star_glob_pattern(event_notifier.event.name)) {
1102 /*
1103 * If the event name is a star globbing pattern,
1104 * we create the special star globbing enabler.
1105 */
1106 return lttng_ust_event_notifier_enabler_create(objd,
1107 owner, &event_notifier,
1108 LTTNG_ENABLER_FORMAT_STAR_GLOB);
1109 } else {
1110 return lttng_ust_event_notifier_enabler_create(objd,
1111 owner, &event_notifier,
1112 LTTNG_ENABLER_FORMAT_EVENT);
1113 }
1114 }
1115 case LTTNG_UST_ABI_COUNTER:
1116 {
1117 return lttng_ust_event_notifier_group_create_error_counter(
1118 objd, (struct lttng_ust_abi_counter_conf *) arg, uargs, owner);
1119 }
1120 default:
1121 return -EINVAL;
1122 }
1123 }
1124
1125 static
1126 int lttng_event_notifier_enabler_release(int objd)
1127 {
1128 struct lttng_event_notifier_enabler *event_notifier_enabler = objd_private(objd);
1129
1130 if (event_notifier_enabler)
1131 return lttng_ust_abi_objd_unref(event_notifier_enabler->group->objd, 0);
1132 return 0;
1133 }
1134
1135 static const struct lttng_ust_abi_objd_ops lttng_event_notifier_enabler_ops = {
1136 .release = lttng_event_notifier_enabler_release,
1137 .cmd = lttng_event_notifier_enabler_cmd,
1138 };
1139
1140 static
1141 int lttng_release_event_notifier_group(int objd)
1142 {
1143 struct lttng_event_notifier_group *event_notifier_group = objd_private(objd);
1144
1145 if (event_notifier_group) {
1146 lttng_event_notifier_group_destroy(event_notifier_group);
1147 return 0;
1148 } else {
1149 return -EINVAL;
1150 }
1151 }
1152
1153 static const struct lttng_ust_abi_objd_ops lttng_event_notifier_group_ops = {
1154 .release = lttng_release_event_notifier_group,
1155 .cmd = lttng_event_notifier_group_cmd,
1156 };
1157
1158 static
1159 long lttng_tracepoint_list_cmd(int objd, unsigned int cmd, unsigned long arg,
1160 union lttng_ust_abi_args *uargs __attribute__((unused)),
1161 void *owner __attribute__((unused)))
1162 {
1163 struct lttng_ust_tracepoint_list *list = objd_private(objd);
1164 struct lttng_ust_abi_tracepoint_iter *tp =
1165 (struct lttng_ust_abi_tracepoint_iter *) arg;
1166 struct lttng_ust_abi_tracepoint_iter *iter;
1167
1168 switch (cmd) {
1169 case LTTNG_UST_ABI_TRACEPOINT_LIST_GET:
1170 {
1171 iter = lttng_ust_tracepoint_list_get_iter_next(list);
1172 if (!iter)
1173 return -LTTNG_UST_ERR_NOENT;
1174 memcpy(tp, iter, sizeof(*tp));
1175 return 0;
1176 }
1177 default:
1178 return -EINVAL;
1179 }
1180 }
1181
1182 static
1183 int lttng_abi_tracepoint_list(void *owner)
1184 {
1185 int list_objd, ret;
1186 struct lttng_ust_tracepoint_list *list;
1187
1188 list_objd = objd_alloc(NULL, &lttng_tracepoint_list_ops, owner, "tp_list");
1189 if (list_objd < 0) {
1190 ret = list_objd;
1191 goto objd_error;
1192 }
1193 list = zmalloc(sizeof(*list));
1194 if (!list) {
1195 ret = -ENOMEM;
1196 goto alloc_error;
1197 }
1198 objd_set_private(list_objd, list);
1199
1200 /* populate list by walking on all registered probes. */
1201 ret = lttng_probes_get_event_list(list);
1202 if (ret) {
1203 goto list_error;
1204 }
1205 return list_objd;
1206
1207 list_error:
1208 free(list);
1209 alloc_error:
1210 {
1211 int err;
1212
1213 err = lttng_ust_abi_objd_unref(list_objd, 1);
1214 assert(!err);
1215 }
1216 objd_error:
1217 return ret;
1218 }
1219
1220 static
1221 int lttng_release_tracepoint_list(int objd)
1222 {
1223 struct lttng_ust_tracepoint_list *list = objd_private(objd);
1224
1225 if (list) {
1226 lttng_probes_prune_event_list(list);
1227 free(list);
1228 return 0;
1229 } else {
1230 return -EINVAL;
1231 }
1232 }
1233
1234 static const struct lttng_ust_abi_objd_ops lttng_tracepoint_list_ops = {
1235 .release = lttng_release_tracepoint_list,
1236 .cmd = lttng_tracepoint_list_cmd,
1237 };
1238
1239 static
1240 long lttng_tracepoint_field_list_cmd(int objd, unsigned int cmd,
1241 unsigned long arg __attribute__((unused)), union lttng_ust_abi_args *uargs,
1242 void *owner __attribute__((unused)))
1243 {
1244 struct lttng_ust_field_list *list = objd_private(objd);
1245 struct lttng_ust_abi_field_iter *tp = &uargs->field_list.entry;
1246 struct lttng_ust_abi_field_iter *iter;
1247
1248 switch (cmd) {
1249 case LTTNG_UST_ABI_TRACEPOINT_FIELD_LIST_GET:
1250 {
1251 iter = lttng_ust_field_list_get_iter_next(list);
1252 if (!iter)
1253 return -LTTNG_UST_ERR_NOENT;
1254 memcpy(tp, iter, sizeof(*tp));
1255 return 0;
1256 }
1257 default:
1258 return -EINVAL;
1259 }
1260 }
1261
1262 static
1263 int lttng_abi_tracepoint_field_list(void *owner)
1264 {
1265 int list_objd, ret;
1266 struct lttng_ust_field_list *list;
1267
1268 list_objd = objd_alloc(NULL, &lttng_tracepoint_field_list_ops, owner,
1269 "tp_field_list");
1270 if (list_objd < 0) {
1271 ret = list_objd;
1272 goto objd_error;
1273 }
1274 list = zmalloc(sizeof(*list));
1275 if (!list) {
1276 ret = -ENOMEM;
1277 goto alloc_error;
1278 }
1279 objd_set_private(list_objd, list);
1280
1281 /* populate list by walking on all registered probes. */
1282 ret = lttng_probes_get_field_list(list);
1283 if (ret) {
1284 goto list_error;
1285 }
1286 return list_objd;
1287
1288 list_error:
1289 free(list);
1290 alloc_error:
1291 {
1292 int err;
1293
1294 err = lttng_ust_abi_objd_unref(list_objd, 1);
1295 assert(!err);
1296 }
1297 objd_error:
1298 return ret;
1299 }
1300
1301 static
1302 int lttng_release_tracepoint_field_list(int objd)
1303 {
1304 struct lttng_ust_field_list *list = objd_private(objd);
1305
1306 if (list) {
1307 lttng_probes_prune_field_list(list);
1308 free(list);
1309 return 0;
1310 } else {
1311 return -EINVAL;
1312 }
1313 }
1314
1315 static const struct lttng_ust_abi_objd_ops lttng_tracepoint_field_list_ops = {
1316 .release = lttng_release_tracepoint_field_list,
1317 .cmd = lttng_tracepoint_field_list_cmd,
1318 };
1319
1320 static
1321 int lttng_abi_map_stream(int channel_objd, struct lttng_ust_abi_stream *info,
1322 union lttng_ust_abi_args *uargs, void *owner __attribute__((unused)))
1323 {
1324 struct lttng_ust_channel_buffer *lttng_chan_buf = objd_private(channel_objd);
1325 int ret;
1326
1327 ret = channel_handle_add_stream(lttng_chan_buf->priv->rb_chan->handle,
1328 uargs->stream.shm_fd, uargs->stream.wakeup_fd,
1329 info->stream_nr, info->len);
1330 if (ret)
1331 goto error_add_stream;
1332 /* Take ownership of shm_fd and wakeup_fd. */
1333 uargs->stream.shm_fd = -1;
1334 uargs->stream.wakeup_fd = -1;
1335
1336 return 0;
1337
1338 error_add_stream:
1339 return ret;
1340 }
1341
1342 static
1343 int lttng_abi_create_event_recorder_enabler(int channel_objd,
1344 struct lttng_ust_channel_buffer *channel,
1345 struct lttng_ust_abi_event *event_param,
1346 void *owner,
1347 enum lttng_enabler_format_type format_type)
1348 {
1349 struct lttng_event_recorder_enabler *enabler;
1350 int event_objd, ret;
1351
1352 event_param->name[LTTNG_UST_ABI_SYM_NAME_LEN - 1] = '\0';
1353 event_objd = objd_alloc(NULL, &lttng_event_enabler_ops, owner,
1354 "event recorder enabler");
1355 if (event_objd < 0) {
1356 ret = event_objd;
1357 goto objd_error;
1358 }
1359 /*
1360 * We tolerate no failure path after event creation. It will stay
1361 * invariant for the rest of the session.
1362 */
1363 enabler = lttng_event_recorder_enabler_create(format_type, event_param,
1364 channel);
1365 if (!enabler) {
1366 ret = -ENOMEM;
1367 goto event_error;
1368 }
1369 objd_set_private(event_objd, &enabler->parent);
1370 /* The event holds a reference on the channel */
1371 objd_ref(channel_objd);
1372 return event_objd;
1373
1374 event_error:
1375 {
1376 int err;
1377
1378 err = lttng_ust_abi_objd_unref(event_objd, 1);
1379 assert(!err);
1380 }
1381 objd_error:
1382 return ret;
1383 }
1384
1385 static
1386 int copy_counter_key_dimension_tokens(const struct lttng_ust_abi_counter_key_dimension_tokens *abi_dim_tokens,
1387 const char *addr, size_t *offset, size_t arg_len, struct lttng_counter_key_dimension *internal_dim)
1388 {
1389 struct lttng_ust_abi_counter_key_dimension_tokens dim_tokens;
1390 size_t nr_key_tokens, j;
1391 int ret;
1392
1393 if (abi_dim_tokens->parent.len < sizeof(struct lttng_ust_abi_counter_key_dimension_tokens))
1394 return -EINVAL;
1395 ret = copy_abi_struct(&dim_tokens, sizeof(dim_tokens), abi_dim_tokens, abi_dim_tokens->parent.len);
1396 if (ret)
1397 return ret;
1398 nr_key_tokens = dim_tokens.nr_key_tokens;
1399 if (!nr_key_tokens || nr_key_tokens > LTTNG_NR_KEY_TOKEN)
1400 return -EINVAL;
1401 internal_dim->key_type = LTTNG_KEY_TYPE_TOKENS;
1402 internal_dim->u.tokens.nr_key_tokens = nr_key_tokens;
1403 *offset += sizeof(struct lttng_ust_abi_counter_key_dimension_tokens);
1404 for (j = 0; j < nr_key_tokens; j++) {
1405 struct lttng_key_token *internal_token = &internal_dim->u.tokens.key_tokens[j];
1406 const struct lttng_ust_abi_key_token *abi_token;
1407
1408 if (*offset + sizeof(struct lttng_ust_abi_key_token) > arg_len)
1409 return -EINVAL;
1410 abi_token = (const struct lttng_ust_abi_key_token *)(addr + *offset);
1411 if (abi_token->len < sizeof(struct lttng_ust_abi_key_token))
1412 return -EINVAL;
1413 if (*offset + abi_token->len > arg_len)
1414 return -EINVAL;
1415 switch (abi_token->type) {
1416 case LTTNG_UST_ABI_KEY_TOKEN_STRING:
1417 {
1418 const struct lttng_ust_abi_key_token_string *abi_key_string;
1419 struct lttng_ust_abi_key_token_string token_string;
1420
1421 if (abi_token->len < sizeof(struct lttng_ust_abi_key_token_string))
1422 return -EINVAL;
1423 abi_key_string = (const struct lttng_ust_abi_key_token_string *)(addr + *offset);
1424 ret = copy_abi_struct(&token_string, sizeof(token_string), abi_key_string, abi_key_string->parent.len);
1425 if (ret)
1426 return ret;
1427 *offset += abi_key_string->parent.len;
1428 internal_token->type = LTTNG_KEY_TOKEN_STRING;
1429 if (!abi_key_string->string_len || abi_key_string->string_len > LTTNG_KEY_TOKEN_STRING_LEN_MAX)
1430 return -EINVAL;
1431 *offset += abi_key_string->string_len;
1432 if (*offset > arg_len)
1433 return -EINVAL;
1434 if (abi_key_string->str[abi_key_string->string_len - 1] != '\0' ||
1435 strlen(abi_key_string->str) + 1 != abi_key_string->string_len)
1436 return -EINVAL;
1437 memcpy(internal_token->arg.string, abi_key_string->str, abi_key_string->string_len);
1438 break;
1439 }
1440 case LTTNG_UST_ABI_KEY_TOKEN_EVENT_NAME:
1441 internal_token->type = LTTNG_KEY_TOKEN_EVENT_NAME;
1442 *offset += abi_token->len;
1443 break;
1444 case LTTNG_UST_ABI_KEY_TOKEN_PROVIDER_NAME:
1445 internal_token->type = LTTNG_KEY_TOKEN_PROVIDER_NAME;
1446 *offset += abi_token->len;
1447 break;
1448 default:
1449 return -EINVAL;
1450 }
1451 }
1452 return 0;
1453 }
1454
1455 static
1456 int copy_counter_key(struct lttng_counter_key *internal_key,
1457 unsigned long arg, size_t action_fields_len, size_t arg_len,
1458 const struct lttng_ust_abi_counter_event *counter_event)
1459 {
1460 size_t i, nr_dimensions, offset = 0;
1461 const char *addr = (const char *)arg;
1462 int ret;
1463
1464 nr_dimensions = counter_event->number_key_dimensions;
1465 if (nr_dimensions != 1)
1466 return -EINVAL;
1467 internal_key->nr_dimensions = nr_dimensions;
1468 offset += counter_event->len + action_fields_len;
1469 for (i = 0; i < nr_dimensions; i++) {
1470 struct lttng_counter_key_dimension *internal_dim = &internal_key->key_dimensions[i];
1471 const struct lttng_ust_abi_counter_key_dimension *abi_dim;
1472
1473 abi_dim = (const struct lttng_ust_abi_counter_key_dimension *)(addr + offset);
1474 if (offset + abi_dim->len > arg_len || abi_dim->len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_key_dimension, key_type))
1475 return -EINVAL;
1476 switch (abi_dim->key_type) {
1477 case LTTNG_UST_ABI_KEY_TYPE_TOKENS:
1478 {
1479 struct lttng_ust_abi_counter_key_dimension_tokens *dim_tokens =
1480 caa_container_of(abi_dim, struct lttng_ust_abi_counter_key_dimension_tokens, parent);
1481 ret = copy_counter_key_dimension_tokens(dim_tokens, addr, &offset, arg_len,
1482 internal_dim);
1483 if (ret)
1484 return ret;
1485 break;
1486 }
1487 default:
1488 return -EINVAL;
1489 }
1490 }
1491 return 0;
1492 }
1493
1494 static
1495 int lttng_abi_create_event_counter_enabler(int channel_objd,
1496 struct lttng_ust_channel_counter *channel,
1497 unsigned long arg, size_t arg_len, void *owner)
1498 {
1499 struct lttng_ust_abi_counter_event *abi_counter_event = (struct lttng_ust_abi_counter_event *)arg;
1500 struct lttng_ust_abi_counter_event counter_event = {};
1501 struct lttng_counter_key counter_key = {};
1502 struct lttng_event_counter_enabler *enabler;
1503 enum lttng_enabler_format_type format_type;
1504 size_t action_fields_len = 0;
1505 int event_objd, ret;
1506 size_t i;
1507
1508 if (arg_len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_event, number_key_dimensions)) {
1509 return -EINVAL;
1510 }
1511 if (arg_len < abi_counter_event->len ||
1512 abi_counter_event->len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_event, number_key_dimensions)) {
1513 return -EINVAL;
1514 }
1515 ret = copy_abi_struct(&counter_event, sizeof(counter_event),
1516 abi_counter_event, abi_counter_event->len);
1517 if (ret) {
1518 return ret;
1519 }
1520 switch (counter_event.action) {
1521 case LTTNG_UST_ABI_COUNTER_ACTION_INCREMENT:
1522 /* No additional fields specific to this action. */
1523 break;
1524 default:
1525 return -EINVAL;
1526 }
1527 counter_event.event.name[LTTNG_UST_ABI_SYM_NAME_LEN - 1] = '\0';
1528 if (strutils_is_star_glob_pattern(counter_event.event.name)) {
1529 format_type = LTTNG_ENABLER_FORMAT_STAR_GLOB;
1530 } else {
1531 format_type = LTTNG_ENABLER_FORMAT_EVENT;
1532 }
1533 ret = copy_counter_key(&counter_key, arg, action_fields_len, arg_len, &counter_event);
1534 if (ret) {
1535 return ret;
1536 }
1537 /*
1538 * Validate that each dimension counter key type match the map
1539 * key type.
1540 */
1541 for (i = 0; i < counter_key.nr_dimensions; i++) {
1542 if (channel->priv->dimension_key_types[i] != counter_key.key_dimensions[i].key_type)
1543 return -EINVAL;
1544 }
1545 event_objd = objd_alloc(NULL, &lttng_event_enabler_ops, owner,
1546 "event enabler");
1547 if (event_objd < 0) {
1548 ret = event_objd;
1549 goto objd_error;
1550 }
1551 /*
1552 * We tolerate no failure path after event creation. It will stay
1553 * invariant for the rest of the session.
1554 */
1555 enabler = lttng_event_counter_enabler_create(format_type, &counter_event, &counter_key, channel);
1556 if (!enabler) {
1557 ret = -ENOMEM;
1558 goto event_error;
1559 }
1560 objd_set_private(event_objd, &enabler->parent);
1561 /* The event holds a reference on the channel */
1562 objd_ref(channel_objd);
1563 return event_objd;
1564
1565 event_error:
1566 {
1567 int err;
1568
1569 err = lttng_ust_abi_objd_unref(event_objd, 1);
1570 assert(!err);
1571 }
1572 objd_error:
1573 return ret;
1574 }
1575
1576 /**
1577 * lttng_channel_cmd - lttng control through object descriptors
1578 *
1579 * @objd: the object descriptor
1580 * @cmd: the command
1581 * @arg: command arg
1582 * @uargs: UST arguments (internal)
1583 * @owner: objd owner
1584 *
1585 * This object descriptor implements lttng commands:
1586 * LTTNG_UST_ABI_STREAM
1587 * Returns an event stream object descriptor or failure.
1588 * (typically, one event stream records events from one CPU)
1589 * LTTNG_UST_ABI_EVENT
1590 * Returns an event object descriptor or failure.
1591 * LTTNG_UST_ABI_CONTEXT
1592 * Prepend a context field to each event in the channel
1593 * LTTNG_UST_ABI_ENABLE
1594 * Enable recording for events in this channel (weak enable)
1595 * LTTNG_UST_ABI_DISABLE
1596 * Disable recording for events in this channel (strong disable)
1597 *
1598 * Channel and event file descriptors also hold a reference on the session.
1599 */
1600 static
1601 long lttng_channel_cmd(int objd, unsigned int cmd, unsigned long arg,
1602 union lttng_ust_abi_args *uargs, void *owner)
1603 {
1604 struct lttng_ust_channel_buffer *lttng_chan_buf = objd_private(objd);
1605
1606 if (cmd != LTTNG_UST_ABI_STREAM) {
1607 /*
1608 * Check if channel received all streams.
1609 */
1610 if (!lttng_is_channel_ready(lttng_chan_buf))
1611 return -EPERM;
1612 }
1613
1614 switch (cmd) {
1615 case LTTNG_UST_ABI_STREAM:
1616 {
1617 struct lttng_ust_abi_stream *stream;
1618
1619 stream = (struct lttng_ust_abi_stream *) arg;
1620 /* stream used as output */
1621 return lttng_abi_map_stream(objd, stream, uargs, owner);
1622 }
1623 case LTTNG_UST_ABI_EVENT:
1624 {
1625 struct lttng_ust_abi_event *event_param =
1626 (struct lttng_ust_abi_event *) arg;
1627
1628 if (strutils_is_star_glob_pattern(event_param->name)) {
1629 /*
1630 * If the event name is a star globbing pattern,
1631 * we create the special star globbing enabler.
1632 */
1633 return lttng_abi_create_event_recorder_enabler(objd, lttng_chan_buf,
1634 event_param, owner,
1635 LTTNG_ENABLER_FORMAT_STAR_GLOB);
1636 } else {
1637 return lttng_abi_create_event_recorder_enabler(objd, lttng_chan_buf,
1638 event_param, owner,
1639 LTTNG_ENABLER_FORMAT_EVENT);
1640 }
1641 }
1642 case LTTNG_UST_ABI_CONTEXT:
1643 return lttng_abi_add_context(objd,
1644 (struct lttng_ust_abi_context *) arg, uargs,
1645 &lttng_chan_buf->priv->ctx,
1646 lttng_chan_buf->parent->session);
1647 case LTTNG_UST_ABI_ENABLE:
1648 return lttng_channel_enable(lttng_chan_buf->parent);
1649 case LTTNG_UST_ABI_DISABLE:
1650 return lttng_channel_disable(lttng_chan_buf->parent);
1651 case LTTNG_UST_ABI_FLUSH_BUFFER:
1652 return lttng_chan_buf->ops->priv->flush_buffer(lttng_chan_buf);
1653 default:
1654 return -EINVAL;
1655 }
1656 }
1657
1658 static
1659 int lttng_channel_release(int objd)
1660 {
1661 struct lttng_ust_channel_buffer *lttng_chan_buf = objd_private(objd);
1662
1663 if (lttng_chan_buf)
1664 return lttng_ust_abi_objd_unref(lttng_chan_buf->parent->session->priv->objd, 0);
1665 return 0;
1666 }
1667
1668 static const struct lttng_ust_abi_objd_ops lttng_channel_ops = {
1669 .release = lttng_channel_release,
1670 .cmd = lttng_channel_cmd,
1671 };
1672
1673 /**
1674 * lttng_counter_cmd - lttng control through object descriptors
1675 *
1676 * @objd: the object descriptor
1677 * @cmd: the command
1678 * @arg: command arg
1679 * @uargs: UST arguments (internal)
1680 * @owner: objd owner
1681 *
1682 * This object descriptor implements lttng commands:
1683 * LTTNG_UST_ABI_COUNTER_GLOBAL:
1684 * Returns a global counter object descriptor or failure.
1685 * LTTNG_UST_ABI_COUNTER_CPU:
1686 * Returns a per-cpu counter object descriptor or failure.
1687 * LTTNG_UST_ABI_COUNTER_EVENT
1688 * Returns an event object descriptor or failure.
1689 * LTTNG_UST_ABI_ENABLE
1690 * Enable recording for events in this channel (weak enable)
1691 * LTTNG_UST_ABI_DISABLE
1692 * Disable recording for events in this channel (strong disable)
1693 *
1694 * Counter and event object descriptors also hold a reference on the session.
1695 */
1696 static
1697 long lttng_counter_cmd(int objd, unsigned int cmd, unsigned long arg,
1698 union lttng_ust_abi_args *uargs, void *owner)
1699 {
1700 struct lttng_ust_channel_counter *counter = objd_private(objd);
1701
1702 if (cmd != LTTNG_UST_ABI_COUNTER_GLOBAL && cmd != LTTNG_UST_ABI_COUNTER_CPU) {
1703 /*
1704 * Check if counter received all global/per-cpu objects.
1705 */
1706 if (!lttng_counter_ready(counter->priv->counter))
1707 return -EPERM;
1708 }
1709
1710 switch (cmd) {
1711 case LTTNG_UST_ABI_COUNTER_GLOBAL:
1712 {
1713 struct lttng_ust_abi_counter_global *abi_counter_global =
1714 (struct lttng_ust_abi_counter_global *) arg;
1715 struct lttng_ust_abi_counter_global counter_global;
1716 long ret;
1717 int shm_fd;
1718
1719 if (uargs->counter_shm.len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_global, shm_len))
1720 return -EINVAL;
1721 if (abi_counter_global->len > uargs->counter_shm.len ||
1722 abi_counter_global->len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_global, shm_len)) {
1723 return -EINVAL;
1724 }
1725 ret = copy_abi_struct(&counter_global, sizeof(counter_global),
1726 abi_counter_global, abi_counter_global->len);
1727 if (ret)
1728 return ret;
1729 shm_fd = uargs->counter_shm.shm_fd;
1730 ret = lttng_counter_set_global_shm(counter->priv->counter, shm_fd);
1731 if (!ret) {
1732 /* Take ownership of shm_fd. */
1733 uargs->counter_shm.shm_fd = -1;
1734 }
1735 return ret;
1736 }
1737 case LTTNG_UST_ABI_COUNTER_CPU:
1738 {
1739 struct lttng_ust_abi_counter_cpu *abi_counter_cpu =
1740 (struct lttng_ust_abi_counter_cpu *) arg;
1741 struct lttng_ust_abi_counter_cpu counter_cpu;
1742 long ret;
1743 int shm_fd;
1744
1745 if (uargs->counter_shm.len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_cpu, cpu_nr))
1746 return -EINVAL;
1747 if (abi_counter_cpu->len > uargs->counter_shm.len ||
1748 abi_counter_cpu->len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_cpu, cpu_nr)) {
1749 return -EINVAL;
1750 }
1751 ret = copy_abi_struct(&counter_cpu, sizeof(counter_cpu),
1752 abi_counter_cpu, abi_counter_cpu->len);
1753 if (ret)
1754 return ret;
1755 shm_fd = uargs->counter_shm.shm_fd;
1756 ret = lttng_counter_set_cpu_shm(counter->priv->counter,
1757 counter_cpu.cpu_nr, shm_fd);
1758 if (!ret) {
1759 /* Take ownership of shm_fd. */
1760 uargs->counter_shm.shm_fd = -1;
1761 }
1762 return ret;
1763 }
1764 case LTTNG_UST_ABI_COUNTER_EVENT:
1765 {
1766 return lttng_abi_create_event_counter_enabler(objd, counter,
1767 arg, uargs->counter_event.len, owner);
1768 }
1769 case LTTNG_UST_ABI_ENABLE:
1770 return lttng_channel_enable(counter->parent);
1771 case LTTNG_UST_ABI_DISABLE:
1772 return lttng_channel_disable(counter->parent);
1773 default:
1774 return -EINVAL;
1775 }
1776 }
1777
1778 static
1779 int lttng_counter_release(int objd)
1780 {
1781 struct lttng_ust_channel_counter *counter = objd_private(objd);
1782
1783 if (counter) {
1784 return lttng_ust_abi_objd_unref(counter->parent->session->priv->objd, 0);
1785 }
1786 return 0;
1787 }
1788
1789 static const struct lttng_ust_abi_objd_ops lttng_counter_ops = {
1790 .release = lttng_counter_release,
1791 .cmd = lttng_counter_cmd,
1792 };
1793
1794 /**
1795 * lttng_enabler_cmd - lttng control through object descriptors
1796 *
1797 * @objd: the object descriptor
1798 * @cmd: the command
1799 * @arg: command arg
1800 * @uargs: UST arguments (internal)
1801 * @owner: objd owner
1802 *
1803 * This object descriptor implements lttng commands:
1804 * LTTNG_UST_ABI_CONTEXT
1805 * Prepend a context field to each record of events of this
1806 * enabler.
1807 * LTTNG_UST_ABI_ENABLE
1808 * Enable recording for this enabler
1809 * LTTNG_UST_ABI_DISABLE
1810 * Disable recording for this enabler
1811 * LTTNG_UST_ABI_FILTER
1812 * Attach a filter to an enabler.
1813 * LTTNG_UST_ABI_EXCLUSION
1814 * Attach exclusions to an enabler.
1815 */
1816 static
1817 long lttng_event_enabler_cmd(int objd, unsigned int cmd, unsigned long arg,
1818 union lttng_ust_abi_args *uargs __attribute__((unused)),
1819 void *owner __attribute__((unused)))
1820 {
1821 struct lttng_event_enabler_session_common *enabler = objd_private(objd);
1822
1823 switch (cmd) {
1824 case LTTNG_UST_ABI_CONTEXT:
1825 return lttng_event_enabler_attach_context(enabler,
1826 (struct lttng_ust_abi_context *) arg);
1827 case LTTNG_UST_ABI_ENABLE:
1828 return lttng_event_enabler_enable(&enabler->parent);
1829 case LTTNG_UST_ABI_DISABLE:
1830 return lttng_event_enabler_disable(&enabler->parent);
1831 case LTTNG_UST_ABI_FILTER:
1832 {
1833 int ret;
1834
1835 ret = lttng_event_enabler_attach_filter_bytecode(&enabler->parent,
1836 (struct lttng_ust_bytecode_node **) arg);
1837 if (ret)
1838 return ret;
1839 return 0;
1840 }
1841 case LTTNG_UST_ABI_EXCLUSION:
1842 {
1843 return lttng_event_enabler_attach_exclusion(&enabler->parent,
1844 (struct lttng_ust_excluder_node **) arg);
1845 }
1846 default:
1847 return -EINVAL;
1848 }
1849 }
1850
1851 static
1852 int lttng_event_enabler_release(int objd)
1853 {
1854 struct lttng_event_recorder_enabler *event_enabler = objd_private(objd);
1855
1856 if (event_enabler)
1857 return lttng_ust_abi_objd_unref(event_enabler->chan->priv->parent.objd, 0);
1858
1859 return 0;
1860 }
1861
1862 static const struct lttng_ust_abi_objd_ops lttng_event_enabler_ops = {
1863 .release = lttng_event_enabler_release,
1864 .cmd = lttng_event_enabler_cmd,
1865 };
1866
1867 void lttng_ust_abi_exit(void)
1868 {
1869 lttng_ust_abi_close_in_progress = 1;
1870 ust_lock_nocheck();
1871 objd_table_destroy();
1872 ust_unlock();
1873 lttng_ust_abi_close_in_progress = 0;
1874 }
This page took 0.068845 seconds and 5 git commands to generate.