Filter iteration: iterate on list of filters
[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 "ltt-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_event_ops;
243 static const struct lttng_ust_objd_ops lttng_wildcard_ops;
244 static const struct lttng_ust_objd_ops lib_ring_buffer_objd_ops;
245 static const struct lttng_ust_objd_ops lttng_tracepoint_list_ops;
246 static const struct lttng_ust_objd_ops lttng_tracepoint_field_list_ops;
247
248 enum channel_type {
249 PER_CPU_CHANNEL,
250 METADATA_CHANNEL,
251 };
252
253 int lttng_abi_create_root_handle(void)
254 {
255 int root_handle;
256
257 /* root handles have NULL owners */
258 root_handle = objd_alloc(NULL, &lttng_ops, NULL);
259 return root_handle;
260 }
261
262 static
263 int lttng_abi_create_session(void *owner)
264 {
265 struct ltt_session *session;
266 int session_objd, ret;
267
268 session = ltt_session_create();
269 if (!session)
270 return -ENOMEM;
271 session_objd = objd_alloc(session, &lttng_session_ops, owner);
272 if (session_objd < 0) {
273 ret = session_objd;
274 goto objd_error;
275 }
276 session->objd = session_objd;
277 return session_objd;
278
279 objd_error:
280 ltt_session_destroy(session);
281 return ret;
282 }
283
284 static
285 long lttng_abi_tracer_version(int objd,
286 struct lttng_ust_tracer_version *v)
287 {
288 v->major = LTTNG_UST_INTERNAL_MAJOR_VERSION;
289 v->minor = LTTNG_UST_INTERNAL_MINOR_VERSION;
290 v->patchlevel = LTTNG_UST_INTERNAL_PATCHLEVEL_VERSION;
291 return 0;
292 }
293
294 static
295 long lttng_abi_add_context(int objd,
296 struct lttng_ust_context *context_param,
297 struct lttng_ctx **ctx, struct ltt_session *session)
298 {
299 if (session->been_active)
300 return -EPERM;
301
302 switch (context_param->ctx) {
303 case LTTNG_UST_CONTEXT_PTHREAD_ID:
304 return lttng_add_pthread_id_to_ctx(ctx);
305 case LTTNG_UST_CONTEXT_VTID:
306 return lttng_add_vtid_to_ctx(ctx);
307 case LTTNG_UST_CONTEXT_VPID:
308 return lttng_add_vpid_to_ctx(ctx);
309 case LTTNG_UST_CONTEXT_PROCNAME:
310 return lttng_add_procname_to_ctx(ctx);
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
322 * @uargs: UST arguments (internal)
323 * @owner: objd owner
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
332 * LTTNG_UST_TRACEPOINT_FIELD_LIST
333 * Returns a file descriptor listing available tracepoint fields
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 */
339 static
340 long lttng_cmd(int objd, unsigned int cmd, unsigned long arg,
341 union ust_args *uargs, void *owner)
342 {
343 switch (cmd) {
344 case LTTNG_UST_SESSION:
345 return lttng_abi_create_session(owner);
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:
350 return lttng_abi_tracepoint_list(owner);
351 case LTTNG_UST_TRACEPOINT_FIELD_LIST:
352 return lttng_abi_tracepoint_field_list(owner);
353 case LTTNG_UST_WAIT_QUIESCENT:
354 synchronize_trace();
355 return 0;
356 default:
357 return -EINVAL;
358 }
359 }
360
361 static const struct lttng_ust_objd_ops lttng_ops = {
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 */
370 static
371 void lttng_metadata_create_events(int channel_objd)
372 {
373 struct ltt_channel *channel = objd_private(channel_objd);
374 static struct lttng_ust_event metadata_params = {
375 .instrumentation = LTTNG_UST_TRACEPOINT,
376 .name = "lttng_ust:metadata",
377 .loglevel_type = LTTNG_UST_LOGLEVEL_ALL,
378 .loglevel = TRACE_DEFAULT,
379 };
380 struct ltt_event *event;
381 int ret;
382
383 /*
384 * We tolerate no failure path after event creation. It will stay
385 * invariant for the rest of the session.
386 */
387 ret = ltt_event_create(channel, &metadata_params, &event);
388 if (ret < 0) {
389 goto create_error;
390 }
391 return;
392
393 create_error:
394 WARN_ON(1);
395 return; /* not allowed to return error */
396 }
397
398 int lttng_abi_create_channel(int session_objd,
399 struct lttng_ust_channel *chan_param,
400 enum channel_type channel_type,
401 union ust_args *uargs,
402 void *owner)
403 {
404 struct ltt_session *session = objd_private(session_objd);
405 const struct lttng_ust_objd_ops *ops;
406 const char *transport_name;
407 struct ltt_channel *chan;
408 int chan_objd;
409 int ret = 0;
410 struct ltt_channel chan_priv_init;
411
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>";
431 return -EINVAL;
432 }
433 chan_objd = objd_alloc(NULL, ops, owner);
434 if (chan_objd < 0) {
435 ret = chan_objd;
436 goto objd_error;
437 }
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
442 /*
443 * We tolerate no failure path after channel creation. It will stay
444 * invariant for the rest of the session.
445 */
446 chan = ltt_channel_create(session, transport_name, NULL,
447 chan_param->subbuf_size,
448 chan_param->num_subbuf,
449 chan_param->switch_timer_interval,
450 chan_param->read_timer_interval,
451 &uargs->channel.shm_fd,
452 &uargs->channel.wait_fd,
453 &uargs->channel.memory_map_size,
454 &chan_priv_init);
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 }
465 /* The channel created holds a reference on the session */
466 objd_ref(session_objd);
467
468 return chan_objd;
469
470 chan_error:
471 {
472 int err;
473
474 err = lttng_ust_objd_unref(chan_objd);
475 assert(!err);
476 }
477 objd_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
487 * @uargs: UST arguments (internal)
488 * @owner: objd owner
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 */
502 static
503 long lttng_session_cmd(int objd, unsigned int cmd, unsigned long arg,
504 union ust_args *uargs, void *owner)
505 {
506 struct ltt_session *session = objd_private(objd);
507
508 switch (cmd) {
509 case LTTNG_UST_CHANNEL:
510 return lttng_abi_create_channel(objd,
511 (struct lttng_ust_channel *) arg,
512 PER_CPU_CHANNEL, uargs, owner);
513 case LTTNG_UST_SESSION_START:
514 case LTTNG_UST_ENABLE:
515 return ltt_session_enable(session);
516 case LTTNG_UST_SESSION_STOP:
517 case LTTNG_UST_DISABLE:
518 return ltt_session_disable(session);
519 case LTTNG_UST_METADATA:
520 return lttng_abi_create_channel(objd,
521 (struct lttng_ust_channel *) arg,
522 METADATA_CHANNEL, uargs, owner);
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 */
536 static
537 int lttng_release_session(int objd)
538 {
539 struct ltt_session *session = objd_private(objd);
540
541 if (session) {
542 ltt_session_destroy(session);
543 return 0;
544 } else {
545 return -EINVAL;
546 }
547 }
548
549 static const struct lttng_ust_objd_ops lttng_session_ops = {
550 .release = lttng_release_session,
551 .cmd = lttng_session_cmd,
552 };
553
554 static
555 long lttng_tracepoint_list_cmd(int objd, unsigned int cmd, unsigned long arg,
556 union ust_args *uargs, void *owner)
557 {
558 struct lttng_ust_tracepoint_list *list = objd_private(objd);
559 struct lttng_ust_tracepoint_iter *tp =
560 (struct lttng_ust_tracepoint_iter *) arg;
561 struct lttng_ust_tracepoint_iter *iter;
562
563 switch (cmd) {
564 case LTTNG_UST_TRACEPOINT_LIST_GET:
565 {
566 retry:
567 iter = lttng_ust_tracepoint_list_get_iter_next(list);
568 if (!iter)
569 return -LTTNG_UST_ERR_NOENT;
570 if (!strcmp(iter->name, "lttng_ust:metadata"))
571 goto retry;
572 memcpy(tp, iter, sizeof(*tp));
573 return 0;
574 }
575 default:
576 return -EINVAL;
577 }
578 }
579
580 static
581 int lttng_abi_tracepoint_list(void *owner)
582 {
583 int list_objd, ret;
584 struct lttng_ust_tracepoint_list *list;
585
586 list_objd = objd_alloc(NULL, &lttng_tracepoint_list_ops, owner);
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
598 /* populate list by walking on all registered probes. */
599 ret = ltt_probes_get_event_list(list);
600 if (ret) {
601 goto list_error;
602 }
603 return list_objd;
604
605 list_error:
606 free(list);
607 alloc_error:
608 {
609 int err;
610
611 err = lttng_ust_objd_unref(list_objd);
612 assert(!err);
613 }
614 objd_error:
615 return ret;
616 }
617
618 static
619 int lttng_release_tracepoint_list(int objd)
620 {
621 struct lttng_ust_tracepoint_list *list = objd_private(objd);
622
623 if (list) {
624 ltt_probes_prune_event_list(list);
625 free(list);
626 return 0;
627 } else {
628 return -EINVAL;
629 }
630 }
631
632 static const struct lttng_ust_objd_ops lttng_tracepoint_list_ops = {
633 .release = lttng_release_tracepoint_list,
634 .cmd = lttng_tracepoint_list_cmd,
635 };
636
637 static
638 long lttng_tracepoint_field_list_cmd(int objd, unsigned int cmd,
639 unsigned long arg, union ust_args *uargs, void *owner)
640 {
641 struct lttng_ust_field_list *list = objd_private(objd);
642 struct lttng_ust_field_iter *tp = &uargs->field_list.entry;
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)
651 return -LTTNG_UST_ERR_NOENT;
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
662 static
663 int lttng_abi_tracepoint_field_list(void *owner)
664 {
665 int list_objd, ret;
666 struct lttng_ust_field_list *list;
667
668 list_objd = objd_alloc(NULL, &lttng_tracepoint_field_list_ops, owner);
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. */
681 ret = ltt_probes_get_field_list(list);
682 if (ret) {
683 goto list_error;
684 }
685 return list_objd;
686
687 list_error:
688 free(list);
689 alloc_error:
690 {
691 int err;
692
693 err = lttng_ust_objd_unref(list_objd);
694 assert(!err);
695 }
696 objd_error:
697 return ret;
698 }
699
700 static
701 int lttng_release_tracepoint_field_list(int objd)
702 {
703 struct lttng_ust_field_list *list = objd_private(objd);
704
705 if (list) {
706 ltt_probes_prune_field_list(list);
707 free(list);
708 return 0;
709 } else {
710 return -EINVAL;
711 }
712 }
713
714 static 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
719 struct stream_priv_data {
720 struct lttng_ust_lib_ring_buffer *buf;
721 struct ltt_channel *ltt_chan;
722 };
723
724 static
725 int lttng_abi_open_stream(int channel_objd, struct lttng_ust_stream *info,
726 union ust_args *uargs, void *owner)
727 {
728 struct ltt_channel *channel = objd_private(channel_objd);
729 struct lttng_ust_lib_ring_buffer *buf;
730 struct stream_priv_data *priv;
731 int stream_objd, ret;
732
733 buf = channel->ops->buffer_read_open(channel->chan, channel->handle,
734 &uargs->stream.shm_fd,
735 &uargs->stream.wait_fd,
736 &uargs->stream.memory_map_size);
737 if (!buf)
738 return -ENOENT;
739
740 priv = zmalloc(sizeof(*priv));
741 if (!priv) {
742 ret = -ENOMEM;
743 goto alloc_error;
744 }
745 priv->buf = buf;
746 priv->ltt_chan = channel;
747 stream_objd = objd_alloc(priv, &lib_ring_buffer_objd_ops, owner);
748 if (stream_objd < 0) {
749 ret = stream_objd;
750 goto objd_error;
751 }
752 /* Hold a reference on the channel object descriptor */
753 objd_ref(channel_objd);
754 return stream_objd;
755
756 objd_error:
757 free(priv);
758 alloc_error:
759 channel->ops->buffer_read_close(buf, channel->handle);
760 return ret;
761 }
762
763 static
764 int lttng_abi_create_event(int channel_objd,
765 struct lttng_ust_event *event_param,
766 void *owner)
767 {
768 struct ltt_channel *channel = objd_private(channel_objd);
769 struct ltt_event *event;
770 int event_objd, ret;
771
772 event_param->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
773 event_objd = objd_alloc(NULL, &lttng_event_ops, owner);
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 */
782 ret = ltt_event_create(channel, event_param, &event);
783 if (ret < 0) {
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
791 event_error:
792 {
793 int err;
794
795 err = lttng_ust_objd_unref(event_objd);
796 assert(!err);
797 }
798 objd_error:
799 return ret;
800 }
801
802 static
803 int lttng_abi_create_wildcard(int channel_objd,
804 struct lttng_ust_event *event_param,
805 void *owner)
806 {
807 struct ltt_channel *channel = objd_private(channel_objd);
808 struct session_wildcard *wildcard;
809 int wildcard_objd, ret;
810
811 event_param->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
812 wildcard_objd = objd_alloc(NULL, &lttng_wildcard_ops, owner);
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 */
821 ret = ltt_wildcard_create(channel, event_param, &wildcard);
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
830 wildcard_error:
831 {
832 int err;
833
834 err = lttng_ust_objd_unref(wildcard_objd);
835 assert(!err);
836 }
837 objd_error:
838 return ret;
839 }
840
841 /**
842 * lttng_channel_cmd - lttng control through object descriptors
843 *
844 * @objd: the object descriptor
845 * @cmd: the command
846 * @arg: command arg
847 * @uargs: UST arguments (internal)
848 * @owner: objd owner
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 */
865 static
866 long lttng_channel_cmd(int objd, unsigned int cmd, unsigned long arg,
867 union ust_args *uargs, void *owner)
868 {
869 struct ltt_channel *channel = objd_private(objd);
870
871 switch (cmd) {
872 case LTTNG_UST_STREAM:
873 {
874 struct lttng_ust_stream *stream;
875
876 stream = (struct lttng_ust_stream *) arg;
877 /* stream used as output */
878 return lttng_abi_open_stream(objd, stream, uargs, owner);
879 }
880 case LTTNG_UST_EVENT:
881 {
882 struct lttng_ust_event *event_param =
883 (struct lttng_ust_event *) arg;
884 if (event_param->name[strlen(event_param->name) - 1] == '*') {
885 /* If ends with wildcard, create wildcard. */
886 return lttng_abi_create_wildcard(objd, event_param,
887 owner);
888 } else {
889 return lttng_abi_create_event(objd, event_param,
890 owner);
891 }
892 }
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:
898 return ltt_channel_enable(channel);
899 case LTTNG_UST_DISABLE:
900 return ltt_channel_disable(channel);
901 case LTTNG_UST_FLUSH_BUFFER:
902 return channel->ops->flush_buffer(channel->chan, channel->handle);
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
914 * @uargs: UST arguments (internal)
915 * @owner: objd owner
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 */
923 static
924 long lttng_metadata_cmd(int objd, unsigned int cmd, unsigned long arg,
925 union ust_args *uargs, void *owner)
926 {
927 struct ltt_channel *channel = objd_private(objd);
928
929 switch (cmd) {
930 case LTTNG_UST_STREAM:
931 {
932 struct lttng_ust_stream *stream;
933
934 stream = (struct lttng_ust_stream *) arg;
935 /* stream used as output */
936 return lttng_abi_open_stream(objd, stream, uargs, owner);
937 }
938 case LTTNG_UST_FLUSH_BUFFER:
939 return channel->ops->flush_buffer(channel->chan, channel->handle);
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 */
952 unsigned int lttng_channel_poll(struct file *file, poll_table *wait)
953 {
954 struct ltt_channel *channel = file->private_data;
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
975 static
976 int lttng_channel_release(int objd)
977 {
978 struct ltt_channel *channel = objd_private(objd);
979
980 if (channel)
981 return lttng_ust_objd_unref(channel->session->objd);
982 return 0;
983 }
984
985 static const struct lttng_ust_objd_ops lttng_channel_ops = {
986 .release = lttng_channel_release,
987 //.poll = lttng_channel_poll,
988 .cmd = lttng_channel_cmd,
989 };
990
991 static const struct lttng_ust_objd_ops lttng_metadata_ops = {
992 .release = lttng_channel_release,
993 .cmd = lttng_metadata_cmd,
994 };
995
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
1002 * @uargs: UST arguments (internal)
1003 * @owner: objd owner
1004 *
1005 * This object descriptor implements lttng commands:
1006 * (None for now. Access is done directly though shm.)
1007 */
1008 static
1009 long lttng_rb_cmd(int objd, unsigned int cmd, unsigned long arg,
1010 union ust_args *uargs, void *owner)
1011 {
1012 switch (cmd) {
1013 default:
1014 return -EINVAL;
1015 }
1016 }
1017
1018 static
1019 int lttng_rb_release(int objd)
1020 {
1021 struct stream_priv_data *priv = objd_private(objd);
1022 struct lttng_ust_lib_ring_buffer *buf;
1023 struct ltt_channel *channel;
1024
1025 if (priv) {
1026 buf = priv->buf;
1027 channel = priv->ltt_chan;
1028 free(priv);
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);
1044
1045 return lttng_ust_objd_unref(channel->objd);
1046 }
1047 return 0;
1048 }
1049
1050 static const struct lttng_ust_objd_ops lib_ring_buffer_objd_ops = {
1051 .release = lttng_rb_release,
1052 .cmd = lttng_rb_cmd,
1053 };
1054
1055 /**
1056 * lttng_event_cmd - lttng control through object descriptors
1057 *
1058 * @objd: the object descriptor
1059 * @cmd: the command
1060 * @arg: command arg
1061 * @uargs: UST arguments (internal)
1062 * @owner: objd owner
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)
1071 * LTTNG_UST_FILTER
1072 * Attach a filter to an event.
1073 */
1074 static
1075 long lttng_event_cmd(int objd, unsigned int cmd, unsigned long arg,
1076 union ust_args *uargs, void *owner)
1077 {
1078 struct ltt_event *event = objd_private(objd);
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:
1086 return ltt_event_enable(event);
1087 case LTTNG_UST_DISABLE:
1088 return ltt_event_disable(event);
1089 case LTTNG_UST_FILTER:
1090 {
1091 int ret;
1092 ret = lttng_filter_event_attach_bytecode(event,
1093 (struct lttng_ust_filter_bytecode_node *) arg);
1094 if (ret)
1095 return ret;
1096 lttng_filter_event_link_bytecode(event);
1097 return 0;
1098 }
1099 default:
1100 return -EINVAL;
1101 }
1102 }
1103
1104 static
1105 int lttng_event_release(int objd)
1106 {
1107 struct ltt_event *event = objd_private(objd);
1108
1109 if (event)
1110 return lttng_ust_objd_unref(event->chan->objd);
1111 return 0;
1112 }
1113
1114 /* TODO: filter control ioctl */
1115 static const struct lttng_ust_objd_ops lttng_event_ops = {
1116 .release = lttng_event_release,
1117 .cmd = lttng_event_cmd,
1118 };
1119
1120 /**
1121 * lttng_wildcard_cmd - lttng control through object descriptors
1122 *
1123 * @objd: the object descriptor
1124 * @cmd: the command
1125 * @arg: command arg
1126 * @uargs: UST arguments (internal)
1127 * @owner: objd owner
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)
1137 * LTTNG_UST_FILTER
1138 * Attach a filter to a wildcard.
1139 */
1140 static
1141 long lttng_wildcard_cmd(int objd, unsigned int cmd, unsigned long arg,
1142 union ust_args *uargs, void *owner)
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:
1155 return ltt_wildcard_enable(wildcard);
1156 case LTTNG_UST_DISABLE:
1157 return ltt_wildcard_disable(wildcard);
1158 case LTTNG_UST_FILTER:
1159 {
1160 int ret;
1161
1162 ret = lttng_filter_wildcard_attach_bytecode(wildcard,
1163 (struct lttng_ust_filter_bytecode_node *) arg);
1164 if (ret)
1165 return ret;
1166 lttng_filter_wildcard_link_bytecode(wildcard);
1167 return 0;
1168 }
1169 default:
1170 return -EINVAL;
1171 }
1172 }
1173
1174 static
1175 int 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 */
1185 static const struct lttng_ust_objd_ops lttng_wildcard_ops = {
1186 .release = lttng_wildcard_release,
1187 .cmd = lttng_wildcard_cmd,
1188 };
1189
1190 void lttng_ust_abi_exit(void)
1191 {
1192 lttng_ust_abi_close_in_progress = 1;
1193 objd_table_destroy();
1194 lttng_ust_abi_close_in_progress = 0;
1195 }
This page took 0.085702 seconds and 5 git commands to generate.