Tests: Fix rundir not created in ust-basic-tracing
[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;
e58095ef 242static const struct lttng_ust_objd_ops lttng_enabler_ops;
b61ce3b2 243static const struct lttng_ust_objd_ops lib_ring_buffer_objd_ops;
51489cad 244static const struct lttng_ust_objd_ops lttng_tracepoint_list_ops;
06d4f27e 245static const struct lttng_ust_objd_ops lttng_tracepoint_field_list_ops;
f4681817
MD
246
247enum channel_type {
248 PER_CPU_CHANNEL,
249 METADATA_CHANNEL,
250};
251
46050b1a
MD
252int lttng_abi_create_root_handle(void)
253{
254 int root_handle;
255
f59ed768
MD
256 /* root handles have NULL owners */
257 root_handle = objd_alloc(NULL, &lttng_ops, NULL);
46050b1a
MD
258 return root_handle;
259}
260
818173b9 261static
f59ed768 262int lttng_abi_create_session(void *owner)
f4681817 263{
7dd08bec 264 struct lttng_session *session;
f4681817
MD
265 int session_objd, ret;
266
7dd08bec 267 session = lttng_session_create();
f4681817
MD
268 if (!session)
269 return -ENOMEM;
f59ed768 270 session_objd = objd_alloc(session, &lttng_session_ops, owner);
f4681817
MD
271 if (session_objd < 0) {
272 ret = session_objd;
273 goto objd_error;
274 }
275 session->objd = session_objd;
276 return session_objd;
277
278objd_error:
7dd08bec 279 lttng_session_destroy(session);
f4681817
MD
280 return ret;
281}
282
f4681817
MD
283static
284long lttng_abi_tracer_version(int objd,
285 struct lttng_ust_tracer_version *v)
286{
0f4eaec3
MD
287 v->major = LTTNG_UST_INTERNAL_MAJOR_VERSION;
288 v->minor = LTTNG_UST_INTERNAL_MINOR_VERSION;
289 v->patchlevel = LTTNG_UST_INTERNAL_PATCHLEVEL_VERSION;
f4681817
MD
290 return 0;
291}
292
293static
294long lttng_abi_add_context(int objd,
295 struct lttng_ust_context *context_param,
7dd08bec 296 struct lttng_ctx **ctx, struct lttng_session *session)
f4681817 297{
e58095ef 298 return lttng_attach_context(context_param, ctx, session);
f4681817
MD
299}
300
301/**
302 * lttng_cmd - lttng control through socket commands
303 *
304 * @objd: the object descriptor
305 * @cmd: the command
306 * @arg: command arg
ef9ff354 307 * @uargs: UST arguments (internal)
f59ed768 308 * @owner: objd owner
f4681817
MD
309 *
310 * This descriptor implements lttng commands:
311 * LTTNG_UST_SESSION
312 * Returns a LTTng trace session object descriptor
313 * LTTNG_UST_TRACER_VERSION
314 * Returns the LTTng kernel tracer version
315 * LTTNG_UST_TRACEPOINT_LIST
316 * Returns a file descriptor listing available tracepoints
06d4f27e
MD
317 * LTTNG_UST_TRACEPOINT_FIELD_LIST
318 * Returns a file descriptor listing available tracepoint fields
f4681817
MD
319 * LTTNG_UST_WAIT_QUIESCENT
320 * Returns after all previously running probes have completed
321 *
322 * The returned session will be deleted when its file descriptor is closed.
323 */
324static
ef9ff354 325long lttng_cmd(int objd, unsigned int cmd, unsigned long arg,
f59ed768 326 union ust_args *uargs, void *owner)
f4681817
MD
327{
328 switch (cmd) {
329 case LTTNG_UST_SESSION:
f59ed768 330 return lttng_abi_create_session(owner);
f4681817
MD
331 case LTTNG_UST_TRACER_VERSION:
332 return lttng_abi_tracer_version(objd,
333 (struct lttng_ust_tracer_version *) arg);
334 case LTTNG_UST_TRACEPOINT_LIST:
f59ed768 335 return lttng_abi_tracepoint_list(owner);
06d4f27e 336 case LTTNG_UST_TRACEPOINT_FIELD_LIST:
f59ed768 337 return lttng_abi_tracepoint_field_list(owner);
f4681817
MD
338 case LTTNG_UST_WAIT_QUIESCENT:
339 synchronize_trace();
340 return 0;
341 default:
342 return -EINVAL;
343 }
344}
345
b61ce3b2 346static const struct lttng_ust_objd_ops lttng_ops = {
f4681817
MD
347 .cmd = lttng_cmd,
348};
349
350/*
351 * We tolerate no failure in this function (if one happens, we print a dmesg
352 * error, but cannot return any error, because the channel information is
353 * invariant.
354 */
355static
356void lttng_metadata_create_events(int channel_objd)
357{
e58095ef
MD
358 struct lttng_channel *chan = objd_private(channel_objd);
359 struct lttng_enabler *enabler;
f4681817
MD
360 static struct lttng_ust_event metadata_params = {
361 .instrumentation = LTTNG_UST_TRACEPOINT,
a4ada9b8 362 .name = "lttng_ust:metadata",
457a6b58
MD
363 .loglevel_type = LTTNG_UST_LOGLEVEL_ALL,
364 .loglevel = TRACE_DEFAULT,
f4681817 365 };
f4681817
MD
366
367 /*
368 * We tolerate no failure path after event creation. It will stay
369 * invariant for the rest of the session.
370 */
e58095ef
MD
371 enabler = lttng_enabler_create(LTTNG_ENABLER_EVENT,
372 &metadata_params, chan);
373 if (!enabler) {
f4681817
MD
374 goto create_error;
375 }
376 return;
377
378create_error:
379 WARN_ON(1);
380 return; /* not allowed to return error */
381}
382
f4681817
MD
383int lttng_abi_create_channel(int session_objd,
384 struct lttng_ust_channel *chan_param,
ef9ff354 385 enum channel_type channel_type,
f59ed768
MD
386 union ust_args *uargs,
387 void *owner)
f4681817 388{
7dd08bec 389 struct lttng_session *session = objd_private(session_objd);
b61ce3b2 390 const struct lttng_ust_objd_ops *ops;
f4681817 391 const char *transport_name;
7dd08bec 392 struct lttng_channel *chan;
f4681817
MD
393 int chan_objd;
394 int ret = 0;
7dd08bec 395 struct lttng_channel chan_priv_init;
f4681817 396
f4681817
MD
397 switch (channel_type) {
398 case PER_CPU_CHANNEL:
399 if (chan_param->output == LTTNG_UST_MMAP) {
400 transport_name = chan_param->overwrite ?
401 "relay-overwrite-mmap" : "relay-discard-mmap";
402 } else {
403 return -EINVAL;
404 }
405 ops = &lttng_channel_ops;
406 break;
407 case METADATA_CHANNEL:
408 if (chan_param->output == LTTNG_UST_MMAP)
409 transport_name = "relay-metadata-mmap";
410 else
411 return -EINVAL;
412 ops = &lttng_metadata_ops;
413 break;
414 default:
415 transport_name = "<unknown>";
fe38d4af
MD
416 return -EINVAL;
417 }
f59ed768 418 chan_objd = objd_alloc(NULL, ops, owner);
fe38d4af
MD
419 if (chan_objd < 0) {
420 ret = chan_objd;
421 goto objd_error;
f4681817 422 }
d028eddb
MD
423 memset(&chan_priv_init, 0, sizeof(chan_priv_init));
424 /* Copy of session UUID for consumer (availability through shm) */
425 memcpy(chan_priv_init.uuid, session->uuid, sizeof(session->uuid));
426
f4681817
MD
427 /*
428 * We tolerate no failure path after channel creation. It will stay
429 * invariant for the rest of the session.
430 */
7dd08bec 431 chan = lttng_channel_create(session, transport_name, NULL,
f4681817
MD
432 chan_param->subbuf_size,
433 chan_param->num_subbuf,
434 chan_param->switch_timer_interval,
193183fb 435 chan_param->read_timer_interval,
ef9ff354
MD
436 &uargs->channel.shm_fd,
437 &uargs->channel.wait_fd,
438 &uargs->channel.memory_map_size,
d028eddb 439 &chan_priv_init);
f4681817
MD
440 if (!chan) {
441 ret = -EINVAL;
442 goto chan_error;
443 }
444 objd_set_private(chan_objd, chan);
445 chan->objd = chan_objd;
446 if (channel_type == METADATA_CHANNEL) {
447 session->metadata = chan;
448 lttng_metadata_create_events(chan_objd);
449 }
f4681817
MD
450 /* The channel created holds a reference on the session */
451 objd_ref(session_objd);
452
453 return chan_objd;
454
455chan_error:
1ea11eab
MD
456 {
457 int err;
458
d4419b81 459 err = lttng_ust_objd_unref(chan_objd);
1ea11eab
MD
460 assert(!err);
461 }
f4681817
MD
462objd_error:
463 return ret;
464}
465
466/**
467 * lttng_session_cmd - lttng session object command
468 *
469 * @obj: the object
470 * @cmd: the command
471 * @arg: command arg
ef9ff354 472 * @uargs: UST arguments (internal)
f59ed768 473 * @owner: objd owner
f4681817
MD
474 *
475 * This descriptor implements lttng commands:
476 * LTTNG_UST_CHANNEL
477 * Returns a LTTng channel object descriptor
478 * LTTNG_UST_ENABLE
479 * Enables tracing for a session (weak enable)
480 * LTTNG_UST_DISABLE
481 * Disables tracing for a session (strong disable)
482 * LTTNG_UST_METADATA
483 * Returns a LTTng metadata object descriptor
484 *
485 * The returned channel will be deleted when its file descriptor is closed.
486 */
487static
ef9ff354 488long lttng_session_cmd(int objd, unsigned int cmd, unsigned long arg,
f59ed768 489 union ust_args *uargs, void *owner)
f4681817 490{
7dd08bec 491 struct lttng_session *session = objd_private(objd);
f4681817
MD
492
493 switch (cmd) {
494 case LTTNG_UST_CHANNEL:
495 return lttng_abi_create_channel(objd,
496 (struct lttng_ust_channel *) arg,
f59ed768 497 PER_CPU_CHANNEL, uargs, owner);
f4681817
MD
498 case LTTNG_UST_SESSION_START:
499 case LTTNG_UST_ENABLE:
7dd08bec 500 return lttng_session_enable(session);
f4681817
MD
501 case LTTNG_UST_SESSION_STOP:
502 case LTTNG_UST_DISABLE:
7dd08bec 503 return lttng_session_disable(session);
f4681817
MD
504 case LTTNG_UST_METADATA:
505 return lttng_abi_create_channel(objd,
506 (struct lttng_ust_channel *) arg,
f59ed768 507 METADATA_CHANNEL, uargs, owner);
f4681817
MD
508 default:
509 return -EINVAL;
510 }
511}
512
513/*
514 * Called when the last file reference is dropped.
515 *
516 * Big fat note: channels and events are invariant for the whole session after
517 * their creation. So this session destruction also destroys all channel and
518 * event structures specific to this session (they are not destroyed when their
519 * individual file is released).
520 */
521static
1ea11eab 522int lttng_release_session(int objd)
f4681817 523{
7dd08bec 524 struct lttng_session *session = objd_private(objd);
f4681817 525
1ea11eab 526 if (session) {
7dd08bec 527 lttng_session_destroy(session);
1ea11eab
MD
528 return 0;
529 } else {
530 return -EINVAL;
531 }
f4681817
MD
532}
533
b61ce3b2 534static const struct lttng_ust_objd_ops lttng_session_ops = {
1ea11eab 535 .release = lttng_release_session,
f4681817
MD
536 .cmd = lttng_session_cmd,
537};
538
51489cad 539static
ef9ff354 540long lttng_tracepoint_list_cmd(int objd, unsigned int cmd, unsigned long arg,
f59ed768 541 union ust_args *uargs, void *owner)
51489cad 542{
c8fcf224 543 struct lttng_ust_tracepoint_list *list = objd_private(objd);
cbef6901
MD
544 struct lttng_ust_tracepoint_iter *tp =
545 (struct lttng_ust_tracepoint_iter *) arg;
c8fcf224 546 struct lttng_ust_tracepoint_iter *iter;
51489cad
MD
547
548 switch (cmd) {
549 case LTTNG_UST_TRACEPOINT_LIST_GET:
c8fcf224
MD
550 {
551 retry:
552 iter = lttng_ust_tracepoint_list_get_iter_next(list);
553 if (!iter)
7bc53e94 554 return -LTTNG_UST_ERR_NOENT;
c8fcf224
MD
555 if (!strcmp(iter->name, "lttng_ust:metadata"))
556 goto retry;
557 memcpy(tp, iter, sizeof(*tp));
51489cad 558 return 0;
c8fcf224 559 }
51489cad
MD
560 default:
561 return -EINVAL;
562 }
563}
564
565static
f59ed768 566int lttng_abi_tracepoint_list(void *owner)
51489cad
MD
567{
568 int list_objd, ret;
c8fcf224 569 struct lttng_ust_tracepoint_list *list;
51489cad 570
f59ed768 571 list_objd = objd_alloc(NULL, &lttng_tracepoint_list_ops, owner);
51489cad
MD
572 if (list_objd < 0) {
573 ret = list_objd;
574 goto objd_error;
575 }
576 list = zmalloc(sizeof(*list));
577 if (!list) {
578 ret = -ENOMEM;
579 goto alloc_error;
580 }
581 objd_set_private(list_objd, list);
582
c8fcf224 583 /* populate list by walking on all registered probes. */
7dd08bec 584 ret = lttng_probes_get_event_list(list);
c8fcf224
MD
585 if (ret) {
586 goto list_error;
587 }
51489cad
MD
588 return list_objd;
589
c8fcf224
MD
590list_error:
591 free(list);
51489cad
MD
592alloc_error:
593 {
594 int err;
595
596 err = lttng_ust_objd_unref(list_objd);
597 assert(!err);
598 }
599objd_error:
600 return ret;
601}
602
603static
604int lttng_release_tracepoint_list(int objd)
605{
c8fcf224 606 struct lttng_ust_tracepoint_list *list = objd_private(objd);
51489cad
MD
607
608 if (list) {
7dd08bec 609 lttng_probes_prune_event_list(list);
51489cad
MD
610 free(list);
611 return 0;
612 } else {
613 return -EINVAL;
614 }
615}
616
617static const struct lttng_ust_objd_ops lttng_tracepoint_list_ops = {
618 .release = lttng_release_tracepoint_list,
619 .cmd = lttng_tracepoint_list_cmd,
620};
621
06d4f27e
MD
622static
623long lttng_tracepoint_field_list_cmd(int objd, unsigned int cmd,
f59ed768 624 unsigned long arg, union ust_args *uargs, void *owner)
06d4f27e
MD
625{
626 struct lttng_ust_field_list *list = objd_private(objd);
40003310 627 struct lttng_ust_field_iter *tp = &uargs->field_list.entry;
06d4f27e
MD
628 struct lttng_ust_field_iter *iter;
629
630 switch (cmd) {
631 case LTTNG_UST_TRACEPOINT_FIELD_LIST_GET:
632 {
633 retry:
634 iter = lttng_ust_field_list_get_iter_next(list);
635 if (!iter)
7bc53e94 636 return -LTTNG_UST_ERR_NOENT;
06d4f27e
MD
637 if (!strcmp(iter->event_name, "lttng_ust:metadata"))
638 goto retry;
639 memcpy(tp, iter, sizeof(*tp));
640 return 0;
641 }
642 default:
643 return -EINVAL;
644 }
645}
646
647static
f59ed768 648int lttng_abi_tracepoint_field_list(void *owner)
06d4f27e
MD
649{
650 int list_objd, ret;
651 struct lttng_ust_field_list *list;
652
f59ed768 653 list_objd = objd_alloc(NULL, &lttng_tracepoint_field_list_ops, owner);
06d4f27e
MD
654 if (list_objd < 0) {
655 ret = list_objd;
656 goto objd_error;
657 }
658 list = zmalloc(sizeof(*list));
659 if (!list) {
660 ret = -ENOMEM;
661 goto alloc_error;
662 }
663 objd_set_private(list_objd, list);
664
665 /* populate list by walking on all registered probes. */
7dd08bec 666 ret = lttng_probes_get_field_list(list);
06d4f27e
MD
667 if (ret) {
668 goto list_error;
669 }
670 return list_objd;
671
672list_error:
673 free(list);
674alloc_error:
675 {
676 int err;
677
678 err = lttng_ust_objd_unref(list_objd);
679 assert(!err);
680 }
681objd_error:
682 return ret;
683}
684
685static
686int lttng_release_tracepoint_field_list(int objd)
687{
688 struct lttng_ust_field_list *list = objd_private(objd);
689
690 if (list) {
7dd08bec 691 lttng_probes_prune_field_list(list);
06d4f27e
MD
692 free(list);
693 return 0;
694 } else {
695 return -EINVAL;
696 }
697}
698
699static const struct lttng_ust_objd_ops lttng_tracepoint_field_list_ops = {
700 .release = lttng_release_tracepoint_field_list,
701 .cmd = lttng_tracepoint_field_list_cmd,
702};
703
381c0f1e 704struct stream_priv_data {
4cfec15c 705 struct lttng_ust_lib_ring_buffer *buf;
7dd08bec 706 struct lttng_channel *lttng_chan;
381c0f1e
MD
707};
708
f4681817 709static
ef9ff354 710int lttng_abi_open_stream(int channel_objd, struct lttng_ust_stream *info,
f59ed768 711 union ust_args *uargs, void *owner)
f4681817 712{
7dd08bec 713 struct lttng_channel *channel = objd_private(channel_objd);
4cfec15c 714 struct lttng_ust_lib_ring_buffer *buf;
381c0f1e 715 struct stream_priv_data *priv;
f4681817
MD
716 int stream_objd, ret;
717
381c0f1e 718 buf = channel->ops->buffer_read_open(channel->chan, channel->handle,
ef9ff354
MD
719 &uargs->stream.shm_fd,
720 &uargs->stream.wait_fd,
721 &uargs->stream.memory_map_size);
f4681817
MD
722 if (!buf)
723 return -ENOENT;
724
381c0f1e
MD
725 priv = zmalloc(sizeof(*priv));
726 if (!priv) {
727 ret = -ENOMEM;
728 goto alloc_error;
729 }
730 priv->buf = buf;
7dd08bec 731 priv->lttng_chan = channel;
f59ed768 732 stream_objd = objd_alloc(priv, &lib_ring_buffer_objd_ops, owner);
f4681817
MD
733 if (stream_objd < 0) {
734 ret = stream_objd;
735 goto objd_error;
736 }
381c0f1e
MD
737 /* Hold a reference on the channel object descriptor */
738 objd_ref(channel_objd);
f4681817
MD
739 return stream_objd;
740
741objd_error:
381c0f1e
MD
742 free(priv);
743alloc_error:
744 channel->ops->buffer_read_close(buf, channel->handle);
f4681817
MD
745 return ret;
746}
f4681817
MD
747
748static
e58095ef 749int lttng_abi_create_enabler(int channel_objd,
f59ed768 750 struct lttng_ust_event *event_param,
e58095ef
MD
751 void *owner,
752 enum lttng_enabler_type type)
f4681817 753{
7dd08bec 754 struct lttng_channel *channel = objd_private(channel_objd);
e58095ef 755 struct lttng_enabler *enabler;
f4681817
MD
756 int event_objd, ret;
757
758 event_param->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
e58095ef 759 event_objd = objd_alloc(NULL, &lttng_enabler_ops, owner);
f4681817
MD
760 if (event_objd < 0) {
761 ret = event_objd;
762 goto objd_error;
763 }
764 /*
765 * We tolerate no failure path after event creation. It will stay
766 * invariant for the rest of the session.
767 */
e58095ef
MD
768 enabler = lttng_enabler_create(type, event_param, channel);
769 if (!enabler) {
770 ret = -ENOMEM;
f4681817
MD
771 goto event_error;
772 }
e58095ef 773 objd_set_private(event_objd, enabler);
f4681817
MD
774 /* The event holds a reference on the channel */
775 objd_ref(channel_objd);
776 return event_objd;
777
778event_error:
1ea11eab
MD
779 {
780 int err;
781
d4419b81 782 err = lttng_ust_objd_unref(event_objd);
1ea11eab
MD
783 assert(!err);
784 }
f4681817
MD
785objd_error:
786 return ret;
787}
788
789/**
790 * lttng_channel_cmd - lttng control through object descriptors
791 *
792 * @objd: the object descriptor
793 * @cmd: the command
794 * @arg: command arg
ef9ff354 795 * @uargs: UST arguments (internal)
f59ed768 796 * @owner: objd owner
f4681817
MD
797 *
798 * This object descriptor implements lttng commands:
799 * LTTNG_UST_STREAM
800 * Returns an event stream object descriptor or failure.
801 * (typically, one event stream records events from one CPU)
802 * LTTNG_UST_EVENT
803 * Returns an event object descriptor or failure.
804 * LTTNG_UST_CONTEXT
805 * Prepend a context field to each event in the channel
806 * LTTNG_UST_ENABLE
807 * Enable recording for events in this channel (weak enable)
808 * LTTNG_UST_DISABLE
809 * Disable recording for events in this channel (strong disable)
810 *
811 * Channel and event file descriptors also hold a reference on the session.
812 */
813static
ef9ff354 814long lttng_channel_cmd(int objd, unsigned int cmd, unsigned long arg,
f59ed768 815 union ust_args *uargs, void *owner)
f4681817 816{
7dd08bec 817 struct lttng_channel *channel = objd_private(objd);
f4681817
MD
818
819 switch (cmd) {
820 case LTTNG_UST_STREAM:
381c0f1e
MD
821 {
822 struct lttng_ust_stream *stream;
823
824 stream = (struct lttng_ust_stream *) arg;
825 /* stream used as output */
f59ed768 826 return lttng_abi_open_stream(objd, stream, uargs, owner);
381c0f1e 827 }
f4681817 828 case LTTNG_UST_EVENT:
1f18504e
MD
829 {
830 struct lttng_ust_event *event_param =
831 (struct lttng_ust_event *) arg;
6b0e60f1
MD
832 if (event_param->name[strlen(event_param->name) - 1] == '*') {
833 /* If ends with wildcard, create wildcard. */
e58095ef
MD
834 return lttng_abi_create_enabler(objd, event_param,
835 owner, LTTNG_ENABLER_WILDCARD);
1f18504e 836 } else {
e58095ef
MD
837 return lttng_abi_create_enabler(objd, event_param,
838 owner, LTTNG_ENABLER_EVENT);
1f18504e
MD
839 }
840 }
f4681817
MD
841 case LTTNG_UST_CONTEXT:
842 return lttng_abi_add_context(objd,
843 (struct lttng_ust_context *) arg,
844 &channel->ctx, channel->session);
845 case LTTNG_UST_ENABLE:
7dd08bec 846 return lttng_channel_enable(channel);
f4681817 847 case LTTNG_UST_DISABLE:
7dd08bec 848 return lttng_channel_disable(channel);
43d330a4
MD
849 case LTTNG_UST_FLUSH_BUFFER:
850 return channel->ops->flush_buffer(channel->chan, channel->handle);
f4681817
MD
851 default:
852 return -EINVAL;
853 }
854}
855
856/**
857 * lttng_metadata_cmd - lttng control through object descriptors
858 *
859 * @objd: the object descriptor
860 * @cmd: the command
861 * @arg: command arg
ef9ff354 862 * @uargs: UST arguments (internal)
f59ed768 863 * @owner: objd owner
f4681817
MD
864 *
865 * This object descriptor implements lttng commands:
866 * LTTNG_UST_STREAM
867 * Returns an event stream file descriptor or failure.
868 *
869 * Channel and event file descriptors also hold a reference on the session.
870 */
871static
ef9ff354 872long lttng_metadata_cmd(int objd, unsigned int cmd, unsigned long arg,
f59ed768 873 union ust_args *uargs, void *owner)
f4681817 874{
7dd08bec 875 struct lttng_channel *channel = objd_private(objd);
43861eab 876
f4681817
MD
877 switch (cmd) {
878 case LTTNG_UST_STREAM:
381c0f1e
MD
879 {
880 struct lttng_ust_stream *stream;
881
882 stream = (struct lttng_ust_stream *) arg;
883 /* stream used as output */
f59ed768 884 return lttng_abi_open_stream(objd, stream, uargs, owner);
381c0f1e 885 }
43d330a4
MD
886 case LTTNG_UST_FLUSH_BUFFER:
887 return channel->ops->flush_buffer(channel->chan, channel->handle);
f4681817
MD
888 default:
889 return -EINVAL;
890 }
891}
892
f4681817
MD
893static
894int lttng_channel_release(int objd)
895{
7dd08bec 896 struct lttng_channel *channel = objd_private(objd);
f4681817
MD
897
898 if (channel)
d4419b81 899 return lttng_ust_objd_unref(channel->session->objd);
f4681817
MD
900 return 0;
901}
902
b61ce3b2 903static const struct lttng_ust_objd_ops lttng_channel_ops = {
f4681817 904 .release = lttng_channel_release,
f4681817
MD
905 .cmd = lttng_channel_cmd,
906};
907
b61ce3b2 908static const struct lttng_ust_objd_ops lttng_metadata_ops = {
f4681817
MD
909 .release = lttng_channel_release,
910 .cmd = lttng_metadata_cmd,
911};
912
381c0f1e
MD
913/**
914 * lttng_rb_cmd - lttng ring buffer control through object descriptors
915 *
916 * @objd: the object descriptor
917 * @cmd: the command
918 * @arg: command arg
ef9ff354 919 * @uargs: UST arguments (internal)
f59ed768 920 * @owner: objd owner
381c0f1e
MD
921 *
922 * This object descriptor implements lttng commands:
923 * (None for now. Access is done directly though shm.)
381c0f1e
MD
924 */
925static
ef9ff354 926long lttng_rb_cmd(int objd, unsigned int cmd, unsigned long arg,
f59ed768 927 union ust_args *uargs, void *owner)
381c0f1e 928{
381c0f1e
MD
929 switch (cmd) {
930 default:
931 return -EINVAL;
932 }
933}
934
935static
936int lttng_rb_release(int objd)
937{
938 struct stream_priv_data *priv = objd_private(objd);
4cfec15c 939 struct lttng_ust_lib_ring_buffer *buf;
7dd08bec 940 struct lttng_channel *channel;
381c0f1e
MD
941
942 if (priv) {
943 buf = priv->buf;
7dd08bec 944 channel = priv->lttng_chan;
381c0f1e 945 free(priv);
45e9e699
MD
946 /*
947 * If we are at ABI exit, we don't want to close the
948 * buffer opened for read: it is being shared between
949 * the parent and child (right after fork), and we don't
950 * want the child to close it for the parent. For a real
951 * exit, we don't care about marking it as closed, as
952 * the consumer daemon (if there is one) will do fine
953 * even if we don't mark it as "closed" for reading on
954 * our side.
955 * We only mark it as closed if it is being explicitely
956 * released by the session daemon with an explicit
957 * release command.
958 */
959 if (!lttng_ust_abi_close_in_progress)
960 channel->ops->buffer_read_close(buf, channel->handle);
381c0f1e 961
d4419b81 962 return lttng_ust_objd_unref(channel->objd);
381c0f1e
MD
963 }
964 return 0;
965}
966
b61ce3b2 967static const struct lttng_ust_objd_ops lib_ring_buffer_objd_ops = {
381c0f1e
MD
968 .release = lttng_rb_release,
969 .cmd = lttng_rb_cmd,
970};
971
f4681817 972/**
e58095ef 973 * lttng_enabler_cmd - lttng control through object descriptors
e6c12e3d
MD
974 *
975 * @objd: the object descriptor
976 * @cmd: the command
977 * @arg: command arg
ef9ff354 978 * @uargs: UST arguments (internal)
f59ed768 979 * @owner: objd owner
e6c12e3d
MD
980 *
981 * This object descriptor implements lttng commands:
982 * LTTNG_UST_CONTEXT
983 * Prepend a context field to each record of events of this
e58095ef 984 * enabler.
e6c12e3d 985 * LTTNG_UST_ENABLE
e58095ef 986 * Enable recording for this enabler
e6c12e3d 987 * LTTNG_UST_DISABLE
e58095ef 988 * Disable recording for this enabler
2d78951a 989 * LTTNG_UST_FILTER
e58095ef 990 * Attach a filter to an enabler.
e6c12e3d
MD
991 */
992static
e58095ef 993long lttng_enabler_cmd(int objd, unsigned int cmd, unsigned long arg,
f59ed768 994 union ust_args *uargs, void *owner)
e6c12e3d 995{
e58095ef 996 struct lttng_enabler *enabler = objd_private(objd);
e6c12e3d
MD
997
998 switch (cmd) {
999 case LTTNG_UST_CONTEXT:
e58095ef
MD
1000 return lttng_enabler_attach_context(enabler,
1001 (struct lttng_ust_context *) arg);
e6c12e3d 1002 case LTTNG_UST_ENABLE:
e58095ef 1003 return lttng_enabler_enable(enabler);
e6c12e3d 1004 case LTTNG_UST_DISABLE:
e58095ef 1005 return lttng_enabler_disable(enabler);
2d78951a
MD
1006 case LTTNG_UST_FILTER:
1007 {
1008 int ret;
1009
e58095ef 1010 ret = lttng_enabler_attach_bytecode(enabler,
f488575f 1011 (struct lttng_ust_filter_bytecode_node *) arg);
2d78951a
MD
1012 if (ret)
1013 return ret;
2d78951a
MD
1014 return 0;
1015 }
e6c12e3d
MD
1016 default:
1017 return -EINVAL;
1018 }
1019}
1020
1021static
e58095ef 1022int lttng_enabler_release(int objd)
e6c12e3d 1023{
e58095ef 1024 struct lttng_enabler *enabler = objd_private(objd);
e6c12e3d 1025
e58095ef
MD
1026 if (enabler)
1027 return lttng_ust_objd_unref(enabler->chan->objd);
e6c12e3d
MD
1028 return 0;
1029}
1030
e58095ef
MD
1031static const struct lttng_ust_objd_ops lttng_enabler_ops = {
1032 .release = lttng_enabler_release,
1033 .cmd = lttng_enabler_cmd,
e6c12e3d
MD
1034};
1035
b35d179d 1036void lttng_ust_abi_exit(void)
f4681817 1037{
45e9e699 1038 lttng_ust_abi_close_in_progress = 1;
f4681817 1039 objd_table_destroy();
45e9e699 1040 lttng_ust_abi_close_in_progress = 0;
f4681817 1041}
This page took 0.078028 seconds and 4 git commands to generate.