Cleanup: add lttng_/lttng-/LTTNG_ prefixes
[lttng-ust.git] / liblttng-ust / lttng-ust-abi.c
CommitLineData
f4681817
MD
1/*
2 * lttng-ust-abi.c
3 *
f4681817
MD
4 * LTTng UST ABI
5 *
e92f3e28
MD
6 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; only
11 * version 2.1 of the License.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 *
22 *
f4681817
MD
23 * Mimic system calls for:
24 * - session creation, returns an object descriptor or failure.
25 * - channel creation, returns an object descriptor or failure.
26 * - Operates on a session object descriptor
27 * - Takes all channel options as parameters.
28 * - stream get, returns an object descriptor or failure.
29 * - Operates on a channel object descriptor.
30 * - stream notifier get, returns an object descriptor or failure.
31 * - Operates on a channel object descriptor.
32 * - event creation, returns an object descriptor or failure.
33 * - Operates on a channel object descriptor
34 * - Takes an event name as parameter
35 * - Takes an instrumentation source as parameter
36 * - e.g. tracepoints, dynamic_probes...
37 * - Takes instrumentation source specific arguments.
f4681817
MD
38 */
39
4318ae1b 40#include <lttng/ust-abi.h>
7bc53e94 41#include <lttng/ust-error.h>
f4681817
MD
42#include <urcu/compiler.h>
43#include <urcu/list.h>
4318ae1b 44#include <lttng/ust-events.h>
23c8854a 45#include <lttng/ust-version.h>
902e1379 46#include <lttng/tracepoint.h>
d8de1354 47#include "tracepoint-internal.h"
44c72f10
MD
48#include <usterr-signal-safe.h>
49#include <helper.h>
7dd08bec 50#include "lttng-tracer.h"
4ab44fbe 51
45e9e699
MD
52static int lttng_ust_abi_close_in_progress;
53
51489cad 54static
f59ed768 55int lttng_abi_tracepoint_list(void *owner);
06d4f27e 56static
f59ed768 57int lttng_abi_tracepoint_field_list(void *owner);
51489cad 58
f4681817
MD
59/*
60 * Object descriptor table. Should be protected from concurrent access
61 * by the caller.
62 */
63
b61ce3b2 64struct lttng_ust_obj {
f4681817
MD
65 union {
66 struct {
67 void *private_data;
b61ce3b2 68 const struct lttng_ust_objd_ops *ops;
f4681817 69 int f_count;
f59ed768 70 void *owner;
f4681817
MD
71 } s;
72 int freelist_next; /* offset freelist. end is -1. */
73 } u;
74};
75
b61ce3b2
MD
76struct lttng_ust_objd_table {
77 struct lttng_ust_obj *array;
f4681817
MD
78 unsigned int len, allocated_len;
79 int freelist_head; /* offset freelist head. end is -1 */
80};
81
b61ce3b2 82static struct lttng_ust_objd_table objd_table = {
f4681817
MD
83 .freelist_head = -1,
84};
85
86static
f59ed768
MD
87int objd_alloc(void *private_data, const struct lttng_ust_objd_ops *ops,
88 void *owner)
f4681817 89{
b61ce3b2 90 struct lttng_ust_obj *obj;
f4681817
MD
91
92 if (objd_table.freelist_head != -1) {
93 obj = &objd_table.array[objd_table.freelist_head];
94 objd_table.freelist_head = obj->u.freelist_next;
95 goto end;
96 }
97
98 if (objd_table.len >= objd_table.allocated_len) {
99 unsigned int new_allocated_len, old_allocated_len;
b61ce3b2 100 struct lttng_ust_obj *new_table, *old_table;
f4681817
MD
101
102 old_allocated_len = objd_table.allocated_len;
103 old_table = objd_table.array;
104 if (!old_allocated_len)
105 new_allocated_len = 1;
106 else
107 new_allocated_len = old_allocated_len << 1;
b61ce3b2 108 new_table = zmalloc(sizeof(struct lttng_ust_obj) * new_allocated_len);
f4681817
MD
109 if (!new_table)
110 return -ENOMEM;
111 memcpy(new_table, old_table,
b61ce3b2 112 sizeof(struct lttng_ust_obj) * old_allocated_len);
f4681817
MD
113 free(old_table);
114 objd_table.array = new_table;
115 objd_table.allocated_len = new_allocated_len;
116 }
117 obj = &objd_table.array[objd_table.len];
118 objd_table.len++;
119end:
120 obj->u.s.private_data = private_data;
121 obj->u.s.ops = ops;
a4be8962
MD
122 obj->u.s.f_count = 2; /* count == 1 : object is allocated */
123 /* count == 2 : allocated + hold ref */
f59ed768 124 obj->u.s.owner = owner;
f4681817
MD
125 return obj - objd_table.array;
126}
127
128static
b61ce3b2 129struct lttng_ust_obj *_objd_get(int id)
f4681817
MD
130{
131 if (id >= objd_table.len)
132 return NULL;
a4be8962
MD
133 if (!objd_table.array[id].u.s.f_count)
134 return NULL;
f4681817
MD
135 return &objd_table.array[id];
136}
137
138static
139void *objd_private(int id)
140{
b61ce3b2 141 struct lttng_ust_obj *obj = _objd_get(id);
f4681817
MD
142 assert(obj);
143 return obj->u.s.private_data;
144}
145
146static
147void objd_set_private(int id, void *private_data)
148{
b61ce3b2 149 struct lttng_ust_obj *obj = _objd_get(id);
f4681817
MD
150 assert(obj);
151 obj->u.s.private_data = private_data;
152}
153
b61ce3b2 154const struct lttng_ust_objd_ops *objd_ops(int id)
f4681817 155{
b61ce3b2 156 struct lttng_ust_obj *obj = _objd_get(id);
46050b1a 157
a4be8962
MD
158 if (!obj)
159 return NULL;
f4681817
MD
160 return obj->u.s.ops;
161}
162
163static
164void objd_free(int id)
165{
b61ce3b2 166 struct lttng_ust_obj *obj = _objd_get(id);
f4681817
MD
167
168 assert(obj);
169 obj->u.freelist_next = objd_table.freelist_head;
170 objd_table.freelist_head = obj - objd_table.array;
a4be8962
MD
171 assert(obj->u.s.f_count == 1);
172 obj->u.s.f_count = 0; /* deallocated */
f4681817
MD
173}
174
175static
176void objd_ref(int id)
177{
b61ce3b2 178 struct lttng_ust_obj *obj = _objd_get(id);
f4681817
MD
179 obj->u.s.f_count++;
180}
181
d4419b81 182int lttng_ust_objd_unref(int id)
f4681817 183{
b61ce3b2 184 struct lttng_ust_obj *obj = _objd_get(id);
f4681817 185
1ea11eab
MD
186 if (!obj)
187 return -EINVAL;
a4be8962
MD
188 if (obj->u.s.f_count == 1) {
189 ERR("Reference counting error\n");
190 return -EINVAL;
191 }
192 if ((--obj->u.s.f_count) == 1) {
b61ce3b2 193 const struct lttng_ust_objd_ops *ops = objd_ops(id);
a4be8962 194
f4681817
MD
195 if (ops->release)
196 ops->release(id);
197 objd_free(id);
198 }
1ea11eab 199 return 0;
f4681817
MD
200}
201
202static
203void objd_table_destroy(void)
204{
a4be8962
MD
205 int i;
206
fb50c39d 207 for (i = 0; i < objd_table.allocated_len; i++)
d4419b81 208 (void) lttng_ust_objd_unref(i);
f4681817 209 free(objd_table.array);
02fb3381
MD
210 objd_table.array = NULL;
211 objd_table.len = 0;
212 objd_table.allocated_len = 0;
17dfb34b 213 objd_table.freelist_head = -1;
f4681817
MD
214}
215
f59ed768
MD
216void lttng_ust_objd_table_owner_cleanup(void *owner)
217{
218 int i;
219
220 for (i = 0; i < objd_table.allocated_len; i++) {
221 struct lttng_ust_obj *obj;
222
223 obj = _objd_get(i);
224 if (!obj)
225 continue;
226 if (!obj->u.s.owner)
227 continue; /* skip root handles */
228 if (obj->u.s.owner == owner)
229 (void) lttng_ust_objd_unref(i);
230 }
231}
232
f4681817
MD
233/*
234 * This is LTTng's own personal way to create an ABI for sessiond.
235 * We send commands over a socket.
236 */
237
b61ce3b2
MD
238static const struct lttng_ust_objd_ops lttng_ops;
239static const struct lttng_ust_objd_ops lttng_session_ops;
240static const struct lttng_ust_objd_ops lttng_channel_ops;
241static const struct lttng_ust_objd_ops lttng_metadata_ops;
242static const struct lttng_ust_objd_ops lttng_event_ops;
e6c12e3d 243static const struct lttng_ust_objd_ops lttng_wildcard_ops;
b61ce3b2 244static const struct lttng_ust_objd_ops lib_ring_buffer_objd_ops;
51489cad 245static const struct lttng_ust_objd_ops lttng_tracepoint_list_ops;
06d4f27e 246static const struct lttng_ust_objd_ops lttng_tracepoint_field_list_ops;
f4681817
MD
247
248enum channel_type {
249 PER_CPU_CHANNEL,
250 METADATA_CHANNEL,
251};
252
46050b1a
MD
253int lttng_abi_create_root_handle(void)
254{
255 int root_handle;
256
f59ed768
MD
257 /* root handles have NULL owners */
258 root_handle = objd_alloc(NULL, &lttng_ops, NULL);
46050b1a
MD
259 return root_handle;
260}
261
818173b9 262static
f59ed768 263int lttng_abi_create_session(void *owner)
f4681817 264{
7dd08bec 265 struct lttng_session *session;
f4681817
MD
266 int session_objd, ret;
267
7dd08bec 268 session = lttng_session_create();
f4681817
MD
269 if (!session)
270 return -ENOMEM;
f59ed768 271 session_objd = objd_alloc(session, &lttng_session_ops, owner);
f4681817
MD
272 if (session_objd < 0) {
273 ret = session_objd;
274 goto objd_error;
275 }
276 session->objd = session_objd;
277 return session_objd;
278
279objd_error:
7dd08bec 280 lttng_session_destroy(session);
f4681817
MD
281 return ret;
282}
283
f4681817
MD
284static
285long lttng_abi_tracer_version(int objd,
286 struct lttng_ust_tracer_version *v)
287{
0f4eaec3
MD
288 v->major = LTTNG_UST_INTERNAL_MAJOR_VERSION;
289 v->minor = LTTNG_UST_INTERNAL_MINOR_VERSION;
290 v->patchlevel = LTTNG_UST_INTERNAL_PATCHLEVEL_VERSION;
f4681817
MD
291 return 0;
292}
293
294static
295long lttng_abi_add_context(int objd,
296 struct lttng_ust_context *context_param,
7dd08bec 297 struct lttng_ctx **ctx, struct lttng_session *session)
f4681817
MD
298{
299 if (session->been_active)
300 return -EPERM;
301
302 switch (context_param->ctx) {
8de38cf7
MD
303 case LTTNG_UST_CONTEXT_PTHREAD_ID:
304 return lttng_add_pthread_id_to_ctx(ctx);
3b402b40
MD
305 case LTTNG_UST_CONTEXT_VTID:
306 return lttng_add_vtid_to_ctx(ctx);
c1ef86f0
MD
307 case LTTNG_UST_CONTEXT_VPID:
308 return lttng_add_vpid_to_ctx(ctx);
4847e9bb
MD
309 case LTTNG_UST_CONTEXT_PROCNAME:
310 return lttng_add_procname_to_ctx(ctx);
f4681817
MD
311 default:
312 return -EINVAL;
313 }
314}
315
316/**
317 * lttng_cmd - lttng control through socket commands
318 *
319 * @objd: the object descriptor
320 * @cmd: the command
321 * @arg: command arg
ef9ff354 322 * @uargs: UST arguments (internal)
f59ed768 323 * @owner: objd owner
f4681817
MD
324 *
325 * This descriptor implements lttng commands:
326 * LTTNG_UST_SESSION
327 * Returns a LTTng trace session object descriptor
328 * LTTNG_UST_TRACER_VERSION
329 * Returns the LTTng kernel tracer version
330 * LTTNG_UST_TRACEPOINT_LIST
331 * Returns a file descriptor listing available tracepoints
06d4f27e
MD
332 * LTTNG_UST_TRACEPOINT_FIELD_LIST
333 * Returns a file descriptor listing available tracepoint fields
f4681817
MD
334 * LTTNG_UST_WAIT_QUIESCENT
335 * Returns after all previously running probes have completed
336 *
337 * The returned session will be deleted when its file descriptor is closed.
338 */
339static
ef9ff354 340long lttng_cmd(int objd, unsigned int cmd, unsigned long arg,
f59ed768 341 union ust_args *uargs, void *owner)
f4681817
MD
342{
343 switch (cmd) {
344 case LTTNG_UST_SESSION:
f59ed768 345 return lttng_abi_create_session(owner);
f4681817
MD
346 case LTTNG_UST_TRACER_VERSION:
347 return lttng_abi_tracer_version(objd,
348 (struct lttng_ust_tracer_version *) arg);
349 case LTTNG_UST_TRACEPOINT_LIST:
f59ed768 350 return lttng_abi_tracepoint_list(owner);
06d4f27e 351 case LTTNG_UST_TRACEPOINT_FIELD_LIST:
f59ed768 352 return lttng_abi_tracepoint_field_list(owner);
f4681817
MD
353 case LTTNG_UST_WAIT_QUIESCENT:
354 synchronize_trace();
355 return 0;
356 default:
357 return -EINVAL;
358 }
359}
360
b61ce3b2 361static const struct lttng_ust_objd_ops lttng_ops = {
f4681817
MD
362 .cmd = lttng_cmd,
363};
364
365/*
366 * We tolerate no failure in this function (if one happens, we print a dmesg
367 * error, but cannot return any error, because the channel information is
368 * invariant.
369 */
370static
371void lttng_metadata_create_events(int channel_objd)
372{
7dd08bec 373 struct lttng_channel *channel = objd_private(channel_objd);
f4681817
MD
374 static struct lttng_ust_event metadata_params = {
375 .instrumentation = LTTNG_UST_TRACEPOINT,
a4ada9b8 376 .name = "lttng_ust:metadata",
457a6b58
MD
377 .loglevel_type = LTTNG_UST_LOGLEVEL_ALL,
378 .loglevel = TRACE_DEFAULT,
f4681817 379 };
7dd08bec 380 struct lttng_event *event;
576599a0 381 int ret;
f4681817
MD
382
383 /*
384 * We tolerate no failure path after event creation. It will stay
385 * invariant for the rest of the session.
386 */
7dd08bec 387 ret = lttng_event_create(channel, &metadata_params, &event);
576599a0 388 if (ret < 0) {
f4681817
MD
389 goto create_error;
390 }
391 return;
392
393create_error:
394 WARN_ON(1);
395 return; /* not allowed to return error */
396}
397
f4681817
MD
398int lttng_abi_create_channel(int session_objd,
399 struct lttng_ust_channel *chan_param,
ef9ff354 400 enum channel_type channel_type,
f59ed768
MD
401 union ust_args *uargs,
402 void *owner)
f4681817 403{
7dd08bec 404 struct lttng_session *session = objd_private(session_objd);
b61ce3b2 405 const struct lttng_ust_objd_ops *ops;
f4681817 406 const char *transport_name;
7dd08bec 407 struct lttng_channel *chan;
f4681817
MD
408 int chan_objd;
409 int ret = 0;
7dd08bec 410 struct lttng_channel chan_priv_init;
f4681817 411
f4681817
MD
412 switch (channel_type) {
413 case PER_CPU_CHANNEL:
414 if (chan_param->output == LTTNG_UST_MMAP) {
415 transport_name = chan_param->overwrite ?
416 "relay-overwrite-mmap" : "relay-discard-mmap";
417 } else {
418 return -EINVAL;
419 }
420 ops = &lttng_channel_ops;
421 break;
422 case METADATA_CHANNEL:
423 if (chan_param->output == LTTNG_UST_MMAP)
424 transport_name = "relay-metadata-mmap";
425 else
426 return -EINVAL;
427 ops = &lttng_metadata_ops;
428 break;
429 default:
430 transport_name = "<unknown>";
fe38d4af
MD
431 return -EINVAL;
432 }
f59ed768 433 chan_objd = objd_alloc(NULL, ops, owner);
fe38d4af
MD
434 if (chan_objd < 0) {
435 ret = chan_objd;
436 goto objd_error;
f4681817 437 }
d028eddb
MD
438 memset(&chan_priv_init, 0, sizeof(chan_priv_init));
439 /* Copy of session UUID for consumer (availability through shm) */
440 memcpy(chan_priv_init.uuid, session->uuid, sizeof(session->uuid));
441
f4681817
MD
442 /*
443 * We tolerate no failure path after channel creation. It will stay
444 * invariant for the rest of the session.
445 */
7dd08bec 446 chan = lttng_channel_create(session, transport_name, NULL,
f4681817
MD
447 chan_param->subbuf_size,
448 chan_param->num_subbuf,
449 chan_param->switch_timer_interval,
193183fb 450 chan_param->read_timer_interval,
ef9ff354
MD
451 &uargs->channel.shm_fd,
452 &uargs->channel.wait_fd,
453 &uargs->channel.memory_map_size,
d028eddb 454 &chan_priv_init);
f4681817
MD
455 if (!chan) {
456 ret = -EINVAL;
457 goto chan_error;
458 }
459 objd_set_private(chan_objd, chan);
460 chan->objd = chan_objd;
461 if (channel_type == METADATA_CHANNEL) {
462 session->metadata = chan;
463 lttng_metadata_create_events(chan_objd);
464 }
f4681817
MD
465 /* The channel created holds a reference on the session */
466 objd_ref(session_objd);
467
468 return chan_objd;
469
470chan_error:
1ea11eab
MD
471 {
472 int err;
473
d4419b81 474 err = lttng_ust_objd_unref(chan_objd);
1ea11eab
MD
475 assert(!err);
476 }
f4681817
MD
477objd_error:
478 return ret;
479}
480
481/**
482 * lttng_session_cmd - lttng session object command
483 *
484 * @obj: the object
485 * @cmd: the command
486 * @arg: command arg
ef9ff354 487 * @uargs: UST arguments (internal)
f59ed768 488 * @owner: objd owner
f4681817
MD
489 *
490 * This descriptor implements lttng commands:
491 * LTTNG_UST_CHANNEL
492 * Returns a LTTng channel object descriptor
493 * LTTNG_UST_ENABLE
494 * Enables tracing for a session (weak enable)
495 * LTTNG_UST_DISABLE
496 * Disables tracing for a session (strong disable)
497 * LTTNG_UST_METADATA
498 * Returns a LTTng metadata object descriptor
499 *
500 * The returned channel will be deleted when its file descriptor is closed.
501 */
502static
ef9ff354 503long lttng_session_cmd(int objd, unsigned int cmd, unsigned long arg,
f59ed768 504 union ust_args *uargs, void *owner)
f4681817 505{
7dd08bec 506 struct lttng_session *session = objd_private(objd);
f4681817
MD
507
508 switch (cmd) {
509 case LTTNG_UST_CHANNEL:
510 return lttng_abi_create_channel(objd,
511 (struct lttng_ust_channel *) arg,
f59ed768 512 PER_CPU_CHANNEL, uargs, owner);
f4681817
MD
513 case LTTNG_UST_SESSION_START:
514 case LTTNG_UST_ENABLE:
7dd08bec 515 return lttng_session_enable(session);
f4681817
MD
516 case LTTNG_UST_SESSION_STOP:
517 case LTTNG_UST_DISABLE:
7dd08bec 518 return lttng_session_disable(session);
f4681817
MD
519 case LTTNG_UST_METADATA:
520 return lttng_abi_create_channel(objd,
521 (struct lttng_ust_channel *) arg,
f59ed768 522 METADATA_CHANNEL, uargs, owner);
f4681817
MD
523 default:
524 return -EINVAL;
525 }
526}
527
528/*
529 * Called when the last file reference is dropped.
530 *
531 * Big fat note: channels and events are invariant for the whole session after
532 * their creation. So this session destruction also destroys all channel and
533 * event structures specific to this session (they are not destroyed when their
534 * individual file is released).
535 */
536static
1ea11eab 537int lttng_release_session(int objd)
f4681817 538{
7dd08bec 539 struct lttng_session *session = objd_private(objd);
f4681817 540
1ea11eab 541 if (session) {
7dd08bec 542 lttng_session_destroy(session);
1ea11eab
MD
543 return 0;
544 } else {
545 return -EINVAL;
546 }
f4681817
MD
547}
548
b61ce3b2 549static const struct lttng_ust_objd_ops lttng_session_ops = {
1ea11eab 550 .release = lttng_release_session,
f4681817
MD
551 .cmd = lttng_session_cmd,
552};
553
51489cad 554static
ef9ff354 555long lttng_tracepoint_list_cmd(int objd, unsigned int cmd, unsigned long arg,
f59ed768 556 union ust_args *uargs, void *owner)
51489cad 557{
c8fcf224 558 struct lttng_ust_tracepoint_list *list = objd_private(objd);
cbef6901
MD
559 struct lttng_ust_tracepoint_iter *tp =
560 (struct lttng_ust_tracepoint_iter *) arg;
c8fcf224 561 struct lttng_ust_tracepoint_iter *iter;
51489cad
MD
562
563 switch (cmd) {
564 case LTTNG_UST_TRACEPOINT_LIST_GET:
c8fcf224
MD
565 {
566 retry:
567 iter = lttng_ust_tracepoint_list_get_iter_next(list);
568 if (!iter)
7bc53e94 569 return -LTTNG_UST_ERR_NOENT;
c8fcf224
MD
570 if (!strcmp(iter->name, "lttng_ust:metadata"))
571 goto retry;
572 memcpy(tp, iter, sizeof(*tp));
51489cad 573 return 0;
c8fcf224 574 }
51489cad
MD
575 default:
576 return -EINVAL;
577 }
578}
579
580static
f59ed768 581int lttng_abi_tracepoint_list(void *owner)
51489cad
MD
582{
583 int list_objd, ret;
c8fcf224 584 struct lttng_ust_tracepoint_list *list;
51489cad 585
f59ed768 586 list_objd = objd_alloc(NULL, &lttng_tracepoint_list_ops, owner);
51489cad
MD
587 if (list_objd < 0) {
588 ret = list_objd;
589 goto objd_error;
590 }
591 list = zmalloc(sizeof(*list));
592 if (!list) {
593 ret = -ENOMEM;
594 goto alloc_error;
595 }
596 objd_set_private(list_objd, list);
597
c8fcf224 598 /* populate list by walking on all registered probes. */
7dd08bec 599 ret = lttng_probes_get_event_list(list);
c8fcf224
MD
600 if (ret) {
601 goto list_error;
602 }
51489cad
MD
603 return list_objd;
604
c8fcf224
MD
605list_error:
606 free(list);
51489cad
MD
607alloc_error:
608 {
609 int err;
610
611 err = lttng_ust_objd_unref(list_objd);
612 assert(!err);
613 }
614objd_error:
615 return ret;
616}
617
618static
619int lttng_release_tracepoint_list(int objd)
620{
c8fcf224 621 struct lttng_ust_tracepoint_list *list = objd_private(objd);
51489cad
MD
622
623 if (list) {
7dd08bec 624 lttng_probes_prune_event_list(list);
51489cad
MD
625 free(list);
626 return 0;
627 } else {
628 return -EINVAL;
629 }
630}
631
632static const struct lttng_ust_objd_ops lttng_tracepoint_list_ops = {
633 .release = lttng_release_tracepoint_list,
634 .cmd = lttng_tracepoint_list_cmd,
635};
636
06d4f27e
MD
637static
638long lttng_tracepoint_field_list_cmd(int objd, unsigned int cmd,
f59ed768 639 unsigned long arg, union ust_args *uargs, void *owner)
06d4f27e
MD
640{
641 struct lttng_ust_field_list *list = objd_private(objd);
40003310 642 struct lttng_ust_field_iter *tp = &uargs->field_list.entry;
06d4f27e
MD
643 struct lttng_ust_field_iter *iter;
644
645 switch (cmd) {
646 case LTTNG_UST_TRACEPOINT_FIELD_LIST_GET:
647 {
648 retry:
649 iter = lttng_ust_field_list_get_iter_next(list);
650 if (!iter)
7bc53e94 651 return -LTTNG_UST_ERR_NOENT;
06d4f27e
MD
652 if (!strcmp(iter->event_name, "lttng_ust:metadata"))
653 goto retry;
654 memcpy(tp, iter, sizeof(*tp));
655 return 0;
656 }
657 default:
658 return -EINVAL;
659 }
660}
661
662static
f59ed768 663int lttng_abi_tracepoint_field_list(void *owner)
06d4f27e
MD
664{
665 int list_objd, ret;
666 struct lttng_ust_field_list *list;
667
f59ed768 668 list_objd = objd_alloc(NULL, &lttng_tracepoint_field_list_ops, owner);
06d4f27e
MD
669 if (list_objd < 0) {
670 ret = list_objd;
671 goto objd_error;
672 }
673 list = zmalloc(sizeof(*list));
674 if (!list) {
675 ret = -ENOMEM;
676 goto alloc_error;
677 }
678 objd_set_private(list_objd, list);
679
680 /* populate list by walking on all registered probes. */
7dd08bec 681 ret = lttng_probes_get_field_list(list);
06d4f27e
MD
682 if (ret) {
683 goto list_error;
684 }
685 return list_objd;
686
687list_error:
688 free(list);
689alloc_error:
690 {
691 int err;
692
693 err = lttng_ust_objd_unref(list_objd);
694 assert(!err);
695 }
696objd_error:
697 return ret;
698}
699
700static
701int lttng_release_tracepoint_field_list(int objd)
702{
703 struct lttng_ust_field_list *list = objd_private(objd);
704
705 if (list) {
7dd08bec 706 lttng_probes_prune_field_list(list);
06d4f27e
MD
707 free(list);
708 return 0;
709 } else {
710 return -EINVAL;
711 }
712}
713
714static const struct lttng_ust_objd_ops lttng_tracepoint_field_list_ops = {
715 .release = lttng_release_tracepoint_field_list,
716 .cmd = lttng_tracepoint_field_list_cmd,
717};
718
381c0f1e 719struct stream_priv_data {
4cfec15c 720 struct lttng_ust_lib_ring_buffer *buf;
7dd08bec 721 struct lttng_channel *lttng_chan;
381c0f1e
MD
722};
723
f4681817 724static
ef9ff354 725int lttng_abi_open_stream(int channel_objd, struct lttng_ust_stream *info,
f59ed768 726 union ust_args *uargs, void *owner)
f4681817 727{
7dd08bec 728 struct lttng_channel *channel = objd_private(channel_objd);
4cfec15c 729 struct lttng_ust_lib_ring_buffer *buf;
381c0f1e 730 struct stream_priv_data *priv;
f4681817
MD
731 int stream_objd, ret;
732
381c0f1e 733 buf = channel->ops->buffer_read_open(channel->chan, channel->handle,
ef9ff354
MD
734 &uargs->stream.shm_fd,
735 &uargs->stream.wait_fd,
736 &uargs->stream.memory_map_size);
f4681817
MD
737 if (!buf)
738 return -ENOENT;
739
381c0f1e
MD
740 priv = zmalloc(sizeof(*priv));
741 if (!priv) {
742 ret = -ENOMEM;
743 goto alloc_error;
744 }
745 priv->buf = buf;
7dd08bec 746 priv->lttng_chan = channel;
f59ed768 747 stream_objd = objd_alloc(priv, &lib_ring_buffer_objd_ops, owner);
f4681817
MD
748 if (stream_objd < 0) {
749 ret = stream_objd;
750 goto objd_error;
751 }
381c0f1e
MD
752 /* Hold a reference on the channel object descriptor */
753 objd_ref(channel_objd);
f4681817
MD
754 return stream_objd;
755
756objd_error:
381c0f1e
MD
757 free(priv);
758alloc_error:
759 channel->ops->buffer_read_close(buf, channel->handle);
f4681817
MD
760 return ret;
761}
f4681817
MD
762
763static
764int lttng_abi_create_event(int channel_objd,
f59ed768
MD
765 struct lttng_ust_event *event_param,
766 void *owner)
f4681817 767{
7dd08bec
MD
768 struct lttng_channel *channel = objd_private(channel_objd);
769 struct lttng_event *event;
f4681817
MD
770 int event_objd, ret;
771
772 event_param->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
f59ed768 773 event_objd = objd_alloc(NULL, &lttng_event_ops, owner);
f4681817
MD
774 if (event_objd < 0) {
775 ret = event_objd;
776 goto objd_error;
777 }
778 /*
779 * We tolerate no failure path after event creation. It will stay
780 * invariant for the rest of the session.
781 */
7dd08bec 782 ret = lttng_event_create(channel, event_param, &event);
576599a0 783 if (ret < 0) {
f4681817
MD
784 goto event_error;
785 }
786 objd_set_private(event_objd, event);
787 /* The event holds a reference on the channel */
788 objd_ref(channel_objd);
789 return event_objd;
790
791event_error:
1ea11eab
MD
792 {
793 int err;
794
d4419b81 795 err = lttng_ust_objd_unref(event_objd);
1ea11eab
MD
796 assert(!err);
797 }
f4681817
MD
798objd_error:
799 return ret;
800}
801
e6c12e3d
MD
802static
803int lttng_abi_create_wildcard(int channel_objd,
f59ed768
MD
804 struct lttng_ust_event *event_param,
805 void *owner)
e6c12e3d 806{
7dd08bec 807 struct lttng_channel *channel = objd_private(channel_objd);
e6c12e3d
MD
808 struct session_wildcard *wildcard;
809 int wildcard_objd, ret;
810
811 event_param->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
f59ed768 812 wildcard_objd = objd_alloc(NULL, &lttng_wildcard_ops, owner);
e6c12e3d
MD
813 if (wildcard_objd < 0) {
814 ret = wildcard_objd;
815 goto objd_error;
816 }
817 /*
818 * We tolerate no failure path after wildcard creation. It will
819 * stay invariant for the rest of the session.
820 */
7dd08bec 821 ret = lttng_wildcard_create(channel, event_param, &wildcard);
e6c12e3d
MD
822 if (ret < 0) {
823 goto wildcard_error;
824 }
825 objd_set_private(wildcard_objd, wildcard);
826 /* The wildcard holds a reference on the channel */
827 objd_ref(channel_objd);
828 return wildcard_objd;
829
830wildcard_error:
831 {
832 int err;
833
834 err = lttng_ust_objd_unref(wildcard_objd);
835 assert(!err);
836 }
837objd_error:
838 return ret;
839}
840
f4681817
MD
841/**
842 * lttng_channel_cmd - lttng control through object descriptors
843 *
844 * @objd: the object descriptor
845 * @cmd: the command
846 * @arg: command arg
ef9ff354 847 * @uargs: UST arguments (internal)
f59ed768 848 * @owner: objd owner
f4681817
MD
849 *
850 * This object descriptor implements lttng commands:
851 * LTTNG_UST_STREAM
852 * Returns an event stream object descriptor or failure.
853 * (typically, one event stream records events from one CPU)
854 * LTTNG_UST_EVENT
855 * Returns an event object descriptor or failure.
856 * LTTNG_UST_CONTEXT
857 * Prepend a context field to each event in the channel
858 * LTTNG_UST_ENABLE
859 * Enable recording for events in this channel (weak enable)
860 * LTTNG_UST_DISABLE
861 * Disable recording for events in this channel (strong disable)
862 *
863 * Channel and event file descriptors also hold a reference on the session.
864 */
865static
ef9ff354 866long lttng_channel_cmd(int objd, unsigned int cmd, unsigned long arg,
f59ed768 867 union ust_args *uargs, void *owner)
f4681817 868{
7dd08bec 869 struct lttng_channel *channel = objd_private(objd);
f4681817
MD
870
871 switch (cmd) {
872 case LTTNG_UST_STREAM:
381c0f1e
MD
873 {
874 struct lttng_ust_stream *stream;
875
876 stream = (struct lttng_ust_stream *) arg;
877 /* stream used as output */
f59ed768 878 return lttng_abi_open_stream(objd, stream, uargs, owner);
381c0f1e 879 }
f4681817 880 case LTTNG_UST_EVENT:
1f18504e
MD
881 {
882 struct lttng_ust_event *event_param =
883 (struct lttng_ust_event *) arg;
6b0e60f1
MD
884 if (event_param->name[strlen(event_param->name) - 1] == '*') {
885 /* If ends with wildcard, create wildcard. */
f59ed768
MD
886 return lttng_abi_create_wildcard(objd, event_param,
887 owner);
1f18504e 888 } else {
f59ed768
MD
889 return lttng_abi_create_event(objd, event_param,
890 owner);
1f18504e
MD
891 }
892 }
f4681817
MD
893 case LTTNG_UST_CONTEXT:
894 return lttng_abi_add_context(objd,
895 (struct lttng_ust_context *) arg,
896 &channel->ctx, channel->session);
897 case LTTNG_UST_ENABLE:
7dd08bec 898 return lttng_channel_enable(channel);
f4681817 899 case LTTNG_UST_DISABLE:
7dd08bec 900 return lttng_channel_disable(channel);
43d330a4
MD
901 case LTTNG_UST_FLUSH_BUFFER:
902 return channel->ops->flush_buffer(channel->chan, channel->handle);
f4681817
MD
903 default:
904 return -EINVAL;
905 }
906}
907
908/**
909 * lttng_metadata_cmd - lttng control through object descriptors
910 *
911 * @objd: the object descriptor
912 * @cmd: the command
913 * @arg: command arg
ef9ff354 914 * @uargs: UST arguments (internal)
f59ed768 915 * @owner: objd owner
f4681817
MD
916 *
917 * This object descriptor implements lttng commands:
918 * LTTNG_UST_STREAM
919 * Returns an event stream file descriptor or failure.
920 *
921 * Channel and event file descriptors also hold a reference on the session.
922 */
923static
ef9ff354 924long lttng_metadata_cmd(int objd, unsigned int cmd, unsigned long arg,
f59ed768 925 union ust_args *uargs, void *owner)
f4681817 926{
7dd08bec 927 struct lttng_channel *channel = objd_private(objd);
43861eab 928
f4681817
MD
929 switch (cmd) {
930 case LTTNG_UST_STREAM:
381c0f1e
MD
931 {
932 struct lttng_ust_stream *stream;
933
934 stream = (struct lttng_ust_stream *) arg;
935 /* stream used as output */
f59ed768 936 return lttng_abi_open_stream(objd, stream, uargs, owner);
381c0f1e 937 }
43d330a4
MD
938 case LTTNG_UST_FLUSH_BUFFER:
939 return channel->ops->flush_buffer(channel->chan, channel->handle);
f4681817
MD
940 default:
941 return -EINVAL;
942 }
943}
944
945#if 0
946/**
947 * lttng_channel_poll - lttng stream addition/removal monitoring
948 *
949 * @file: the file
950 * @wait: poll table
951 */
952unsigned int lttng_channel_poll(struct file *file, poll_table *wait)
953{
7dd08bec 954 struct lttng_channel *channel = file->private_data;
f4681817
MD
955 unsigned int mask = 0;
956
957 if (file->f_mode & FMODE_READ) {
958 poll_wait_set_exclusive(wait);
959 poll_wait(file, channel->ops->get_hp_wait_queue(channel->chan),
960 wait);
961
962 if (channel->ops->is_disabled(channel->chan))
963 return POLLERR;
964 if (channel->ops->is_finalized(channel->chan))
965 return POLLHUP;
966 if (channel->ops->buffer_has_read_closed_stream(channel->chan))
967 return POLLIN | POLLRDNORM;
968 return 0;
969 }
970 return mask;
971
972}
973#endif //0
974
975static
976int lttng_channel_release(int objd)
977{
7dd08bec 978 struct lttng_channel *channel = objd_private(objd);
f4681817
MD
979
980 if (channel)
d4419b81 981 return lttng_ust_objd_unref(channel->session->objd);
f4681817
MD
982 return 0;
983}
984
b61ce3b2 985static const struct lttng_ust_objd_ops lttng_channel_ops = {
f4681817
MD
986 .release = lttng_channel_release,
987 //.poll = lttng_channel_poll,
988 .cmd = lttng_channel_cmd,
989};
990
b61ce3b2 991static const struct lttng_ust_objd_ops lttng_metadata_ops = {
f4681817
MD
992 .release = lttng_channel_release,
993 .cmd = lttng_metadata_cmd,
994};
995
381c0f1e
MD
996/**
997 * lttng_rb_cmd - lttng ring buffer control through object descriptors
998 *
999 * @objd: the object descriptor
1000 * @cmd: the command
1001 * @arg: command arg
ef9ff354 1002 * @uargs: UST arguments (internal)
f59ed768 1003 * @owner: objd owner
381c0f1e
MD
1004 *
1005 * This object descriptor implements lttng commands:
1006 * (None for now. Access is done directly though shm.)
381c0f1e
MD
1007 */
1008static
ef9ff354 1009long lttng_rb_cmd(int objd, unsigned int cmd, unsigned long arg,
f59ed768 1010 union ust_args *uargs, void *owner)
381c0f1e 1011{
381c0f1e
MD
1012 switch (cmd) {
1013 default:
1014 return -EINVAL;
1015 }
1016}
1017
1018static
1019int lttng_rb_release(int objd)
1020{
1021 struct stream_priv_data *priv = objd_private(objd);
4cfec15c 1022 struct lttng_ust_lib_ring_buffer *buf;
7dd08bec 1023 struct lttng_channel *channel;
381c0f1e
MD
1024
1025 if (priv) {
1026 buf = priv->buf;
7dd08bec 1027 channel = priv->lttng_chan;
381c0f1e 1028 free(priv);
45e9e699
MD
1029 /*
1030 * If we are at ABI exit, we don't want to close the
1031 * buffer opened for read: it is being shared between
1032 * the parent and child (right after fork), and we don't
1033 * want the child to close it for the parent. For a real
1034 * exit, we don't care about marking it as closed, as
1035 * the consumer daemon (if there is one) will do fine
1036 * even if we don't mark it as "closed" for reading on
1037 * our side.
1038 * We only mark it as closed if it is being explicitely
1039 * released by the session daemon with an explicit
1040 * release command.
1041 */
1042 if (!lttng_ust_abi_close_in_progress)
1043 channel->ops->buffer_read_close(buf, channel->handle);
381c0f1e 1044
d4419b81 1045 return lttng_ust_objd_unref(channel->objd);
381c0f1e
MD
1046 }
1047 return 0;
1048}
1049
b61ce3b2 1050static const struct lttng_ust_objd_ops lib_ring_buffer_objd_ops = {
381c0f1e
MD
1051 .release = lttng_rb_release,
1052 .cmd = lttng_rb_cmd,
1053};
1054
f4681817
MD
1055/**
1056 * lttng_event_cmd - lttng control through object descriptors
1057 *
1058 * @objd: the object descriptor
1059 * @cmd: the command
1060 * @arg: command arg
ef9ff354 1061 * @uargs: UST arguments (internal)
f59ed768 1062 * @owner: objd owner
f4681817
MD
1063 *
1064 * This object descriptor implements lttng commands:
1065 * LTTNG_UST_CONTEXT
1066 * Prepend a context field to each record of this event
1067 * LTTNG_UST_ENABLE
1068 * Enable recording for this event (weak enable)
1069 * LTTNG_UST_DISABLE
1070 * Disable recording for this event (strong disable)
2d78951a
MD
1071 * LTTNG_UST_FILTER
1072 * Attach a filter to an event.
f4681817
MD
1073 */
1074static
ef9ff354 1075long lttng_event_cmd(int objd, unsigned int cmd, unsigned long arg,
f59ed768 1076 union ust_args *uargs, void *owner)
f4681817 1077{
7dd08bec 1078 struct lttng_event *event = objd_private(objd);
f4681817
MD
1079
1080 switch (cmd) {
1081 case LTTNG_UST_CONTEXT:
1082 return lttng_abi_add_context(objd,
1083 (struct lttng_ust_context *) arg,
1084 &event->ctx, event->chan->session);
1085 case LTTNG_UST_ENABLE:
7dd08bec 1086 return lttng_event_enable(event);
f4681817 1087 case LTTNG_UST_DISABLE:
7dd08bec 1088 return lttng_event_disable(event);
2d78951a
MD
1089 case LTTNG_UST_FILTER:
1090 {
1091 int ret;
1092 ret = lttng_filter_event_attach_bytecode(event,
f488575f 1093 (struct lttng_ust_filter_bytecode_node *) arg);
2d78951a
MD
1094 if (ret)
1095 return ret;
f488575f 1096 lttng_filter_event_link_bytecode(event);
2d78951a
MD
1097 return 0;
1098 }
f4681817
MD
1099 default:
1100 return -EINVAL;
1101 }
1102}
1103
1104static
1105int lttng_event_release(int objd)
1106{
7dd08bec 1107 struct lttng_event *event = objd_private(objd);
f4681817
MD
1108
1109 if (event)
d4419b81 1110 return lttng_ust_objd_unref(event->chan->objd);
f4681817
MD
1111 return 0;
1112}
1113
1114/* TODO: filter control ioctl */
b61ce3b2 1115static const struct lttng_ust_objd_ops lttng_event_ops = {
f4681817
MD
1116 .release = lttng_event_release,
1117 .cmd = lttng_event_cmd,
1118};
1119
e6c12e3d
MD
1120/**
1121 * lttng_wildcard_cmd - lttng control through object descriptors
1122 *
1123 * @objd: the object descriptor
1124 * @cmd: the command
1125 * @arg: command arg
ef9ff354 1126 * @uargs: UST arguments (internal)
f59ed768 1127 * @owner: objd owner
e6c12e3d
MD
1128 *
1129 * This object descriptor implements lttng commands:
1130 * LTTNG_UST_CONTEXT
1131 * Prepend a context field to each record of events of this
1132 * wildcard.
1133 * LTTNG_UST_ENABLE
1134 * Enable recording for these wildcard events (weak enable)
1135 * LTTNG_UST_DISABLE
1136 * Disable recording for these wildcard events (strong disable)
2d78951a
MD
1137 * LTTNG_UST_FILTER
1138 * Attach a filter to a wildcard.
e6c12e3d
MD
1139 */
1140static
ef9ff354 1141long lttng_wildcard_cmd(int objd, unsigned int cmd, unsigned long arg,
f59ed768 1142 union ust_args *uargs, void *owner)
e6c12e3d
MD
1143{
1144 struct session_wildcard *wildcard = objd_private(objd);
1145
1146 switch (cmd) {
1147 case LTTNG_UST_CONTEXT:
1148 return -ENOSYS; /* not implemented yet */
1149#if 0
1150 return lttng_abi_add_context(objd,
1151 (struct lttng_ust_context *) arg,
1152 &wildcard->ctx, wildcard->chan->session);
1153#endif
1154 case LTTNG_UST_ENABLE:
7dd08bec 1155 return lttng_wildcard_enable(wildcard);
e6c12e3d 1156 case LTTNG_UST_DISABLE:
7dd08bec 1157 return lttng_wildcard_disable(wildcard);
2d78951a
MD
1158 case LTTNG_UST_FILTER:
1159 {
1160 int ret;
1161
1162 ret = lttng_filter_wildcard_attach_bytecode(wildcard,
f488575f 1163 (struct lttng_ust_filter_bytecode_node *) arg);
2d78951a
MD
1164 if (ret)
1165 return ret;
1166 lttng_filter_wildcard_link_bytecode(wildcard);
1167 return 0;
1168 }
e6c12e3d
MD
1169 default:
1170 return -EINVAL;
1171 }
1172}
1173
1174static
1175int lttng_wildcard_release(int objd)
1176{
1177 struct session_wildcard *wildcard = objd_private(objd);
1178
1179 if (wildcard)
1180 return lttng_ust_objd_unref(wildcard->chan->objd);
1181 return 0;
1182}
1183
1184/* TODO: filter control ioctl */
1185static const struct lttng_ust_objd_ops lttng_wildcard_ops = {
1186 .release = lttng_wildcard_release,
1187 .cmd = lttng_wildcard_cmd,
1188};
1189
b35d179d 1190void lttng_ust_abi_exit(void)
f4681817 1191{
45e9e699 1192 lttng_ust_abi_close_in_progress = 1;
f4681817 1193 objd_table_destroy();
45e9e699 1194 lttng_ust_abi_close_in_progress = 0;
f4681817 1195}
This page took 0.084117 seconds and 4 git commands to generate.