Implement support for overlapping wildcard/events
[lttng-ust.git] / liblttng-ust / lttng-ust-abi.c
1 /*
2 * lttng-ust-abi.c
3 *
4 * LTTng UST ABI
5 *
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 *
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.
38 */
39
40 #include <lttng/ust-abi.h>
41 #include <lttng/ust-error.h>
42 #include <urcu/compiler.h>
43 #include <urcu/list.h>
44 #include <lttng/ust-events.h>
45 #include <lttng/ust-version.h>
46 #include <lttng/tracepoint.h>
47 #include "tracepoint-internal.h"
48 #include <usterr-signal-safe.h>
49 #include <helper.h>
50 #include "lttng-tracer.h"
51
52 static int lttng_ust_abi_close_in_progress;
53
54 static
55 int lttng_abi_tracepoint_list(void *owner);
56 static
57 int lttng_abi_tracepoint_field_list(void *owner);
58
59 /*
60 * Object descriptor table. Should be protected from concurrent access
61 * by the caller.
62 */
63
64 struct lttng_ust_obj {
65 union {
66 struct {
67 void *private_data;
68 const struct lttng_ust_objd_ops *ops;
69 int f_count;
70 void *owner;
71 } s;
72 int freelist_next; /* offset freelist. end is -1. */
73 } u;
74 };
75
76 struct lttng_ust_objd_table {
77 struct lttng_ust_obj *array;
78 unsigned int len, allocated_len;
79 int freelist_head; /* offset freelist head. end is -1 */
80 };
81
82 static struct lttng_ust_objd_table objd_table = {
83 .freelist_head = -1,
84 };
85
86 static
87 int objd_alloc(void *private_data, const struct lttng_ust_objd_ops *ops,
88 void *owner)
89 {
90 struct lttng_ust_obj *obj;
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;
100 struct lttng_ust_obj *new_table, *old_table;
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;
108 new_table = zmalloc(sizeof(struct lttng_ust_obj) * new_allocated_len);
109 if (!new_table)
110 return -ENOMEM;
111 memcpy(new_table, old_table,
112 sizeof(struct lttng_ust_obj) * old_allocated_len);
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++;
119 end:
120 obj->u.s.private_data = private_data;
121 obj->u.s.ops = ops;
122 obj->u.s.f_count = 2; /* count == 1 : object is allocated */
123 /* count == 2 : allocated + hold ref */
124 obj->u.s.owner = owner;
125 return obj - objd_table.array;
126 }
127
128 static
129 struct lttng_ust_obj *_objd_get(int id)
130 {
131 if (id >= objd_table.len)
132 return NULL;
133 if (!objd_table.array[id].u.s.f_count)
134 return NULL;
135 return &objd_table.array[id];
136 }
137
138 static
139 void *objd_private(int id)
140 {
141 struct lttng_ust_obj *obj = _objd_get(id);
142 assert(obj);
143 return obj->u.s.private_data;
144 }
145
146 static
147 void objd_set_private(int id, void *private_data)
148 {
149 struct lttng_ust_obj *obj = _objd_get(id);
150 assert(obj);
151 obj->u.s.private_data = private_data;
152 }
153
154 const struct lttng_ust_objd_ops *objd_ops(int id)
155 {
156 struct lttng_ust_obj *obj = _objd_get(id);
157
158 if (!obj)
159 return NULL;
160 return obj->u.s.ops;
161 }
162
163 static
164 void objd_free(int id)
165 {
166 struct lttng_ust_obj *obj = _objd_get(id);
167
168 assert(obj);
169 obj->u.freelist_next = objd_table.freelist_head;
170 objd_table.freelist_head = obj - objd_table.array;
171 assert(obj->u.s.f_count == 1);
172 obj->u.s.f_count = 0; /* deallocated */
173 }
174
175 static
176 void objd_ref(int id)
177 {
178 struct lttng_ust_obj *obj = _objd_get(id);
179 obj->u.s.f_count++;
180 }
181
182 int lttng_ust_objd_unref(int id)
183 {
184 struct lttng_ust_obj *obj = _objd_get(id);
185
186 if (!obj)
187 return -EINVAL;
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) {
193 const struct lttng_ust_objd_ops *ops = objd_ops(id);
194
195 if (ops->release)
196 ops->release(id);
197 objd_free(id);
198 }
199 return 0;
200 }
201
202 static
203 void objd_table_destroy(void)
204 {
205 int i;
206
207 for (i = 0; i < objd_table.allocated_len; i++)
208 (void) lttng_ust_objd_unref(i);
209 free(objd_table.array);
210 objd_table.array = NULL;
211 objd_table.len = 0;
212 objd_table.allocated_len = 0;
213 objd_table.freelist_head = -1;
214 }
215
216 void 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
233 /*
234 * This is LTTng's own personal way to create an ABI for sessiond.
235 * We send commands over a socket.
236 */
237
238 static const struct lttng_ust_objd_ops lttng_ops;
239 static const struct lttng_ust_objd_ops lttng_session_ops;
240 static const struct lttng_ust_objd_ops lttng_channel_ops;
241 static const struct lttng_ust_objd_ops lttng_metadata_ops;
242 static const struct lttng_ust_objd_ops lttng_enabler_ops;
243 static const struct lttng_ust_objd_ops lib_ring_buffer_objd_ops;
244 static const struct lttng_ust_objd_ops lttng_tracepoint_list_ops;
245 static const struct lttng_ust_objd_ops lttng_tracepoint_field_list_ops;
246
247 enum channel_type {
248 PER_CPU_CHANNEL,
249 METADATA_CHANNEL,
250 };
251
252 int lttng_abi_create_root_handle(void)
253 {
254 int root_handle;
255
256 /* root handles have NULL owners */
257 root_handle = objd_alloc(NULL, &lttng_ops, NULL);
258 return root_handle;
259 }
260
261 static
262 int lttng_abi_create_session(void *owner)
263 {
264 struct lttng_session *session;
265 int session_objd, ret;
266
267 session = lttng_session_create();
268 if (!session)
269 return -ENOMEM;
270 session_objd = objd_alloc(session, &lttng_session_ops, owner);
271 if (session_objd < 0) {
272 ret = session_objd;
273 goto objd_error;
274 }
275 session->objd = session_objd;
276 return session_objd;
277
278 objd_error:
279 lttng_session_destroy(session);
280 return ret;
281 }
282
283 static
284 long lttng_abi_tracer_version(int objd,
285 struct lttng_ust_tracer_version *v)
286 {
287 v->major = LTTNG_UST_INTERNAL_MAJOR_VERSION;
288 v->minor = LTTNG_UST_INTERNAL_MINOR_VERSION;
289 v->patchlevel = LTTNG_UST_INTERNAL_PATCHLEVEL_VERSION;
290 return 0;
291 }
292
293 static
294 long lttng_abi_add_context(int objd,
295 struct lttng_ust_context *context_param,
296 struct lttng_ctx **ctx, struct lttng_session *session)
297 {
298 return lttng_attach_context(context_param, ctx, session);
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
307 * @uargs: UST arguments (internal)
308 * @owner: objd owner
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
317 * LTTNG_UST_TRACEPOINT_FIELD_LIST
318 * Returns a file descriptor listing available tracepoint fields
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 */
324 static
325 long lttng_cmd(int objd, unsigned int cmd, unsigned long arg,
326 union ust_args *uargs, void *owner)
327 {
328 switch (cmd) {
329 case LTTNG_UST_SESSION:
330 return lttng_abi_create_session(owner);
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:
335 return lttng_abi_tracepoint_list(owner);
336 case LTTNG_UST_TRACEPOINT_FIELD_LIST:
337 return lttng_abi_tracepoint_field_list(owner);
338 case LTTNG_UST_WAIT_QUIESCENT:
339 synchronize_trace();
340 return 0;
341 default:
342 return -EINVAL;
343 }
344 }
345
346 static const struct lttng_ust_objd_ops lttng_ops = {
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 */
355 static
356 void lttng_metadata_create_events(int channel_objd)
357 {
358 struct lttng_channel *chan = objd_private(channel_objd);
359 struct lttng_enabler *enabler;
360 static struct lttng_ust_event metadata_params = {
361 .instrumentation = LTTNG_UST_TRACEPOINT,
362 .name = "lttng_ust:metadata",
363 .loglevel_type = LTTNG_UST_LOGLEVEL_ALL,
364 .loglevel = TRACE_DEFAULT,
365 };
366
367 /*
368 * We tolerate no failure path after event creation. It will stay
369 * invariant for the rest of the session.
370 */
371 enabler = lttng_enabler_create(LTTNG_ENABLER_EVENT,
372 &metadata_params, chan);
373 if (!enabler) {
374 goto create_error;
375 }
376 return;
377
378 create_error:
379 WARN_ON(1);
380 return; /* not allowed to return error */
381 }
382
383 int lttng_abi_create_channel(int session_objd,
384 struct lttng_ust_channel *chan_param,
385 enum channel_type channel_type,
386 union ust_args *uargs,
387 void *owner)
388 {
389 struct lttng_session *session = objd_private(session_objd);
390 const struct lttng_ust_objd_ops *ops;
391 const char *transport_name;
392 struct lttng_channel *chan;
393 int chan_objd;
394 int ret = 0;
395 struct lttng_channel chan_priv_init;
396
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>";
416 return -EINVAL;
417 }
418 chan_objd = objd_alloc(NULL, ops, owner);
419 if (chan_objd < 0) {
420 ret = chan_objd;
421 goto objd_error;
422 }
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
427 /*
428 * We tolerate no failure path after channel creation. It will stay
429 * invariant for the rest of the session.
430 */
431 chan = lttng_channel_create(session, transport_name, NULL,
432 chan_param->subbuf_size,
433 chan_param->num_subbuf,
434 chan_param->switch_timer_interval,
435 chan_param->read_timer_interval,
436 &uargs->channel.shm_fd,
437 &uargs->channel.wait_fd,
438 &uargs->channel.memory_map_size,
439 &chan_priv_init);
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 }
450 /* The channel created holds a reference on the session */
451 objd_ref(session_objd);
452
453 return chan_objd;
454
455 chan_error:
456 {
457 int err;
458
459 err = lttng_ust_objd_unref(chan_objd);
460 assert(!err);
461 }
462 objd_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
472 * @uargs: UST arguments (internal)
473 * @owner: objd owner
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 */
487 static
488 long lttng_session_cmd(int objd, unsigned int cmd, unsigned long arg,
489 union ust_args *uargs, void *owner)
490 {
491 struct lttng_session *session = objd_private(objd);
492
493 switch (cmd) {
494 case LTTNG_UST_CHANNEL:
495 return lttng_abi_create_channel(objd,
496 (struct lttng_ust_channel *) arg,
497 PER_CPU_CHANNEL, uargs, owner);
498 case LTTNG_UST_SESSION_START:
499 case LTTNG_UST_ENABLE:
500 return lttng_session_enable(session);
501 case LTTNG_UST_SESSION_STOP:
502 case LTTNG_UST_DISABLE:
503 return lttng_session_disable(session);
504 case LTTNG_UST_METADATA:
505 return lttng_abi_create_channel(objd,
506 (struct lttng_ust_channel *) arg,
507 METADATA_CHANNEL, uargs, owner);
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 */
521 static
522 int lttng_release_session(int objd)
523 {
524 struct lttng_session *session = objd_private(objd);
525
526 if (session) {
527 lttng_session_destroy(session);
528 return 0;
529 } else {
530 return -EINVAL;
531 }
532 }
533
534 static const struct lttng_ust_objd_ops lttng_session_ops = {
535 .release = lttng_release_session,
536 .cmd = lttng_session_cmd,
537 };
538
539 static
540 long lttng_tracepoint_list_cmd(int objd, unsigned int cmd, unsigned long arg,
541 union ust_args *uargs, void *owner)
542 {
543 struct lttng_ust_tracepoint_list *list = objd_private(objd);
544 struct lttng_ust_tracepoint_iter *tp =
545 (struct lttng_ust_tracepoint_iter *) arg;
546 struct lttng_ust_tracepoint_iter *iter;
547
548 switch (cmd) {
549 case LTTNG_UST_TRACEPOINT_LIST_GET:
550 {
551 retry:
552 iter = lttng_ust_tracepoint_list_get_iter_next(list);
553 if (!iter)
554 return -LTTNG_UST_ERR_NOENT;
555 if (!strcmp(iter->name, "lttng_ust:metadata"))
556 goto retry;
557 memcpy(tp, iter, sizeof(*tp));
558 return 0;
559 }
560 default:
561 return -EINVAL;
562 }
563 }
564
565 static
566 int lttng_abi_tracepoint_list(void *owner)
567 {
568 int list_objd, ret;
569 struct lttng_ust_tracepoint_list *list;
570
571 list_objd = objd_alloc(NULL, &lttng_tracepoint_list_ops, owner);
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
583 /* populate list by walking on all registered probes. */
584 ret = lttng_probes_get_event_list(list);
585 if (ret) {
586 goto list_error;
587 }
588 return list_objd;
589
590 list_error:
591 free(list);
592 alloc_error:
593 {
594 int err;
595
596 err = lttng_ust_objd_unref(list_objd);
597 assert(!err);
598 }
599 objd_error:
600 return ret;
601 }
602
603 static
604 int lttng_release_tracepoint_list(int objd)
605 {
606 struct lttng_ust_tracepoint_list *list = objd_private(objd);
607
608 if (list) {
609 lttng_probes_prune_event_list(list);
610 free(list);
611 return 0;
612 } else {
613 return -EINVAL;
614 }
615 }
616
617 static const struct lttng_ust_objd_ops lttng_tracepoint_list_ops = {
618 .release = lttng_release_tracepoint_list,
619 .cmd = lttng_tracepoint_list_cmd,
620 };
621
622 static
623 long lttng_tracepoint_field_list_cmd(int objd, unsigned int cmd,
624 unsigned long arg, union ust_args *uargs, void *owner)
625 {
626 struct lttng_ust_field_list *list = objd_private(objd);
627 struct lttng_ust_field_iter *tp = &uargs->field_list.entry;
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)
636 return -LTTNG_UST_ERR_NOENT;
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
647 static
648 int lttng_abi_tracepoint_field_list(void *owner)
649 {
650 int list_objd, ret;
651 struct lttng_ust_field_list *list;
652
653 list_objd = objd_alloc(NULL, &lttng_tracepoint_field_list_ops, owner);
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. */
666 ret = lttng_probes_get_field_list(list);
667 if (ret) {
668 goto list_error;
669 }
670 return list_objd;
671
672 list_error:
673 free(list);
674 alloc_error:
675 {
676 int err;
677
678 err = lttng_ust_objd_unref(list_objd);
679 assert(!err);
680 }
681 objd_error:
682 return ret;
683 }
684
685 static
686 int lttng_release_tracepoint_field_list(int objd)
687 {
688 struct lttng_ust_field_list *list = objd_private(objd);
689
690 if (list) {
691 lttng_probes_prune_field_list(list);
692 free(list);
693 return 0;
694 } else {
695 return -EINVAL;
696 }
697 }
698
699 static 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
704 struct stream_priv_data {
705 struct lttng_ust_lib_ring_buffer *buf;
706 struct lttng_channel *lttng_chan;
707 };
708
709 static
710 int lttng_abi_open_stream(int channel_objd, struct lttng_ust_stream *info,
711 union ust_args *uargs, void *owner)
712 {
713 struct lttng_channel *channel = objd_private(channel_objd);
714 struct lttng_ust_lib_ring_buffer *buf;
715 struct stream_priv_data *priv;
716 int stream_objd, ret;
717
718 buf = channel->ops->buffer_read_open(channel->chan, channel->handle,
719 &uargs->stream.shm_fd,
720 &uargs->stream.wait_fd,
721 &uargs->stream.memory_map_size);
722 if (!buf)
723 return -ENOENT;
724
725 priv = zmalloc(sizeof(*priv));
726 if (!priv) {
727 ret = -ENOMEM;
728 goto alloc_error;
729 }
730 priv->buf = buf;
731 priv->lttng_chan = channel;
732 stream_objd = objd_alloc(priv, &lib_ring_buffer_objd_ops, owner);
733 if (stream_objd < 0) {
734 ret = stream_objd;
735 goto objd_error;
736 }
737 /* Hold a reference on the channel object descriptor */
738 objd_ref(channel_objd);
739 return stream_objd;
740
741 objd_error:
742 free(priv);
743 alloc_error:
744 channel->ops->buffer_read_close(buf, channel->handle);
745 return ret;
746 }
747
748 static
749 int lttng_abi_create_enabler(int channel_objd,
750 struct lttng_ust_event *event_param,
751 void *owner,
752 enum lttng_enabler_type type)
753 {
754 struct lttng_channel *channel = objd_private(channel_objd);
755 struct lttng_enabler *enabler;
756 int event_objd, ret;
757
758 event_param->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
759 event_objd = objd_alloc(NULL, &lttng_enabler_ops, owner);
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 */
768 enabler = lttng_enabler_create(type, event_param, channel);
769 if (!enabler) {
770 ret = -ENOMEM;
771 goto event_error;
772 }
773 objd_set_private(event_objd, enabler);
774 /* The event holds a reference on the channel */
775 objd_ref(channel_objd);
776 return event_objd;
777
778 event_error:
779 {
780 int err;
781
782 err = lttng_ust_objd_unref(event_objd);
783 assert(!err);
784 }
785 objd_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
795 * @uargs: UST arguments (internal)
796 * @owner: objd owner
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 */
813 static
814 long lttng_channel_cmd(int objd, unsigned int cmd, unsigned long arg,
815 union ust_args *uargs, void *owner)
816 {
817 struct lttng_channel *channel = objd_private(objd);
818
819 switch (cmd) {
820 case LTTNG_UST_STREAM:
821 {
822 struct lttng_ust_stream *stream;
823
824 stream = (struct lttng_ust_stream *) arg;
825 /* stream used as output */
826 return lttng_abi_open_stream(objd, stream, uargs, owner);
827 }
828 case LTTNG_UST_EVENT:
829 {
830 struct lttng_ust_event *event_param =
831 (struct lttng_ust_event *) arg;
832 if (event_param->name[strlen(event_param->name) - 1] == '*') {
833 /* If ends with wildcard, create wildcard. */
834 return lttng_abi_create_enabler(objd, event_param,
835 owner, LTTNG_ENABLER_WILDCARD);
836 } else {
837 return lttng_abi_create_enabler(objd, event_param,
838 owner, LTTNG_ENABLER_EVENT);
839 }
840 }
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:
846 return lttng_channel_enable(channel);
847 case LTTNG_UST_DISABLE:
848 return lttng_channel_disable(channel);
849 case LTTNG_UST_FLUSH_BUFFER:
850 return channel->ops->flush_buffer(channel->chan, channel->handle);
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
862 * @uargs: UST arguments (internal)
863 * @owner: objd owner
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 */
871 static
872 long lttng_metadata_cmd(int objd, unsigned int cmd, unsigned long arg,
873 union ust_args *uargs, void *owner)
874 {
875 struct lttng_channel *channel = objd_private(objd);
876
877 switch (cmd) {
878 case LTTNG_UST_STREAM:
879 {
880 struct lttng_ust_stream *stream;
881
882 stream = (struct lttng_ust_stream *) arg;
883 /* stream used as output */
884 return lttng_abi_open_stream(objd, stream, uargs, owner);
885 }
886 case LTTNG_UST_FLUSH_BUFFER:
887 return channel->ops->flush_buffer(channel->chan, channel->handle);
888 default:
889 return -EINVAL;
890 }
891 }
892
893 static
894 int lttng_channel_release(int objd)
895 {
896 struct lttng_channel *channel = objd_private(objd);
897
898 if (channel)
899 return lttng_ust_objd_unref(channel->session->objd);
900 return 0;
901 }
902
903 static const struct lttng_ust_objd_ops lttng_channel_ops = {
904 .release = lttng_channel_release,
905 .cmd = lttng_channel_cmd,
906 };
907
908 static const struct lttng_ust_objd_ops lttng_metadata_ops = {
909 .release = lttng_channel_release,
910 .cmd = lttng_metadata_cmd,
911 };
912
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
919 * @uargs: UST arguments (internal)
920 * @owner: objd owner
921 *
922 * This object descriptor implements lttng commands:
923 * (None for now. Access is done directly though shm.)
924 */
925 static
926 long lttng_rb_cmd(int objd, unsigned int cmd, unsigned long arg,
927 union ust_args *uargs, void *owner)
928 {
929 switch (cmd) {
930 default:
931 return -EINVAL;
932 }
933 }
934
935 static
936 int lttng_rb_release(int objd)
937 {
938 struct stream_priv_data *priv = objd_private(objd);
939 struct lttng_ust_lib_ring_buffer *buf;
940 struct lttng_channel *channel;
941
942 if (priv) {
943 buf = priv->buf;
944 channel = priv->lttng_chan;
945 free(priv);
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);
961
962 return lttng_ust_objd_unref(channel->objd);
963 }
964 return 0;
965 }
966
967 static const struct lttng_ust_objd_ops lib_ring_buffer_objd_ops = {
968 .release = lttng_rb_release,
969 .cmd = lttng_rb_cmd,
970 };
971
972 /**
973 * lttng_enabler_cmd - lttng control through object descriptors
974 *
975 * @objd: the object descriptor
976 * @cmd: the command
977 * @arg: command arg
978 * @uargs: UST arguments (internal)
979 * @owner: objd owner
980 *
981 * This object descriptor implements lttng commands:
982 * LTTNG_UST_CONTEXT
983 * Prepend a context field to each record of events of this
984 * enabler.
985 * LTTNG_UST_ENABLE
986 * Enable recording for this enabler
987 * LTTNG_UST_DISABLE
988 * Disable recording for this enabler
989 * LTTNG_UST_FILTER
990 * Attach a filter to an enabler.
991 */
992 static
993 long lttng_enabler_cmd(int objd, unsigned int cmd, unsigned long arg,
994 union ust_args *uargs, void *owner)
995 {
996 struct lttng_enabler *enabler = objd_private(objd);
997
998 switch (cmd) {
999 case LTTNG_UST_CONTEXT:
1000 return lttng_enabler_attach_context(enabler,
1001 (struct lttng_ust_context *) arg);
1002 case LTTNG_UST_ENABLE:
1003 return lttng_enabler_enable(enabler);
1004 case LTTNG_UST_DISABLE:
1005 return lttng_enabler_disable(enabler);
1006 case LTTNG_UST_FILTER:
1007 {
1008 int ret;
1009
1010 ret = lttng_enabler_attach_bytecode(enabler,
1011 (struct lttng_ust_filter_bytecode_node *) arg);
1012 if (ret)
1013 return ret;
1014 return 0;
1015 }
1016 default:
1017 return -EINVAL;
1018 }
1019 }
1020
1021 static
1022 int lttng_enabler_release(int objd)
1023 {
1024 struct lttng_enabler *enabler = objd_private(objd);
1025
1026 if (enabler)
1027 return lttng_ust_objd_unref(enabler->chan->objd);
1028 return 0;
1029 }
1030
1031 static const struct lttng_ust_objd_ops lttng_enabler_ops = {
1032 .release = lttng_enabler_release,
1033 .cmd = lttng_enabler_cmd,
1034 };
1035
1036 void lttng_ust_abi_exit(void)
1037 {
1038 lttng_ust_abi_close_in_progress = 1;
1039 objd_table_destroy();
1040 lttng_ust_abi_close_in_progress = 0;
1041 }
This page took 0.054152 seconds and 5 git commands to generate.