Move the ringbuffer and counter clients to 'src/common/'
[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
42 #include "common/ringbuffer/frontend_types.h"
43 #include "common/ringbuffer/frontend.h"
44 #include "common/ringbuffer/shm.h"
45 #include "common/counter/counter.h"
46 #include "common/tracepoint.h"
47 #include "common/tracer.h"
48 #include "common/strutils.h"
49 #include "lib/lttng-ust/events.h"
50 #include "lib/lttng-ust/lttng-tracer-core.h"
51 #include "context-internal.h"
52 #include "common/macros.h"
53
54 #define OBJ_NAME_LEN 16
55
56 static int lttng_ust_abi_close_in_progress;
57
58 static
59 int lttng_abi_tracepoint_list(void *owner);
60 static
61 int lttng_abi_tracepoint_field_list(void *owner);
62
63 /*
64 * Object descriptor table. Should be protected from concurrent access
65 * by the caller.
66 */
67
68 struct lttng_ust_abi_obj {
69 union {
70 struct {
71 void *private_data;
72 const struct lttng_ust_abi_objd_ops *ops;
73 int f_count;
74 int owner_ref; /* has ref from owner */
75 void *owner;
76 char name[OBJ_NAME_LEN];
77 } s;
78 int freelist_next; /* offset freelist. end is -1. */
79 } u;
80 };
81
82 struct lttng_ust_abi_objd_table {
83 struct lttng_ust_abi_obj *array;
84 unsigned int len, allocated_len;
85 int freelist_head; /* offset freelist head. end is -1 */
86 };
87
88 static struct lttng_ust_abi_objd_table objd_table = {
89 .freelist_head = -1,
90 };
91
92 static
93 int objd_alloc(void *private_data, const struct lttng_ust_abi_objd_ops *ops,
94 void *owner, const char *name)
95 {
96 struct lttng_ust_abi_obj *obj;
97
98 if (objd_table.freelist_head != -1) {
99 obj = &objd_table.array[objd_table.freelist_head];
100 objd_table.freelist_head = obj->u.freelist_next;
101 goto end;
102 }
103
104 if (objd_table.len >= objd_table.allocated_len) {
105 unsigned int new_allocated_len, old_allocated_len;
106 struct lttng_ust_abi_obj *new_table, *old_table;
107
108 old_allocated_len = objd_table.allocated_len;
109 old_table = objd_table.array;
110 if (!old_allocated_len)
111 new_allocated_len = 1;
112 else
113 new_allocated_len = old_allocated_len << 1;
114 new_table = zmalloc(sizeof(struct lttng_ust_abi_obj) * new_allocated_len);
115 if (!new_table)
116 return -ENOMEM;
117 memcpy(new_table, old_table,
118 sizeof(struct lttng_ust_abi_obj) * old_allocated_len);
119 free(old_table);
120 objd_table.array = new_table;
121 objd_table.allocated_len = new_allocated_len;
122 }
123 obj = &objd_table.array[objd_table.len];
124 objd_table.len++;
125 end:
126 obj->u.s.private_data = private_data;
127 obj->u.s.ops = ops;
128 obj->u.s.f_count = 2; /* count == 1 : object is allocated */
129 /* count == 2 : allocated + hold ref */
130 obj->u.s.owner_ref = 1; /* One owner reference */
131 obj->u.s.owner = owner;
132 strncpy(obj->u.s.name, name, OBJ_NAME_LEN);
133 obj->u.s.name[OBJ_NAME_LEN - 1] = '\0';
134 return obj - objd_table.array;
135 }
136
137 static
138 struct lttng_ust_abi_obj *_objd_get(int id)
139 {
140 if (id >= objd_table.len)
141 return NULL;
142 if (!objd_table.array[id].u.s.f_count)
143 return NULL;
144 return &objd_table.array[id];
145 }
146
147 static
148 void *objd_private(int id)
149 {
150 struct lttng_ust_abi_obj *obj = _objd_get(id);
151 assert(obj);
152 return obj->u.s.private_data;
153 }
154
155 static
156 void objd_set_private(int id, void *private_data)
157 {
158 struct lttng_ust_abi_obj *obj = _objd_get(id);
159 assert(obj);
160 obj->u.s.private_data = private_data;
161 }
162
163 const struct lttng_ust_abi_objd_ops *lttng_ust_abi_objd_ops(int id)
164 {
165 struct lttng_ust_abi_obj *obj = _objd_get(id);
166
167 if (!obj)
168 return NULL;
169 return obj->u.s.ops;
170 }
171
172 static
173 void objd_free(int id)
174 {
175 struct lttng_ust_abi_obj *obj = _objd_get(id);
176
177 assert(obj);
178 obj->u.freelist_next = objd_table.freelist_head;
179 objd_table.freelist_head = obj - objd_table.array;
180 assert(obj->u.s.f_count == 1);
181 obj->u.s.f_count = 0; /* deallocated */
182 }
183
184 static
185 void objd_ref(int id)
186 {
187 struct lttng_ust_abi_obj *obj = _objd_get(id);
188 assert(obj != NULL);
189 obj->u.s.f_count++;
190 }
191
192 int lttng_ust_abi_objd_unref(int id, int is_owner)
193 {
194 struct lttng_ust_abi_obj *obj = _objd_get(id);
195
196 if (!obj)
197 return -EINVAL;
198 if (obj->u.s.f_count == 1) {
199 ERR("Reference counting error\n");
200 return -EINVAL;
201 }
202 if (is_owner) {
203 if (!obj->u.s.owner_ref) {
204 ERR("Error decrementing owner reference");
205 return -EINVAL;
206 }
207 obj->u.s.owner_ref--;
208 }
209 if ((--obj->u.s.f_count) == 1) {
210 const struct lttng_ust_abi_objd_ops *ops = lttng_ust_abi_objd_ops(id);
211
212 if (ops->release)
213 ops->release(id);
214 objd_free(id);
215 }
216 return 0;
217 }
218
219 static
220 void objd_table_destroy(void)
221 {
222 int i;
223
224 for (i = 0; i < objd_table.allocated_len; i++) {
225 struct lttng_ust_abi_obj *obj;
226
227 obj = _objd_get(i);
228 if (!obj)
229 continue;
230 if (!obj->u.s.owner_ref)
231 continue; /* only unref owner ref. */
232 (void) lttng_ust_abi_objd_unref(i, 1);
233 }
234 free(objd_table.array);
235 objd_table.array = NULL;
236 objd_table.len = 0;
237 objd_table.allocated_len = 0;
238 objd_table.freelist_head = -1;
239 }
240
241 const char *lttng_ust_obj_get_name(int id)
242 {
243 struct lttng_ust_abi_obj *obj = _objd_get(id);
244
245 if (!obj)
246 return NULL;
247 return obj->u.s.name;
248 }
249
250 void lttng_ust_abi_objd_table_owner_cleanup(void *owner)
251 {
252 int i;
253
254 for (i = 0; i < objd_table.allocated_len; i++) {
255 struct lttng_ust_abi_obj *obj;
256
257 obj = _objd_get(i);
258 if (!obj)
259 continue;
260 if (!obj->u.s.owner)
261 continue; /* skip root handles */
262 if (!obj->u.s.owner_ref)
263 continue; /* only unref owner ref. */
264 if (obj->u.s.owner == owner)
265 (void) lttng_ust_abi_objd_unref(i, 1);
266 }
267 }
268
269 /*
270 * This is LTTng's own personal way to create an ABI for sessiond.
271 * We send commands over a socket.
272 */
273
274 static const struct lttng_ust_abi_objd_ops lttng_ops;
275 static const struct lttng_ust_abi_objd_ops lttng_event_notifier_group_ops;
276 static const struct lttng_ust_abi_objd_ops lttng_session_ops;
277 static const struct lttng_ust_abi_objd_ops lttng_channel_ops;
278 static const struct lttng_ust_abi_objd_ops lttng_event_enabler_ops;
279 static const struct lttng_ust_abi_objd_ops lttng_event_notifier_enabler_ops;
280 static const struct lttng_ust_abi_objd_ops lttng_tracepoint_list_ops;
281 static const struct lttng_ust_abi_objd_ops lttng_tracepoint_field_list_ops;
282
283 int lttng_abi_create_root_handle(void)
284 {
285 int root_handle;
286
287 /* root handles have NULL owners */
288 root_handle = objd_alloc(NULL, &lttng_ops, NULL, "root");
289 return root_handle;
290 }
291
292 static
293 int lttng_is_channel_ready(struct lttng_ust_channel_buffer *lttng_chan)
294 {
295 struct lttng_ust_ring_buffer_channel *chan;
296 unsigned int nr_streams, exp_streams;
297
298 chan = lttng_chan->priv->rb_chan;
299 nr_streams = channel_handle_get_nr_streams(lttng_chan->priv->rb_chan->handle);
300 exp_streams = chan->nr_streams;
301 return nr_streams == exp_streams;
302 }
303
304 static
305 int lttng_abi_create_session(void *owner)
306 {
307 struct lttng_ust_session *session;
308 int session_objd, ret;
309
310 session = lttng_session_create();
311 if (!session)
312 return -ENOMEM;
313 session_objd = objd_alloc(session, &lttng_session_ops, owner, "session");
314 if (session_objd < 0) {
315 ret = session_objd;
316 goto objd_error;
317 }
318 session->priv->objd = session_objd;
319 session->priv->owner = owner;
320 return session_objd;
321
322 objd_error:
323 lttng_session_destroy(session);
324 return ret;
325 }
326
327 static
328 long lttng_abi_tracer_version(int objd __attribute__((unused)),
329 struct lttng_ust_abi_tracer_version *v)
330 {
331 v->major = LTTNG_UST_MAJOR_VERSION;
332 v->minor = LTTNG_UST_MINOR_VERSION;
333 v->patchlevel = LTTNG_UST_PATCHLEVEL_VERSION;
334 return 0;
335 }
336
337 static
338 int lttng_abi_event_notifier_send_fd(void *owner, int *event_notifier_notif_fd)
339 {
340 struct lttng_event_notifier_group *event_notifier_group;
341 int event_notifier_group_objd, ret, fd_flag;
342
343 event_notifier_group = lttng_event_notifier_group_create();
344 if (!event_notifier_group)
345 return -ENOMEM;
346
347 /*
348 * Set this file descriptor as NON-BLOCKING.
349 */
350 fd_flag = fcntl(*event_notifier_notif_fd, F_GETFL);
351
352 fd_flag |= O_NONBLOCK;
353
354 ret = fcntl(*event_notifier_notif_fd, F_SETFL, fd_flag);
355 if (ret) {
356 ret = -errno;
357 goto fd_error;
358 }
359
360 event_notifier_group_objd = objd_alloc(event_notifier_group,
361 &lttng_event_notifier_group_ops, owner, "event_notifier_group");
362 if (event_notifier_group_objd < 0) {
363 ret = event_notifier_group_objd;
364 goto objd_error;
365 }
366
367 event_notifier_group->objd = event_notifier_group_objd;
368 event_notifier_group->owner = owner;
369 event_notifier_group->notification_fd = *event_notifier_notif_fd;
370 /* Object descriptor takes ownership of notification fd. */
371 *event_notifier_notif_fd = -1;
372
373 return event_notifier_group_objd;
374
375 objd_error:
376 lttng_event_notifier_group_destroy(event_notifier_group);
377 fd_error:
378 return ret;
379 }
380
381 static
382 long lttng_abi_add_context(int objd __attribute__((unused)),
383 struct lttng_ust_abi_context *context_param,
384 union lttng_ust_abi_args *uargs,
385 struct lttng_ust_ctx **ctx, struct lttng_ust_session *session)
386 {
387 return lttng_attach_context(context_param, uargs, ctx, session);
388 }
389
390 /**
391 * lttng_cmd - lttng control through socket commands
392 *
393 * @objd: the object descriptor
394 * @cmd: the command
395 * @arg: command arg
396 * @uargs: UST arguments (internal)
397 * @owner: objd owner
398 *
399 * This descriptor implements lttng commands:
400 * LTTNG_UST_ABI_SESSION
401 * Returns a LTTng trace session object descriptor
402 * LTTNG_UST_ABI_TRACER_VERSION
403 * Returns the LTTng kernel tracer version
404 * LTTNG_UST_ABI_TRACEPOINT_LIST
405 * Returns a file descriptor listing available tracepoints
406 * LTTNG_UST_ABI_TRACEPOINT_FIELD_LIST
407 * Returns a file descriptor listing available tracepoint fields
408 * LTTNG_UST_ABI_WAIT_QUIESCENT
409 * Returns after all previously running probes have completed
410 *
411 * The returned session will be deleted when its file descriptor is closed.
412 */
413 static
414 long lttng_cmd(int objd, unsigned int cmd, unsigned long arg,
415 union lttng_ust_abi_args *uargs, void *owner)
416 {
417 switch (cmd) {
418 case LTTNG_UST_ABI_SESSION:
419 return lttng_abi_create_session(owner);
420 case LTTNG_UST_ABI_TRACER_VERSION:
421 return lttng_abi_tracer_version(objd,
422 (struct lttng_ust_abi_tracer_version *) arg);
423 case LTTNG_UST_ABI_TRACEPOINT_LIST:
424 return lttng_abi_tracepoint_list(owner);
425 case LTTNG_UST_ABI_TRACEPOINT_FIELD_LIST:
426 return lttng_abi_tracepoint_field_list(owner);
427 case LTTNG_UST_ABI_WAIT_QUIESCENT:
428 lttng_ust_urcu_synchronize_rcu();
429 return 0;
430 case LTTNG_UST_ABI_EVENT_NOTIFIER_GROUP_CREATE:
431 return lttng_abi_event_notifier_send_fd(owner,
432 &uargs->event_notifier_handle.event_notifier_notif_fd);
433 default:
434 return -EINVAL;
435 }
436 }
437
438 static const struct lttng_ust_abi_objd_ops lttng_ops = {
439 .cmd = lttng_cmd,
440 };
441
442 static
443 int lttng_abi_map_channel(int session_objd,
444 struct lttng_ust_abi_channel *ust_chan,
445 union lttng_ust_abi_args *uargs,
446 void *owner)
447 {
448 struct lttng_ust_session *session = objd_private(session_objd);
449 const char *transport_name;
450 struct lttng_transport *transport;
451 const char *chan_name;
452 int chan_objd;
453 struct lttng_ust_shm_handle *channel_handle;
454 struct lttng_ust_abi_channel_config *lttng_chan_config;
455 struct lttng_ust_channel_buffer *lttng_chan_buf;
456 struct lttng_ust_ring_buffer_channel *chan;
457 struct lttng_ust_ring_buffer_config *config;
458 void *chan_data;
459 int wakeup_fd;
460 uint64_t len;
461 int ret;
462 enum lttng_ust_abi_chan_type type;
463
464 chan_data = uargs->channel.chan_data;
465 wakeup_fd = uargs->channel.wakeup_fd;
466 len = ust_chan->len;
467 type = ust_chan->type;
468
469 switch (type) {
470 case LTTNG_UST_ABI_CHAN_PER_CPU:
471 break;
472 default:
473 ret = -EINVAL;
474 goto invalid;
475 }
476
477 if (session->priv->been_active) {
478 ret = -EBUSY;
479 goto active; /* Refuse to add channel to active session */
480 }
481
482 lttng_chan_buf = lttng_ust_alloc_channel_buffer();
483 if (!lttng_chan_buf) {
484 ret = -ENOMEM;
485 goto lttng_chan_buf_error;
486 }
487
488 channel_handle = channel_handle_create(chan_data, len, wakeup_fd);
489 if (!channel_handle) {
490 ret = -EINVAL;
491 goto handle_error;
492 }
493
494 /* Ownership of chan_data and wakeup_fd taken by channel handle. */
495 uargs->channel.chan_data = NULL;
496 uargs->channel.wakeup_fd = -1;
497
498 chan = shmp(channel_handle, channel_handle->chan);
499 assert(chan);
500 chan->handle = channel_handle;
501 config = &chan->backend.config;
502 lttng_chan_config = channel_get_private_config(chan);
503 if (!lttng_chan_config) {
504 ret = -EINVAL;
505 goto alloc_error;
506 }
507
508 if (lttng_ust_session_uuid_validate(session, lttng_chan_config->uuid)) {
509 ret = -EINVAL;
510 goto uuid_error;
511 }
512
513 /* Lookup transport name */
514 switch (type) {
515 case LTTNG_UST_ABI_CHAN_PER_CPU:
516 if (config->output == RING_BUFFER_MMAP) {
517 if (config->mode == RING_BUFFER_OVERWRITE) {
518 if (config->wakeup == RING_BUFFER_WAKEUP_BY_WRITER) {
519 transport_name = "relay-overwrite-mmap";
520 } else {
521 transport_name = "relay-overwrite-rt-mmap";
522 }
523 } else {
524 if (config->wakeup == RING_BUFFER_WAKEUP_BY_WRITER) {
525 transport_name = "relay-discard-mmap";
526 } else {
527 transport_name = "relay-discard-rt-mmap";
528 }
529 }
530 } else {
531 ret = -EINVAL;
532 goto notransport;
533 }
534 chan_name = "channel";
535 break;
536 default:
537 ret = -EINVAL;
538 goto notransport;
539 }
540 transport = lttng_ust_transport_find(transport_name);
541 if (!transport) {
542 DBG("LTTng transport %s not found\n",
543 transport_name);
544 ret = -EINVAL;
545 goto notransport;
546 }
547
548 chan_objd = objd_alloc(NULL, &lttng_channel_ops, owner, chan_name);
549 if (chan_objd < 0) {
550 ret = chan_objd;
551 goto objd_error;
552 }
553
554 /* Initialize our lttng chan */
555 lttng_chan_buf->parent->enabled = 1;
556 lttng_chan_buf->parent->session = session;
557
558 lttng_chan_buf->priv->parent.tstate = 1;
559 lttng_chan_buf->priv->ctx = NULL;
560 lttng_chan_buf->priv->rb_chan = chan;
561
562 lttng_chan_buf->ops = &transport->ops;
563
564 memcpy(&chan->backend.config,
565 transport->client_config,
566 sizeof(chan->backend.config));
567 cds_list_add(&lttng_chan_buf->priv->node, &session->priv->chan_head);
568 lttng_chan_buf->priv->header_type = 0;
569 lttng_chan_buf->priv->type = type;
570 /* Copy fields from lttng ust chan config. */
571 lttng_chan_buf->priv->id = lttng_chan_config->id;
572 memcpy(lttng_chan_buf->priv->uuid, lttng_chan_config->uuid, LTTNG_UST_UUID_LEN);
573 channel_set_private(chan, lttng_chan_buf);
574
575 /*
576 * We tolerate no failure path after channel creation. It will stay
577 * invariant for the rest of the session.
578 */
579 objd_set_private(chan_objd, lttng_chan_buf);
580 lttng_chan_buf->priv->parent.objd = chan_objd;
581 /* The channel created holds a reference on the session */
582 objd_ref(session_objd);
583 return chan_objd;
584
585 /* error path after channel was created */
586 objd_error:
587 notransport:
588 uuid_error:
589 alloc_error:
590 channel_destroy(chan, channel_handle, 0);
591 lttng_ust_free_channel_common(lttng_chan_buf->parent);
592 return ret;
593
594 handle_error:
595 lttng_ust_free_channel_common(lttng_chan_buf->parent);
596 lttng_chan_buf_error:
597 active:
598 invalid:
599 return ret;
600 }
601
602 /**
603 * lttng_session_cmd - lttng session object command
604 *
605 * @obj: the object
606 * @cmd: the command
607 * @arg: command arg
608 * @uargs: UST arguments (internal)
609 * @owner: objd owner
610 *
611 * This descriptor implements lttng commands:
612 * LTTNG_UST_ABI_CHANNEL
613 * Returns a LTTng channel object descriptor
614 * LTTNG_UST_ABI_ENABLE
615 * Enables tracing for a session (weak enable)
616 * LTTNG_UST_ABI_DISABLE
617 * Disables tracing for a session (strong disable)
618 *
619 * The returned channel will be deleted when its file descriptor is closed.
620 */
621 static
622 long lttng_session_cmd(int objd, unsigned int cmd, unsigned long arg,
623 union lttng_ust_abi_args *uargs, void *owner)
624 {
625 struct lttng_ust_session *session = objd_private(objd);
626
627 switch (cmd) {
628 case LTTNG_UST_ABI_CHANNEL:
629 return lttng_abi_map_channel(objd,
630 (struct lttng_ust_abi_channel *) arg,
631 uargs, owner);
632 case LTTNG_UST_ABI_SESSION_START:
633 case LTTNG_UST_ABI_ENABLE:
634 return lttng_session_enable(session);
635 case LTTNG_UST_ABI_SESSION_STOP:
636 case LTTNG_UST_ABI_DISABLE:
637 return lttng_session_disable(session);
638 case LTTNG_UST_ABI_SESSION_STATEDUMP:
639 return lttng_session_statedump(session);
640 case LTTNG_UST_ABI_COUNTER:
641 case LTTNG_UST_ABI_COUNTER_GLOBAL:
642 case LTTNG_UST_ABI_COUNTER_CPU:
643 /* Not implemented yet. */
644 return -EINVAL;
645 default:
646 return -EINVAL;
647 }
648 }
649
650 /*
651 * Called when the last file reference is dropped.
652 *
653 * Big fat note: channels and events are invariant for the whole session after
654 * their creation. So this session destruction also destroys all channel and
655 * event structures specific to this session (they are not destroyed when their
656 * individual file is released).
657 */
658 static
659 int lttng_release_session(int objd)
660 {
661 struct lttng_ust_session *session = objd_private(objd);
662
663 if (session) {
664 lttng_session_destroy(session);
665 return 0;
666 } else {
667 return -EINVAL;
668 }
669 }
670
671 static const struct lttng_ust_abi_objd_ops lttng_session_ops = {
672 .release = lttng_release_session,
673 .cmd = lttng_session_cmd,
674 };
675
676 static int lttng_ust_event_notifier_enabler_create(int event_notifier_group_obj,
677 void *owner, struct lttng_ust_abi_event_notifier *event_notifier_param,
678 enum lttng_enabler_format_type type)
679 {
680 struct lttng_event_notifier_group *event_notifier_group =
681 objd_private(event_notifier_group_obj);
682 struct lttng_event_notifier_enabler *event_notifier_enabler;
683 int event_notifier_objd, ret;
684
685 event_notifier_param->event.name[LTTNG_UST_ABI_SYM_NAME_LEN - 1] = '\0';
686 event_notifier_objd = objd_alloc(NULL, &lttng_event_notifier_enabler_ops, owner,
687 "event_notifier enabler");
688 if (event_notifier_objd < 0) {
689 ret = event_notifier_objd;
690 goto objd_error;
691 }
692
693 event_notifier_enabler = lttng_event_notifier_enabler_create(
694 event_notifier_group, type, event_notifier_param);
695 if (!event_notifier_enabler) {
696 ret = -ENOMEM;
697 goto event_notifier_error;
698 }
699
700 objd_set_private(event_notifier_objd, event_notifier_enabler);
701 /* The event_notifier holds a reference on the event_notifier group. */
702 objd_ref(event_notifier_enabler->group->objd);
703
704 return event_notifier_objd;
705
706 event_notifier_error:
707 {
708 int err;
709
710 err = lttng_ust_abi_objd_unref(event_notifier_objd, 1);
711 assert(!err);
712 }
713 objd_error:
714 return ret;
715 }
716
717 static
718 long lttng_event_notifier_enabler_cmd(int objd, unsigned int cmd, unsigned long arg,
719 union lttng_ust_abi_args *uargs __attribute__((unused)),
720 void *owner __attribute__((unused)))
721 {
722 struct lttng_event_notifier_enabler *event_notifier_enabler = objd_private(objd);
723 switch (cmd) {
724 case LTTNG_UST_ABI_FILTER:
725 return lttng_event_notifier_enabler_attach_filter_bytecode(
726 event_notifier_enabler,
727 (struct lttng_ust_bytecode_node **) arg);
728 case LTTNG_UST_ABI_EXCLUSION:
729 return lttng_event_notifier_enabler_attach_exclusion(event_notifier_enabler,
730 (struct lttng_ust_excluder_node **) arg);
731 case LTTNG_UST_ABI_CAPTURE:
732 return lttng_event_notifier_enabler_attach_capture_bytecode(
733 event_notifier_enabler,
734 (struct lttng_ust_bytecode_node **) arg);
735 case LTTNG_UST_ABI_ENABLE:
736 return lttng_event_notifier_enabler_enable(event_notifier_enabler);
737 case LTTNG_UST_ABI_DISABLE:
738 return lttng_event_notifier_enabler_disable(event_notifier_enabler);
739 default:
740 return -EINVAL;
741 }
742 }
743
744 /**
745 * lttng_event_notifier_group_error_counter_cmd - lttng event_notifier group error counter object command
746 *
747 * @obj: the object
748 * @cmd: the command
749 * @arg: command arg
750 * @uargs: UST arguments (internal)
751 * @owner: objd owner
752 *
753 * This descriptor implements lttng commands:
754 * LTTNG_UST_ABI_COUNTER_GLOBAL
755 * Return negative error code on error, 0 on success.
756 * LTTNG_UST_ABI_COUNTER_CPU
757 * Return negative error code on error, 0 on success.
758 */
759 static
760 long lttng_event_notifier_group_error_counter_cmd(int objd, unsigned int cmd, unsigned long arg,
761 union lttng_ust_abi_args *uargs, void *owner __attribute__((unused)))
762 {
763 int ret;
764 struct lttng_counter *counter = objd_private(objd);
765
766 switch (cmd) {
767 case LTTNG_UST_ABI_COUNTER_GLOBAL:
768 ret = -EINVAL; /* Unimplemented. */
769 break;
770 case LTTNG_UST_ABI_COUNTER_CPU:
771 {
772 struct lttng_ust_abi_counter_cpu *counter_cpu =
773 (struct lttng_ust_abi_counter_cpu *)arg;
774
775 ret = lttng_counter_set_cpu_shm(counter->counter,
776 counter_cpu->cpu_nr, uargs->counter_shm.shm_fd);
777 if (!ret) {
778 /* Take ownership of the shm_fd. */
779 uargs->counter_shm.shm_fd = -1;
780 }
781 break;
782 }
783 default:
784 ret = -EINVAL;
785 break;
786 }
787
788 return ret;
789 }
790
791 int lttng_release_event_notifier_group_error_counter(int objd)
792 __attribute__((visibility("hidden")));
793 int lttng_release_event_notifier_group_error_counter(int objd)
794 {
795 struct lttng_counter *counter = objd_private(objd);
796
797 if (counter) {
798 return lttng_ust_abi_objd_unref(counter->event_notifier_group->objd, 0);
799 } else {
800 return -EINVAL;
801 }
802 }
803
804 static const struct lttng_ust_abi_objd_ops lttng_event_notifier_group_error_counter_ops = {
805 .release = lttng_release_event_notifier_group_error_counter,
806 .cmd = lttng_event_notifier_group_error_counter_cmd,
807 };
808
809 static
810 int lttng_ust_event_notifier_group_create_error_counter(int event_notifier_group_objd, void *owner,
811 struct lttng_ust_abi_counter_conf *error_counter_conf)
812 {
813 const char *counter_transport_name;
814 struct lttng_event_notifier_group *event_notifier_group =
815 objd_private(event_notifier_group_objd);
816 struct lttng_counter *counter;
817 int counter_objd, ret;
818 struct lttng_counter_dimension dimensions[1];
819 size_t counter_len;
820
821 if (event_notifier_group->error_counter)
822 return -EBUSY;
823
824 if (error_counter_conf->arithmetic != LTTNG_UST_ABI_COUNTER_ARITHMETIC_MODULAR)
825 return -EINVAL;
826
827 if (error_counter_conf->number_dimensions != 1)
828 return -EINVAL;
829
830 switch (error_counter_conf->bitness) {
831 case LTTNG_UST_ABI_COUNTER_BITNESS_64:
832 counter_transport_name = "counter-per-cpu-64-modular";
833 break;
834 case LTTNG_UST_ABI_COUNTER_BITNESS_32:
835 counter_transport_name = "counter-per-cpu-32-modular";
836 break;
837 default:
838 return -EINVAL;
839 }
840
841 counter_objd = objd_alloc(NULL, &lttng_event_notifier_group_error_counter_ops, owner,
842 "event_notifier group error counter");
843 if (counter_objd < 0) {
844 ret = counter_objd;
845 goto objd_error;
846 }
847
848 counter_len = error_counter_conf->dimensions[0].size;
849 dimensions[0].size = counter_len;
850 dimensions[0].underflow_index = 0;
851 dimensions[0].overflow_index = 0;
852 dimensions[0].has_underflow = 0;
853 dimensions[0].has_overflow = 0;
854
855 counter = lttng_ust_counter_create(counter_transport_name, 1, dimensions);
856 if (!counter) {
857 ret = -EINVAL;
858 goto create_error;
859 }
860
861 event_notifier_group->error_counter_len = counter_len;
862 /*
863 * store-release to publish error counter matches load-acquire
864 * in record_error. Ensures the counter is created and the
865 * error_counter_len is set before they are used.
866 * Currently a full memory barrier is used, which could be
867 * turned into acquire-release barriers.
868 */
869 cmm_smp_mb();
870 CMM_STORE_SHARED(event_notifier_group->error_counter, counter);
871
872 counter->objd = counter_objd;
873 counter->event_notifier_group = event_notifier_group; /* owner */
874
875 objd_set_private(counter_objd, counter);
876 /* The error counter holds a reference on the event_notifier group. */
877 objd_ref(event_notifier_group->objd);
878
879 return counter_objd;
880
881 create_error:
882 {
883 int err;
884
885 err = lttng_ust_abi_objd_unref(counter_objd, 1);
886 assert(!err);
887 }
888 objd_error:
889 return ret;
890 }
891
892 static
893 long lttng_event_notifier_group_cmd(int objd, unsigned int cmd, unsigned long arg,
894 union lttng_ust_abi_args *uargs, void *owner)
895 {
896 switch (cmd) {
897 case LTTNG_UST_ABI_EVENT_NOTIFIER_CREATE:
898 {
899 struct lttng_ust_abi_event_notifier *event_notifier_param =
900 (struct lttng_ust_abi_event_notifier *) arg;
901 if (strutils_is_star_glob_pattern(event_notifier_param->event.name)) {
902 /*
903 * If the event name is a star globbing pattern,
904 * we create the special star globbing enabler.
905 */
906 return lttng_ust_event_notifier_enabler_create(objd,
907 owner, event_notifier_param,
908 LTTNG_ENABLER_FORMAT_STAR_GLOB);
909 } else {
910 return lttng_ust_event_notifier_enabler_create(objd,
911 owner, event_notifier_param,
912 LTTNG_ENABLER_FORMAT_EVENT);
913 }
914 }
915 case LTTNG_UST_ABI_COUNTER:
916 {
917 struct lttng_ust_abi_counter_conf *counter_conf =
918 (struct lttng_ust_abi_counter_conf *) uargs->counter.counter_data;
919 return lttng_ust_event_notifier_group_create_error_counter(
920 objd, owner, counter_conf);
921 }
922 default:
923 return -EINVAL;
924 }
925 }
926
927 static
928 int lttng_event_notifier_enabler_release(int objd)
929 {
930 struct lttng_event_notifier_enabler *event_notifier_enabler = objd_private(objd);
931
932 if (event_notifier_enabler)
933 return lttng_ust_abi_objd_unref(event_notifier_enabler->group->objd, 0);
934 return 0;
935 }
936
937 static const struct lttng_ust_abi_objd_ops lttng_event_notifier_enabler_ops = {
938 .release = lttng_event_notifier_enabler_release,
939 .cmd = lttng_event_notifier_enabler_cmd,
940 };
941
942 static
943 int lttng_release_event_notifier_group(int objd)
944 {
945 struct lttng_event_notifier_group *event_notifier_group = objd_private(objd);
946
947 if (event_notifier_group) {
948 lttng_event_notifier_group_destroy(event_notifier_group);
949 return 0;
950 } else {
951 return -EINVAL;
952 }
953 }
954
955 static const struct lttng_ust_abi_objd_ops lttng_event_notifier_group_ops = {
956 .release = lttng_release_event_notifier_group,
957 .cmd = lttng_event_notifier_group_cmd,
958 };
959
960 static
961 long lttng_tracepoint_list_cmd(int objd, unsigned int cmd, unsigned long arg,
962 union lttng_ust_abi_args *uargs __attribute__((unused)),
963 void *owner __attribute__((unused)))
964 {
965 struct lttng_ust_tracepoint_list *list = objd_private(objd);
966 struct lttng_ust_abi_tracepoint_iter *tp =
967 (struct lttng_ust_abi_tracepoint_iter *) arg;
968 struct lttng_ust_abi_tracepoint_iter *iter;
969
970 switch (cmd) {
971 case LTTNG_UST_ABI_TRACEPOINT_LIST_GET:
972 {
973 iter = lttng_ust_tracepoint_list_get_iter_next(list);
974 if (!iter)
975 return -LTTNG_UST_ERR_NOENT;
976 memcpy(tp, iter, sizeof(*tp));
977 return 0;
978 }
979 default:
980 return -EINVAL;
981 }
982 }
983
984 static
985 int lttng_abi_tracepoint_list(void *owner)
986 {
987 int list_objd, ret;
988 struct lttng_ust_tracepoint_list *list;
989
990 list_objd = objd_alloc(NULL, &lttng_tracepoint_list_ops, owner, "tp_list");
991 if (list_objd < 0) {
992 ret = list_objd;
993 goto objd_error;
994 }
995 list = zmalloc(sizeof(*list));
996 if (!list) {
997 ret = -ENOMEM;
998 goto alloc_error;
999 }
1000 objd_set_private(list_objd, list);
1001
1002 /* populate list by walking on all registered probes. */
1003 ret = lttng_probes_get_event_list(list);
1004 if (ret) {
1005 goto list_error;
1006 }
1007 return list_objd;
1008
1009 list_error:
1010 free(list);
1011 alloc_error:
1012 {
1013 int err;
1014
1015 err = lttng_ust_abi_objd_unref(list_objd, 1);
1016 assert(!err);
1017 }
1018 objd_error:
1019 return ret;
1020 }
1021
1022 static
1023 int lttng_release_tracepoint_list(int objd)
1024 {
1025 struct lttng_ust_tracepoint_list *list = objd_private(objd);
1026
1027 if (list) {
1028 lttng_probes_prune_event_list(list);
1029 free(list);
1030 return 0;
1031 } else {
1032 return -EINVAL;
1033 }
1034 }
1035
1036 static const struct lttng_ust_abi_objd_ops lttng_tracepoint_list_ops = {
1037 .release = lttng_release_tracepoint_list,
1038 .cmd = lttng_tracepoint_list_cmd,
1039 };
1040
1041 static
1042 long lttng_tracepoint_field_list_cmd(int objd, unsigned int cmd,
1043 unsigned long arg __attribute__((unused)), union lttng_ust_abi_args *uargs,
1044 void *owner __attribute__((unused)))
1045 {
1046 struct lttng_ust_field_list *list = objd_private(objd);
1047 struct lttng_ust_abi_field_iter *tp = &uargs->field_list.entry;
1048 struct lttng_ust_abi_field_iter *iter;
1049
1050 switch (cmd) {
1051 case LTTNG_UST_ABI_TRACEPOINT_FIELD_LIST_GET:
1052 {
1053 iter = lttng_ust_field_list_get_iter_next(list);
1054 if (!iter)
1055 return -LTTNG_UST_ERR_NOENT;
1056 memcpy(tp, iter, sizeof(*tp));
1057 return 0;
1058 }
1059 default:
1060 return -EINVAL;
1061 }
1062 }
1063
1064 static
1065 int lttng_abi_tracepoint_field_list(void *owner)
1066 {
1067 int list_objd, ret;
1068 struct lttng_ust_field_list *list;
1069
1070 list_objd = objd_alloc(NULL, &lttng_tracepoint_field_list_ops, owner,
1071 "tp_field_list");
1072 if (list_objd < 0) {
1073 ret = list_objd;
1074 goto objd_error;
1075 }
1076 list = zmalloc(sizeof(*list));
1077 if (!list) {
1078 ret = -ENOMEM;
1079 goto alloc_error;
1080 }
1081 objd_set_private(list_objd, list);
1082
1083 /* populate list by walking on all registered probes. */
1084 ret = lttng_probes_get_field_list(list);
1085 if (ret) {
1086 goto list_error;
1087 }
1088 return list_objd;
1089
1090 list_error:
1091 free(list);
1092 alloc_error:
1093 {
1094 int err;
1095
1096 err = lttng_ust_abi_objd_unref(list_objd, 1);
1097 assert(!err);
1098 }
1099 objd_error:
1100 return ret;
1101 }
1102
1103 static
1104 int lttng_release_tracepoint_field_list(int objd)
1105 {
1106 struct lttng_ust_field_list *list = objd_private(objd);
1107
1108 if (list) {
1109 lttng_probes_prune_field_list(list);
1110 free(list);
1111 return 0;
1112 } else {
1113 return -EINVAL;
1114 }
1115 }
1116
1117 static const struct lttng_ust_abi_objd_ops lttng_tracepoint_field_list_ops = {
1118 .release = lttng_release_tracepoint_field_list,
1119 .cmd = lttng_tracepoint_field_list_cmd,
1120 };
1121
1122 static
1123 int lttng_abi_map_stream(int channel_objd, struct lttng_ust_abi_stream *info,
1124 union lttng_ust_abi_args *uargs, void *owner __attribute__((unused)))
1125 {
1126 struct lttng_ust_channel_buffer *lttng_chan_buf = objd_private(channel_objd);
1127 int ret;
1128
1129 ret = channel_handle_add_stream(lttng_chan_buf->priv->rb_chan->handle,
1130 uargs->stream.shm_fd, uargs->stream.wakeup_fd,
1131 info->stream_nr, info->len);
1132 if (ret)
1133 goto error_add_stream;
1134 /* Take ownership of shm_fd and wakeup_fd. */
1135 uargs->stream.shm_fd = -1;
1136 uargs->stream.wakeup_fd = -1;
1137
1138 return 0;
1139
1140 error_add_stream:
1141 return ret;
1142 }
1143
1144 static
1145 int lttng_abi_create_event_enabler(int channel_objd,
1146 struct lttng_ust_abi_event *event_param,
1147 void *owner,
1148 enum lttng_enabler_format_type format_type)
1149 {
1150 struct lttng_ust_channel_buffer *channel = objd_private(channel_objd);
1151 struct lttng_event_enabler *enabler;
1152 int event_objd, ret;
1153
1154 event_param->name[LTTNG_UST_ABI_SYM_NAME_LEN - 1] = '\0';
1155 event_objd = objd_alloc(NULL, &lttng_event_enabler_ops, owner,
1156 "event enabler");
1157 if (event_objd < 0) {
1158 ret = event_objd;
1159 goto objd_error;
1160 }
1161 /*
1162 * We tolerate no failure path after event creation. It will stay
1163 * invariant for the rest of the session.
1164 */
1165 enabler = lttng_event_enabler_create(format_type, event_param, channel);
1166 if (!enabler) {
1167 ret = -ENOMEM;
1168 goto event_error;
1169 }
1170 objd_set_private(event_objd, enabler);
1171 /* The event holds a reference on the channel */
1172 objd_ref(channel_objd);
1173 return event_objd;
1174
1175 event_error:
1176 {
1177 int err;
1178
1179 err = lttng_ust_abi_objd_unref(event_objd, 1);
1180 assert(!err);
1181 }
1182 objd_error:
1183 return ret;
1184 }
1185
1186 /**
1187 * lttng_channel_cmd - lttng control through object descriptors
1188 *
1189 * @objd: the object descriptor
1190 * @cmd: the command
1191 * @arg: command arg
1192 * @uargs: UST arguments (internal)
1193 * @owner: objd owner
1194 *
1195 * This object descriptor implements lttng commands:
1196 * LTTNG_UST_ABI_STREAM
1197 * Returns an event stream object descriptor or failure.
1198 * (typically, one event stream records events from one CPU)
1199 * LTTNG_UST_ABI_EVENT
1200 * Returns an event object descriptor or failure.
1201 * LTTNG_UST_ABI_CONTEXT
1202 * Prepend a context field to each event in the channel
1203 * LTTNG_UST_ABI_ENABLE
1204 * Enable recording for events in this channel (weak enable)
1205 * LTTNG_UST_ABI_DISABLE
1206 * Disable recording for events in this channel (strong disable)
1207 *
1208 * Channel and event file descriptors also hold a reference on the session.
1209 */
1210 static
1211 long lttng_channel_cmd(int objd, unsigned int cmd, unsigned long arg,
1212 union lttng_ust_abi_args *uargs, void *owner)
1213 {
1214 struct lttng_ust_channel_buffer *lttng_chan_buf = objd_private(objd);
1215
1216 if (cmd != LTTNG_UST_ABI_STREAM) {
1217 /*
1218 * Check if channel received all streams.
1219 */
1220 if (!lttng_is_channel_ready(lttng_chan_buf))
1221 return -EPERM;
1222 }
1223
1224 switch (cmd) {
1225 case LTTNG_UST_ABI_STREAM:
1226 {
1227 struct lttng_ust_abi_stream *stream;
1228
1229 stream = (struct lttng_ust_abi_stream *) arg;
1230 /* stream used as output */
1231 return lttng_abi_map_stream(objd, stream, uargs, owner);
1232 }
1233 case LTTNG_UST_ABI_EVENT:
1234 {
1235 struct lttng_ust_abi_event *event_param =
1236 (struct lttng_ust_abi_event *) arg;
1237
1238 if (strutils_is_star_glob_pattern(event_param->name)) {
1239 /*
1240 * If the event name is a star globbing pattern,
1241 * we create the special star globbing enabler.
1242 */
1243 return lttng_abi_create_event_enabler(objd, event_param,
1244 owner, LTTNG_ENABLER_FORMAT_STAR_GLOB);
1245 } else {
1246 return lttng_abi_create_event_enabler(objd, event_param,
1247 owner, LTTNG_ENABLER_FORMAT_EVENT);
1248 }
1249 }
1250 case LTTNG_UST_ABI_CONTEXT:
1251 return lttng_abi_add_context(objd,
1252 (struct lttng_ust_abi_context *) arg, uargs,
1253 &lttng_chan_buf->priv->ctx,
1254 lttng_chan_buf->parent->session);
1255 case LTTNG_UST_ABI_ENABLE:
1256 return lttng_channel_enable(lttng_chan_buf->parent);
1257 case LTTNG_UST_ABI_DISABLE:
1258 return lttng_channel_disable(lttng_chan_buf->parent);
1259 case LTTNG_UST_ABI_FLUSH_BUFFER:
1260 return lttng_chan_buf->ops->priv->flush_buffer(lttng_chan_buf);
1261 default:
1262 return -EINVAL;
1263 }
1264 }
1265
1266 static
1267 int lttng_channel_release(int objd)
1268 {
1269 struct lttng_ust_channel_buffer *lttng_chan_buf = objd_private(objd);
1270
1271 if (lttng_chan_buf)
1272 return lttng_ust_abi_objd_unref(lttng_chan_buf->parent->session->priv->objd, 0);
1273 return 0;
1274 }
1275
1276 static const struct lttng_ust_abi_objd_ops lttng_channel_ops = {
1277 .release = lttng_channel_release,
1278 .cmd = lttng_channel_cmd,
1279 };
1280
1281 /**
1282 * lttng_enabler_cmd - lttng control through object descriptors
1283 *
1284 * @objd: the object descriptor
1285 * @cmd: the command
1286 * @arg: command arg
1287 * @uargs: UST arguments (internal)
1288 * @owner: objd owner
1289 *
1290 * This object descriptor implements lttng commands:
1291 * LTTNG_UST_ABI_CONTEXT
1292 * Prepend a context field to each record of events of this
1293 * enabler.
1294 * LTTNG_UST_ABI_ENABLE
1295 * Enable recording for this enabler
1296 * LTTNG_UST_ABI_DISABLE
1297 * Disable recording for this enabler
1298 * LTTNG_UST_ABI_FILTER
1299 * Attach a filter to an enabler.
1300 * LTTNG_UST_ABI_EXCLUSION
1301 * Attach exclusions to an enabler.
1302 */
1303 static
1304 long lttng_event_enabler_cmd(int objd, unsigned int cmd, unsigned long arg,
1305 union lttng_ust_abi_args *uargs __attribute__((unused)),
1306 void *owner __attribute__((unused)))
1307 {
1308 struct lttng_event_enabler *enabler = objd_private(objd);
1309
1310 switch (cmd) {
1311 case LTTNG_UST_ABI_CONTEXT:
1312 return lttng_event_enabler_attach_context(enabler,
1313 (struct lttng_ust_abi_context *) arg);
1314 case LTTNG_UST_ABI_ENABLE:
1315 return lttng_event_enabler_enable(enabler);
1316 case LTTNG_UST_ABI_DISABLE:
1317 return lttng_event_enabler_disable(enabler);
1318 case LTTNG_UST_ABI_FILTER:
1319 {
1320 int ret;
1321
1322 ret = lttng_event_enabler_attach_filter_bytecode(enabler,
1323 (struct lttng_ust_bytecode_node **) arg);
1324 if (ret)
1325 return ret;
1326 return 0;
1327 }
1328 case LTTNG_UST_ABI_EXCLUSION:
1329 {
1330 return lttng_event_enabler_attach_exclusion(enabler,
1331 (struct lttng_ust_excluder_node **) arg);
1332 }
1333 default:
1334 return -EINVAL;
1335 }
1336 }
1337
1338 static
1339 int lttng_event_enabler_release(int objd)
1340 {
1341 struct lttng_event_enabler *event_enabler = objd_private(objd);
1342
1343 if (event_enabler)
1344 return lttng_ust_abi_objd_unref(event_enabler->chan->priv->parent.objd, 0);
1345
1346 return 0;
1347 }
1348
1349 static const struct lttng_ust_abi_objd_ops lttng_event_enabler_ops = {
1350 .release = lttng_event_enabler_release,
1351 .cmd = lttng_event_enabler_cmd,
1352 };
1353
1354 void lttng_ust_abi_exit(void)
1355 {
1356 lttng_ust_abi_close_in_progress = 1;
1357 ust_lock_nocheck();
1358 objd_table_destroy();
1359 ust_unlock();
1360 lttng_ust_abi_close_in_progress = 0;
1361 }
This page took 0.056189 seconds and 4 git commands to generate.